summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilliam Wilgus <me.theuser@yahoo.com>2019-01-04 02:01:18 -0600
committerSolomon Peachy <pizza@shaftnet.org>2021-04-23 14:23:04 +0000
commit14c6bb798d6bebc80f07e863236adbaf8d156a9c (patch)
tree551a4b641906c2626af844fa3239c1b2b1ff0ad3
parent75d93937965ec4df70d37df6d4feea04577c996b (diff)
downloadrockbox-14c6bb798d6bebc80f07e863236adbaf8d156a9c.tar.gz
rockbox-14c6bb798d6bebc80f07e863236adbaf8d156a9c.zip
Sync opus codec to upstream git
Change-Id: I0cfcc0005c4ad7bfbb1aaf454188ce70fb043dc1
-rw-r--r--lib/rbcodec/codecs/libopus/README.rockbox16
-rw-r--r--lib/rbcodec/codecs/libopus/SOURCES2
-rw-r--r--lib/rbcodec/codecs/libopus/analysis.c945
-rw-r--r--lib/rbcodec/codecs/libopus/analysis.h102
-rw-r--r--lib/rbcodec/codecs/libopus/celt/_kiss_fft_guts.h21
-rw-r--r--lib/rbcodec/codecs/libopus/celt/arch.h66
-rwxr-xr-xlib/rbcodec/codecs/libopus/celt/arm/arm2gnu.pl353
-rw-r--r--lib/rbcodec/codecs/libopus/celt/arm/arm_celt_map.c160
-rw-r--r--lib/rbcodec/codecs/libopus/celt/arm/armcpu.c185
-rw-r--r--lib/rbcodec/codecs/libopus/celt/arm/armcpu.h77
-rw-r--r--lib/rbcodec/codecs/libopus/celt/arm/armopts.s.in37
-rw-r--r--lib/rbcodec/codecs/libopus/celt/arm/celt_fft_ne10.c173
-rw-r--r--lib/rbcodec/codecs/libopus/celt/arm/celt_mdct_ne10.c258
-rw-r--r--lib/rbcodec/codecs/libopus/celt/arm/celt_neon_intr.c211
-rw-r--r--lib/rbcodec/codecs/libopus/celt/arm/celt_pitch_xcorr_arm.s551
-rw-r--r--lib/rbcodec/codecs/libopus/celt/arm/fft_arm.h71
-rw-r--r--lib/rbcodec/codecs/libopus/celt/arm/fixed_arm64.h35
-rw-r--r--lib/rbcodec/codecs/libopus/celt/arm/fixed_armv4.h6
-rw-r--r--lib/rbcodec/codecs/libopus/celt/arm/fixed_armv5e.h4
-rw-r--r--lib/rbcodec/codecs/libopus/celt/arm/mdct_arm.h59
-rw-r--r--lib/rbcodec/codecs/libopus/celt/arm/pitch_arm.h160
-rw-r--r--lib/rbcodec/codecs/libopus/celt/arm/pitch_neon_intr.c290
-rw-r--r--lib/rbcodec/codecs/libopus/celt/bands.c351
-rw-r--r--lib/rbcodec/codecs/libopus/celt/bands.h26
-rw-r--r--lib/rbcodec/codecs/libopus/celt/celt.c44
-rw-r--r--lib/rbcodec/codecs/libopus/celt/celt.h44
-rw-r--r--lib/rbcodec/codecs/libopus/celt/celt_decoder.c263
-rw-r--r--lib/rbcodec/codecs/libopus/celt/celt_encoder.c2607
-rw-r--r--lib/rbcodec/codecs/libopus/celt/celt_lpc.c73
-rw-r--r--lib/rbcodec/codecs/libopus/celt/celt_lpc.h18
-rw-r--r--lib/rbcodec/codecs/libopus/celt/cpu_support.h20
-rw-r--r--lib/rbcodec/codecs/libopus/celt/cwrs.c8
-rw-r--r--lib/rbcodec/codecs/libopus/celt/dump_modes/Makefile32
-rw-r--r--lib/rbcodec/codecs/libopus/celt/dump_modes/dump_modes.c353
-rw-r--r--lib/rbcodec/codecs/libopus/celt/dump_modes/dump_modes_arch.h45
-rw-r--r--lib/rbcodec/codecs/libopus/celt/dump_modes/dump_modes_arm_ne10.c152
-rw-r--r--lib/rbcodec/codecs/libopus/celt/entcode.c2
-rw-r--r--lib/rbcodec/codecs/libopus/celt/entcode.h4
-rw-r--r--lib/rbcodec/codecs/libopus/celt/entdec.h2
-rw-r--r--lib/rbcodec/codecs/libopus/celt/entenc.c2
-rw-r--r--lib/rbcodec/codecs/libopus/celt/entenc.h2
-rw-r--r--lib/rbcodec/codecs/libopus/celt/fixed_c5x.h79
-rw-r--r--lib/rbcodec/codecs/libopus/celt/fixed_c6x.h70
-rw-r--r--lib/rbcodec/codecs/libopus/celt/fixed_debug.h791
-rw-r--r--lib/rbcodec/codecs/libopus/celt/fixed_generic.h27
-rw-r--r--lib/rbcodec/codecs/libopus/celt/float_cast.h16
-rw-r--r--lib/rbcodec/codecs/libopus/celt/kiss_fft.c91
-rw-r--r--lib/rbcodec/codecs/libopus/celt/kiss_fft.h67
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mathops.c7
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mathops.h40
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mdct.c38
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mdct.h56
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mips/celt_mipsr1.h151
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mips/fixed_generic_mipsr1.h126
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mips/kiss_fft_mipsr1.h167
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mips/mdct_mipsr1.h288
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mips/pitch_mipsr1.h161
-rw-r--r--lib/rbcodec/codecs/libopus/celt/mips/vq_mipsr1.h122
-rw-r--r--lib/rbcodec/codecs/libopus/celt/modes.c10
-rw-r--r--lib/rbcodec/codecs/libopus/celt/opus_custom_demo.c210
-rw-r--r--lib/rbcodec/codecs/libopus/celt/os_support.h6
-rw-r--r--lib/rbcodec/codecs/libopus/celt/pitch.c138
-rw-r--r--lib/rbcodec/codecs/libopus/celt/pitch.h65
-rw-r--r--lib/rbcodec/codecs/libopus/celt/quant_bands.c13
-rw-r--r--lib/rbcodec/codecs/libopus/celt/rate.c17
-rw-r--r--lib/rbcodec/codecs/libopus/celt/rate.h4
-rw-r--r--lib/rbcodec/codecs/libopus/celt/static_modes_fixed.h65
-rw-r--r--lib/rbcodec/codecs/libopus/celt/static_modes_fixed_arm_ne10.h388
-rw-r--r--lib/rbcodec/codecs/libopus/celt/static_modes_float.h888
-rw-r--r--lib/rbcodec/codecs/libopus/celt/static_modes_float_arm_ne10.h404
-rw-r--r--lib/rbcodec/codecs/libopus/celt/tests/test_unit_cwrs32.c161
-rw-r--r--lib/rbcodec/codecs/libopus/celt/tests/test_unit_dft.c179
-rw-r--r--lib/rbcodec/codecs/libopus/celt/tests/test_unit_entropy.c383
-rw-r--r--lib/rbcodec/codecs/libopus/celt/tests/test_unit_laplace.c93
-rw-r--r--lib/rbcodec/codecs/libopus/celt/tests/test_unit_mathops.c266
-rw-r--r--lib/rbcodec/codecs/libopus/celt/tests/test_unit_mdct.c227
-rw-r--r--lib/rbcodec/codecs/libopus/celt/tests/test_unit_rotation.c86
-rw-r--r--lib/rbcodec/codecs/libopus/celt/tests/test_unit_types.c50
-rw-r--r--lib/rbcodec/codecs/libopus/celt/vq.c130
-rw-r--r--lib/rbcodec/codecs/libopus/celt/vq.h29
-rw-r--r--lib/rbcodec/codecs/libopus/celt/x86/celt_lpc_sse.h66
-rw-r--r--lib/rbcodec/codecs/libopus/celt/x86/celt_lpc_sse4_1.c89
-rw-r--r--lib/rbcodec/codecs/libopus/celt/x86/pitch_sse.c185
-rw-r--r--lib/rbcodec/codecs/libopus/celt/x86/pitch_sse.h192
-rw-r--r--lib/rbcodec/codecs/libopus/celt/x86/pitch_sse2.c95
-rw-r--r--lib/rbcodec/codecs/libopus/celt/x86/pitch_sse4_1.c195
-rw-r--r--lib/rbcodec/codecs/libopus/celt/x86/vq_sse.h50
-rw-r--r--lib/rbcodec/codecs/libopus/celt/x86/vq_sse2.c217
-rw-r--r--lib/rbcodec/codecs/libopus/celt/x86/x86_celt_map.c167
-rw-r--r--lib/rbcodec/codecs/libopus/celt/x86/x86cpu.c157
-rw-r--r--lib/rbcodec/codecs/libopus/celt/x86/x86cpu.h95
-rw-r--r--lib/rbcodec/codecs/libopus/mapping_matrix.c378
-rw-r--r--lib/rbcodec/codecs/libopus/mapping_matrix.h133
-rw-r--r--lib/rbcodec/codecs/libopus/mlp.c144
-rw-r--r--lib/rbcodec/codecs/libopus/mlp.h60
-rw-r--r--lib/rbcodec/codecs/libopus/mlp_data.c672
-rw-r--r--lib/rbcodec/codecs/libopus/ogg/crctable.h278
-rw-r--r--lib/rbcodec/codecs/libopus/ogg/framing.c1294
-rw-r--r--lib/rbcodec/codecs/libopus/ogg/ogg.h1
-rw-r--r--lib/rbcodec/codecs/libopus/opus.c14
-rw-r--r--lib/rbcodec/codecs/libopus/opus.h9
-rw-r--r--lib/rbcodec/codecs/libopus/opus_compare.c382
-rw-r--r--lib/rbcodec/codecs/libopus/opus_decoder.c134
-rw-r--r--lib/rbcodec/codecs/libopus/opus_defines.h90
-rw-r--r--lib/rbcodec/codecs/libopus/opus_demo.c892
-rw-r--r--lib/rbcodec/codecs/libopus/opus_encoder.c2754
-rw-r--r--lib/rbcodec/codecs/libopus/opus_header.c117
-rw-r--r--lib/rbcodec/codecs/libopus/opus_header.h4
-rw-r--r--lib/rbcodec/codecs/libopus/opus_multistream.c92
-rw-r--r--lib/rbcodec/codecs/libopus/opus_multistream.h660
-rw-r--r--lib/rbcodec/codecs/libopus/opus_multistream_decoder.c549
-rw-r--r--lib/rbcodec/codecs/libopus/opus_multistream_encoder.c1328
-rw-r--r--lib/rbcodec/codecs/libopus/opus_private.h96
-rw-r--r--lib/rbcodec/codecs/libopus/opus_projection.h568
-rw-r--r--lib/rbcodec/codecs/libopus/opus_projection_decoder.c258
-rw-r--r--lib/rbcodec/codecs/libopus/opus_projection_encoder.c468
-rw-r--r--lib/rbcodec/codecs/libopus/opus_types.h27
-rw-r--r--lib/rbcodec/codecs/libopus/repacketizer.c349
-rw-r--r--lib/rbcodec/codecs/libopus/repacketizer_demo.c217
-rw-r--r--lib/rbcodec/codecs/libopus/silk/A2NLSF.c267
-rw-r--r--lib/rbcodec/codecs/libopus/silk/API.h6
-rw-r--r--lib/rbcodec/codecs/libopus/silk/CNG.c83
-rw-r--r--lib/rbcodec/codecs/libopus/silk/HP_variable_cutoff.c77
-rw-r--r--lib/rbcodec/codecs/libopus/silk/LPC_analysis_filter.c29
-rw-r--r--lib/rbcodec/codecs/libopus/silk/LPC_fit.c81
-rw-r--r--lib/rbcodec/codecs/libopus/silk/LPC_inv_pred_gain.c99
-rw-r--r--lib/rbcodec/codecs/libopus/silk/LP_variable_cutoff.c135
-rw-r--r--lib/rbcodec/codecs/libopus/silk/MacroCount.h10
-rw-r--r--lib/rbcodec/codecs/libopus/silk/MacroDebug.h3
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF2A.c59
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF_VQ.c76
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF_VQ_weights_laroia.c4
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF_decode.c22
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF_del_dec_quant.c215
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF_encode.c124
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NLSF_stabilize.c2
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NSQ.c437
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NSQ.h101
-rw-r--r--lib/rbcodec/codecs/libopus/silk/NSQ_del_dec.c733
-rw-r--r--lib/rbcodec/codecs/libopus/silk/PLC.c28
-rw-r--r--lib/rbcodec/codecs/libopus/silk/PLC.h3
-rw-r--r--lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h80
-rw-r--r--lib/rbcodec/codecs/libopus/silk/VAD.c360
-rw-r--r--lib/rbcodec/codecs/libopus/silk/VQ_WMat_EC.c131
-rw-r--r--lib/rbcodec/codecs/libopus/silk/ana_filt_bank_1.c74
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_arm.h57
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_neon_intr.c280
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_arm.h100
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_neon_intr.c1124
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.c112
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.h114
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/arm_silk_map.c123
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_arm.h68
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_neon_intr.c156
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/macros_arm64.h39
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/macros_armv4.h13
-rw-r--r--lib/rbcodec/codecs/libopus/silk/arm/macros_armv5e.h9
-rw-r--r--lib/rbcodec/codecs/libopus/silk/biquad_alt.c121
-rw-r--r--lib/rbcodec/codecs/libopus/silk/bwexpander.c2
-rw-r--r--lib/rbcodec/codecs/libopus/silk/check_control_input.c106
-rw-r--r--lib/rbcodec/codecs/libopus/silk/code_signs.c2
-rw-r--r--lib/rbcodec/codecs/libopus/silk/control.h8
-rw-r--r--lib/rbcodec/codecs/libopus/silk/control_SNR.c113
-rw-r--r--lib/rbcodec/codecs/libopus/silk/control_audio_bandwidth.c132
-rw-r--r--lib/rbcodec/codecs/libopus/silk/control_codec.c423
-rw-r--r--lib/rbcodec/codecs/libopus/silk/debug.c170
-rw-r--r--lib/rbcodec/codecs/libopus/silk/debug.h266
-rw-r--r--lib/rbcodec/codecs/libopus/silk/dec_API.c11
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decode_core.c13
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decode_frame.c16
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decode_indices.c2
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decode_parameters.c4
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decode_pitch.c4
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decode_pulses.c6
-rw-r--r--lib/rbcodec/codecs/libopus/silk/decoder_set_fs.c8
-rw-r--r--lib/rbcodec/codecs/libopus/silk/define.h19
-rw-r--r--lib/rbcodec/codecs/libopus/silk/enc_API.c576
-rw-r--r--lib/rbcodec/codecs/libopus/silk/encode_indices.c181
-rw-r--r--lib/rbcodec/codecs/libopus/silk/encode_pulses.c206
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/LTP_analysis_filter_FIX.c90
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/LTP_scale_ctrl_FIX.c53
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/apply_sine_window_FIX.c101
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_arm.h68
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c260
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/autocorr_FIX.c48
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/burg_modified_FIX.c280
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/corrMatrix_FIX.c150
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/encode_frame_FIX.c448
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/find_LPC_FIX.c151
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/find_LTP_FIX.c99
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/find_pitch_lags_FIX.c143
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/find_pred_coefs_FIX.c145
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/k2a_FIX.c54
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/k2a_Q16_FIX.c54
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/main_FIX.h244
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h336
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/mips/prefilter_FIX_mipsr1.h184
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h166
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/noise_shape_analysis_FIX.c407
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/pitch_analysis_core_FIX.c721
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/process_gains_FIX.c117
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/regularize_correlations_FIX.c47
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/residual_energy16_FIX.c103
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/residual_energy_FIX.c98
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/schur64_FIX.c93
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/schur_FIX.c107
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/structs_FIX.h116
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/vector_ops_FIX.c102
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/warped_autocorrelation_FIX.c90
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/x86/burg_modified_FIX_sse4_1.c377
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/x86/prefilter_FIX_sse.c160
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/x86/vector_ops_FIX_sse4_1.c88
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/LPC_analysis_filter_FLP.c249
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/LPC_inv_pred_gain_FLP.c73
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/LTP_analysis_filter_FLP.c75
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/LTP_scale_ctrl_FLP.c52
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/SigProc_FLP.h197
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/apply_sine_window_FLP.c81
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/autocorrelation_FLP.c52
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/burg_modified_FLP.c186
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/bwexpander_FLP.c49
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/corrMatrix_FLP.c93
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/encode_frame_FLP.c435
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/energy_FLP.c59
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/find_LPC_FLP.c104
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/find_LTP_FLP.c64
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/find_pitch_lags_FLP.c132
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/find_pred_coefs_FLP.c116
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/inner_product_FLP.c59
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/k2a_FLP.c54
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/main_FLP.h286
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/noise_shape_analysis_FLP.c350
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/pitch_analysis_core_FLP.c630
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/process_gains_FLP.c103
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/regularize_correlations_FLP.c48
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/residual_energy_FLP.c117
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/scale_copy_vector_FLP.c57
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/scale_vector_FLP.c56
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/schur_FLP.c70
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/sort_FLP.c83
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/structs_FLP.h112
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/warped_autocorrelation_FLP.c73
-rw-r--r--lib/rbcodec/codecs/libopus/silk/float/wrappers_FLP.c207
-rw-r--r--lib/rbcodec/codecs/libopus/silk/gain_quant.c5
-rw-r--r--lib/rbcodec/codecs/libopus/silk/init_decoder.c1
-rw-r--r--lib/rbcodec/codecs/libopus/silk/init_encoder.c64
-rw-r--r--lib/rbcodec/codecs/libopus/silk/inner_prod_aligned.c47
-rw-r--r--lib/rbcodec/codecs/libopus/silk/interpolate.c51
-rw-r--r--lib/rbcodec/codecs/libopus/silk/lin2log.c46
-rw-r--r--lib/rbcodec/codecs/libopus/silk/log2lin.c6
-rw-r--r--lib/rbcodec/codecs/libopus/silk/macros.h29
-rw-r--r--lib/rbcodec/codecs/libopus/silk/main.h108
-rw-r--r--lib/rbcodec/codecs/libopus/silk/mips/NSQ_del_dec_mipsr1.h410
-rw-r--r--lib/rbcodec/codecs/libopus/silk/mips/macros_mipsr1.h92
-rw-r--r--lib/rbcodec/codecs/libopus/silk/mips/sigproc_fix_mipsr1.h60
-rw-r--r--lib/rbcodec/codecs/libopus/silk/process_NLSFs.c107
-rw-r--r--lib/rbcodec/codecs/libopus/silk/quant_LTP_gains.c132
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler.c10
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler_down2.c74
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler_down2_3.c103
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler_private_down_FIR.c2
-rw-r--r--lib/rbcodec/codecs/libopus/silk/resampler_rom.c54
-rw-r--r--lib/rbcodec/codecs/libopus/silk/shell_coder.c4
-rw-r--r--lib/rbcodec/codecs/libopus/silk/sigm_Q15.c76
-rw-r--r--lib/rbcodec/codecs/libopus/silk/sort.c18
-rw-r--r--lib/rbcodec/codecs/libopus/silk/stereo_LR_to_MS.c229
-rw-r--r--lib/rbcodec/codecs/libopus/silk/stereo_encode_pred.c62
-rw-r--r--lib/rbcodec/codecs/libopus/silk/stereo_find_predictor.c79
-rw-r--r--lib/rbcodec/codecs/libopus/silk/stereo_quant_pred.c73
-rw-r--r--lib/rbcodec/codecs/libopus/silk/structs.h8
-rw-r--r--lib/rbcodec/codecs/libopus/silk/sum_sqr_shift.c51
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tables.h14
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tables_LTP.c8
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_NB_MB.c36
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_WB.c36
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tables_other.c14
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tests/test_unit_LPC_inv_pred_gain.c129
-rw-r--r--lib/rbcodec/codecs/libopus/silk/tuning_parameters.h155
-rw-r--r--lib/rbcodec/codecs/libopus/silk/x86/NSQ_del_dec_sse4_1.c859
-rw-r--r--lib/rbcodec/codecs/libopus/silk/x86/NSQ_sse4_1.c719
-rw-r--r--lib/rbcodec/codecs/libopus/silk/x86/SigProc_FIX_sse.h94
-rw-r--r--lib/rbcodec/codecs/libopus/silk/x86/VAD_sse4_1.c277
-rw-r--r--lib/rbcodec/codecs/libopus/silk/x86/VQ_WMat_EC_sse4_1.c142
-rw-r--r--lib/rbcodec/codecs/libopus/silk/x86/main_sse.h248
-rw-r--r--lib/rbcodec/codecs/libopus/silk/x86/x86_silk_map.c164
-rw-r--r--lib/rbcodec/codecs/libopus/tansig_table.h45
286 files changed, 48927 insertions, 1274 deletions
diff --git a/lib/rbcodec/codecs/libopus/README.rockbox b/lib/rbcodec/codecs/libopus/README.rockbox
index 370a5823f2..dd0ce70795 100644
--- a/lib/rbcodec/codecs/libopus/README.rockbox
+++ b/lib/rbcodec/codecs/libopus/README.rockbox
@@ -1,5 +1,5 @@
1Libraries: Opus (snapshot) / Opus-tools (snapshot) / libogg 1.3 1Libraries: Opus (snapshot) / Opus-tools (snapshot) / libogg 1.3
2Imported: September 15th, 2012 2Imported: January 1st, 2019
3 3
4Steps taken to adapt original opus/opus-tool/ogg source files to rockbox 4Steps taken to adapt original opus/opus-tool/ogg source files to rockbox
5(useful when for example syncing a new snapshot) 5(useful when for example syncing a new snapshot)
@@ -10,13 +10,21 @@ Opus:
10* copied .c/.h files from opus/celt to lib/rbcodec/codecs/libopus/celt 10* copied .c/.h files from opus/celt to lib/rbcodec/codecs/libopus/celt
11* copied .c/.h files from opus/silk to lib/rbcodec/codecs/libopus/silk 11* copied .c/.h files from opus/silk to lib/rbcodec/codecs/libopus/silk
12 12
13Celt:
14* changed #if FIXED_POINT to #ifdef FIXED_POINT in bands.c
15* changed #elif OPUS_ARM_INLINE_EDSP to #elif defined (OPUS_ARM_INLINE_EDSP)
16* add #define ABS(a)(((a) < 0) ? - (a) :(a)) to mathops.h
17
13Opus-tools: 18Opus-tools:
14* copied src/opus_header.h and src/opus_header.c to lib/rbcodec/codecs/libopus 19* copied src/opus_header.h and src/opus_header.c to lib/rbcodec/codecs/libopus
15* changed #include <ogg/ogg.h> to #include "ogg/ogg.h" in opus_header.c 20* changed #include <ogg/ogg.h> to #include "ogg/ogg.h" in opus_header.h
16 21
17Ogg: 22Ogg:
18* copied libogg/src/framing.c to lib/rbcodec/codecs/libopus/ogg 23* copied libogg/src/framing.c to lib/rbcodec/codecs/libopus/ogg
19* copied libogg/include/ogg.h to lib/rbcodec/codecs/libopus/ogg 24* copied libogg/include/ogg.h to lib/rbcodec/codecs/libopus/ogg
25* copied libogg/include/crctable.h to lib/rbcodec/codecs/libopus/ogg
20* changed #include "ogg/ogg.h" to #include "ogg.h" in framing.c 26* changed #include "ogg/ogg.h" to #include "ogg.h" in framing.c
21* added os_config.h to lib/rbcodec/codecs/libopus/ogg 27* -- added os_config.h to lib/rbcodec/codecs/libopus/ogg
22 28* added our own os_types.h
29* changed #include <ogg/os_types.h> to #include "os_types.h" in ogg.h
30* changed #include <ogg/os_types.h> to #include "os_types.h" in crctable.h
diff --git a/lib/rbcodec/codecs/libopus/SOURCES b/lib/rbcodec/codecs/libopus/SOURCES
index 417cf01d88..53806545c7 100644
--- a/lib/rbcodec/codecs/libopus/SOURCES
+++ b/lib/rbcodec/codecs/libopus/SOURCES
@@ -32,8 +32,10 @@ silk/decode_pulses.c
32silk/decoder_set_fs.c 32silk/decoder_set_fs.c
33silk/gain_quant.c 33silk/gain_quant.c
34silk/init_decoder.c 34silk/init_decoder.c
35silk/lin2log.c
35silk/log2lin.c 36silk/log2lin.c
36silk/LPC_analysis_filter.c 37silk/LPC_analysis_filter.c
38silk/LPC_fit.c
37silk/LPC_inv_pred_gain.c 39silk/LPC_inv_pred_gain.c
38silk/NLSF2A.c 40silk/NLSF2A.c
39silk/NLSF_decode.c 41silk/NLSF_decode.c
diff --git a/lib/rbcodec/codecs/libopus/analysis.c b/lib/rbcodec/codecs/libopus/analysis.c
new file mode 100644
index 0000000000..b192ae4e8d
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/analysis.c
@@ -0,0 +1,945 @@
1/* Copyright (c) 2011 Xiph.Org Foundation
2 Written by Jean-Marc Valin */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
19 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#define ANALYSIS_C
33
34#include <stdio.h>
35
36#include "mathops.h"
37#include "kiss_fft.h"
38#include "celt.h"
39#include "modes.h"
40#include "arch.h"
41#include "quant_bands.h"
42#include "analysis.h"
43#include "mlp.h"
44#include "stack_alloc.h"
45#include "float_cast.h"
46
47#ifndef M_PI
48#define M_PI 3.141592653
49#endif
50
51#ifndef DISABLE_FLOAT_API
52
53#define TRANSITION_PENALTY 10
54
55static const float dct_table[128] = {
56 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f,
57 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f,
58 0.351851f, 0.338330f, 0.311806f, 0.273300f, 0.224292f, 0.166664f, 0.102631f, 0.034654f,
59 -0.034654f,-0.102631f,-0.166664f,-0.224292f,-0.273300f,-0.311806f,-0.338330f,-0.351851f,
60 0.346760f, 0.293969f, 0.196424f, 0.068975f,-0.068975f,-0.196424f,-0.293969f,-0.346760f,
61 -0.346760f,-0.293969f,-0.196424f,-0.068975f, 0.068975f, 0.196424f, 0.293969f, 0.346760f,
62 0.338330f, 0.224292f, 0.034654f,-0.166664f,-0.311806f,-0.351851f,-0.273300f,-0.102631f,
63 0.102631f, 0.273300f, 0.351851f, 0.311806f, 0.166664f,-0.034654f,-0.224292f,-0.338330f,
64 0.326641f, 0.135299f,-0.135299f,-0.326641f,-0.326641f,-0.135299f, 0.135299f, 0.326641f,
65 0.326641f, 0.135299f,-0.135299f,-0.326641f,-0.326641f,-0.135299f, 0.135299f, 0.326641f,
66 0.311806f, 0.034654f,-0.273300f,-0.338330f,-0.102631f, 0.224292f, 0.351851f, 0.166664f,
67 -0.166664f,-0.351851f,-0.224292f, 0.102631f, 0.338330f, 0.273300f,-0.034654f,-0.311806f,
68 0.293969f,-0.068975f,-0.346760f,-0.196424f, 0.196424f, 0.346760f, 0.068975f,-0.293969f,
69 -0.293969f, 0.068975f, 0.346760f, 0.196424f,-0.196424f,-0.346760f,-0.068975f, 0.293969f,
70 0.273300f,-0.166664f,-0.338330f, 0.034654f, 0.351851f, 0.102631f,-0.311806f,-0.224292f,
71 0.224292f, 0.311806f,-0.102631f,-0.351851f,-0.034654f, 0.338330f, 0.166664f,-0.273300f,
72};
73
74static const float analysis_window[240] = {
75 0.000043f, 0.000171f, 0.000385f, 0.000685f, 0.001071f, 0.001541f, 0.002098f, 0.002739f,
76 0.003466f, 0.004278f, 0.005174f, 0.006156f, 0.007222f, 0.008373f, 0.009607f, 0.010926f,
77 0.012329f, 0.013815f, 0.015385f, 0.017037f, 0.018772f, 0.020590f, 0.022490f, 0.024472f,
78 0.026535f, 0.028679f, 0.030904f, 0.033210f, 0.035595f, 0.038060f, 0.040604f, 0.043227f,
79 0.045928f, 0.048707f, 0.051564f, 0.054497f, 0.057506f, 0.060591f, 0.063752f, 0.066987f,
80 0.070297f, 0.073680f, 0.077136f, 0.080665f, 0.084265f, 0.087937f, 0.091679f, 0.095492f,
81 0.099373f, 0.103323f, 0.107342f, 0.111427f, 0.115579f, 0.119797f, 0.124080f, 0.128428f,
82 0.132839f, 0.137313f, 0.141849f, 0.146447f, 0.151105f, 0.155823f, 0.160600f, 0.165435f,
83 0.170327f, 0.175276f, 0.180280f, 0.185340f, 0.190453f, 0.195619f, 0.200838f, 0.206107f,
84 0.211427f, 0.216797f, 0.222215f, 0.227680f, 0.233193f, 0.238751f, 0.244353f, 0.250000f,
85 0.255689f, 0.261421f, 0.267193f, 0.273005f, 0.278856f, 0.284744f, 0.290670f, 0.296632f,
86 0.302628f, 0.308658f, 0.314721f, 0.320816f, 0.326941f, 0.333097f, 0.339280f, 0.345492f,
87 0.351729f, 0.357992f, 0.364280f, 0.370590f, 0.376923f, 0.383277f, 0.389651f, 0.396044f,
88 0.402455f, 0.408882f, 0.415325f, 0.421783f, 0.428254f, 0.434737f, 0.441231f, 0.447736f,
89 0.454249f, 0.460770f, 0.467298f, 0.473832f, 0.480370f, 0.486912f, 0.493455f, 0.500000f,
90 0.506545f, 0.513088f, 0.519630f, 0.526168f, 0.532702f, 0.539230f, 0.545751f, 0.552264f,
91 0.558769f, 0.565263f, 0.571746f, 0.578217f, 0.584675f, 0.591118f, 0.597545f, 0.603956f,
92 0.610349f, 0.616723f, 0.623077f, 0.629410f, 0.635720f, 0.642008f, 0.648271f, 0.654508f,
93 0.660720f, 0.666903f, 0.673059f, 0.679184f, 0.685279f, 0.691342f, 0.697372f, 0.703368f,
94 0.709330f, 0.715256f, 0.721144f, 0.726995f, 0.732807f, 0.738579f, 0.744311f, 0.750000f,
95 0.755647f, 0.761249f, 0.766807f, 0.772320f, 0.777785f, 0.783203f, 0.788573f, 0.793893f,
96 0.799162f, 0.804381f, 0.809547f, 0.814660f, 0.819720f, 0.824724f, 0.829673f, 0.834565f,
97 0.839400f, 0.844177f, 0.848895f, 0.853553f, 0.858151f, 0.862687f, 0.867161f, 0.871572f,
98 0.875920f, 0.880203f, 0.884421f, 0.888573f, 0.892658f, 0.896677f, 0.900627f, 0.904508f,
99 0.908321f, 0.912063f, 0.915735f, 0.919335f, 0.922864f, 0.926320f, 0.929703f, 0.933013f,
100 0.936248f, 0.939409f, 0.942494f, 0.945503f, 0.948436f, 0.951293f, 0.954072f, 0.956773f,
101 0.959396f, 0.961940f, 0.964405f, 0.966790f, 0.969096f, 0.971321f, 0.973465f, 0.975528f,
102 0.977510f, 0.979410f, 0.981228f, 0.982963f, 0.984615f, 0.986185f, 0.987671f, 0.989074f,
103 0.990393f, 0.991627f, 0.992778f, 0.993844f, 0.994826f, 0.995722f, 0.996534f, 0.997261f,
104 0.997902f, 0.998459f, 0.998929f, 0.999315f, 0.999615f, 0.999829f, 0.999957f, 1.000000f,
105};
106
107static const int tbands[NB_TBANDS+1] = {
108 4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 136, 160, 192, 240
109};
110
111#define NB_TONAL_SKIP_BANDS 9
112
113static opus_val32 silk_resampler_down2_hp(
114 opus_val32 *S, /* I/O State vector [ 2 ] */
115 opus_val32 *out, /* O Output signal [ floor(len/2) ] */
116 const opus_val32 *in, /* I Input signal [ len ] */
117 int inLen /* I Number of input samples */
118)
119{
120 int k, len2 = inLen/2;
121 opus_val32 in32, out32, out32_hp, Y, X;
122 opus_val64 hp_ener = 0;
123 /* Internal variables and state are in Q10 format */
124 for( k = 0; k < len2; k++ ) {
125 /* Convert to Q10 */
126 in32 = in[ 2 * k ];
127
128 /* All-pass section for even input sample */
129 Y = SUB32( in32, S[ 0 ] );
130 X = MULT16_32_Q15(QCONST16(0.6074371f, 15), Y);
131 out32 = ADD32( S[ 0 ], X );
132 S[ 0 ] = ADD32( in32, X );
133 out32_hp = out32;
134 /* Convert to Q10 */
135 in32 = in[ 2 * k + 1 ];
136
137 /* All-pass section for odd input sample, and add to output of previous section */
138 Y = SUB32( in32, S[ 1 ] );
139 X = MULT16_32_Q15(QCONST16(0.15063f, 15), Y);
140 out32 = ADD32( out32, S[ 1 ] );
141 out32 = ADD32( out32, X );
142 S[ 1 ] = ADD32( in32, X );
143
144 Y = SUB32( -in32, S[ 2 ] );
145 X = MULT16_32_Q15(QCONST16(0.15063f, 15), Y);
146 out32_hp = ADD32( out32_hp, S[ 2 ] );
147 out32_hp = ADD32( out32_hp, X );
148 S[ 2 ] = ADD32( -in32, X );
149
150 hp_ener += out32_hp*(opus_val64)out32_hp;
151 /* Add, convert back to int16 and store to output */
152 out[ k ] = HALF32(out32);
153 }
154#ifdef FIXED_POINT
155 /* len2 can be up to 480, so we shift by 8 more to make it fit. */
156 hp_ener = hp_ener >> (2*SIG_SHIFT + 8);
157#endif
158 return (opus_val32)hp_ener;
159}
160
161static opus_val32 downmix_and_resample(downmix_func downmix, const void *_x, opus_val32 *y, opus_val32 S[3], int subframe, int offset, int c1, int c2, int C, int Fs)
162{
163 VARDECL(opus_val32, tmp);
164 opus_val32 scale;
165 int j;
166 opus_val32 ret = 0;
167 SAVE_STACK;
168
169 if (subframe==0) return 0;
170 if (Fs == 48000)
171 {
172 subframe *= 2;
173 offset *= 2;
174 } else if (Fs == 16000) {
175 subframe = subframe*2/3;
176 offset = offset*2/3;
177 }
178 ALLOC(tmp, subframe, opus_val32);
179
180 downmix(_x, tmp, subframe, offset, c1, c2, C);
181#ifdef FIXED_POINT
182 scale = (1<<SIG_SHIFT);
183#else
184 scale = 1.f/32768;
185#endif
186 if (c2==-2)
187 scale /= C;
188 else if (c2>-1)
189 scale /= 2;
190 for (j=0;j<subframe;j++)
191 tmp[j] *= scale;
192 if (Fs == 48000)
193 {
194 ret = silk_resampler_down2_hp(S, y, tmp, subframe);
195 } else if (Fs == 24000) {
196 OPUS_COPY(y, tmp, subframe);
197 } else if (Fs == 16000) {
198 VARDECL(opus_val32, tmp3x);
199 ALLOC(tmp3x, 3*subframe, opus_val32);
200 /* Don't do this at home! This resampler is horrible and it's only (barely)
201 usable for the purpose of the analysis because we don't care about all
202 the aliasing between 8 kHz and 12 kHz. */
203 for (j=0;j<subframe;j++)
204 {
205 tmp3x[3*j] = tmp[j];
206 tmp3x[3*j+1] = tmp[j];
207 tmp3x[3*j+2] = tmp[j];
208 }
209 silk_resampler_down2_hp(S, y, tmp3x, 3*subframe);
210 }
211 RESTORE_STACK;
212 return ret;
213}
214
215void tonality_analysis_init(TonalityAnalysisState *tonal, opus_int32 Fs)
216{
217 /* Initialize reusable fields. */
218 tonal->arch = opus_select_arch();
219 tonal->Fs = Fs;
220 /* Clear remaining fields. */
221 tonality_analysis_reset(tonal);
222}
223
224void tonality_analysis_reset(TonalityAnalysisState *tonal)
225{
226 /* Clear non-reusable fields. */
227 char *start = (char*)&tonal->TONALITY_ANALYSIS_RESET_START;
228 OPUS_CLEAR(start, sizeof(TonalityAnalysisState) - (start - (char*)tonal));
229}
230
231void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int len)
232{
233 int pos;
234 int curr_lookahead;
235 float tonality_max;
236 float tonality_avg;
237 int tonality_count;
238 int i;
239 int pos0;
240 float prob_avg;
241 float prob_count;
242 float prob_min, prob_max;
243 float vad_prob;
244 int mpos, vpos;
245 int bandwidth_span;
246
247 pos = tonal->read_pos;
248 curr_lookahead = tonal->write_pos-tonal->read_pos;
249 if (curr_lookahead<0)
250 curr_lookahead += DETECT_SIZE;
251
252 /* On long frames, look at the second analysis window rather than the first. */
253 if (len > tonal->Fs/50 && pos != tonal->write_pos)
254 {
255 pos++;
256 if (pos==DETECT_SIZE)
257 pos=0;
258 }
259 if (pos == tonal->write_pos)
260 pos--;
261 if (pos<0)
262 pos = DETECT_SIZE-1;
263 pos0 = pos;
264 OPUS_COPY(info_out, &tonal->info[pos], 1);
265 tonality_max = tonality_avg = info_out->tonality;
266 tonality_count = 1;
267 /* Look at the neighbouring frames and pick largest bandwidth found (to be safe). */
268 bandwidth_span = 6;
269 /* If possible, look ahead for a tone to compensate for the delay in the tone detector. */
270 for (i=0;i<3;i++)
271 {
272 pos++;
273 if (pos==DETECT_SIZE)
274 pos = 0;
275 if (pos == tonal->write_pos)
276 break;
277 tonality_max = MAX32(tonality_max, tonal->info[pos].tonality);
278 tonality_avg += tonal->info[pos].tonality;
279 tonality_count++;
280 info_out->bandwidth = IMAX(info_out->bandwidth, tonal->info[pos].bandwidth);
281 bandwidth_span--;
282 }
283 pos = pos0;
284 /* Look back in time to see if any has a wider bandwidth than the current frame. */
285 for (i=0;i<bandwidth_span;i++)
286 {
287 pos--;
288 if (pos < 0)
289 pos = DETECT_SIZE-1;
290 if (pos == tonal->write_pos)
291 break;
292 info_out->bandwidth = IMAX(info_out->bandwidth, tonal->info[pos].bandwidth);
293 }
294 info_out->tonality = MAX32(tonality_avg/tonality_count, tonality_max-.2f);
295
296 mpos = vpos = pos0;
297 /* If we have enough look-ahead, compensate for the ~5-frame delay in the music prob and
298 ~1 frame delay in the VAD prob. */
299 if (curr_lookahead > 15)
300 {
301 mpos += 5;
302 if (mpos>=DETECT_SIZE)
303 mpos -= DETECT_SIZE;
304 vpos += 1;
305 if (vpos>=DETECT_SIZE)
306 vpos -= DETECT_SIZE;
307 }
308
309 /* The following calculations attempt to minimize a "badness function"
310 for the transition. When switching from speech to music, the badness
311 of switching at frame k is
312 b_k = S*v_k + \sum_{i=0}^{k-1} v_i*(p_i - T)
313 where
314 v_i is the activity probability (VAD) at frame i,
315 p_i is the music probability at frame i
316 T is the probability threshold for switching
317 S is the penalty for switching during active audio rather than silence
318 the current frame has index i=0
319
320 Rather than apply badness to directly decide when to switch, what we compute
321 instead is the threshold for which the optimal switching point is now. When
322 considering whether to switch now (frame 0) or at frame k, we have:
323 S*v_0 = S*v_k + \sum_{i=0}^{k-1} v_i*(p_i - T)
324 which gives us:
325 T = ( \sum_{i=0}^{k-1} v_i*p_i + S*(v_k-v_0) ) / ( \sum_{i=0}^{k-1} v_i )
326 We take the min threshold across all positive values of k (up to the maximum
327 amount of lookahead we have) to give us the threshold for which the current
328 frame is the optimal switch point.
329
330 The last step is that we need to consider whether we want to switch at all.
331 For that we use the average of the music probability over the entire window.
332 If the threshold is higher than that average we're not going to
333 switch, so we compute a min with the average as well. The result of all these
334 min operations is music_prob_min, which gives the threshold for switching to music
335 if we're currently encoding for speech.
336
337 We do the exact opposite to compute music_prob_max which is used for switching
338 from music to speech.
339 */
340 prob_min = 1.f;
341 prob_max = 0.f;
342 vad_prob = tonal->info[vpos].activity_probability;
343 prob_count = MAX16(.1f, vad_prob);
344 prob_avg = MAX16(.1f, vad_prob)*tonal->info[mpos].music_prob;
345 while (1)
346 {
347 float pos_vad;
348 mpos++;
349 if (mpos==DETECT_SIZE)
350 mpos = 0;
351 if (mpos == tonal->write_pos)
352 break;
353 vpos++;
354 if (vpos==DETECT_SIZE)
355 vpos = 0;
356 if (vpos == tonal->write_pos)
357 break;
358 pos_vad = tonal->info[vpos].activity_probability;
359 prob_min = MIN16((prob_avg - TRANSITION_PENALTY*(vad_prob - pos_vad))/prob_count, prob_min);
360 prob_max = MAX16((prob_avg + TRANSITION_PENALTY*(vad_prob - pos_vad))/prob_count, prob_max);
361 prob_count += MAX16(.1f, pos_vad);
362 prob_avg += MAX16(.1f, pos_vad)*tonal->info[mpos].music_prob;
363 }
364 info_out->music_prob = prob_avg/prob_count;
365 prob_min = MIN16(prob_avg/prob_count, prob_min);
366 prob_max = MAX16(prob_avg/prob_count, prob_max);
367 prob_min = MAX16(prob_min, 0.f);
368 prob_max = MIN16(prob_max, 1.f);
369
370 /* If we don't have enough look-ahead, do our best to make a decent decision. */
371 if (curr_lookahead < 10)
372 {
373 float pmin, pmax;
374 pmin = prob_min;
375 pmax = prob_max;
376 pos = pos0;
377 /* Look for min/max in the past. */
378 for (i=0;i<IMIN(tonal->count-1, 15);i++)
379 {
380 pos--;
381 if (pos < 0)
382 pos = DETECT_SIZE-1;
383 pmin = MIN16(pmin, tonal->info[pos].music_prob);
384 pmax = MAX16(pmax, tonal->info[pos].music_prob);
385 }
386 /* Bias against switching on active audio. */
387 pmin = MAX16(0.f, pmin - .1f*vad_prob);
388 pmax = MIN16(1.f, pmax + .1f*vad_prob);
389 prob_min += (1.f-.1f*curr_lookahead)*(pmin - prob_min);
390 prob_max += (1.f-.1f*curr_lookahead)*(pmax - prob_max);
391 }
392 info_out->music_prob_min = prob_min;
393 info_out->music_prob_max = prob_max;
394
395 /* printf("%f %f %f %f %f\n", prob_min, prob_max, prob_avg/prob_count, vad_prob, info_out->music_prob); */
396 tonal->read_subframe += len/(tonal->Fs/400);
397 while (tonal->read_subframe>=8)
398 {
399 tonal->read_subframe -= 8;
400 tonal->read_pos++;
401 }
402 if (tonal->read_pos>=DETECT_SIZE)
403 tonal->read_pos-=DETECT_SIZE;
404}
405
406static const float std_feature_bias[9] = {
407 5.684947f, 3.475288f, 1.770634f, 1.599784f, 3.773215f,
408 2.163313f, 1.260756f, 1.116868f, 1.918795f
409};
410
411#define LEAKAGE_OFFSET 2.5f
412#define LEAKAGE_SLOPE 2.f
413
414#ifdef FIXED_POINT
415/* For fixed-point, the input is +/-2^15 shifted up by SIG_SHIFT, so we need to
416 compensate for that in the energy. */
417#define SCALE_COMPENS (1.f/((opus_int32)1<<(15+SIG_SHIFT)))
418#define SCALE_ENER(e) ((SCALE_COMPENS*SCALE_COMPENS)*(e))
419#else
420#define SCALE_ENER(e) (e)
421#endif
422
423static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt_mode, const void *x, int len, int offset, int c1, int c2, int C, int lsb_depth, downmix_func downmix)
424{
425 int i, b;
426 const kiss_fft_state *kfft;
427 VARDECL(kiss_fft_cpx, in);
428 VARDECL(kiss_fft_cpx, out);
429 int N = 480, N2=240;
430 float * OPUS_RESTRICT A = tonal->angle;
431 float * OPUS_RESTRICT dA = tonal->d_angle;
432 float * OPUS_RESTRICT d2A = tonal->d2_angle;
433 VARDECL(float, tonality);
434 VARDECL(float, noisiness);
435 float band_tonality[NB_TBANDS];
436 float logE[NB_TBANDS];
437 float BFCC[8];
438 float features[25];
439 float frame_tonality;
440 float max_frame_tonality;
441 /*float tw_sum=0;*/
442 float frame_noisiness;
443 const float pi4 = (float)(M_PI*M_PI*M_PI*M_PI);
444 float slope=0;
445 float frame_stationarity;
446 float relativeE;
447 float frame_probs[2];
448 float alpha, alphaE, alphaE2;
449 float frame_loudness;
450 float bandwidth_mask;
451 int is_masked[NB_TBANDS+1];
452 int bandwidth=0;
453 float maxE = 0;
454 float noise_floor;
455 int remaining;
456 AnalysisInfo *info;
457 float hp_ener;
458 float tonality2[240];
459 float midE[8];
460 float spec_variability=0;
461 float band_log2[NB_TBANDS+1];
462 float leakage_from[NB_TBANDS+1];
463 float leakage_to[NB_TBANDS+1];
464 float layer_out[MAX_NEURONS];
465 float below_max_pitch;
466 float above_max_pitch;
467 SAVE_STACK;
468
469 alpha = 1.f/IMIN(10, 1+tonal->count);
470 alphaE = 1.f/IMIN(25, 1+tonal->count);
471 /* Noise floor related decay for bandwidth detection: -2.2 dB/second */
472 alphaE2 = 1.f/IMIN(100, 1+tonal->count);
473 if (tonal->count <= 1) alphaE2 = 1;
474
475 if (tonal->Fs == 48000)
476 {
477 /* len and offset are now at 24 kHz. */
478 len/= 2;
479 offset /= 2;
480 } else if (tonal->Fs == 16000) {
481 len = 3*len/2;
482 offset = 3*offset/2;
483 }
484
485 kfft = celt_mode->mdct.kfft[0];
486 if (tonal->count==0)
487 tonal->mem_fill = 240;
488 tonal->hp_ener_accum += (float)downmix_and_resample(downmix, x,
489 &tonal->inmem[tonal->mem_fill], tonal->downmix_state,
490 IMIN(len, ANALYSIS_BUF_SIZE-tonal->mem_fill), offset, c1, c2, C, tonal->Fs);
491 if (tonal->mem_fill+len < ANALYSIS_BUF_SIZE)
492 {
493 tonal->mem_fill += len;
494 /* Don't have enough to update the analysis */
495 RESTORE_STACK;
496 return;
497 }
498 hp_ener = tonal->hp_ener_accum;
499 info = &tonal->info[tonal->write_pos++];
500 if (tonal->write_pos>=DETECT_SIZE)
501 tonal->write_pos-=DETECT_SIZE;
502
503 ALLOC(in, 480, kiss_fft_cpx);
504 ALLOC(out, 480, kiss_fft_cpx);
505 ALLOC(tonality, 240, float);
506 ALLOC(noisiness, 240, float);
507 for (i=0;i<N2;i++)
508 {
509 float w = analysis_window[i];
510 in[i].r = (kiss_fft_scalar)(w*tonal->inmem[i]);
511 in[i].i = (kiss_fft_scalar)(w*tonal->inmem[N2+i]);
512 in[N-i-1].r = (kiss_fft_scalar)(w*tonal->inmem[N-i-1]);
513 in[N-i-1].i = (kiss_fft_scalar)(w*tonal->inmem[N+N2-i-1]);
514 }
515 OPUS_MOVE(tonal->inmem, tonal->inmem+ANALYSIS_BUF_SIZE-240, 240);
516 remaining = len - (ANALYSIS_BUF_SIZE-tonal->mem_fill);
517 tonal->hp_ener_accum = (float)downmix_and_resample(downmix, x,
518 &tonal->inmem[240], tonal->downmix_state, remaining,
519 offset+ANALYSIS_BUF_SIZE-tonal->mem_fill, c1, c2, C, tonal->Fs);
520 tonal->mem_fill = 240 + remaining;
521 opus_fft(kfft, in, out, tonal->arch);
522#ifndef FIXED_POINT
523 /* If there's any NaN on the input, the entire output will be NaN, so we only need to check one value. */
524 if (celt_isnan(out[0].r))
525 {
526 info->valid = 0;
527 RESTORE_STACK;
528 return;
529 }
530#endif
531
532 for (i=1;i<N2;i++)
533 {
534 float X1r, X2r, X1i, X2i;
535 float angle, d_angle, d2_angle;
536 float angle2, d_angle2, d2_angle2;
537 float mod1, mod2, avg_mod;
538 X1r = (float)out[i].r+out[N-i].r;
539 X1i = (float)out[i].i-out[N-i].i;
540 X2r = (float)out[i].i+out[N-i].i;
541 X2i = (float)out[N-i].r-out[i].r;
542
543 angle = (float)(.5f/M_PI)*fast_atan2f(X1i, X1r);
544 d_angle = angle - A[i];
545 d2_angle = d_angle - dA[i];
546
547 angle2 = (float)(.5f/M_PI)*fast_atan2f(X2i, X2r);
548 d_angle2 = angle2 - angle;
549 d2_angle2 = d_angle2 - d_angle;
550
551 mod1 = d2_angle - (float)float2int(d2_angle);
552 noisiness[i] = ABS16(mod1);
553 mod1 *= mod1;
554 mod1 *= mod1;
555
556 mod2 = d2_angle2 - (float)float2int(d2_angle2);
557 noisiness[i] += ABS16(mod2);
558 mod2 *= mod2;
559 mod2 *= mod2;
560
561 avg_mod = .25f*(d2A[i]+mod1+2*mod2);
562 /* This introduces an extra delay of 2 frames in the detection. */
563 tonality[i] = 1.f/(1.f+40.f*16.f*pi4*avg_mod)-.015f;
564 /* No delay on this detection, but it's less reliable. */
565 tonality2[i] = 1.f/(1.f+40.f*16.f*pi4*mod2)-.015f;
566
567 A[i] = angle2;
568 dA[i] = d_angle2;
569 d2A[i] = mod2;
570 }
571 for (i=2;i<N2-1;i++)
572 {
573 float tt = MIN32(tonality2[i], MAX32(tonality2[i-1], tonality2[i+1]));
574 tonality[i] = .9f*MAX32(tonality[i], tt-.1f);
575 }
576 frame_tonality = 0;
577 max_frame_tonality = 0;
578 /*tw_sum = 0;*/
579 info->activity = 0;
580 frame_noisiness = 0;
581 frame_stationarity = 0;
582 if (!tonal->count)
583 {
584 for (b=0;b<NB_TBANDS;b++)
585 {
586 tonal->lowE[b] = 1e10;
587 tonal->highE[b] = -1e10;
588 }
589 }
590 relativeE = 0;
591 frame_loudness = 0;
592 /* The energy of the very first band is special because of DC. */
593 {
594 float E = 0;
595 float X1r, X2r;
596 X1r = 2*(float)out[0].r;
597 X2r = 2*(float)out[0].i;
598 E = X1r*X1r + X2r*X2r;
599 for (i=1;i<4;i++)
600 {
601 float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r
602 + out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;
603 E += binE;
604 }
605 E = SCALE_ENER(E);
606 band_log2[0] = .5f*1.442695f*(float)log(E+1e-10f);
607 }
608 for (b=0;b<NB_TBANDS;b++)
609 {
610 float E=0, tE=0, nE=0;
611 float L1, L2;
612 float stationarity;
613 for (i=tbands[b];i<tbands[b+1];i++)
614 {
615 float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r
616 + out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;
617 binE = SCALE_ENER(binE);
618 E += binE;
619 tE += binE*MAX32(0, tonality[i]);
620 nE += binE*2.f*(.5f-noisiness[i]);
621 }
622#ifndef FIXED_POINT
623 /* Check for extreme band energies that could cause NaNs later. */
624 if (!(E<1e9f) || celt_isnan(E))
625 {
626 info->valid = 0;
627 RESTORE_STACK;
628 return;
629 }
630#endif
631
632 tonal->E[tonal->E_count][b] = E;
633 frame_noisiness += nE/(1e-15f+E);
634
635 frame_loudness += (float)sqrt(E+1e-10f);
636 logE[b] = (float)log(E+1e-10f);
637 band_log2[b+1] = .5f*1.442695f*(float)log(E+1e-10f);
638 tonal->logE[tonal->E_count][b] = logE[b];
639 if (tonal->count==0)
640 tonal->highE[b] = tonal->lowE[b] = logE[b];
641 if (tonal->highE[b] > tonal->lowE[b] + 7.5)
642 {
643 if (tonal->highE[b] - logE[b] > logE[b] - tonal->lowE[b])
644 tonal->highE[b] -= .01f;
645 else
646 tonal->lowE[b] += .01f;
647 }
648 if (logE[b] > tonal->highE[b])
649 {
650 tonal->highE[b] = logE[b];
651 tonal->lowE[b] = MAX32(tonal->highE[b]-15, tonal->lowE[b]);
652 } else if (logE[b] < tonal->lowE[b])
653 {
654 tonal->lowE[b] = logE[b];
655 tonal->highE[b] = MIN32(tonal->lowE[b]+15, tonal->highE[b]);
656 }
657 relativeE += (logE[b]-tonal->lowE[b])/(1e-15f + (tonal->highE[b]-tonal->lowE[b]));
658
659 L1=L2=0;
660 for (i=0;i<NB_FRAMES;i++)
661 {
662 L1 += (float)sqrt(tonal->E[i][b]);
663 L2 += tonal->E[i][b];
664 }
665
666 stationarity = MIN16(0.99f,L1/(float)sqrt(1e-15+NB_FRAMES*L2));
667 stationarity *= stationarity;
668 stationarity *= stationarity;
669 frame_stationarity += stationarity;
670 /*band_tonality[b] = tE/(1e-15+E)*/;
671 band_tonality[b] = MAX16(tE/(1e-15f+E), stationarity*tonal->prev_band_tonality[b]);
672#if 0
673 if (b>=NB_TONAL_SKIP_BANDS)
674 {
675 frame_tonality += tweight[b]*band_tonality[b];
676 tw_sum += tweight[b];
677 }
678#else
679 frame_tonality += band_tonality[b];
680 if (b>=NB_TBANDS-NB_TONAL_SKIP_BANDS)
681 frame_tonality -= band_tonality[b-NB_TBANDS+NB_TONAL_SKIP_BANDS];
682#endif
683 max_frame_tonality = MAX16(max_frame_tonality, (1.f+.03f*(b-NB_TBANDS))*frame_tonality);
684 slope += band_tonality[b]*(b-8);
685 /*printf("%f %f ", band_tonality[b], stationarity);*/
686 tonal->prev_band_tonality[b] = band_tonality[b];
687 }
688
689 leakage_from[0] = band_log2[0];
690 leakage_to[0] = band_log2[0] - LEAKAGE_OFFSET;
691 for (b=1;b<NB_TBANDS+1;b++)
692 {
693 float leak_slope = LEAKAGE_SLOPE*(tbands[b]-tbands[b-1])/4;
694 leakage_from[b] = MIN16(leakage_from[b-1]+leak_slope, band_log2[b]);
695 leakage_to[b] = MAX16(leakage_to[b-1]-leak_slope, band_log2[b]-LEAKAGE_OFFSET);
696 }
697 for (b=NB_TBANDS-2;b>=0;b--)
698 {
699 float leak_slope = LEAKAGE_SLOPE*(tbands[b+1]-tbands[b])/4;
700 leakage_from[b] = MIN16(leakage_from[b+1]+leak_slope, leakage_from[b]);
701 leakage_to[b] = MAX16(leakage_to[b+1]-leak_slope, leakage_to[b]);
702 }
703 celt_assert(NB_TBANDS+1 <= LEAK_BANDS);
704 for (b=0;b<NB_TBANDS+1;b++)
705 {
706 /* leak_boost[] is made up of two terms. The first, based on leakage_to[],
707 represents the boost needed to overcome the amount of analysis leakage
708 cause in a weaker band b by louder neighbouring bands.
709 The second, based on leakage_from[], applies to a loud band b for
710 which the quantization noise causes synthesis leakage to the weaker
711 neighbouring bands. */
712 float boost = MAX16(0, leakage_to[b] - band_log2[b]) +
713 MAX16(0, band_log2[b] - (leakage_from[b]+LEAKAGE_OFFSET));
714 info->leak_boost[b] = IMIN(255, (int)floor(.5 + 64.f*boost));
715 }
716 for (;b<LEAK_BANDS;b++) info->leak_boost[b] = 0;
717
718 for (i=0;i<NB_FRAMES;i++)
719 {
720 int j;
721 float mindist = 1e15f;
722 for (j=0;j<NB_FRAMES;j++)
723 {
724 int k;
725 float dist=0;
726 for (k=0;k<NB_TBANDS;k++)
727 {
728 float tmp;
729 tmp = tonal->logE[i][k] - tonal->logE[j][k];
730 dist += tmp*tmp;
731 }
732 if (j!=i)
733 mindist = MIN32(mindist, dist);
734 }
735 spec_variability += mindist;
736 }
737 spec_variability = (float)sqrt(spec_variability/NB_FRAMES/NB_TBANDS);
738 bandwidth_mask = 0;
739 bandwidth = 0;
740 maxE = 0;
741 noise_floor = 5.7e-4f/(1<<(IMAX(0,lsb_depth-8)));
742 noise_floor *= noise_floor;
743 below_max_pitch=0;
744 above_max_pitch=0;
745 for (b=0;b<NB_TBANDS;b++)
746 {
747 float E=0;
748 float Em;
749 int band_start, band_end;
750 /* Keep a margin of 300 Hz for aliasing */
751 band_start = tbands[b];
752 band_end = tbands[b+1];
753 for (i=band_start;i<band_end;i++)
754 {
755 float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r
756 + out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;
757 E += binE;
758 }
759 E = SCALE_ENER(E);
760 maxE = MAX32(maxE, E);
761 if (band_start < 64)
762 {
763 below_max_pitch += E;
764 } else {
765 above_max_pitch += E;
766 }
767 tonal->meanE[b] = MAX32((1-alphaE2)*tonal->meanE[b], E);
768 Em = MAX32(E, tonal->meanE[b]);
769 /* Consider the band "active" only if all these conditions are met:
770 1) less than 90 dB below the peak band (maximal masking possible considering
771 both the ATH and the loudness-dependent slope of the spreading function)
772 2) above the PCM quantization noise floor
773 We use b+1 because the first CELT band isn't included in tbands[]
774 */
775 if (E*1e9f > maxE && (Em > 3*noise_floor*(band_end-band_start) || E > noise_floor*(band_end-band_start)))
776 bandwidth = b+1;
777 /* Check if the band is masked (see below). */
778 is_masked[b] = E < (tonal->prev_bandwidth >= b+1 ? .01f : .05f)*bandwidth_mask;
779 /* Use a simple follower with 13 dB/Bark slope for spreading function. */
780 bandwidth_mask = MAX32(.05f*bandwidth_mask, E);
781 }
782 /* Special case for the last two bands, for which we don't have spectrum but only
783 the energy above 12 kHz. The difficulty here is that the high-pass we use
784 leaks some LF energy, so we need to increase the threshold without accidentally cutting
785 off the band. */
786 if (tonal->Fs == 48000) {
787 float noise_ratio;
788 float Em;
789 float E = hp_ener*(1.f/(60*60));
790 noise_ratio = tonal->prev_bandwidth==20 ? 10.f : 30.f;
791
792#ifdef FIXED_POINT
793 /* silk_resampler_down2_hp() shifted right by an extra 8 bits. */
794 E *= 256.f*(1.f/Q15ONE)*(1.f/Q15ONE);
795#endif
796 above_max_pitch += E;
797 tonal->meanE[b] = MAX32((1-alphaE2)*tonal->meanE[b], E);
798 Em = MAX32(E, tonal->meanE[b]);
799 if (Em > 3*noise_ratio*noise_floor*160 || E > noise_ratio*noise_floor*160)
800 bandwidth = 20;
801 /* Check if the band is masked (see below). */
802 is_masked[b] = E < (tonal->prev_bandwidth == 20 ? .01f : .05f)*bandwidth_mask;
803 }
804 if (above_max_pitch > below_max_pitch)
805 info->max_pitch_ratio = below_max_pitch/above_max_pitch;
806 else
807 info->max_pitch_ratio = 1;
808 /* In some cases, resampling aliasing can create a small amount of energy in the first band
809 being cut. So if the last band is masked, we don't include it. */
810 if (bandwidth == 20 && is_masked[NB_TBANDS])
811 bandwidth-=2;
812 else if (bandwidth > 0 && bandwidth <= NB_TBANDS && is_masked[bandwidth-1])
813 bandwidth--;
814 if (tonal->count<=2)
815 bandwidth = 20;
816 frame_loudness = 20*(float)log10(frame_loudness);
817 tonal->Etracker = MAX32(tonal->Etracker-.003f, frame_loudness);
818 tonal->lowECount *= (1-alphaE);
819 if (frame_loudness < tonal->Etracker-30)
820 tonal->lowECount += alphaE;
821
822 for (i=0;i<8;i++)
823 {
824 float sum=0;
825 for (b=0;b<16;b++)
826 sum += dct_table[i*16+b]*logE[b];
827 BFCC[i] = sum;
828 }
829 for (i=0;i<8;i++)
830 {
831 float sum=0;
832 for (b=0;b<16;b++)
833 sum += dct_table[i*16+b]*.5f*(tonal->highE[b]+tonal->lowE[b]);
834 midE[i] = sum;
835 }
836
837 frame_stationarity /= NB_TBANDS;
838 relativeE /= NB_TBANDS;
839 if (tonal->count<10)
840 relativeE = .5f;
841 frame_noisiness /= NB_TBANDS;
842#if 1
843 info->activity = frame_noisiness + (1-frame_noisiness)*relativeE;
844#else
845 info->activity = .5*(1+frame_noisiness-frame_stationarity);
846#endif
847 frame_tonality = (max_frame_tonality/(NB_TBANDS-NB_TONAL_SKIP_BANDS));
848 frame_tonality = MAX16(frame_tonality, tonal->prev_tonality*.8f);
849 tonal->prev_tonality = frame_tonality;
850
851 slope /= 8*8;
852 info->tonality_slope = slope;
853
854 tonal->E_count = (tonal->E_count+1)%NB_FRAMES;
855 tonal->count = IMIN(tonal->count+1, ANALYSIS_COUNT_MAX);
856 info->tonality = frame_tonality;
857
858 for (i=0;i<4;i++)
859 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];
860
861 for (i=0;i<4;i++)
862 tonal->cmean[i] = (1-alpha)*tonal->cmean[i] + alpha*BFCC[i];
863
864 for (i=0;i<4;i++)
865 features[4+i] = 0.63246f*(BFCC[i]-tonal->mem[i+24]) + 0.31623f*(tonal->mem[i]-tonal->mem[i+16]);
866 for (i=0;i<3;i++)
867 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];
868
869 if (tonal->count > 5)
870 {
871 for (i=0;i<9;i++)
872 tonal->std[i] = (1-alpha)*tonal->std[i] + alpha*features[i]*features[i];
873 }
874 for (i=0;i<4;i++)
875 features[i] = BFCC[i]-midE[i];
876
877 for (i=0;i<8;i++)
878 {
879 tonal->mem[i+24] = tonal->mem[i+16];
880 tonal->mem[i+16] = tonal->mem[i+8];
881 tonal->mem[i+8] = tonal->mem[i];
882 tonal->mem[i] = BFCC[i];
883 }
884 for (i=0;i<9;i++)
885 features[11+i] = (float)sqrt(tonal->std[i]) - std_feature_bias[i];
886 features[18] = spec_variability - 0.78f;
887 features[20] = info->tonality - 0.154723f;
888 features[21] = info->activity - 0.724643f;
889 features[22] = frame_stationarity - 0.743717f;
890 features[23] = info->tonality_slope + 0.069216f;
891 features[24] = tonal->lowECount - 0.067930f;
892
893 compute_dense(&layer0, layer_out, features);
894 compute_gru(&layer1, tonal->rnn_state, layer_out);
895 compute_dense(&layer2, frame_probs, tonal->rnn_state);
896
897 /* Probability of speech or music vs noise */
898 info->activity_probability = frame_probs[1];
899 info->music_prob = frame_probs[0];
900
901 /*printf("%f %f %f\n", frame_probs[0], frame_probs[1], info->music_prob);*/
902#ifdef MLP_TRAINING
903 for (i=0;i<25;i++)
904 printf("%f ", features[i]);
905 printf("\n");
906#endif
907
908 info->bandwidth = bandwidth;
909 tonal->prev_bandwidth = bandwidth;
910 /*printf("%d %d\n", info->bandwidth, info->opus_bandwidth);*/
911 info->noisiness = frame_noisiness;
912 info->valid = 1;
913 RESTORE_STACK;
914}
915
916void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, const void *analysis_pcm,
917 int analysis_frame_size, int frame_size, int c1, int c2, int C, opus_int32 Fs,
918 int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info)
919{
920 int offset;
921 int pcm_len;
922
923 analysis_frame_size -= analysis_frame_size&1;
924 if (analysis_pcm != NULL)
925 {
926 /* Avoid overflow/wrap-around of the analysis buffer */
927 analysis_frame_size = IMIN((DETECT_SIZE-5)*Fs/50, analysis_frame_size);
928
929 pcm_len = analysis_frame_size - analysis->analysis_offset;
930 offset = analysis->analysis_offset;
931 while (pcm_len>0) {
932 tonality_analysis(analysis, celt_mode, analysis_pcm, IMIN(Fs/50, pcm_len), offset, c1, c2, C, lsb_depth, downmix);
933 offset += Fs/50;
934 pcm_len -= Fs/50;
935 }
936 analysis->analysis_offset = analysis_frame_size;
937
938 analysis->analysis_offset -= frame_size;
939 }
940
941 analysis_info->valid = 0;
942 tonality_get_info(analysis, analysis_info, frame_size);
943}
944
945#endif /* DISABLE_FLOAT_API */
diff --git a/lib/rbcodec/codecs/libopus/analysis.h b/lib/rbcodec/codecs/libopus/analysis.h
new file mode 100644
index 0000000000..289c845e82
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/analysis.h
@@ -0,0 +1,102 @@
1/* Copyright (c) 2011 Xiph.Org Foundation
2 Written by Jean-Marc Valin */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
19 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifndef ANALYSIS_H
29#define ANALYSIS_H
30
31#include "celt.h"
32#include "opus_private.h"
33#include "mlp.h"
34
35#define NB_FRAMES 8
36#define NB_TBANDS 18
37#define ANALYSIS_BUF_SIZE 720 /* 30 ms at 24 kHz */
38
39/* At that point we can stop counting frames because it no longer matters. */
40#define ANALYSIS_COUNT_MAX 10000
41
42#define DETECT_SIZE 100
43
44/* Uncomment this to print the MLP features on stdout. */
45/*#define MLP_TRAINING*/
46
47typedef struct {
48 int arch;
49 int application;
50 opus_int32 Fs;
51#define TONALITY_ANALYSIS_RESET_START angle
52 float angle[240];
53 float d_angle[240];
54 float d2_angle[240];
55 opus_val32 inmem[ANALYSIS_BUF_SIZE];
56 int mem_fill; /* number of usable samples in the buffer */
57 float prev_band_tonality[NB_TBANDS];
58 float prev_tonality;
59 int prev_bandwidth;
60 float E[NB_FRAMES][NB_TBANDS];
61 float logE[NB_FRAMES][NB_TBANDS];
62 float lowE[NB_TBANDS];
63 float highE[NB_TBANDS];
64 float meanE[NB_TBANDS+1];
65 float mem[32];
66 float cmean[8];
67 float std[9];
68 float Etracker;
69 float lowECount;
70 int E_count;
71 int count;
72 int analysis_offset;
73 int write_pos;
74 int read_pos;
75 int read_subframe;
76 float hp_ener_accum;
77 float rnn_state[MAX_NEURONS];
78 opus_val32 downmix_state[3];
79 AnalysisInfo info[DETECT_SIZE];
80} TonalityAnalysisState;
81
82/** Initialize a TonalityAnalysisState struct.
83 *
84 * This performs some possibly slow initialization steps which should
85 * not be repeated every analysis step. No allocated memory is retained
86 * by the state struct, so no cleanup call is required.
87 */
88void tonality_analysis_init(TonalityAnalysisState *analysis, opus_int32 Fs);
89
90/** Reset a TonalityAnalysisState stuct.
91 *
92 * Call this when there's a discontinuity in the data.
93 */
94void tonality_analysis_reset(TonalityAnalysisState *analysis);
95
96void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int len);
97
98void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, const void *analysis_pcm,
99 int analysis_frame_size, int frame_size, int c1, int c2, int C, opus_int32 Fs,
100 int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info);
101
102#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/_kiss_fft_guts.h b/lib/rbcodec/codecs/libopus/celt/_kiss_fft_guts.h
index 8ddb9adc96..17392b3e90 100644
--- a/lib/rbcodec/codecs/libopus/celt/_kiss_fft_guts.h
+++ b/lib/rbcodec/codecs/libopus/celt/_kiss_fft_guts.h
@@ -58,12 +58,12 @@
58# define S_MUL(a,b) MULT16_32_Q15(b, a) 58# define S_MUL(a,b) MULT16_32_Q15(b, a)
59 59
60# define C_MUL(m,a,b) \ 60# define C_MUL(m,a,b) \
61 do{ (m).r = SUB32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \ 61 do{ (m).r = SUB32_ovflw(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
62 (m).i = ADD32(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)); }while(0) 62 (m).i = ADD32_ovflw(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)); }while(0)
63 63
64# define C_MULC(m,a,b) \ 64# define C_MULC(m,a,b) \
65 do{ (m).r = ADD32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \ 65 do{ (m).r = ADD32_ovflw(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
66 (m).i = SUB32(S_MUL((a).i,(b).r) , S_MUL((a).r,(b).i)); }while(0) 66 (m).i = SUB32_ovflw(S_MUL((a).i,(b).r) , S_MUL((a).r,(b).i)); }while(0)
67 67
68# define C_MULBYSCALAR( c, s ) \ 68# define C_MULBYSCALAR( c, s ) \
69 do{ (c).r = S_MUL( (c).r , s ) ;\ 69 do{ (c).r = S_MUL( (c).r , s ) ;\
@@ -77,17 +77,17 @@
77 DIVSCALAR( (c).i , div); }while (0) 77 DIVSCALAR( (c).i , div); }while (0)
78 78
79#define C_ADD( res, a,b)\ 79#define C_ADD( res, a,b)\
80 do {(res).r=ADD32((a).r,(b).r); (res).i=ADD32((a).i,(b).i); \ 80 do {(res).r=ADD32_ovflw((a).r,(b).r); (res).i=ADD32_ovflw((a).i,(b).i); \
81 }while(0) 81 }while(0)
82#define C_SUB( res, a,b)\ 82#define C_SUB( res, a,b)\
83 do {(res).r=SUB32((a).r,(b).r); (res).i=SUB32((a).i,(b).i); \ 83 do {(res).r=SUB32_ovflw((a).r,(b).r); (res).i=SUB32_ovflw((a).i,(b).i); \
84 }while(0) 84 }while(0)
85#define C_ADDTO( res , a)\ 85#define C_ADDTO( res , a)\
86 do {(res).r = ADD32((res).r, (a).r); (res).i = ADD32((res).i,(a).i);\ 86 do {(res).r = ADD32_ovflw((res).r, (a).r); (res).i = ADD32_ovflw((res).i,(a).i);\
87 }while(0) 87 }while(0)
88 88
89#define C_SUBFROM( res , a)\ 89#define C_SUBFROM( res , a)\
90 do {(res).r = ADD32((res).r,(a).r); (res).i = SUB32((res).i,(a).i); \ 90 do {(res).r = ADD32_ovflw((res).r,(a).r); (res).i = SUB32_ovflw((res).i,(a).i); \
91 }while(0) 91 }while(0)
92 92
93#if defined(OPUS_ARM_INLINE_ASM) 93#if defined(OPUS_ARM_INLINE_ASM)
@@ -97,9 +97,8 @@
97#if defined(OPUS_ARM_INLINE_EDSP) 97#if defined(OPUS_ARM_INLINE_EDSP)
98#include "arm/kiss_fft_armv5e.h" 98#include "arm/kiss_fft_armv5e.h"
99#endif 99#endif
100 100#if defined(MIPSr1_ASM)
101#if defined(OPUS_CF_INLINE_ASM) 101#include "mips/kiss_fft_mipsr1.h"
102#include "cf/kiss_fft_cf.h"
103#endif 102#endif
104 103
105#else /* not FIXED_POINT*/ 104#else /* not FIXED_POINT*/
diff --git a/lib/rbcodec/codecs/libopus/celt/arch.h b/lib/rbcodec/codecs/libopus/celt/arch.h
index 035b92ff29..08b07db598 100644
--- a/lib/rbcodec/codecs/libopus/celt/arch.h
+++ b/lib/rbcodec/codecs/libopus/celt/arch.h
@@ -46,30 +46,54 @@
46# endif 46# endif
47# endif 47# endif
48 48
49#if OPUS_GNUC_PREREQ(3, 0)
50#define opus_likely(x) (__builtin_expect(!!(x), 1))
51#define opus_unlikely(x) (__builtin_expect(!!(x), 0))
52#else
53#define opus_likely(x) (!!(x))
54#define opus_unlikely(x) (!!(x))
55#endif
56
49#define CELT_SIG_SCALE 32768.f 57#define CELT_SIG_SCALE 32768.f
50 58
51#define celt_fatal(str) _celt_fatal(str, __FILE__, __LINE__); 59#define CELT_FATAL(str) celt_fatal(str, __FILE__, __LINE__);
52#ifdef ENABLE_ASSERTIONS 60
61#if defined(ENABLE_ASSERTIONS) || defined(ENABLE_HARDENING)
62#ifdef __GNUC__
63__attribute__((noreturn))
64#endif
65void celt_fatal(const char *str, const char *file, int line);
66
67#if defined(CELT_C) && !defined(OVERRIDE_celt_fatal)
53#include <stdio.h> 68#include <stdio.h>
54#include <stdlib.h> 69#include <stdlib.h>
55#ifdef __GNUC__ 70#ifdef __GNUC__
56__attribute__((noreturn)) 71__attribute__((noreturn))
57#endif 72#endif
58static OPUS_INLINE void _celt_fatal(const char *str, const char *file, int line) 73void celt_fatal(const char *str, const char *file, int line)
59{ 74{
60 fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str); 75 fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
61 abort(); 76 abort();
62} 77}
63#define celt_assert(cond) {if (!(cond)) {celt_fatal("assertion failed: " #cond);}} 78#endif
64#define celt_assert2(cond, message) {if (!(cond)) {celt_fatal("assertion failed: " #cond "\n" message);}} 79
80#define celt_assert(cond) {if (!(cond)) {CELT_FATAL("assertion failed: " #cond);}}
81#define celt_assert2(cond, message) {if (!(cond)) {CELT_FATAL("assertion failed: " #cond "\n" message);}}
82#define MUST_SUCCEED(call) celt_assert((call) == OPUS_OK)
65#else 83#else
66#define celt_assert(cond) 84#define celt_assert(cond)
67#define celt_assert2(cond, message) 85#define celt_assert2(cond, message)
86#define MUST_SUCCEED(call) do {if((call) != OPUS_OK) {RESTORE_STACK; return OPUS_INTERNAL_ERROR;} } while (0)
87#endif
88
89#if defined(ENABLE_ASSERTIONS)
90#define celt_sig_assert(cond) {if (!(cond)) {CELT_FATAL("signal assertion failed: " #cond);}}
91#else
92#define celt_sig_assert(cond)
68#endif 93#endif
69 94
70#define IMUL32(a,b) ((a)*(b)) 95#define IMUL32(a,b) ((a)*(b))
71 96
72#define ABS(x) ((x) < 0 ? (-(x)) : (x))
73#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 16-bit value. */ 97#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 16-bit value. */
74#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */ 98#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */
75#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 32-bit value. */ 99#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 32-bit value. */
@@ -79,20 +103,35 @@ static OPUS_INLINE void _celt_fatal(const char *str, const char *file, int line)
79#define UADD32(a,b) ((a)+(b)) 103#define UADD32(a,b) ((a)+(b))
80#define USUB32(a,b) ((a)-(b)) 104#define USUB32(a,b) ((a)-(b))
81 105
106/* Set this if opus_int64 is a native type of the CPU. */
107/* Assume that all LP64 architectures have fast 64-bit types; also x86_64
108 (which can be ILP32 for x32) and Win64 (which is LLP64). */
109#if defined(__x86_64__) || defined(__LP64__) || defined(_WIN64)
110#define OPUS_FAST_INT64 1
111#else
112#define OPUS_FAST_INT64 0
113#endif
114
82#define PRINT_MIPS(file) 115#define PRINT_MIPS(file)
83 116
84#ifdef FIXED_POINT 117#ifdef FIXED_POINT
85 118
86typedef opus_int16 opus_val16; 119typedef opus_int16 opus_val16;
87typedef opus_int32 opus_val32; 120typedef opus_int32 opus_val32;
121typedef opus_int64 opus_val64;
88 122
89typedef opus_val32 celt_sig; 123typedef opus_val32 celt_sig;
90typedef opus_val16 celt_norm; 124typedef opus_val16 celt_norm;
91typedef opus_val32 celt_ener; 125typedef opus_val32 celt_ener;
92 126
127#define celt_isnan(x) 0
128
93#define Q15ONE 32767 129#define Q15ONE 32767
94 130
95#define SIG_SHIFT 12 131#define SIG_SHIFT 12
132/* Safe saturation value for 32-bit signals. Should be less than
133 2^31*(1-0.85) to avoid blowing up on DC at deemphasis.*/
134#define SIG_SAT (300000000)
96 135
97#define NORM_SCALING 16384 136#define NORM_SCALING 16384
98 137
@@ -119,7 +158,9 @@ static OPUS_INLINE opus_int16 SAT16(opus_int32 x) {
119 158
120#include "fixed_generic.h" 159#include "fixed_generic.h"
121 160
122#ifdef OPUS_ARM_INLINE_EDSP 161#ifdef OPUS_ARM_PRESUME_AARCH64_NEON_INTR
162#include "arm/fixed_arm64.h"
163#elif defined (OPUS_ARM_INLINE_EDSP)
123#include "arm/fixed_armv5e.h" 164#include "arm/fixed_armv5e.h"
124#elif defined (OPUS_ARM_INLINE_ASM) 165#elif defined (OPUS_ARM_INLINE_ASM)
125#include "arm/fixed_armv4.h" 166#include "arm/fixed_armv4.h"
@@ -129,8 +170,6 @@ static OPUS_INLINE opus_int16 SAT16(opus_int32 x) {
129#include "fixed_c5x.h" 170#include "fixed_c5x.h"
130#elif defined (TI_C6X_ASM) 171#elif defined (TI_C6X_ASM)
131#include "fixed_c6x.h" 172#include "fixed_c6x.h"
132#elif defined (OPUS_CF_INLINE_ASM)
133#include "cf/fixed_cf.h"
134#endif 173#endif
135 174
136#endif 175#endif
@@ -139,6 +178,7 @@ static OPUS_INLINE opus_int16 SAT16(opus_int32 x) {
139 178
140typedef float opus_val16; 179typedef float opus_val16;
141typedef float opus_val32; 180typedef float opus_val32;
181typedef float opus_val64;
142 182
143typedef float celt_sig; 183typedef float celt_sig;
144typedef float celt_norm; 184typedef float celt_norm;
@@ -178,6 +218,7 @@ static OPUS_INLINE int celt_isnan(float x)
178 218
179#define NEG16(x) (-(x)) 219#define NEG16(x) (-(x))
180#define NEG32(x) (-(x)) 220#define NEG32(x) (-(x))
221#define NEG32_ovflw(x) (-(x))
181#define EXTRACT16(x) (x) 222#define EXTRACT16(x) (x)
182#define EXTEND32(x) (x) 223#define EXTEND32(x) (x)
183#define SHR16(a,shift) (a) 224#define SHR16(a,shift) (a)
@@ -194,6 +235,7 @@ static OPUS_INLINE int celt_isnan(float x)
194#define SATURATE16(x) (x) 235#define SATURATE16(x) (x)
195 236
196#define ROUND16(a,shift) (a) 237#define ROUND16(a,shift) (a)
238#define SROUND16(a,shift) (a)
197#define HALF16(x) (.5f*(x)) 239#define HALF16(x) (.5f*(x))
198#define HALF32(x) (.5f*(x)) 240#define HALF32(x) (.5f*(x))
199 241
@@ -201,6 +243,8 @@ static OPUS_INLINE int celt_isnan(float x)
201#define SUB16(a,b) ((a)-(b)) 243#define SUB16(a,b) ((a)-(b))
202#define ADD32(a,b) ((a)+(b)) 244#define ADD32(a,b) ((a)+(b))
203#define SUB32(a,b) ((a)-(b)) 245#define SUB32(a,b) ((a)-(b))
246#define ADD32_ovflw(a,b) ((a)+(b))
247#define SUB32_ovflw(a,b) ((a)-(b))
204#define MULT16_16_16(a,b) ((a)*(b)) 248#define MULT16_16_16(a,b) ((a)*(b))
205#define MULT16_16(a,b) ((opus_val32)(a)*(opus_val32)(b)) 249#define MULT16_16(a,b) ((opus_val32)(a)*(opus_val32)(b))
206#define MAC16_16(c,a,b) ((c)+(opus_val32)(a)*(opus_val32)(b)) 250#define MAC16_16(c,a,b) ((c)+(opus_val32)(a)*(opus_val32)(b))
@@ -235,9 +279,9 @@ static OPUS_INLINE int celt_isnan(float x)
235 279
236#ifndef GLOBAL_STACK_SIZE 280#ifndef GLOBAL_STACK_SIZE
237#ifdef FIXED_POINT 281#ifdef FIXED_POINT
238#define GLOBAL_STACK_SIZE 100000 282#define GLOBAL_STACK_SIZE 120000
239#else 283#else
240#define GLOBAL_STACK_SIZE 100000 284#define GLOBAL_STACK_SIZE 120000
241#endif 285#endif
242#endif 286#endif
243 287
diff --git a/lib/rbcodec/codecs/libopus/celt/arm/arm2gnu.pl b/lib/rbcodec/codecs/libopus/celt/arm/arm2gnu.pl
new file mode 100755
index 0000000000..a2895f7445
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/arm/arm2gnu.pl
@@ -0,0 +1,353 @@
1#!/usr/bin/perl
2# Copyright (C) 2002-2013 Xiph.org Foundation
3#
4# Redistribution and use in source and binary forms, with or without
5# modification, are permitted provided that the following conditions
6# are met:
7#
8# - Redistributions of source code must retain the above copyright
9# notice, this list of conditions and the following disclaimer.
10#
11# - Redistributions in binary form must reproduce the above copyright
12# notice, this list of conditions and the following disclaimer in the
13# documentation and/or other materials provided with the distribution.
14#
15# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27my $bigend; # little/big endian
28my $nxstack;
29my $apple = 0;
30my $symprefix = "";
31
32$nxstack = 0;
33
34eval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}'
35 if $running_under_some_shell;
36
37while ($ARGV[0] =~ /^-/) {
38 $_ = shift;
39 last if /^--$/;
40 if (/^-n$/) {
41 $nflag++;
42 next;
43 }
44 if (/^--apple$/) {
45 $apple = 1;
46 $symprefix = "_";
47 next;
48 }
49 die "I don't recognize this switch: $_\\n";
50}
51$printit++ unless $nflag;
52
53$\ = "\n"; # automatically add newline on print
54$n=0;
55
56$thumb = 0; # ARM mode by default, not Thumb.
57@proc_stack = ();
58
59printf (" .syntax unified\n");
60
61LINE:
62while (<>) {
63
64 # For ADRLs we need to add a new line after the substituted one.
65 $addPadding = 0;
66
67 # First, we do not dare to touch *anything* inside double quotes, do we?
68 # Second, if you want a dollar character in the string,
69 # insert two of them -- that's how ARM C and assembler treat strings.
70 s/^([A-Za-z_]\w*)[ \t]+DCB[ \t]*\"/$1: .ascii \"/ && do { s/\$\$/\$/g; next };
71 s/\bDCB\b[ \t]*\"/.ascii \"/ && do { s/\$\$/\$/g; next };
72 s/^(\S+)\s+RN\s+(\S+)/$1 .req r$2/ && do { s/\$\$/\$/g; next };
73 # If there's nothing on a line but a comment, don't try to apply any further
74 # substitutions (this is a cheap hack to avoid mucking up the license header)
75 s/^([ \t]*);/$1@/ && do { s/\$\$/\$/g; next };
76 # If substituted -- leave immediately !
77
78 s/@/,:/;
79 s/;/@/;
80 while ( /@.*'/ ) {
81 s/(@.*)'/$1/g;
82 }
83 s/\{FALSE\}/0/g;
84 s/\{TRUE\}/1/g;
85 s/\{(\w\w\w\w+)\}/$1/g;
86 s/\bINCLUDE[ \t]*([^ \t\n]+)/.include \"$1\"/;
87 s/\bGET[ \t]*([^ \t\n]+)/.include \"${ my $x=$1; $x =~ s|\.s|-gnu.S|; \$x }\"/;
88 s/\bIMPORT\b/.extern/;
89 s/\bEXPORT\b\s*/.global $symprefix/;
90 s/^(\s+)\[/$1IF/;
91 s/^(\s+)\|/$1ELSE/;
92 s/^(\s+)\]/$1ENDIF/;
93 s/IF *:DEF:/ .ifdef/;
94 s/IF *:LNOT: *:DEF:/ .ifndef/;
95 s/ELSE/ .else/;
96 s/ENDIF/ .endif/;
97
98 if( /\bIF\b/ ) {
99 s/\bIF\b/ .if/;
100 s/=/==/;
101 }
102 if ( $n == 2) {
103 s/\$/\\/g;
104 }
105 if ($n == 1) {
106 s/\$//g;
107 s/label//g;
108 $n = 2;
109 }
110 if ( /MACRO/ ) {
111 s/MACRO *\n/.macro/;
112 $n=1;
113 }
114 if ( /\bMEND\b/ ) {
115 s/\bMEND\b/.endm/;
116 $n=0;
117 }
118
119 # ".rdata" doesn't work in 'as' version 2.13.2, as it is ".rodata" there.
120 #
121 if ( /\bAREA\b/ ) {
122 my $align;
123 $align = "2";
124 if ( /ALIGN=(\d+)/ ) {
125 $align = $1;
126 }
127 if ( /CODE/ ) {
128 $nxstack = 1;
129 }
130 s/^(.+)CODE(.+)READONLY(.*)/ .text/;
131 s/^(.+)DATA(.+)READONLY(.*)/ .section .rdata/;
132 s/^(.+)\|\|\.data\|\|(.+)/ .data/;
133 s/^(.+)\|\|\.bss\|\|(.+)/ .bss/;
134 s/$/; .p2align $align/;
135 # Enable NEON instructions but don't produce a binary that requires
136 # ARMv7. RVCT does not have equivalent directives, so we just do this
137 # for all CODE areas.
138 if ( /.text/ ) {
139 # Separating .arch, .fpu, etc., by semicolons does not work (gas
140 # thinks the semicolon is part of the arch name, even when there's
141 # whitespace separating them). Sadly this means our line numbers
142 # won't match the original source file (we could use the .line
143 # directive, which is documented to be obsolete, but then gdb will
144 # show the wrong line in the translated source file).
145 s/$/; .arch armv7-a\n .fpu neon\n .object_arch armv4t/ unless ($apple);
146 }
147 }
148
149 s/\|\|\.constdata\$(\d+)\|\|/.L_CONST$1/; # ||.constdata$3||
150 s/\|\|\.bss\$(\d+)\|\|/.L_BSS$1/; # ||.bss$2||
151 s/\|\|\.data\$(\d+)\|\|/.L_DATA$1/; # ||.data$2||
152 s/\|\|([a-zA-Z0-9_]+)\@([a-zA-Z0-9_]+)\|\|/@ $&/;
153 s/^(\s+)\%(\s)/ .space $1/;
154
155 s/\|(.+)\.(\d+)\|/\.$1_$2/; # |L80.123| -> .L80_123
156 s/\bCODE32\b/.code 32/ && do {$thumb = 0};
157 s/\bCODE16\b/.code 16/ && do {$thumb = 1};
158 if (/\bPROC\b/)
159 {
160 my $prefix;
161 my $proc;
162 /^([A-Za-z_\.]\w+)\b/;
163 $proc = $1;
164 $prefix = "";
165 if ($proc)
166 {
167 $prefix = $prefix.sprintf("\t.type\t%s, %%function", $proc) unless ($apple);
168 # Make sure we $prefix isn't empty here (for the $apple case).
169 # We handle mangling the label here, make sure it doesn't match
170 # the label handling below (if $prefix would be empty).
171 $prefix = $prefix."; ";
172 push(@proc_stack, $proc);
173 s/^[A-Za-z_\.]\w+/$symprefix$&:/;
174 }
175 $prefix = $prefix."\t.thumb_func; " if ($thumb);
176 s/\bPROC\b/@ $&/;
177 $_ = $prefix.$_;
178 }
179 s/^(\s*)(S|Q|SH|U|UQ|UH)ASX\b/$1$2ADDSUBX/;
180 s/^(\s*)(S|Q|SH|U|UQ|UH)SAX\b/$1$2SUBADDX/;
181 if (/\bENDP\b/)
182 {
183 my $proc;
184 s/\bENDP\b/@ $&/;
185 $proc = pop(@proc_stack);
186 $_ = "\t.size $proc, .-$proc".$_ if ($proc && !$apple);
187 }
188 s/\bSUBT\b/@ $&/;
189 s/\bDATA\b/@ $&/; # DATA directive is deprecated -- Asm guide, p.7-25
190 s/\bKEEP\b/@ $&/;
191 s/\bEXPORTAS\b/@ $&/;
192 s/\|\|(.)+\bEQU\b/@ $&/;
193 s/\|\|([\w\$]+)\|\|/$1/;
194 s/\bENTRY\b/@ $&/;
195 s/\bASSERT\b/@ $&/;
196 s/\bGBLL\b/@ $&/;
197 s/\bGBLA\b/@ $&/;
198 s/^\W+OPT\b/@ $&/;
199 s/:OR:/|/g;
200 s/:SHL:/<</g;
201 s/:SHR:/>>/g;
202 s/:AND:/&/g;
203 s/:LAND:/&&/g;
204 s/CPSR/cpsr/;
205 s/SPSR/spsr/;
206 s/ALIGN$/.balign 4/;
207 s/ALIGN\s+([0-9x]+)$/.balign $1/;
208 s/psr_cxsf/psr_all/;
209 s/LTORG/.ltorg/;
210 s/^([A-Za-z_]\w*)[ \t]+EQU/ .set $1,/;
211 s/^([A-Za-z_]\w*)[ \t]+SETL/ .set $1,/;
212 s/^([A-Za-z_]\w*)[ \t]+SETA/ .set $1,/;
213 s/^([A-Za-z_]\w*)[ \t]+\*/ .set $1,/;
214
215 # {PC} + 0xdeadfeed --> . + 0xdeadfeed
216 s/\{PC\} \+/ \. +/;
217
218 # Single hex constant on the line !
219 #
220 # >>> NOTE <<<
221 # Double-precision floats in gcc are always mixed-endian, which means
222 # bytes in two words are little-endian, but words are big-endian.
223 # So, 0x0000deadfeed0000 would be stored as 0x0000dead at low address
224 # and 0xfeed0000 at high address.
225 #
226 s/\bDCFD\b[ \t]+0x([a-fA-F0-9]{8})([a-fA-F0-9]{8})/.long 0x$1, 0x$2/;
227 # Only decimal constants on the line, no hex !
228 s/\bDCFD\b[ \t]+([0-9\.\-]+)/.double $1/;
229
230 # Single hex constant on the line !
231# s/\bDCFS\b[ \t]+0x([a-f0-9]{8})([a-f0-9]{8})/.long 0x$1, 0x$2/;
232 # Only decimal constants on the line, no hex !
233# s/\bDCFS\b[ \t]+([0-9\.\-]+)/.double $1/;
234 s/\bDCFS[ \t]+0x/.word 0x/;
235 s/\bDCFS\b/.float/;
236
237 s/^([A-Za-z_]\w*)[ \t]+DCD/$1 .word/;
238 s/\bDCD\b/.word/;
239 s/^([A-Za-z_]\w*)[ \t]+DCW/$1 .short/;
240 s/\bDCW\b/.short/;
241 s/^([A-Za-z_]\w*)[ \t]+DCB/$1 .byte/;
242 s/\bDCB\b/.byte/;
243 s/^([A-Za-z_]\w*)[ \t]+\%/.comm $1,/;
244 s/^[A-Za-z_\.]\w+/$&:/;
245 s/^(\d+)/$1:/;
246 s/\%(\d+)/$1b_or_f/;
247 s/\%[Bb](\d+)/$1b/;
248 s/\%[Ff](\d+)/$1f/;
249 s/\%[Ff][Tt](\d+)/$1f/;
250 s/&([\dA-Fa-f]+)/0x$1/;
251 if ( /\b2_[01]+\b/ ) {
252 s/\b2_([01]+)\b/conv$1&&&&/g;
253 while ( /[01][01][01][01]&&&&/ ) {
254 s/0000&&&&/&&&&0/g;
255 s/0001&&&&/&&&&1/g;
256 s/0010&&&&/&&&&2/g;
257 s/0011&&&&/&&&&3/g;
258 s/0100&&&&/&&&&4/g;
259 s/0101&&&&/&&&&5/g;
260 s/0110&&&&/&&&&6/g;
261 s/0111&&&&/&&&&7/g;
262 s/1000&&&&/&&&&8/g;
263 s/1001&&&&/&&&&9/g;
264 s/1010&&&&/&&&&A/g;
265 s/1011&&&&/&&&&B/g;
266 s/1100&&&&/&&&&C/g;
267 s/1101&&&&/&&&&D/g;
268 s/1110&&&&/&&&&E/g;
269 s/1111&&&&/&&&&F/g;
270 }
271 s/000&&&&/&&&&0/g;
272 s/001&&&&/&&&&1/g;
273 s/010&&&&/&&&&2/g;
274 s/011&&&&/&&&&3/g;
275 s/100&&&&/&&&&4/g;
276 s/101&&&&/&&&&5/g;
277 s/110&&&&/&&&&6/g;
278 s/111&&&&/&&&&7/g;
279 s/00&&&&/&&&&0/g;
280 s/01&&&&/&&&&1/g;
281 s/10&&&&/&&&&2/g;
282 s/11&&&&/&&&&3/g;
283 s/0&&&&/&&&&0/g;
284 s/1&&&&/&&&&1/g;
285 s/conv&&&&/0x/g;
286 }
287
288 if ( /commandline/)
289 {
290 if( /-bigend/)
291 {
292 $bigend=1;
293 }
294 }
295
296 if ( /\bDCDU\b/ )
297 {
298 my $cmd=$_;
299 my $value;
300 my $prefix;
301 my $w1;
302 my $w2;
303 my $w3;
304 my $w4;
305
306 s/\s+DCDU\b/@ $&/;
307
308 $cmd =~ /\bDCDU\b\s+0x(\d+)/;
309 $value = $1;
310 $value =~ /(\w\w)(\w\w)(\w\w)(\w\w)/;
311 $w1 = $1;
312 $w2 = $2;
313 $w3 = $3;
314 $w4 = $4;
315
316 if( $bigend ne "")
317 {
318 # big endian
319 $prefix = "\t.byte\t0x".$w1.";".
320 "\t.byte\t0x".$w2.";".
321 "\t.byte\t0x".$w3.";".
322 "\t.byte\t0x".$w4."; ";
323 }
324 else
325 {
326 # little endian
327 $prefix = "\t.byte\t0x".$w4.";".
328 "\t.byte\t0x".$w3.";".
329 "\t.byte\t0x".$w2.";".
330 "\t.byte\t0x".$w1."; ";
331 }
332 $_=$prefix.$_;
333 }
334
335 if ( /\badrl\b/i )
336 {
337 s/\badrl\s+(\w+)\s*,\s*(\w+)/ldr $1,=$2/i;
338 $addPadding = 1;
339 }
340 s/\bEND\b/@ END/;
341} continue {
342 printf ("%s", $_) if $printit;
343 if ($addPadding != 0)
344 {
345 printf (" mov r0,r0\n");
346 $addPadding = 0;
347 }
348}
349#If we had a code section, mark that this object doesn't need an executable
350# stack.
351if ($nxstack && !$apple) {
352 printf (" .section\t.note.GNU-stack,\"\",\%\%progbits\n");
353}
diff --git a/lib/rbcodec/codecs/libopus/celt/arm/arm_celt_map.c b/lib/rbcodec/codecs/libopus/celt/arm/arm_celt_map.c
new file mode 100644
index 0000000000..ca988b66f5
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/arm/arm_celt_map.c
@@ -0,0 +1,160 @@
1/* Copyright (c) 2010 Xiph.Org Foundation
2 * Copyright (c) 2013 Parrot */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "pitch.h"
33#include "kiss_fft.h"
34#include "mdct.h"
35
36#if defined(OPUS_HAVE_RTCD)
37
38# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)
39opus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x, const opus_val16 *y, int N) = {
40 celt_inner_prod_c, /* ARMv4 */
41 celt_inner_prod_c, /* EDSP */
42 celt_inner_prod_c, /* Media */
43 celt_inner_prod_neon /* NEON */
44};
45
46void (*const DUAL_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
47 int N, opus_val32 *xy1, opus_val32 *xy2) = {
48 dual_inner_prod_c, /* ARMv4 */
49 dual_inner_prod_c, /* EDSP */
50 dual_inner_prod_c, /* Media */
51 dual_inner_prod_neon /* NEON */
52};
53# endif
54
55# if defined(FIXED_POINT)
56# if ((defined(OPUS_ARM_MAY_HAVE_NEON) && !defined(OPUS_ARM_PRESUME_NEON)) || \
57 (defined(OPUS_ARM_MAY_HAVE_MEDIA) && !defined(OPUS_ARM_PRESUME_MEDIA)) || \
58 (defined(OPUS_ARM_MAY_HAVE_EDSP) && !defined(OPUS_ARM_PRESUME_EDSP)))
59opus_val32 (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
60 const opus_val16 *, opus_val32 *, int, int, int) = {
61 celt_pitch_xcorr_c, /* ARMv4 */
62 MAY_HAVE_EDSP(celt_pitch_xcorr), /* EDSP */
63 MAY_HAVE_MEDIA(celt_pitch_xcorr), /* Media */
64 MAY_HAVE_NEON(celt_pitch_xcorr) /* NEON */
65};
66
67# endif
68# else /* !FIXED_POINT */
69# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)
70void (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
71 const opus_val16 *, opus_val32 *, int, int, int) = {
72 celt_pitch_xcorr_c, /* ARMv4 */
73 celt_pitch_xcorr_c, /* EDSP */
74 celt_pitch_xcorr_c, /* Media */
75 celt_pitch_xcorr_float_neon /* Neon */
76};
77# endif
78# endif /* FIXED_POINT */
79
80#if defined(FIXED_POINT) && defined(OPUS_HAVE_RTCD) && \
81 defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)
82
83void (*const XCORR_KERNEL_IMPL[OPUS_ARCHMASK + 1])(
84 const opus_val16 *x,
85 const opus_val16 *y,
86 opus_val32 sum[4],
87 int len
88) = {
89 xcorr_kernel_c, /* ARMv4 */
90 xcorr_kernel_c, /* EDSP */
91 xcorr_kernel_c, /* Media */
92 xcorr_kernel_neon_fixed, /* Neon */
93};
94
95#endif
96
97# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
98# if defined(HAVE_ARM_NE10)
99# if defined(CUSTOM_MODES)
100int (*const OPUS_FFT_ALLOC_ARCH_IMPL[OPUS_ARCHMASK+1])(kiss_fft_state *st) = {
101 opus_fft_alloc_arch_c, /* ARMv4 */
102 opus_fft_alloc_arch_c, /* EDSP */
103 opus_fft_alloc_arch_c, /* Media */
104 opus_fft_alloc_arm_neon /* Neon with NE10 library support */
105};
106
107void (*const OPUS_FFT_FREE_ARCH_IMPL[OPUS_ARCHMASK+1])(kiss_fft_state *st) = {
108 opus_fft_free_arch_c, /* ARMv4 */
109 opus_fft_free_arch_c, /* EDSP */
110 opus_fft_free_arch_c, /* Media */
111 opus_fft_free_arm_neon /* Neon with NE10 */
112};
113# endif /* CUSTOM_MODES */
114
115void (*const OPUS_FFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg,
116 const kiss_fft_cpx *fin,
117 kiss_fft_cpx *fout) = {
118 opus_fft_c, /* ARMv4 */
119 opus_fft_c, /* EDSP */
120 opus_fft_c, /* Media */
121 opus_fft_neon /* Neon with NE10 */
122};
123
124void (*const OPUS_IFFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg,
125 const kiss_fft_cpx *fin,
126 kiss_fft_cpx *fout) = {
127 opus_ifft_c, /* ARMv4 */
128 opus_ifft_c, /* EDSP */
129 opus_ifft_c, /* Media */
130 opus_ifft_neon /* Neon with NE10 */
131};
132
133void (*const CLT_MDCT_FORWARD_IMPL[OPUS_ARCHMASK+1])(const mdct_lookup *l,
134 kiss_fft_scalar *in,
135 kiss_fft_scalar * OPUS_RESTRICT out,
136 const opus_val16 *window,
137 int overlap, int shift,
138 int stride, int arch) = {
139 clt_mdct_forward_c, /* ARMv4 */
140 clt_mdct_forward_c, /* EDSP */
141 clt_mdct_forward_c, /* Media */
142 clt_mdct_forward_neon /* Neon with NE10 */
143};
144
145void (*const CLT_MDCT_BACKWARD_IMPL[OPUS_ARCHMASK+1])(const mdct_lookup *l,
146 kiss_fft_scalar *in,
147 kiss_fft_scalar * OPUS_RESTRICT out,
148 const opus_val16 *window,
149 int overlap, int shift,
150 int stride, int arch) = {
151 clt_mdct_backward_c, /* ARMv4 */
152 clt_mdct_backward_c, /* EDSP */
153 clt_mdct_backward_c, /* Media */
154 clt_mdct_backward_neon /* Neon with NE10 */
155};
156
157# endif /* HAVE_ARM_NE10 */
158# endif /* OPUS_ARM_MAY_HAVE_NEON_INTR */
159
160#endif /* OPUS_HAVE_RTCD */
diff --git a/lib/rbcodec/codecs/libopus/celt/arm/armcpu.c b/lib/rbcodec/codecs/libopus/celt/arm/armcpu.c
new file mode 100644
index 0000000000..694a63b78e
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/arm/armcpu.c
@@ -0,0 +1,185 @@
1/* Copyright (c) 2010 Xiph.Org Foundation
2 * Copyright (c) 2013 Parrot */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28/* Original code from libtheora modified to suit to Opus */
29
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
34#ifdef OPUS_HAVE_RTCD
35
36#include "armcpu.h"
37#include "cpu_support.h"
38#include "os_support.h"
39#include "opus_types.h"
40#include "arch.h"
41
42#define OPUS_CPU_ARM_V4_FLAG (1<<OPUS_ARCH_ARM_V4)
43#define OPUS_CPU_ARM_EDSP_FLAG (1<<OPUS_ARCH_ARM_EDSP)
44#define OPUS_CPU_ARM_MEDIA_FLAG (1<<OPUS_ARCH_ARM_MEDIA)
45#define OPUS_CPU_ARM_NEON_FLAG (1<<OPUS_ARCH_ARM_NEON)
46
47#if defined(_MSC_VER)
48/*For GetExceptionCode() and EXCEPTION_ILLEGAL_INSTRUCTION.*/
49# define WIN32_LEAN_AND_MEAN
50# define WIN32_EXTRA_LEAN
51# include <windows.h>
52
53static OPUS_INLINE opus_uint32 opus_cpu_capabilities(void){
54 opus_uint32 flags;
55 flags=0;
56 /* MSVC has no OPUS_INLINE __asm support for ARM, but it does let you __emit
57 * instructions via their assembled hex code.
58 * All of these instructions should be essentially nops. */
59# if defined(OPUS_ARM_MAY_HAVE_EDSP) || defined(OPUS_ARM_MAY_HAVE_MEDIA) \
60 || defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
61 __try{
62 /*PLD [r13]*/
63 __emit(0xF5DDF000);
64 flags|=OPUS_CPU_ARM_EDSP_FLAG;
65 }
66 __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){
67 /*Ignore exception.*/
68 }
69# if defined(OPUS_ARM_MAY_HAVE_MEDIA) \
70 || defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
71 __try{
72 /*SHADD8 r3,r3,r3*/
73 __emit(0xE6333F93);
74 flags|=OPUS_CPU_ARM_MEDIA_FLAG;
75 }
76 __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){
77 /*Ignore exception.*/
78 }
79# if defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
80 __try{
81 /*VORR q0,q0,q0*/
82 __emit(0xF2200150);
83 flags|=OPUS_CPU_ARM_NEON_FLAG;
84 }
85 __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){
86 /*Ignore exception.*/
87 }
88# endif
89# endif
90# endif
91 return flags;
92}
93
94#elif defined(__linux__)
95/* Linux based */
96opus_uint32 opus_cpu_capabilities(void)
97{
98 opus_uint32 flags = 0;
99 FILE *cpuinfo;
100
101 /* Reading /proc/self/auxv would be easier, but that doesn't work reliably on
102 * Android */
103 cpuinfo = fopen("/proc/cpuinfo", "r");
104
105 if(cpuinfo != NULL)
106 {
107 /* 512 should be enough for anybody (it's even enough for all the flags that
108 * x86 has accumulated... so far). */
109 char buf[512];
110
111 while(fgets(buf, 512, cpuinfo) != NULL)
112 {
113# if defined(OPUS_ARM_MAY_HAVE_EDSP) || defined(OPUS_ARM_MAY_HAVE_MEDIA) \
114 || defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
115 /* Search for edsp and neon flag */
116 if(memcmp(buf, "Features", 8) == 0)
117 {
118 char *p;
119 p = strstr(buf, " edsp");
120 if(p != NULL && (p[5] == ' ' || p[5] == '\n'))
121 flags |= OPUS_CPU_ARM_EDSP_FLAG;
122
123# if defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
124 p = strstr(buf, " neon");
125 if(p != NULL && (p[5] == ' ' || p[5] == '\n'))
126 flags |= OPUS_CPU_ARM_NEON_FLAG;
127# endif
128 }
129# endif
130
131# if defined(OPUS_ARM_MAY_HAVE_MEDIA) \
132 || defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
133 /* Search for media capabilities (>= ARMv6) */
134 if(memcmp(buf, "CPU architecture:", 17) == 0)
135 {
136 int version;
137 version = atoi(buf+17);
138
139 if(version >= 6)
140 flags |= OPUS_CPU_ARM_MEDIA_FLAG;
141 }
142# endif
143 }
144
145 fclose(cpuinfo);
146 }
147 return flags;
148}
149#else
150/* The feature registers which can tell us what the processor supports are
151 * accessible in priveleged modes only, so we can't have a general user-space
152 * detection method like on x86.*/
153# error "Configured to use ARM asm but no CPU detection method available for " \
154 "your platform. Reconfigure with --disable-rtcd (or send patches)."
155#endif
156
157int opus_select_arch(void)
158{
159 opus_uint32 flags = opus_cpu_capabilities();
160 int arch = 0;
161
162 if(!(flags & OPUS_CPU_ARM_EDSP_FLAG)) {
163 /* Asserts ensure arch values are sequential */
164 celt_assert(arch == OPUS_ARCH_ARM_V4);
165 return arch;
166 }
167 arch++;
168
169 if(!(flags & OPUS_CPU_ARM_MEDIA_FLAG)) {
170 celt_assert(arch == OPUS_ARCH_ARM_EDSP);
171 return arch;
172 }
173 arch++;
174
175 if(!(flags & OPUS_CPU_ARM_NEON_FLAG)) {
176 celt_assert(arch == OPUS_ARCH_ARM_MEDIA);
177 return arch;
178 }
179 arch++;
180
181 celt_assert(arch == OPUS_ARCH_ARM_NEON);
182 return arch;
183}
184
185#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/arm/armcpu.h b/lib/rbcodec/codecs/libopus/celt/arm/armcpu.h
new file mode 100644
index 0000000000..820262ff5f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/arm/armcpu.h
@@ -0,0 +1,77 @@
1/* Copyright (c) 2010 Xiph.Org Foundation
2 * Copyright (c) 2013 Parrot */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#if !defined(ARMCPU_H)
29# define ARMCPU_H
30
31# if defined(OPUS_ARM_MAY_HAVE_EDSP)
32# define MAY_HAVE_EDSP(name) name ## _edsp
33# else
34# define MAY_HAVE_EDSP(name) name ## _c
35# endif
36
37# if defined(OPUS_ARM_MAY_HAVE_MEDIA)
38# define MAY_HAVE_MEDIA(name) name ## _media
39# else
40# define MAY_HAVE_MEDIA(name) MAY_HAVE_EDSP(name)
41# endif
42
43# if defined(OPUS_ARM_MAY_HAVE_NEON)
44# define MAY_HAVE_NEON(name) name ## _neon
45# else
46# define MAY_HAVE_NEON(name) MAY_HAVE_MEDIA(name)
47# endif
48
49# if defined(OPUS_ARM_PRESUME_EDSP)
50# define PRESUME_EDSP(name) name ## _edsp
51# else
52# define PRESUME_EDSP(name) name ## _c
53# endif
54
55# if defined(OPUS_ARM_PRESUME_MEDIA)
56# define PRESUME_MEDIA(name) name ## _media
57# else
58# define PRESUME_MEDIA(name) PRESUME_EDSP(name)
59# endif
60
61# if defined(OPUS_ARM_PRESUME_NEON)
62# define PRESUME_NEON(name) name ## _neon
63# else
64# define PRESUME_NEON(name) PRESUME_MEDIA(name)
65# endif
66
67# if defined(OPUS_HAVE_RTCD)
68int opus_select_arch(void);
69
70#define OPUS_ARCH_ARM_V4 (0)
71#define OPUS_ARCH_ARM_EDSP (1)
72#define OPUS_ARCH_ARM_MEDIA (2)
73#define OPUS_ARCH_ARM_NEON (3)
74
75# endif
76
77#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/arm/armopts.s.in b/lib/rbcodec/codecs/libopus/celt/arm/armopts.s.in
new file mode 100644
index 0000000000..3d8aaf2754
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/arm/armopts.s.in
@@ -0,0 +1,37 @@
1/* Copyright (C) 2013 Mozilla Corporation */
2/*
3 Redistribution and use in source and binary forms, with or without
4 modification, are permitted provided that the following conditions
5 are met:
6
7 - Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9
10 - Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
18 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*/
26
27; Set the following to 1 if we have EDSP instructions
28; (LDRD/STRD, etc., ARMv5E and later).
29OPUS_ARM_MAY_HAVE_EDSP * @OPUS_ARM_MAY_HAVE_EDSP@
30
31; Set the following to 1 if we have ARMv6 media instructions.
32OPUS_ARM_MAY_HAVE_MEDIA * @OPUS_ARM_MAY_HAVE_MEDIA@
33
34; Set the following to 1 if we have NEON (some ARMv7)
35OPUS_ARM_MAY_HAVE_NEON * @OPUS_ARM_MAY_HAVE_NEON@
36
37END
diff --git a/lib/rbcodec/codecs/libopus/celt/arm/celt_fft_ne10.c b/lib/rbcodec/codecs/libopus/celt/arm/celt_fft_ne10.c
new file mode 100644
index 0000000000..ea5fd7808b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/arm/celt_fft_ne10.c
@@ -0,0 +1,173 @@
1/* Copyright (c) 2015 Xiph.Org Foundation
2 Written by Viswanath Puttagunta */
3/**
4 @file celt_fft_ne10.c
5 @brief ARM Neon optimizations for fft using NE10 library
6 */
7
8/*
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions
11 are met:
12
13 - Redistributions of source code must retain the above copyright
14 notice, this list of conditions and the following disclaimer.
15
16 - Redistributions in binary form must reproduce the above copyright
17 notice, this list of conditions and the following disclaimer in the
18 documentation and/or other materials provided with the distribution.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
24 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#ifndef SKIP_CONFIG_H
34#ifdef HAVE_CONFIG_H
35#include "config.h"
36#endif
37#endif
38
39#include <NE10_dsp.h>
40#include "os_support.h"
41#include "kiss_fft.h"
42#include "stack_alloc.h"
43
44#if !defined(FIXED_POINT)
45# define NE10_FFT_ALLOC_C2C_TYPE_NEON ne10_fft_alloc_c2c_float32_neon
46# define NE10_FFT_CFG_TYPE_T ne10_fft_cfg_float32_t
47# define NE10_FFT_STATE_TYPE_T ne10_fft_state_float32_t
48# define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_float32
49# define NE10_FFT_CPX_TYPE_T ne10_fft_cpx_float32_t
50# define NE10_FFT_C2C_1D_TYPE_NEON ne10_fft_c2c_1d_float32_neon
51#else
52# define NE10_FFT_ALLOC_C2C_TYPE_NEON(nfft) ne10_fft_alloc_c2c_int32_neon(nfft)
53# define NE10_FFT_CFG_TYPE_T ne10_fft_cfg_int32_t
54# define NE10_FFT_STATE_TYPE_T ne10_fft_state_int32_t
55# define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_int32
56# define NE10_FFT_DESTROY_C2C_TYPE ne10_fft_destroy_c2c_int32
57# define NE10_FFT_CPX_TYPE_T ne10_fft_cpx_int32_t
58# define NE10_FFT_C2C_1D_TYPE_NEON ne10_fft_c2c_1d_int32_neon
59#endif
60
61#if defined(CUSTOM_MODES)
62
63/* nfft lengths in NE10 that support scaled fft */
64# define NE10_FFTSCALED_SUPPORT_MAX 4
65static const int ne10_fft_scaled_support[NE10_FFTSCALED_SUPPORT_MAX] = {
66 480, 240, 120, 60
67};
68
69int opus_fft_alloc_arm_neon(kiss_fft_state *st)
70{
71 int i;
72 size_t memneeded = sizeof(struct arch_fft_state);
73
74 st->arch_fft = (arch_fft_state *)opus_alloc(memneeded);
75 if (!st->arch_fft)
76 return -1;
77
78 for (i = 0; i < NE10_FFTSCALED_SUPPORT_MAX; i++) {
79 if(st->nfft == ne10_fft_scaled_support[i])
80 break;
81 }
82 if (i == NE10_FFTSCALED_SUPPORT_MAX) {
83 /* This nfft length (scaled fft) is not supported in NE10 */
84 st->arch_fft->is_supported = 0;
85 st->arch_fft->priv = NULL;
86 }
87 else {
88 st->arch_fft->is_supported = 1;
89 st->arch_fft->priv = (void *)NE10_FFT_ALLOC_C2C_TYPE_NEON(st->nfft);
90 if (st->arch_fft->priv == NULL) {
91 return -1;
92 }
93 }
94 return 0;
95}
96
97void opus_fft_free_arm_neon(kiss_fft_state *st)
98{
99 NE10_FFT_CFG_TYPE_T cfg;
100
101 if (!st->arch_fft)
102 return;
103
104 cfg = (NE10_FFT_CFG_TYPE_T)st->arch_fft->priv;
105 if (cfg)
106 NE10_FFT_DESTROY_C2C_TYPE(cfg);
107 opus_free(st->arch_fft);
108}
109#endif
110
111void opus_fft_neon(const kiss_fft_state *st,
112 const kiss_fft_cpx *fin,
113 kiss_fft_cpx *fout)
114{
115 NE10_FFT_STATE_TYPE_T state;
116 NE10_FFT_CFG_TYPE_T cfg = &state;
117 VARDECL(NE10_FFT_CPX_TYPE_T, buffer);
118 SAVE_STACK;
119 ALLOC(buffer, st->nfft, NE10_FFT_CPX_TYPE_T);
120
121 if (!st->arch_fft->is_supported) {
122 /* This nfft length (scaled fft) not supported in NE10 */
123 opus_fft_c(st, fin, fout);
124 }
125 else {
126 memcpy((void *)cfg, st->arch_fft->priv, sizeof(NE10_FFT_STATE_TYPE_T));
127 state.buffer = (NE10_FFT_CPX_TYPE_T *)&buffer[0];
128#if !defined(FIXED_POINT)
129 state.is_forward_scaled = 1;
130
131 NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
132 (NE10_FFT_CPX_TYPE_T *)fin,
133 cfg, 0);
134#else
135 NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
136 (NE10_FFT_CPX_TYPE_T *)fin,
137 cfg, 0, 1);
138#endif
139 }
140 RESTORE_STACK;
141}
142
143void opus_ifft_neon(const kiss_fft_state *st,
144 const kiss_fft_cpx *fin,
145 kiss_fft_cpx *fout)
146{
147 NE10_FFT_STATE_TYPE_T state;
148 NE10_FFT_CFG_TYPE_T cfg = &state;
149 VARDECL(NE10_FFT_CPX_TYPE_T, buffer);
150 SAVE_STACK;
151 ALLOC(buffer, st->nfft, NE10_FFT_CPX_TYPE_T);
152
153 if (!st->arch_fft->is_supported) {
154 /* This nfft length (scaled fft) not supported in NE10 */
155 opus_ifft_c(st, fin, fout);
156 }
157 else {
158 memcpy((void *)cfg, st->arch_fft->priv, sizeof(NE10_FFT_STATE_TYPE_T));
159 state.buffer = (NE10_FFT_CPX_TYPE_T *)&buffer[0];
160#if !defined(FIXED_POINT)
161 state.is_backward_scaled = 0;
162
163 NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
164 (NE10_FFT_CPX_TYPE_T *)fin,
165 cfg, 1);
166#else
167 NE10_FFT_C2C_1D_TYPE_NEON((NE10_FFT_CPX_TYPE_T *)fout,
168 (NE10_FFT_CPX_TYPE_T *)fin,
169 cfg, 1, 0);
170#endif
171 }
172 RESTORE_STACK;
173}
diff --git a/lib/rbcodec/codecs/libopus/celt/arm/celt_mdct_ne10.c b/lib/rbcodec/codecs/libopus/celt/arm/celt_mdct_ne10.c
new file mode 100644
index 0000000000..3531d02d10
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/arm/celt_mdct_ne10.c
@@ -0,0 +1,258 @@
1/* Copyright (c) 2015 Xiph.Org Foundation
2 Written by Viswanath Puttagunta */
3/**
4 @file celt_mdct_ne10.c
5 @brief ARM Neon optimizations for mdct using NE10 library
6 */
7
8/*
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions
11 are met:
12
13 - Redistributions of source code must retain the above copyright
14 notice, this list of conditions and the following disclaimer.
15
16 - Redistributions in binary form must reproduce the above copyright
17 notice, this list of conditions and the following disclaimer in the
18 documentation and/or other materials provided with the distribution.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
24 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#ifndef SKIP_CONFIG_H
34#ifdef HAVE_CONFIG_H
35#include "config.h"
36#endif
37#endif
38
39#include "kiss_fft.h"
40#include "_kiss_fft_guts.h"
41#include "mdct.h"
42#include "stack_alloc.h"
43
44void clt_mdct_forward_neon(const mdct_lookup *l,
45 kiss_fft_scalar *in,
46 kiss_fft_scalar * OPUS_RESTRICT out,
47 const opus_val16 *window,
48 int overlap, int shift, int stride, int arch)
49{
50 int i;
51 int N, N2, N4;
52 VARDECL(kiss_fft_scalar, f);
53 VARDECL(kiss_fft_cpx, f2);
54 const kiss_fft_state *st = l->kfft[shift];
55 const kiss_twiddle_scalar *trig;
56
57 SAVE_STACK;
58
59 N = l->n;
60 trig = l->trig;
61 for (i=0;i<shift;i++)
62 {
63 N >>= 1;
64 trig += N;
65 }
66 N2 = N>>1;
67 N4 = N>>2;
68
69 ALLOC(f, N2, kiss_fft_scalar);
70 ALLOC(f2, N4, kiss_fft_cpx);
71
72 /* Consider the input to be composed of four blocks: [a, b, c, d] */
73 /* Window, shuffle, fold */
74 {
75 /* Temp pointers to make it really clear to the compiler what we're doing */
76 const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1);
77 const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1);
78 kiss_fft_scalar * OPUS_RESTRICT yp = f;
79 const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1);
80 const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;
81 for(i=0;i<((overlap+3)>>2);i++)
82 {
83 /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/
84 *yp++ = MULT16_32_Q15(*wp2, xp1[N2]) + MULT16_32_Q15(*wp1,*xp2);
85 *yp++ = MULT16_32_Q15(*wp1, *xp1) - MULT16_32_Q15(*wp2, xp2[-N2]);
86 xp1+=2;
87 xp2-=2;
88 wp1+=2;
89 wp2-=2;
90 }
91 wp1 = window;
92 wp2 = window+overlap-1;
93 for(;i<N4-((overlap+3)>>2);i++)
94 {
95 /* Real part arranged as a-bR, Imag part arranged as -c-dR */
96 *yp++ = *xp2;
97 *yp++ = *xp1;
98 xp1+=2;
99 xp2-=2;
100 }
101 for(;i<N4;i++)
102 {
103 /* Real part arranged as a-bR, Imag part arranged as -c-dR */
104 *yp++ = -MULT16_32_Q15(*wp1, xp1[-N2]) + MULT16_32_Q15(*wp2, *xp2);
105 *yp++ = MULT16_32_Q15(*wp2, *xp1) + MULT16_32_Q15(*wp1, xp2[N2]);
106 xp1+=2;
107 xp2-=2;
108 wp1+=2;
109 wp2-=2;
110 }
111 }
112 /* Pre-rotation */
113 {
114 kiss_fft_scalar * OPUS_RESTRICT yp = f;
115 const kiss_twiddle_scalar *t = &trig[0];
116 for(i=0;i<N4;i++)
117 {
118 kiss_fft_cpx yc;
119 kiss_twiddle_scalar t0, t1;
120 kiss_fft_scalar re, im, yr, yi;
121 t0 = t[i];
122 t1 = t[N4+i];
123 re = *yp++;
124 im = *yp++;
125 yr = S_MUL(re,t0) - S_MUL(im,t1);
126 yi = S_MUL(im,t0) + S_MUL(re,t1);
127 yc.r = yr;
128 yc.i = yi;
129 f2[i] = yc;
130 }
131 }
132
133 opus_fft(st, f2, (kiss_fft_cpx *)f, arch);
134
135 /* Post-rotate */
136 {
137 /* Temp pointers to make it really clear to the compiler what we're doing */
138 const kiss_fft_cpx * OPUS_RESTRICT fp = (kiss_fft_cpx *)f;
139 kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
140 kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1);
141 const kiss_twiddle_scalar *t = &trig[0];
142 /* Temp pointers to make it really clear to the compiler what we're doing */
143 for(i=0;i<N4;i++)
144 {
145 kiss_fft_scalar yr, yi;
146 yr = S_MUL(fp->i,t[N4+i]) - S_MUL(fp->r,t[i]);
147 yi = S_MUL(fp->r,t[N4+i]) + S_MUL(fp->i,t[i]);
148 *yp1 = yr;
149 *yp2 = yi;
150 fp++;
151 yp1 += 2*stride;
152 yp2 -= 2*stride;
153 }
154 }
155 RESTORE_STACK;
156}
157
158void clt_mdct_backward_neon(const mdct_lookup *l,
159 kiss_fft_scalar *in,
160 kiss_fft_scalar * OPUS_RESTRICT out,
161 const opus_val16 * OPUS_RESTRICT window,
162 int overlap, int shift, int stride, int arch)
163{
164 int i;
165 int N, N2, N4;
166 VARDECL(kiss_fft_scalar, f);
167 const kiss_twiddle_scalar *trig;
168 const kiss_fft_state *st = l->kfft[shift];
169
170 N = l->n;
171 trig = l->trig;
172 for (i=0;i<shift;i++)
173 {
174 N >>= 1;
175 trig += N;
176 }
177 N2 = N>>1;
178 N4 = N>>2;
179
180 ALLOC(f, N2, kiss_fft_scalar);
181
182 /* Pre-rotate */
183 {
184 /* Temp pointers to make it really clear to the compiler what we're doing */
185 const kiss_fft_scalar * OPUS_RESTRICT xp1 = in;
186 const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1);
187 kiss_fft_scalar * OPUS_RESTRICT yp = f;
188 const kiss_twiddle_scalar * OPUS_RESTRICT t = &trig[0];
189 for(i=0;i<N4;i++)
190 {
191 kiss_fft_scalar yr, yi;
192 yr = S_MUL(*xp2, t[i]) + S_MUL(*xp1, t[N4+i]);
193 yi = S_MUL(*xp1, t[i]) - S_MUL(*xp2, t[N4+i]);
194 yp[2*i] = yr;
195 yp[2*i+1] = yi;
196 xp1+=2*stride;
197 xp2-=2*stride;
198 }
199 }
200
201 opus_ifft(st, (kiss_fft_cpx *)f, (kiss_fft_cpx*)(out+(overlap>>1)), arch);
202
203 /* Post-rotate and de-shuffle from both ends of the buffer at once to make
204 it in-place. */
205 {
206 kiss_fft_scalar * yp0 = out+(overlap>>1);
207 kiss_fft_scalar * yp1 = out+(overlap>>1)+N2-2;
208 const kiss_twiddle_scalar *t = &trig[0];
209 /* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the
210 middle pair will be computed twice. */
211 for(i=0;i<(N4+1)>>1;i++)
212 {
213 kiss_fft_scalar re, im, yr, yi;
214 kiss_twiddle_scalar t0, t1;
215 re = yp0[0];
216 im = yp0[1];
217 t0 = t[i];
218 t1 = t[N4+i];
219 /* We'd scale up by 2 here, but instead it's done when mixing the windows */
220 yr = S_MUL(re,t0) + S_MUL(im,t1);
221 yi = S_MUL(re,t1) - S_MUL(im,t0);
222 re = yp1[0];
223 im = yp1[1];
224 yp0[0] = yr;
225 yp1[1] = yi;
226
227 t0 = t[(N4-i-1)];
228 t1 = t[(N2-i-1)];
229 /* We'd scale up by 2 here, but instead it's done when mixing the windows */
230 yr = S_MUL(re,t0) + S_MUL(im,t1);
231 yi = S_MUL(re,t1) - S_MUL(im,t0);
232 yp1[0] = yr;
233 yp0[1] = yi;
234 yp0 += 2;
235 yp1 -= 2;
236 }
237 }
238
239 /* Mirror on both sides for TDAC */
240 {
241 kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1;
242 kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
243 const opus_val16 * OPUS_RESTRICT wp1 = window;
244 const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1;
245
246 for(i = 0; i < overlap/2; i++)
247 {
248 kiss_fft_scalar x1, x2;
249 x1 = *xp1;
250 x2 = *yp1;
251 *yp1++ = MULT16_32_Q15(*wp2, x2) - MULT16_32_Q15(*wp1, x1);
252 *xp1-- = MULT16_32_Q15(*wp1, x2) + MULT16_32_Q15(*wp2, x1);
253 wp1++;
254 wp2--;
255 }
256 }
257 RESTORE_STACK;
258}
diff --git a/lib/rbcodec/codecs/libopus/celt/arm/celt_neon_intr.c b/lib/rbcodec/codecs/libopus/celt/arm/celt_neon_intr.c
new file mode 100644
index 0000000000..effda769d0
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/arm/celt_neon_intr.c
@@ -0,0 +1,211 @@
1/* Copyright (c) 2014-2015 Xiph.Org Foundation
2 Written by Viswanath Puttagunta */
3/**
4 @file celt_neon_intr.c
5 @brief ARM Neon Intrinsic optimizations for celt
6 */
7
8/*
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions
11 are met:
12
13 - Redistributions of source code must retain the above copyright
14 notice, this list of conditions and the following disclaimer.
15
16 - Redistributions in binary form must reproduce the above copyright
17 notice, this list of conditions and the following disclaimer in the
18 documentation and/or other materials provided with the distribution.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
24 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#ifdef HAVE_CONFIG_H
34#include "config.h"
35#endif
36
37#include <arm_neon.h>
38#include "../pitch.h"
39
40#if defined(FIXED_POINT)
41void xcorr_kernel_neon_fixed(const opus_val16 * x, const opus_val16 * y, opus_val32 sum[4], int len)
42{
43 int j;
44 int32x4_t a = vld1q_s32(sum);
45 /* Load y[0...3] */
46 /* This requires len>0 to always be valid (which we assert in the C code). */
47 int16x4_t y0 = vld1_s16(y);
48 y += 4;
49
50 for (j = 0; j + 8 <= len; j += 8)
51 {
52 /* Load x[0...7] */
53 int16x8_t xx = vld1q_s16(x);
54 int16x4_t x0 = vget_low_s16(xx);
55 int16x4_t x4 = vget_high_s16(xx);
56 /* Load y[4...11] */
57 int16x8_t yy = vld1q_s16(y);
58 int16x4_t y4 = vget_low_s16(yy);
59 int16x4_t y8 = vget_high_s16(yy);
60 int32x4_t a0 = vmlal_lane_s16(a, y0, x0, 0);
61 int32x4_t a1 = vmlal_lane_s16(a0, y4, x4, 0);
62
63 int16x4_t y1 = vext_s16(y0, y4, 1);
64 int16x4_t y5 = vext_s16(y4, y8, 1);
65 int32x4_t a2 = vmlal_lane_s16(a1, y1, x0, 1);
66 int32x4_t a3 = vmlal_lane_s16(a2, y5, x4, 1);
67
68 int16x4_t y2 = vext_s16(y0, y4, 2);
69 int16x4_t y6 = vext_s16(y4, y8, 2);
70 int32x4_t a4 = vmlal_lane_s16(a3, y2, x0, 2);
71 int32x4_t a5 = vmlal_lane_s16(a4, y6, x4, 2);
72
73 int16x4_t y3 = vext_s16(y0, y4, 3);
74 int16x4_t y7 = vext_s16(y4, y8, 3);
75 int32x4_t a6 = vmlal_lane_s16(a5, y3, x0, 3);
76 int32x4_t a7 = vmlal_lane_s16(a6, y7, x4, 3);
77
78 y0 = y8;
79 a = a7;
80 x += 8;
81 y += 8;
82 }
83
84 for (; j < len; j++)
85 {
86 int16x4_t x0 = vld1_dup_s16(x); /* load next x */
87 int32x4_t a0 = vmlal_s16(a, y0, x0);
88
89 int16x4_t y4 = vld1_dup_s16(y); /* load next y */
90 y0 = vext_s16(y0, y4, 1);
91 a = a0;
92 x++;
93 y++;
94 }
95
96 vst1q_s32(sum, a);
97}
98
99#else
100/*
101 * Function: xcorr_kernel_neon_float
102 * ---------------------------------
103 * Computes 4 correlation values and stores them in sum[4]
104 */
105static void xcorr_kernel_neon_float(const float32_t *x, const float32_t *y,
106 float32_t sum[4], int len) {
107 float32x4_t YY[3];
108 float32x4_t YEXT[3];
109 float32x4_t XX[2];
110 float32x2_t XX_2;
111 float32x4_t SUMM;
112 const float32_t *xi = x;
113 const float32_t *yi = y;
114
115 celt_assert(len>0);
116
117 YY[0] = vld1q_f32(yi);
118 SUMM = vdupq_n_f32(0);
119
120 /* Consume 8 elements in x vector and 12 elements in y
121 * vector. However, the 12'th element never really gets
122 * touched in this loop. So, if len == 8, then we only
123 * must access y[0] to y[10]. y[11] must not be accessed
124 * hence make sure len > 8 and not len >= 8
125 */
126 while (len > 8) {
127 yi += 4;
128 YY[1] = vld1q_f32(yi);
129 yi += 4;
130 YY[2] = vld1q_f32(yi);
131
132 XX[0] = vld1q_f32(xi);
133 xi += 4;
134 XX[1] = vld1q_f32(xi);
135 xi += 4;
136
137 SUMM = vmlaq_lane_f32(SUMM, YY[0], vget_low_f32(XX[0]), 0);
138 YEXT[0] = vextq_f32(YY[0], YY[1], 1);
139 SUMM = vmlaq_lane_f32(SUMM, YEXT[0], vget_low_f32(XX[0]), 1);
140 YEXT[1] = vextq_f32(YY[0], YY[1], 2);
141 SUMM = vmlaq_lane_f32(SUMM, YEXT[1], vget_high_f32(XX[0]), 0);
142 YEXT[2] = vextq_f32(YY[0], YY[1], 3);
143 SUMM = vmlaq_lane_f32(SUMM, YEXT[2], vget_high_f32(XX[0]), 1);
144
145 SUMM = vmlaq_lane_f32(SUMM, YY[1], vget_low_f32(XX[1]), 0);
146 YEXT[0] = vextq_f32(YY[1], YY[2], 1);
147 SUMM = vmlaq_lane_f32(SUMM, YEXT[0], vget_low_f32(XX[1]), 1);
148 YEXT[1] = vextq_f32(YY[1], YY[2], 2);
149 SUMM = vmlaq_lane_f32(SUMM, YEXT[1], vget_high_f32(XX[1]), 0);
150 YEXT[2] = vextq_f32(YY[1], YY[2], 3);
151 SUMM = vmlaq_lane_f32(SUMM, YEXT[2], vget_high_f32(XX[1]), 1);
152
153 YY[0] = YY[2];
154 len -= 8;
155 }
156
157 /* Consume 4 elements in x vector and 8 elements in y
158 * vector. However, the 8'th element in y never really gets
159 * touched in this loop. So, if len == 4, then we only
160 * must access y[0] to y[6]. y[7] must not be accessed
161 * hence make sure len>4 and not len>=4
162 */
163 if (len > 4) {
164 yi += 4;
165 YY[1] = vld1q_f32(yi);
166
167 XX[0] = vld1q_f32(xi);
168 xi += 4;
169
170 SUMM = vmlaq_lane_f32(SUMM, YY[0], vget_low_f32(XX[0]), 0);
171 YEXT[0] = vextq_f32(YY[0], YY[1], 1);
172 SUMM = vmlaq_lane_f32(SUMM, YEXT[0], vget_low_f32(XX[0]), 1);
173 YEXT[1] = vextq_f32(YY[0], YY[1], 2);
174 SUMM = vmlaq_lane_f32(SUMM, YEXT[1], vget_high_f32(XX[0]), 0);
175 YEXT[2] = vextq_f32(YY[0], YY[1], 3);
176 SUMM = vmlaq_lane_f32(SUMM, YEXT[2], vget_high_f32(XX[0]), 1);
177
178 YY[0] = YY[1];
179 len -= 4;
180 }
181
182 while (--len > 0) {
183 XX_2 = vld1_dup_f32(xi++);
184 SUMM = vmlaq_lane_f32(SUMM, YY[0], XX_2, 0);
185 YY[0]= vld1q_f32(++yi);
186 }
187
188 XX_2 = vld1_dup_f32(xi);
189 SUMM = vmlaq_lane_f32(SUMM, YY[0], XX_2, 0);
190
191 vst1q_f32(sum, SUMM);
192}
193
194void celt_pitch_xcorr_float_neon(const opus_val16 *_x, const opus_val16 *_y,
195 opus_val32 *xcorr, int len, int max_pitch, int arch) {
196 int i;
197 (void)arch;
198 celt_assert(max_pitch > 0);
199 celt_sig_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0);
200
201 for (i = 0; i < (max_pitch-3); i += 4) {
202 xcorr_kernel_neon_float((const float32_t *)_x, (const float32_t *)_y+i,
203 (float32_t *)xcorr+i, len);
204 }
205
206 /* In case max_pitch isn't a multiple of 4, do non-unrolled version. */
207 for (; i < max_pitch; i++) {
208 xcorr[i] = celt_inner_prod_neon(_x, _y+i, len);
209 }
210}
211#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/arm/celt_pitch_xcorr_arm.s b/lib/rbcodec/codecs/libopus/celt/arm/celt_pitch_xcorr_arm.s
new file mode 100644
index 0000000000..6e873afc37
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/arm/celt_pitch_xcorr_arm.s
@@ -0,0 +1,551 @@
1; Copyright (c) 2007-2008 CSIRO
2; Copyright (c) 2007-2009 Xiph.Org Foundation
3; Copyright (c) 2013 Parrot
4; Written by Aurélien Zanelli
5;
6; Redistribution and use in source and binary forms, with or without
7; modification, are permitted provided that the following conditions
8; are met:
9;
10; - Redistributions of source code must retain the above copyright
11; notice, this list of conditions and the following disclaimer.
12;
13; - Redistributions in binary form must reproduce the above copyright
14; notice, this list of conditions and the following disclaimer in the
15; documentation and/or other materials provided with the distribution.
16;
17; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18; ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21; OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 AREA |.text|, CODE, READONLY
30
31 GET celt/arm/armopts.s
32
33IF OPUS_ARM_MAY_HAVE_EDSP
34 EXPORT celt_pitch_xcorr_edsp
35ENDIF
36
37IF OPUS_ARM_MAY_HAVE_NEON
38 EXPORT celt_pitch_xcorr_neon
39ENDIF
40
41IF OPUS_ARM_MAY_HAVE_NEON
42
43; Compute sum[k]=sum(x[j]*y[j+k],j=0...len-1), k=0...3
44xcorr_kernel_neon PROC
45xcorr_kernel_neon_start
46 ; input:
47 ; r3 = int len
48 ; r4 = opus_val16 *x
49 ; r5 = opus_val16 *y
50 ; q0 = opus_val32 sum[4]
51 ; output:
52 ; q0 = opus_val32 sum[4]
53 ; preserved: r0-r3, r6-r11, d2, q4-q7, q9-q15
54 ; internal usage:
55 ; r12 = int j
56 ; d3 = y_3|y_2|y_1|y_0
57 ; q2 = y_B|y_A|y_9|y_8|y_7|y_6|y_5|y_4
58 ; q3 = x_7|x_6|x_5|x_4|x_3|x_2|x_1|x_0
59 ; q8 = scratch
60 ;
61 ; Load y[0...3]
62 ; This requires len>0 to always be valid (which we assert in the C code).
63 VLD1.16 {d5}, [r5]!
64 SUBS r12, r3, #8
65 BLE xcorr_kernel_neon_process4
66; Process 8 samples at a time.
67; This loop loads one y value more than we actually need. Therefore we have to
68; stop as soon as there are 8 or fewer samples left (instead of 7), to avoid
69; reading past the end of the array.
70xcorr_kernel_neon_process8
71 ; This loop has 19 total instructions (10 cycles to issue, minimum), with
72 ; - 2 cycles of ARM insrtuctions,
73 ; - 10 cycles of load/store/byte permute instructions, and
74 ; - 9 cycles of data processing instructions.
75 ; On a Cortex A8, we dual-issue the maximum amount (9 cycles) between the
76 ; latter two categories, meaning the whole loop should run in 10 cycles per
77 ; iteration, barring cache misses.
78 ;
79 ; Load x[0...7]
80 VLD1.16 {d6, d7}, [r4]!
81 ; Unlike VMOV, VAND is a data processsing instruction (and doesn't get
82 ; assembled to VMOV, like VORR would), so it dual-issues with the prior VLD1.
83 VAND d3, d5, d5
84 SUBS r12, r12, #8
85 ; Load y[4...11]
86 VLD1.16 {d4, d5}, [r5]!
87 VMLAL.S16 q0, d3, d6[0]
88 VEXT.16 d16, d3, d4, #1
89 VMLAL.S16 q0, d4, d7[0]
90 VEXT.16 d17, d4, d5, #1
91 VMLAL.S16 q0, d16, d6[1]
92 VEXT.16 d16, d3, d4, #2
93 VMLAL.S16 q0, d17, d7[1]
94 VEXT.16 d17, d4, d5, #2
95 VMLAL.S16 q0, d16, d6[2]
96 VEXT.16 d16, d3, d4, #3
97 VMLAL.S16 q0, d17, d7[2]
98 VEXT.16 d17, d4, d5, #3
99 VMLAL.S16 q0, d16, d6[3]
100 VMLAL.S16 q0, d17, d7[3]
101 BGT xcorr_kernel_neon_process8
102; Process 4 samples here if we have > 4 left (still reading one extra y value).
103xcorr_kernel_neon_process4
104 ADDS r12, r12, #4
105 BLE xcorr_kernel_neon_process2
106 ; Load x[0...3]
107 VLD1.16 d6, [r4]!
108 ; Use VAND since it's a data processing instruction again.
109 VAND d4, d5, d5
110 SUB r12, r12, #4
111 ; Load y[4...7]
112 VLD1.16 d5, [r5]!
113 VMLAL.S16 q0, d4, d6[0]
114 VEXT.16 d16, d4, d5, #1
115 VMLAL.S16 q0, d16, d6[1]
116 VEXT.16 d16, d4, d5, #2
117 VMLAL.S16 q0, d16, d6[2]
118 VEXT.16 d16, d4, d5, #3
119 VMLAL.S16 q0, d16, d6[3]
120; Process 2 samples here if we have > 2 left (still reading one extra y value).
121xcorr_kernel_neon_process2
122 ADDS r12, r12, #2
123 BLE xcorr_kernel_neon_process1
124 ; Load x[0...1]
125 VLD2.16 {d6[],d7[]}, [r4]!
126 ; Use VAND since it's a data processing instruction again.
127 VAND d4, d5, d5
128 SUB r12, r12, #2
129 ; Load y[4...5]
130 VLD1.32 {d5[]}, [r5]!
131 VMLAL.S16 q0, d4, d6
132 VEXT.16 d16, d4, d5, #1
133 ; Replace bottom copy of {y5,y4} in d5 with {y3,y2} from d4, using VSRI
134 ; instead of VEXT, since it's a data-processing instruction.
135 VSRI.64 d5, d4, #32
136 VMLAL.S16 q0, d16, d7
137; Process 1 sample using the extra y value we loaded above.
138xcorr_kernel_neon_process1
139 ; Load next *x
140 VLD1.16 {d6[]}, [r4]!
141 ADDS r12, r12, #1
142 ; y[0...3] are left in d5 from prior iteration(s) (if any)
143 VMLAL.S16 q0, d5, d6
144 MOVLE pc, lr
145; Now process 1 last sample, not reading ahead.
146 ; Load last *y
147 VLD1.16 {d4[]}, [r5]!
148 VSRI.64 d4, d5, #16
149 ; Load last *x
150 VLD1.16 {d6[]}, [r4]!
151 VMLAL.S16 q0, d4, d6
152 MOV pc, lr
153 ENDP
154
155; opus_val32 celt_pitch_xcorr_neon(opus_val16 *_x, opus_val16 *_y,
156; opus_val32 *xcorr, int len, int max_pitch, int arch)
157celt_pitch_xcorr_neon PROC
158 ; input:
159 ; r0 = opus_val16 *_x
160 ; r1 = opus_val16 *_y
161 ; r2 = opus_val32 *xcorr
162 ; r3 = int len
163 ; output:
164 ; r0 = int maxcorr
165 ; internal usage:
166 ; r4 = opus_val16 *x (for xcorr_kernel_neon())
167 ; r5 = opus_val16 *y (for xcorr_kernel_neon())
168 ; r6 = int max_pitch
169 ; r12 = int j
170 ; q15 = int maxcorr[4] (q15 is not used by xcorr_kernel_neon())
171 ; ignored:
172 ; int arch
173 STMFD sp!, {r4-r6, lr}
174 LDR r6, [sp, #16]
175 VMOV.S32 q15, #1
176 ; if (max_pitch < 4) goto celt_pitch_xcorr_neon_process4_done
177 SUBS r6, r6, #4
178 BLT celt_pitch_xcorr_neon_process4_done
179celt_pitch_xcorr_neon_process4
180 ; xcorr_kernel_neon parameters:
181 ; r3 = len, r4 = _x, r5 = _y, q0 = {0, 0, 0, 0}
182 MOV r4, r0
183 MOV r5, r1
184 VEOR q0, q0, q0
185 ; xcorr_kernel_neon only modifies r4, r5, r12, and q0...q3.
186 ; So we don't save/restore any other registers.
187 BL xcorr_kernel_neon_start
188 SUBS r6, r6, #4
189 VST1.32 {q0}, [r2]!
190 ; _y += 4
191 ADD r1, r1, #8
192 VMAX.S32 q15, q15, q0
193 ; if (max_pitch < 4) goto celt_pitch_xcorr_neon_process4_done
194 BGE celt_pitch_xcorr_neon_process4
195; We have less than 4 sums left to compute.
196celt_pitch_xcorr_neon_process4_done
197 ADDS r6, r6, #4
198 ; Reduce maxcorr to a single value
199 VMAX.S32 d30, d30, d31
200 VPMAX.S32 d30, d30, d30
201 ; if (max_pitch <= 0) goto celt_pitch_xcorr_neon_done
202 BLE celt_pitch_xcorr_neon_done
203; Now compute each remaining sum one at a time.
204celt_pitch_xcorr_neon_process_remaining
205 MOV r4, r0
206 MOV r5, r1
207 VMOV.I32 q0, #0
208 SUBS r12, r3, #8
209 BLT celt_pitch_xcorr_neon_process_remaining4
210; Sum terms 8 at a time.
211celt_pitch_xcorr_neon_process_remaining_loop8
212 ; Load x[0...7]
213 VLD1.16 {q1}, [r4]!
214 ; Load y[0...7]
215 VLD1.16 {q2}, [r5]!
216 SUBS r12, r12, #8
217 VMLAL.S16 q0, d4, d2
218 VMLAL.S16 q0, d5, d3
219 BGE celt_pitch_xcorr_neon_process_remaining_loop8
220; Sum terms 4 at a time.
221celt_pitch_xcorr_neon_process_remaining4
222 ADDS r12, r12, #4
223 BLT celt_pitch_xcorr_neon_process_remaining4_done
224 ; Load x[0...3]
225 VLD1.16 {d2}, [r4]!
226 ; Load y[0...3]
227 VLD1.16 {d3}, [r5]!
228 SUB r12, r12, #4
229 VMLAL.S16 q0, d3, d2
230celt_pitch_xcorr_neon_process_remaining4_done
231 ; Reduce the sum to a single value.
232 VADD.S32 d0, d0, d1
233 VPADDL.S32 d0, d0
234 ADDS r12, r12, #4
235 BLE celt_pitch_xcorr_neon_process_remaining_loop_done
236; Sum terms 1 at a time.
237celt_pitch_xcorr_neon_process_remaining_loop1
238 VLD1.16 {d2[]}, [r4]!
239 VLD1.16 {d3[]}, [r5]!
240 SUBS r12, r12, #1
241 VMLAL.S16 q0, d2, d3
242 BGT celt_pitch_xcorr_neon_process_remaining_loop1
243celt_pitch_xcorr_neon_process_remaining_loop_done
244 VST1.32 {d0[0]}, [r2]!
245 VMAX.S32 d30, d30, d0
246 SUBS r6, r6, #1
247 ; _y++
248 ADD r1, r1, #2
249 ; if (--max_pitch > 0) goto celt_pitch_xcorr_neon_process_remaining
250 BGT celt_pitch_xcorr_neon_process_remaining
251celt_pitch_xcorr_neon_done
252 VMOV.32 r0, d30[0]
253 LDMFD sp!, {r4-r6, pc}
254 ENDP
255
256ENDIF
257
258IF OPUS_ARM_MAY_HAVE_EDSP
259
260; This will get used on ARMv7 devices without NEON, so it has been optimized
261; to take advantage of dual-issuing where possible.
262xcorr_kernel_edsp PROC
263xcorr_kernel_edsp_start
264 ; input:
265 ; r3 = int len
266 ; r4 = opus_val16 *_x (must be 32-bit aligned)
267 ; r5 = opus_val16 *_y (must be 32-bit aligned)
268 ; r6...r9 = opus_val32 sum[4]
269 ; output:
270 ; r6...r9 = opus_val32 sum[4]
271 ; preserved: r0-r5
272 ; internal usage
273 ; r2 = int j
274 ; r12,r14 = opus_val16 x[4]
275 ; r10,r11 = opus_val16 y[4]
276 STMFD sp!, {r2,r4,r5,lr}
277 LDR r10, [r5], #4 ; Load y[0...1]
278 SUBS r2, r3, #4 ; j = len-4
279 LDR r11, [r5], #4 ; Load y[2...3]
280 BLE xcorr_kernel_edsp_process4_done
281 LDR r12, [r4], #4 ; Load x[0...1]
282 ; Stall
283xcorr_kernel_edsp_process4
284 ; The multiplies must issue from pipeline 0, and can't dual-issue with each
285 ; other. Every other instruction here dual-issues with a multiply, and is
286 ; thus "free". There should be no stalls in the body of the loop.
287 SMLABB r6, r12, r10, r6 ; sum[0] = MAC16_16(sum[0],x_0,y_0)
288 LDR r14, [r4], #4 ; Load x[2...3]
289 SMLABT r7, r12, r10, r7 ; sum[1] = MAC16_16(sum[1],x_0,y_1)
290 SUBS r2, r2, #4 ; j-=4
291 SMLABB r8, r12, r11, r8 ; sum[2] = MAC16_16(sum[2],x_0,y_2)
292 SMLABT r9, r12, r11, r9 ; sum[3] = MAC16_16(sum[3],x_0,y_3)
293 SMLATT r6, r12, r10, r6 ; sum[0] = MAC16_16(sum[0],x_1,y_1)
294 LDR r10, [r5], #4 ; Load y[4...5]
295 SMLATB r7, r12, r11, r7 ; sum[1] = MAC16_16(sum[1],x_1,y_2)
296 SMLATT r8, r12, r11, r8 ; sum[2] = MAC16_16(sum[2],x_1,y_3)
297 SMLATB r9, r12, r10, r9 ; sum[3] = MAC16_16(sum[3],x_1,y_4)
298 LDRGT r12, [r4], #4 ; Load x[0...1]
299 SMLABB r6, r14, r11, r6 ; sum[0] = MAC16_16(sum[0],x_2,y_2)
300 SMLABT r7, r14, r11, r7 ; sum[1] = MAC16_16(sum[1],x_2,y_3)
301 SMLABB r8, r14, r10, r8 ; sum[2] = MAC16_16(sum[2],x_2,y_4)
302 SMLABT r9, r14, r10, r9 ; sum[3] = MAC16_16(sum[3],x_2,y_5)
303 SMLATT r6, r14, r11, r6 ; sum[0] = MAC16_16(sum[0],x_3,y_3)
304 LDR r11, [r5], #4 ; Load y[6...7]
305 SMLATB r7, r14, r10, r7 ; sum[1] = MAC16_16(sum[1],x_3,y_4)
306 SMLATT r8, r14, r10, r8 ; sum[2] = MAC16_16(sum[2],x_3,y_5)
307 SMLATB r9, r14, r11, r9 ; sum[3] = MAC16_16(sum[3],x_3,y_6)
308 BGT xcorr_kernel_edsp_process4
309xcorr_kernel_edsp_process4_done
310 ADDS r2, r2, #4
311 BLE xcorr_kernel_edsp_done
312 LDRH r12, [r4], #2 ; r12 = *x++
313 SUBS r2, r2, #1 ; j--
314 ; Stall
315 SMLABB r6, r12, r10, r6 ; sum[0] = MAC16_16(sum[0],x,y_0)
316 LDRHGT r14, [r4], #2 ; r14 = *x++
317 SMLABT r7, r12, r10, r7 ; sum[1] = MAC16_16(sum[1],x,y_1)
318 SMLABB r8, r12, r11, r8 ; sum[2] = MAC16_16(sum[2],x,y_2)
319 SMLABT r9, r12, r11, r9 ; sum[3] = MAC16_16(sum[3],x,y_3)
320 BLE xcorr_kernel_edsp_done
321 SMLABT r6, r14, r10, r6 ; sum[0] = MAC16_16(sum[0],x,y_1)
322 SUBS r2, r2, #1 ; j--
323 SMLABB r7, r14, r11, r7 ; sum[1] = MAC16_16(sum[1],x,y_2)
324 LDRH r10, [r5], #2 ; r10 = y_4 = *y++
325 SMLABT r8, r14, r11, r8 ; sum[2] = MAC16_16(sum[2],x,y_3)
326 LDRHGT r12, [r4], #2 ; r12 = *x++
327 SMLABB r9, r14, r10, r9 ; sum[3] = MAC16_16(sum[3],x,y_4)
328 BLE xcorr_kernel_edsp_done
329 SMLABB r6, r12, r11, r6 ; sum[0] = MAC16_16(sum[0],tmp,y_2)
330 CMP r2, #1 ; j--
331 SMLABT r7, r12, r11, r7 ; sum[1] = MAC16_16(sum[1],tmp,y_3)
332 LDRH r2, [r5], #2 ; r2 = y_5 = *y++
333 SMLABB r8, r12, r10, r8 ; sum[2] = MAC16_16(sum[2],tmp,y_4)
334 LDRHGT r14, [r4] ; r14 = *x
335 SMLABB r9, r12, r2, r9 ; sum[3] = MAC16_16(sum[3],tmp,y_5)
336 BLE xcorr_kernel_edsp_done
337 SMLABT r6, r14, r11, r6 ; sum[0] = MAC16_16(sum[0],tmp,y_3)
338 LDRH r11, [r5] ; r11 = y_6 = *y
339 SMLABB r7, r14, r10, r7 ; sum[1] = MAC16_16(sum[1],tmp,y_4)
340 SMLABB r8, r14, r2, r8 ; sum[2] = MAC16_16(sum[2],tmp,y_5)
341 SMLABB r9, r14, r11, r9 ; sum[3] = MAC16_16(sum[3],tmp,y_6)
342xcorr_kernel_edsp_done
343 LDMFD sp!, {r2,r4,r5,pc}
344 ENDP
345
346celt_pitch_xcorr_edsp PROC
347 ; input:
348 ; r0 = opus_val16 *_x (must be 32-bit aligned)
349 ; r1 = opus_val16 *_y (only needs to be 16-bit aligned)
350 ; r2 = opus_val32 *xcorr
351 ; r3 = int len
352 ; output:
353 ; r0 = maxcorr
354 ; internal usage
355 ; r4 = opus_val16 *x
356 ; r5 = opus_val16 *y
357 ; r6 = opus_val32 sum0
358 ; r7 = opus_val32 sum1
359 ; r8 = opus_val32 sum2
360 ; r9 = opus_val32 sum3
361 ; r1 = int max_pitch
362 ; r12 = int j
363 ; ignored:
364 ; int arch
365 STMFD sp!, {r4-r11, lr}
366 MOV r5, r1
367 LDR r1, [sp, #36]
368 MOV r4, r0
369 TST r5, #3
370 ; maxcorr = 1
371 MOV r0, #1
372 BEQ celt_pitch_xcorr_edsp_process1u_done
373; Compute one sum at the start to make y 32-bit aligned.
374 SUBS r12, r3, #4
375 ; r14 = sum = 0
376 MOV r14, #0
377 LDRH r8, [r5], #2
378 BLE celt_pitch_xcorr_edsp_process1u_loop4_done
379 LDR r6, [r4], #4
380 MOV r8, r8, LSL #16
381celt_pitch_xcorr_edsp_process1u_loop4
382 LDR r9, [r5], #4
383 SMLABT r14, r6, r8, r14 ; sum = MAC16_16(sum, x_0, y_0)
384 LDR r7, [r4], #4
385 SMLATB r14, r6, r9, r14 ; sum = MAC16_16(sum, x_1, y_1)
386 LDR r8, [r5], #4
387 SMLABT r14, r7, r9, r14 ; sum = MAC16_16(sum, x_2, y_2)
388 SUBS r12, r12, #4 ; j-=4
389 SMLATB r14, r7, r8, r14 ; sum = MAC16_16(sum, x_3, y_3)
390 LDRGT r6, [r4], #4
391 BGT celt_pitch_xcorr_edsp_process1u_loop4
392 MOV r8, r8, LSR #16
393celt_pitch_xcorr_edsp_process1u_loop4_done
394 ADDS r12, r12, #4
395celt_pitch_xcorr_edsp_process1u_loop1
396 LDRHGE r6, [r4], #2
397 ; Stall
398 SMLABBGE r14, r6, r8, r14 ; sum = MAC16_16(sum, *x, *y)
399 SUBSGE r12, r12, #1
400 LDRHGT r8, [r5], #2
401 BGT celt_pitch_xcorr_edsp_process1u_loop1
402 ; Restore _x
403 SUB r4, r4, r3, LSL #1
404 ; Restore and advance _y
405 SUB r5, r5, r3, LSL #1
406 ; maxcorr = max(maxcorr, sum)
407 CMP r0, r14
408 ADD r5, r5, #2
409 MOVLT r0, r14
410 SUBS r1, r1, #1
411 ; xcorr[i] = sum
412 STR r14, [r2], #4
413 BLE celt_pitch_xcorr_edsp_done
414celt_pitch_xcorr_edsp_process1u_done
415 ; if (max_pitch < 4) goto celt_pitch_xcorr_edsp_process2
416 SUBS r1, r1, #4
417 BLT celt_pitch_xcorr_edsp_process2
418celt_pitch_xcorr_edsp_process4
419 ; xcorr_kernel_edsp parameters:
420 ; r3 = len, r4 = _x, r5 = _y, r6...r9 = sum[4] = {0, 0, 0, 0}
421 MOV r6, #0
422 MOV r7, #0
423 MOV r8, #0
424 MOV r9, #0
425 BL xcorr_kernel_edsp_start ; xcorr_kernel_edsp(_x, _y+i, xcorr+i, len)
426 ; maxcorr = max(maxcorr, sum0, sum1, sum2, sum3)
427 CMP r0, r6
428 ; _y+=4
429 ADD r5, r5, #8
430 MOVLT r0, r6
431 CMP r0, r7
432 MOVLT r0, r7
433 CMP r0, r8
434 MOVLT r0, r8
435 CMP r0, r9
436 MOVLT r0, r9
437 STMIA r2!, {r6-r9}
438 SUBS r1, r1, #4
439 BGE celt_pitch_xcorr_edsp_process4
440celt_pitch_xcorr_edsp_process2
441 ADDS r1, r1, #2
442 BLT celt_pitch_xcorr_edsp_process1a
443 SUBS r12, r3, #4
444 ; {r10, r11} = {sum0, sum1} = {0, 0}
445 MOV r10, #0
446 MOV r11, #0
447 LDR r8, [r5], #4
448 BLE celt_pitch_xcorr_edsp_process2_loop_done
449 LDR r6, [r4], #4
450 LDR r9, [r5], #4
451celt_pitch_xcorr_edsp_process2_loop4
452 SMLABB r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_0)
453 LDR r7, [r4], #4
454 SMLABT r11, r6, r8, r11 ; sum1 = MAC16_16(sum1, x_0, y_1)
455 SUBS r12, r12, #4 ; j-=4
456 SMLATT r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_1, y_1)
457 LDR r8, [r5], #4
458 SMLATB r11, r6, r9, r11 ; sum1 = MAC16_16(sum1, x_1, y_2)
459 LDRGT r6, [r4], #4
460 SMLABB r10, r7, r9, r10 ; sum0 = MAC16_16(sum0, x_2, y_2)
461 SMLABT r11, r7, r9, r11 ; sum1 = MAC16_16(sum1, x_2, y_3)
462 SMLATT r10, r7, r9, r10 ; sum0 = MAC16_16(sum0, x_3, y_3)
463 LDRGT r9, [r5], #4
464 SMLATB r11, r7, r8, r11 ; sum1 = MAC16_16(sum1, x_3, y_4)
465 BGT celt_pitch_xcorr_edsp_process2_loop4
466celt_pitch_xcorr_edsp_process2_loop_done
467 ADDS r12, r12, #2
468 BLE celt_pitch_xcorr_edsp_process2_1
469 LDR r6, [r4], #4
470 ; Stall
471 SMLABB r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_0)
472 LDR r9, [r5], #4
473 SMLABT r11, r6, r8, r11 ; sum1 = MAC16_16(sum1, x_0, y_1)
474 SUB r12, r12, #2
475 SMLATT r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_1, y_1)
476 MOV r8, r9
477 SMLATB r11, r6, r9, r11 ; sum1 = MAC16_16(sum1, x_1, y_2)
478celt_pitch_xcorr_edsp_process2_1
479 LDRH r6, [r4], #2
480 ADDS r12, r12, #1
481 ; Stall
482 SMLABB r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_0)
483 LDRHGT r7, [r4], #2
484 SMLABT r11, r6, r8, r11 ; sum1 = MAC16_16(sum1, x_0, y_1)
485 BLE celt_pitch_xcorr_edsp_process2_done
486 LDRH r9, [r5], #2
487 SMLABT r10, r7, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_1)
488 SMLABB r11, r7, r9, r11 ; sum1 = MAC16_16(sum1, x_0, y_2)
489celt_pitch_xcorr_edsp_process2_done
490 ; Restore _x
491 SUB r4, r4, r3, LSL #1
492 ; Restore and advance _y
493 SUB r5, r5, r3, LSL #1
494 ; maxcorr = max(maxcorr, sum0)
495 CMP r0, r10
496 ADD r5, r5, #2
497 MOVLT r0, r10
498 SUB r1, r1, #2
499 ; maxcorr = max(maxcorr, sum1)
500 CMP r0, r11
501 ; xcorr[i] = sum
502 STR r10, [r2], #4
503 MOVLT r0, r11
504 STR r11, [r2], #4
505celt_pitch_xcorr_edsp_process1a
506 ADDS r1, r1, #1
507 BLT celt_pitch_xcorr_edsp_done
508 SUBS r12, r3, #4
509 ; r14 = sum = 0
510 MOV r14, #0
511 BLT celt_pitch_xcorr_edsp_process1a_loop_done
512 LDR r6, [r4], #4
513 LDR r8, [r5], #4
514 LDR r7, [r4], #4
515 LDR r9, [r5], #4
516celt_pitch_xcorr_edsp_process1a_loop4
517 SMLABB r14, r6, r8, r14 ; sum = MAC16_16(sum, x_0, y_0)
518 SUBS r12, r12, #4 ; j-=4
519 SMLATT r14, r6, r8, r14 ; sum = MAC16_16(sum, x_1, y_1)
520 LDRGE r6, [r4], #4
521 SMLABB r14, r7, r9, r14 ; sum = MAC16_16(sum, x_2, y_2)
522 LDRGE r8, [r5], #4
523 SMLATT r14, r7, r9, r14 ; sum = MAC16_16(sum, x_3, y_3)
524 LDRGE r7, [r4], #4
525 LDRGE r9, [r5], #4
526 BGE celt_pitch_xcorr_edsp_process1a_loop4
527celt_pitch_xcorr_edsp_process1a_loop_done
528 ADDS r12, r12, #2
529 LDRGE r6, [r4], #4
530 LDRGE r8, [r5], #4
531 ; Stall
532 SMLABBGE r14, r6, r8, r14 ; sum = MAC16_16(sum, x_0, y_0)
533 SUBGE r12, r12, #2
534 SMLATTGE r14, r6, r8, r14 ; sum = MAC16_16(sum, x_1, y_1)
535 ADDS r12, r12, #1
536 LDRHGE r6, [r4], #2
537 LDRHGE r8, [r5], #2
538 ; Stall
539 SMLABBGE r14, r6, r8, r14 ; sum = MAC16_16(sum, *x, *y)
540 ; maxcorr = max(maxcorr, sum)
541 CMP r0, r14
542 ; xcorr[i] = sum
543 STR r14, [r2], #4
544 MOVLT r0, r14
545celt_pitch_xcorr_edsp_done
546 LDMFD sp!, {r4-r11, pc}
547 ENDP
548
549ENDIF
550
551END
diff --git a/lib/rbcodec/codecs/libopus/celt/arm/fft_arm.h b/lib/rbcodec/codecs/libopus/celt/arm/fft_arm.h
new file mode 100644
index 0000000000..0b78175f3a
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/arm/fft_arm.h
@@ -0,0 +1,71 @@
1/* Copyright (c) 2015 Xiph.Org Foundation
2 Written by Viswanath Puttagunta */
3/**
4 @file fft_arm.h
5 @brief ARM Neon Intrinsic optimizations for fft using NE10 library
6 */
7
8/*
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions
11 are met:
12
13 - Redistributions of source code must retain the above copyright
14 notice, this list of conditions and the following disclaimer.
15
16 - Redistributions in binary form must reproduce the above copyright
17 notice, this list of conditions and the following disclaimer in the
18 documentation and/or other materials provided with the distribution.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
24 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33
34#if !defined(FFT_ARM_H)
35#define FFT_ARM_H
36
37#include "kiss_fft.h"
38
39#if defined(HAVE_ARM_NE10)
40
41int opus_fft_alloc_arm_neon(kiss_fft_state *st);
42void opus_fft_free_arm_neon(kiss_fft_state *st);
43
44void opus_fft_neon(const kiss_fft_state *st,
45 const kiss_fft_cpx *fin,
46 kiss_fft_cpx *fout);
47
48void opus_ifft_neon(const kiss_fft_state *st,
49 const kiss_fft_cpx *fin,
50 kiss_fft_cpx *fout);
51
52#if !defined(OPUS_HAVE_RTCD)
53#define OVERRIDE_OPUS_FFT (1)
54
55#define opus_fft_alloc_arch(_st, arch) \
56 ((void)(arch), opus_fft_alloc_arm_neon(_st))
57
58#define opus_fft_free_arch(_st, arch) \
59 ((void)(arch), opus_fft_free_arm_neon(_st))
60
61#define opus_fft(_st, _fin, _fout, arch) \
62 ((void)(arch), opus_fft_neon(_st, _fin, _fout))
63
64#define opus_ifft(_st, _fin, _fout, arch) \
65 ((void)(arch), opus_ifft_neon(_st, _fin, _fout))
66
67#endif /* OPUS_HAVE_RTCD */
68
69#endif /* HAVE_ARM_NE10 */
70
71#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/arm/fixed_arm64.h b/lib/rbcodec/codecs/libopus/celt/arm/fixed_arm64.h
new file mode 100644
index 0000000000..c6fbd3db2c
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/arm/fixed_arm64.h
@@ -0,0 +1,35 @@
1/* Copyright (C) 2015 Vidyo */
2/*
3 Redistribution and use in source and binary forms, with or without
4 modification, are permitted provided that the following conditions
5 are met:
6
7 - Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9
10 - Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
18 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*/
26
27#ifndef FIXED_ARM64_H
28#define FIXED_ARM64_H
29
30#include <arm_neon.h>
31
32#undef SIG2WORD16
33#define SIG2WORD16(x) (vqmovns_s32(PSHR32((x), SIG_SHIFT)))
34
35#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/arm/fixed_armv4.h b/lib/rbcodec/codecs/libopus/celt/arm/fixed_armv4.h
index efb3b1896a..d84888a772 100644
--- a/lib/rbcodec/codecs/libopus/celt/arm/fixed_armv4.h
+++ b/lib/rbcodec/codecs/libopus/celt/arm/fixed_armv4.h
@@ -37,7 +37,7 @@ static OPUS_INLINE opus_val32 MULT16_32_Q16_armv4(opus_val16 a, opus_val32 b)
37 "#MULT16_32_Q16\n\t" 37 "#MULT16_32_Q16\n\t"
38 "smull %0, %1, %2, %3\n\t" 38 "smull %0, %1, %2, %3\n\t"
39 : "=&r"(rd_lo), "=&r"(rd_hi) 39 : "=&r"(rd_lo), "=&r"(rd_hi)
40 : "%r"(b),"r"(a<<16) 40 : "%r"(b),"r"(SHL32(a,16))
41 ); 41 );
42 return rd_hi; 42 return rd_hi;
43} 43}
@@ -54,10 +54,10 @@ static OPUS_INLINE opus_val32 MULT16_32_Q15_armv4(opus_val16 a, opus_val32 b)
54 "#MULT16_32_Q15\n\t" 54 "#MULT16_32_Q15\n\t"
55 "smull %0, %1, %2, %3\n\t" 55 "smull %0, %1, %2, %3\n\t"
56 : "=&r"(rd_lo), "=&r"(rd_hi) 56 : "=&r"(rd_lo), "=&r"(rd_hi)
57 : "%r"(b), "r"(a<<16) 57 : "%r"(b), "r"(SHL32(a,16))
58 ); 58 );
59 /*We intentionally don't OR in the high bit of rd_lo for speed.*/ 59 /*We intentionally don't OR in the high bit of rd_lo for speed.*/
60 return rd_hi<<1; 60 return SHL32(rd_hi,1);
61} 61}
62#define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv4(a, b)) 62#define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv4(a, b))
63 63
diff --git a/lib/rbcodec/codecs/libopus/celt/arm/fixed_armv5e.h b/lib/rbcodec/codecs/libopus/celt/arm/fixed_armv5e.h
index 36a6321101..6bf73cbace 100644
--- a/lib/rbcodec/codecs/libopus/celt/arm/fixed_armv5e.h
+++ b/lib/rbcodec/codecs/libopus/celt/arm/fixed_armv5e.h
@@ -59,7 +59,7 @@ static OPUS_INLINE opus_val32 MULT16_32_Q15_armv5e(opus_val16 a, opus_val32 b)
59 : "=r"(res) 59 : "=r"(res)
60 : "r"(b), "r"(a) 60 : "r"(b), "r"(a)
61 ); 61 );
62 return res<<1; 62 return SHL32(res,1);
63} 63}
64#define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv5e(a, b)) 64#define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv5e(a, b))
65 65
@@ -76,7 +76,7 @@ static OPUS_INLINE opus_val32 MAC16_32_Q15_armv5e(opus_val32 c, opus_val16 a,
76 "#MAC16_32_Q15\n\t" 76 "#MAC16_32_Q15\n\t"
77 "smlawb %0, %1, %2, %3;\n" 77 "smlawb %0, %1, %2, %3;\n"
78 : "=r"(res) 78 : "=r"(res)
79 : "r"(b<<1), "r"(a), "r"(c) 79 : "r"(SHL32(b,1)), "r"(a), "r"(c)
80 ); 80 );
81 return res; 81 return res;
82} 82}
diff --git a/lib/rbcodec/codecs/libopus/celt/arm/mdct_arm.h b/lib/rbcodec/codecs/libopus/celt/arm/mdct_arm.h
new file mode 100644
index 0000000000..14200bac4b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/arm/mdct_arm.h
@@ -0,0 +1,59 @@
1/* Copyright (c) 2015 Xiph.Org Foundation
2 Written by Viswanath Puttagunta */
3/**
4 @file arm_mdct.h
5 @brief ARM Neon Intrinsic optimizations for mdct using NE10 library
6 */
7
8/*
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions
11 are met:
12
13 - Redistributions of source code must retain the above copyright
14 notice, this list of conditions and the following disclaimer.
15
16 - Redistributions in binary form must reproduce the above copyright
17 notice, this list of conditions and the following disclaimer in the
18 documentation and/or other materials provided with the distribution.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
24 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#if !defined(MDCT_ARM_H)
34#define MDCT_ARM_H
35
36#include "mdct.h"
37
38#if defined(HAVE_ARM_NE10)
39/** Compute a forward MDCT and scale by 4/N, trashes the input array */
40void clt_mdct_forward_neon(const mdct_lookup *l, kiss_fft_scalar *in,
41 kiss_fft_scalar * OPUS_RESTRICT out,
42 const opus_val16 *window, int overlap,
43 int shift, int stride, int arch);
44
45void clt_mdct_backward_neon(const mdct_lookup *l, kiss_fft_scalar *in,
46 kiss_fft_scalar * OPUS_RESTRICT out,
47 const opus_val16 *window, int overlap,
48 int shift, int stride, int arch);
49
50#if !defined(OPUS_HAVE_RTCD)
51#define OVERRIDE_OPUS_MDCT (1)
52#define clt_mdct_forward(_l, _in, _out, _window, _int, _shift, _stride, _arch) \
53 clt_mdct_forward_neon(_l, _in, _out, _window, _int, _shift, _stride, _arch)
54#define clt_mdct_backward(_l, _in, _out, _window, _int, _shift, _stride, _arch) \
55 clt_mdct_backward_neon(_l, _in, _out, _window, _int, _shift, _stride, _arch)
56#endif /* OPUS_HAVE_RTCD */
57#endif /* HAVE_ARM_NE10 */
58
59#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/arm/pitch_arm.h b/lib/rbcodec/codecs/libopus/celt/arm/pitch_arm.h
new file mode 100644
index 0000000000..bed8b04eac
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/arm/pitch_arm.h
@@ -0,0 +1,160 @@
1/* Copyright (c) 2010 Xiph.Org Foundation
2 * Copyright (c) 2013 Parrot */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#if !defined(PITCH_ARM_H)
29# define PITCH_ARM_H
30
31# include "armcpu.h"
32
33# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
34opus_val32 celt_inner_prod_neon(const opus_val16 *x, const opus_val16 *y, int N);
35void dual_inner_prod_neon(const opus_val16 *x, const opus_val16 *y01,
36 const opus_val16 *y02, int N, opus_val32 *xy1, opus_val32 *xy2);
37
38# if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON)
39# define OVERRIDE_CELT_INNER_PROD (1)
40# define OVERRIDE_DUAL_INNER_PROD (1)
41# define celt_inner_prod(x, y, N, arch) ((void)(arch), PRESUME_NEON(celt_inner_prod)(x, y, N))
42# define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) ((void)(arch), PRESUME_NEON(dual_inner_prod)(x, y01, y02, N, xy1, xy2))
43# endif
44# endif
45
46# if !defined(OVERRIDE_CELT_INNER_PROD)
47# if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
48extern opus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x, const opus_val16 *y, int N);
49# define OVERRIDE_CELT_INNER_PROD (1)
50# define celt_inner_prod(x, y, N, arch) ((*CELT_INNER_PROD_IMPL[(arch)&OPUS_ARCHMASK])(x, y, N))
51# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
52# define OVERRIDE_CELT_INNER_PROD (1)
53# define celt_inner_prod(x, y, N, arch) ((void)(arch), celt_inner_prod_neon(x, y, N))
54# endif
55# endif
56
57# if !defined(OVERRIDE_DUAL_INNER_PROD)
58# if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
59extern void (*const DUAL_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x,
60 const opus_val16 *y01, const opus_val16 *y02, int N, opus_val32 *xy1, opus_val32 *xy2);
61# define OVERRIDE_DUAL_INNER_PROD (1)
62# define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) ((*DUAL_INNER_PROD_IMPL[(arch)&OPUS_ARCHMASK])(x, y01, y02, N, xy1, xy2))
63# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
64# define OVERRIDE_DUAL_INNER_PROD (1)
65# define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) ((void)(arch), dual_inner_prod_neon(x, y01, y02, N, xy1, xy2))
66# endif
67# endif
68
69# if defined(FIXED_POINT)
70
71# if defined(OPUS_ARM_MAY_HAVE_NEON)
72opus_val32 celt_pitch_xcorr_neon(const opus_val16 *_x, const opus_val16 *_y,
73 opus_val32 *xcorr, int len, int max_pitch, int arch);
74# endif
75
76# if defined(OPUS_ARM_MAY_HAVE_MEDIA)
77# define celt_pitch_xcorr_media MAY_HAVE_EDSP(celt_pitch_xcorr)
78# endif
79
80# if defined(OPUS_ARM_MAY_HAVE_EDSP)
81opus_val32 celt_pitch_xcorr_edsp(const opus_val16 *_x, const opus_val16 *_y,
82 opus_val32 *xcorr, int len, int max_pitch, int arch);
83# endif
84
85# if defined(OPUS_HAVE_RTCD) && \
86 ((defined(OPUS_ARM_MAY_HAVE_NEON) && !defined(OPUS_ARM_PRESUME_NEON)) || \
87 (defined(OPUS_ARM_MAY_HAVE_MEDIA) && !defined(OPUS_ARM_PRESUME_MEDIA)) || \
88 (defined(OPUS_ARM_MAY_HAVE_EDSP) && !defined(OPUS_ARM_PRESUME_EDSP)))
89extern opus_val32
90(*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
91 const opus_val16 *, opus_val32 *, int, int, int);
92# define OVERRIDE_PITCH_XCORR (1)
93# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
94 ((*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])(_x, _y, \
95 xcorr, len, max_pitch, arch))
96
97# elif defined(OPUS_ARM_PRESUME_EDSP) || \
98 defined(OPUS_ARM_PRESUME_MEDIA) || \
99 defined(OPUS_ARM_PRESUME_NEON)
100# define OVERRIDE_PITCH_XCORR (1)
101# define celt_pitch_xcorr (PRESUME_NEON(celt_pitch_xcorr))
102
103# endif
104
105# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
106void xcorr_kernel_neon_fixed(
107 const opus_val16 *x,
108 const opus_val16 *y,
109 opus_val32 sum[4],
110 int len);
111# endif
112
113# if defined(OPUS_HAVE_RTCD) && \
114 (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
115
116extern void (*const XCORR_KERNEL_IMPL[OPUS_ARCHMASK + 1])(
117 const opus_val16 *x,
118 const opus_val16 *y,
119 opus_val32 sum[4],
120 int len);
121
122# define OVERRIDE_XCORR_KERNEL (1)
123# define xcorr_kernel(x, y, sum, len, arch) \
124 ((*XCORR_KERNEL_IMPL[(arch) & OPUS_ARCHMASK])(x, y, sum, len))
125
126# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
127# define OVERRIDE_XCORR_KERNEL (1)
128# define xcorr_kernel(x, y, sum, len, arch) \
129 ((void)arch, xcorr_kernel_neon_fixed(x, y, sum, len))
130
131# endif
132
133#else /* Start !FIXED_POINT */
134/* Float case */
135#if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
136void celt_pitch_xcorr_float_neon(const opus_val16 *_x, const opus_val16 *_y,
137 opus_val32 *xcorr, int len, int max_pitch, int arch);
138#endif
139
140# if defined(OPUS_HAVE_RTCD) && \
141 (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
142extern void
143(*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
144 const opus_val16 *, opus_val32 *, int, int, int);
145
146# define OVERRIDE_PITCH_XCORR (1)
147# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
148 ((*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])(_x, _y, \
149 xcorr, len, max_pitch, arch))
150
151# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
152
153# define OVERRIDE_PITCH_XCORR (1)
154# define celt_pitch_xcorr celt_pitch_xcorr_float_neon
155
156# endif
157
158#endif /* end !FIXED_POINT */
159
160#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/arm/pitch_neon_intr.c b/lib/rbcodec/codecs/libopus/celt/arm/pitch_neon_intr.c
new file mode 100644
index 0000000000..1ac38c433a
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/arm/pitch_neon_intr.c
@@ -0,0 +1,290 @@
1/***********************************************************************
2Copyright (c) 2017 Google Inc.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <arm_neon.h>
33#include "pitch.h"
34
35#ifdef FIXED_POINT
36
37opus_val32 celt_inner_prod_neon(const opus_val16 *x, const opus_val16 *y, int N)
38{
39 int i;
40 opus_val32 xy;
41 int16x8_t x_s16x8, y_s16x8;
42 int32x4_t xy_s32x4 = vdupq_n_s32(0);
43 int64x2_t xy_s64x2;
44 int64x1_t xy_s64x1;
45
46 for (i = 0; i < N - 7; i += 8) {
47 x_s16x8 = vld1q_s16(&x[i]);
48 y_s16x8 = vld1q_s16(&y[i]);
49 xy_s32x4 = vmlal_s16(xy_s32x4, vget_low_s16 (x_s16x8), vget_low_s16 (y_s16x8));
50 xy_s32x4 = vmlal_s16(xy_s32x4, vget_high_s16(x_s16x8), vget_high_s16(y_s16x8));
51 }
52
53 if (N - i >= 4) {
54 const int16x4_t x_s16x4 = vld1_s16(&x[i]);
55 const int16x4_t y_s16x4 = vld1_s16(&y[i]);
56 xy_s32x4 = vmlal_s16(xy_s32x4, x_s16x4, y_s16x4);
57 i += 4;
58 }
59
60 xy_s64x2 = vpaddlq_s32(xy_s32x4);
61 xy_s64x1 = vadd_s64(vget_low_s64(xy_s64x2), vget_high_s64(xy_s64x2));
62 xy = vget_lane_s32(vreinterpret_s32_s64(xy_s64x1), 0);
63
64 for (; i < N; i++) {
65 xy = MAC16_16(xy, x[i], y[i]);
66 }
67
68#ifdef OPUS_CHECK_ASM
69 celt_assert(celt_inner_prod_c(x, y, N) == xy);
70#endif
71
72 return xy;
73}
74
75void dual_inner_prod_neon(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
76 int N, opus_val32 *xy1, opus_val32 *xy2)
77{
78 int i;
79 opus_val32 xy01, xy02;
80 int16x8_t x_s16x8, y01_s16x8, y02_s16x8;
81 int32x4_t xy01_s32x4 = vdupq_n_s32(0);
82 int32x4_t xy02_s32x4 = vdupq_n_s32(0);
83 int64x2_t xy01_s64x2, xy02_s64x2;
84 int64x1_t xy01_s64x1, xy02_s64x1;
85
86 for (i = 0; i < N - 7; i += 8) {
87 x_s16x8 = vld1q_s16(&x[i]);
88 y01_s16x8 = vld1q_s16(&y01[i]);
89 y02_s16x8 = vld1q_s16(&y02[i]);
90 xy01_s32x4 = vmlal_s16(xy01_s32x4, vget_low_s16 (x_s16x8), vget_low_s16 (y01_s16x8));
91 xy02_s32x4 = vmlal_s16(xy02_s32x4, vget_low_s16 (x_s16x8), vget_low_s16 (y02_s16x8));
92 xy01_s32x4 = vmlal_s16(xy01_s32x4, vget_high_s16(x_s16x8), vget_high_s16(y01_s16x8));
93 xy02_s32x4 = vmlal_s16(xy02_s32x4, vget_high_s16(x_s16x8), vget_high_s16(y02_s16x8));
94 }
95
96 if (N - i >= 4) {
97 const int16x4_t x_s16x4 = vld1_s16(&x[i]);
98 const int16x4_t y01_s16x4 = vld1_s16(&y01[i]);
99 const int16x4_t y02_s16x4 = vld1_s16(&y02[i]);
100 xy01_s32x4 = vmlal_s16(xy01_s32x4, x_s16x4, y01_s16x4);
101 xy02_s32x4 = vmlal_s16(xy02_s32x4, x_s16x4, y02_s16x4);
102 i += 4;
103 }
104
105 xy01_s64x2 = vpaddlq_s32(xy01_s32x4);
106 xy02_s64x2 = vpaddlq_s32(xy02_s32x4);
107 xy01_s64x1 = vadd_s64(vget_low_s64(xy01_s64x2), vget_high_s64(xy01_s64x2));
108 xy02_s64x1 = vadd_s64(vget_low_s64(xy02_s64x2), vget_high_s64(xy02_s64x2));
109 xy01 = vget_lane_s32(vreinterpret_s32_s64(xy01_s64x1), 0);
110 xy02 = vget_lane_s32(vreinterpret_s32_s64(xy02_s64x1), 0);
111
112 for (; i < N; i++) {
113 xy01 = MAC16_16(xy01, x[i], y01[i]);
114 xy02 = MAC16_16(xy02, x[i], y02[i]);
115 }
116 *xy1 = xy01;
117 *xy2 = xy02;
118
119#ifdef OPUS_CHECK_ASM
120 {
121 opus_val32 xy1_c, xy2_c;
122 dual_inner_prod_c(x, y01, y02, N, &xy1_c, &xy2_c);
123 celt_assert(xy1_c == *xy1);
124 celt_assert(xy2_c == *xy2);
125 }
126#endif
127}
128
129#else /* !FIXED_POINT */
130
131/* ========================================================================== */
132
133#ifdef OPUS_CHECK_ASM
134
135/* This part of code simulates floating-point NEON operations. */
136
137/* celt_inner_prod_neon_float_c_simulation() simulates the floating-point */
138/* operations of celt_inner_prod_neon(), and both functions should have bit */
139/* exact output. */
140static opus_val32 celt_inner_prod_neon_float_c_simulation(const opus_val16 *x, const opus_val16 *y, int N)
141{
142 int i;
143 opus_val32 xy, xy0 = 0, xy1 = 0, xy2 = 0, xy3 = 0;
144 for (i = 0; i < N - 3; i += 4) {
145 xy0 = MAC16_16(xy0, x[i + 0], y[i + 0]);
146 xy1 = MAC16_16(xy1, x[i + 1], y[i + 1]);
147 xy2 = MAC16_16(xy2, x[i + 2], y[i + 2]);
148 xy3 = MAC16_16(xy3, x[i + 3], y[i + 3]);
149 }
150 xy0 += xy2;
151 xy1 += xy3;
152 xy = xy0 + xy1;
153 for (; i < N; i++) {
154 xy = MAC16_16(xy, x[i], y[i]);
155 }
156 return xy;
157}
158
159/* dual_inner_prod_neon_float_c_simulation() simulates the floating-point */
160/* operations of dual_inner_prod_neon(), and both functions should have bit */
161/* exact output. */
162static void dual_inner_prod_neon_float_c_simulation(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
163 int N, opus_val32 *xy1, opus_val32 *xy2)
164{
165 int i;
166 opus_val32 xy01, xy02, xy01_0 = 0, xy01_1 = 0, xy01_2 = 0, xy01_3 = 0, xy02_0 = 0, xy02_1 = 0, xy02_2 = 0, xy02_3 = 0;
167 for (i = 0; i < N - 3; i += 4) {
168 xy01_0 = MAC16_16(xy01_0, x[i + 0], y01[i + 0]);
169 xy01_1 = MAC16_16(xy01_1, x[i + 1], y01[i + 1]);
170 xy01_2 = MAC16_16(xy01_2, x[i + 2], y01[i + 2]);
171 xy01_3 = MAC16_16(xy01_3, x[i + 3], y01[i + 3]);
172 xy02_0 = MAC16_16(xy02_0, x[i + 0], y02[i + 0]);
173 xy02_1 = MAC16_16(xy02_1, x[i + 1], y02[i + 1]);
174 xy02_2 = MAC16_16(xy02_2, x[i + 2], y02[i + 2]);
175 xy02_3 = MAC16_16(xy02_3, x[i + 3], y02[i + 3]);
176 }
177 xy01_0 += xy01_2;
178 xy02_0 += xy02_2;
179 xy01_1 += xy01_3;
180 xy02_1 += xy02_3;
181 xy01 = xy01_0 + xy01_1;
182 xy02 = xy02_0 + xy02_1;
183 for (; i < N; i++) {
184 xy01 = MAC16_16(xy01, x[i], y01[i]);
185 xy02 = MAC16_16(xy02, x[i], y02[i]);
186 }
187 *xy1 = xy01;
188 *xy2 = xy02;
189}
190
191#endif /* OPUS_CHECK_ASM */
192
193/* ========================================================================== */
194
195opus_val32 celt_inner_prod_neon(const opus_val16 *x, const opus_val16 *y, int N)
196{
197 int i;
198 opus_val32 xy;
199 float32x4_t xy_f32x4 = vdupq_n_f32(0);
200 float32x2_t xy_f32x2;
201
202 for (i = 0; i < N - 7; i += 8) {
203 float32x4_t x_f32x4, y_f32x4;
204 x_f32x4 = vld1q_f32(&x[i]);
205 y_f32x4 = vld1q_f32(&y[i]);
206 xy_f32x4 = vmlaq_f32(xy_f32x4, x_f32x4, y_f32x4);
207 x_f32x4 = vld1q_f32(&x[i + 4]);
208 y_f32x4 = vld1q_f32(&y[i + 4]);
209 xy_f32x4 = vmlaq_f32(xy_f32x4, x_f32x4, y_f32x4);
210 }
211
212 if (N - i >= 4) {
213 const float32x4_t x_f32x4 = vld1q_f32(&x[i]);
214 const float32x4_t y_f32x4 = vld1q_f32(&y[i]);
215 xy_f32x4 = vmlaq_f32(xy_f32x4, x_f32x4, y_f32x4);
216 i += 4;
217 }
218
219 xy_f32x2 = vadd_f32(vget_low_f32(xy_f32x4), vget_high_f32(xy_f32x4));
220 xy_f32x2 = vpadd_f32(xy_f32x2, xy_f32x2);
221 xy = vget_lane_f32(xy_f32x2, 0);
222
223 for (; i < N; i++) {
224 xy = MAC16_16(xy, x[i], y[i]);
225 }
226
227#ifdef OPUS_CHECK_ASM
228 celt_assert(ABS32(celt_inner_prod_neon_float_c_simulation(x, y, N) - xy) <= VERY_SMALL);
229#endif
230
231 return xy;
232}
233
234void dual_inner_prod_neon(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
235 int N, opus_val32 *xy1, opus_val32 *xy2)
236{
237 int i;
238 opus_val32 xy01, xy02;
239 float32x4_t xy01_f32x4 = vdupq_n_f32(0);
240 float32x4_t xy02_f32x4 = vdupq_n_f32(0);
241 float32x2_t xy01_f32x2, xy02_f32x2;
242
243 for (i = 0; i < N - 7; i += 8) {
244 float32x4_t x_f32x4, y01_f32x4, y02_f32x4;
245 x_f32x4 = vld1q_f32(&x[i]);
246 y01_f32x4 = vld1q_f32(&y01[i]);
247 y02_f32x4 = vld1q_f32(&y02[i]);
248 xy01_f32x4 = vmlaq_f32(xy01_f32x4, x_f32x4, y01_f32x4);
249 xy02_f32x4 = vmlaq_f32(xy02_f32x4, x_f32x4, y02_f32x4);
250 x_f32x4 = vld1q_f32(&x[i + 4]);
251 y01_f32x4 = vld1q_f32(&y01[i + 4]);
252 y02_f32x4 = vld1q_f32(&y02[i + 4]);
253 xy01_f32x4 = vmlaq_f32(xy01_f32x4, x_f32x4, y01_f32x4);
254 xy02_f32x4 = vmlaq_f32(xy02_f32x4, x_f32x4, y02_f32x4);
255 }
256
257 if (N - i >= 4) {
258 const float32x4_t x_f32x4 = vld1q_f32(&x[i]);
259 const float32x4_t y01_f32x4 = vld1q_f32(&y01[i]);
260 const float32x4_t y02_f32x4 = vld1q_f32(&y02[i]);
261 xy01_f32x4 = vmlaq_f32(xy01_f32x4, x_f32x4, y01_f32x4);
262 xy02_f32x4 = vmlaq_f32(xy02_f32x4, x_f32x4, y02_f32x4);
263 i += 4;
264 }
265
266 xy01_f32x2 = vadd_f32(vget_low_f32(xy01_f32x4), vget_high_f32(xy01_f32x4));
267 xy02_f32x2 = vadd_f32(vget_low_f32(xy02_f32x4), vget_high_f32(xy02_f32x4));
268 xy01_f32x2 = vpadd_f32(xy01_f32x2, xy01_f32x2);
269 xy02_f32x2 = vpadd_f32(xy02_f32x2, xy02_f32x2);
270 xy01 = vget_lane_f32(xy01_f32x2, 0);
271 xy02 = vget_lane_f32(xy02_f32x2, 0);
272
273 for (; i < N; i++) {
274 xy01 = MAC16_16(xy01, x[i], y01[i]);
275 xy02 = MAC16_16(xy02, x[i], y02[i]);
276 }
277 *xy1 = xy01;
278 *xy2 = xy02;
279
280#ifdef OPUS_CHECK_ASM
281 {
282 opus_val32 xy1_c, xy2_c;
283 dual_inner_prod_neon_float_c_simulation(x, y01, y02, N, &xy1_c, &xy2_c);
284 celt_assert(ABS32(xy1_c - *xy1) <= VERY_SMALL);
285 celt_assert(ABS32(xy2_c - *xy2) <= VERY_SMALL);
286 }
287#endif
288}
289
290#endif /* FIXED_POINT */
diff --git a/lib/rbcodec/codecs/libopus/celt/bands.c b/lib/rbcodec/codecs/libopus/celt/bands.c
index caa70163b4..2702963c37 100644
--- a/lib/rbcodec/codecs/libopus/celt/bands.c
+++ b/lib/rbcodec/codecs/libopus/celt/bands.c
@@ -65,19 +65,19 @@ opus_uint32 celt_lcg_rand(opus_uint32 seed)
65 65
66/* This is a cos() approximation designed to be bit-exact on any platform. Bit exactness 66/* This is a cos() approximation designed to be bit-exact on any platform. Bit exactness
67 with this approximation is important because it has an impact on the bit allocation */ 67 with this approximation is important because it has an impact on the bit allocation */
68static opus_int16 bitexact_cos(opus_int16 x) 68opus_int16 bitexact_cos(opus_int16 x)
69{ 69{
70 opus_int32 tmp; 70 opus_int32 tmp;
71 opus_int16 x2; 71 opus_int16 x2;
72 tmp = (4096+((opus_int32)(x)*(x)))>>13; 72 tmp = (4096+((opus_int32)(x)*(x)))>>13;
73 celt_assert(tmp<=32767); 73 celt_sig_assert(tmp<=32767);
74 x2 = tmp; 74 x2 = tmp;
75 x2 = (32767-x2) + FRAC_MUL16(x2, (-7651 + FRAC_MUL16(x2, (8277 + FRAC_MUL16(-626, x2))))); 75 x2 = (32767-x2) + FRAC_MUL16(x2, (-7651 + FRAC_MUL16(x2, (8277 + FRAC_MUL16(-626, x2)))));
76 celt_assert(x2<=32766); 76 celt_sig_assert(x2<=32766);
77 return 1+x2; 77 return 1+x2;
78} 78}
79 79
80static int bitexact_log2tan(int isin,int icos) 80int bitexact_log2tan(int isin,int icos)
81{ 81{
82 int lc; 82 int lc;
83 int ls; 83 int ls;
@@ -90,13 +90,13 @@ static int bitexact_log2tan(int isin,int icos)
90 -FRAC_MUL16(icos, FRAC_MUL16(icos, -2597) + 7932); 90 -FRAC_MUL16(icos, FRAC_MUL16(icos, -2597) + 7932);
91} 91}
92 92
93#if 0
94#ifdef FIXED_POINT 93#ifdef FIXED_POINT
95/* Compute the amplitude (sqrt energy) in each of the bands */ 94/* Compute the amplitude (sqrt energy) in each of the bands */
96void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM) 95void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM, int arch)
97{ 96{
98 int i, c, N; 97 int i, c, N;
99 const opus_int16 *eBands = m->eBands; 98 const opus_int16 *eBands = m->eBands;
99 (void)arch;
100 N = m->shortMdctSize<<LM; 100 N = m->shortMdctSize<<LM;
101 c=0; do { 101 c=0; do {
102 for (i=0;i<end;i++) 102 for (i=0;i<end;i++)
@@ -156,7 +156,7 @@ void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, cel
156 156
157#else /* FIXED_POINT */ 157#else /* FIXED_POINT */
158/* Compute the amplitude (sqrt energy) in each of the bands */ 158/* Compute the amplitude (sqrt energy) in each of the bands */
159void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM) 159void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM, int arch)
160{ 160{
161 int i, c, N; 161 int i, c, N;
162 const opus_int16 *eBands = m->eBands; 162 const opus_int16 *eBands = m->eBands;
@@ -165,7 +165,7 @@ void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *band
165 for (i=0;i<end;i++) 165 for (i=0;i<end;i++)
166 { 166 {
167 opus_val32 sum; 167 opus_val32 sum;
168 sum = 1e-27f + celt_inner_prod(&X[c*N+(eBands[i]<<LM)], &X[c*N+(eBands[i]<<LM)], (eBands[i+1]-eBands[i])<<LM); 168 sum = 1e-27f + celt_inner_prod(&X[c*N+(eBands[i]<<LM)], &X[c*N+(eBands[i]<<LM)], (eBands[i+1]-eBands[i])<<LM, arch);
169 bandE[i+c*m->nbEBands] = celt_sqrt(sum); 169 bandE[i+c*m->nbEBands] = celt_sqrt(sum);
170 /*printf ("%f ", bandE[i+c*m->nbEBands]);*/ 170 /*printf ("%f ", bandE[i+c*m->nbEBands]);*/
171 } 171 }
@@ -191,7 +191,6 @@ void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, cel
191} 191}
192 192
193#endif /* FIXED_POINT */ 193#endif /* FIXED_POINT */
194#endif
195 194
196/* De-normalise the energy to produce the synthesis from the unit-energy bands */ 195/* De-normalise the energy to produce the synthesis from the unit-energy bands */
197void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X, 196void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
@@ -226,9 +225,9 @@ void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
226#endif 225#endif
227 j=M*eBands[i]; 226 j=M*eBands[i];
228 band_end = M*eBands[i+1]; 227 band_end = M*eBands[i+1];
229 lg = ADD16(bandLogE[i], SHL16((opus_val16)eMeans[i],6)); 228 lg = SATURATE16(ADD32(bandLogE[i], SHL32((opus_val32)eMeans[i],6)));
230#ifndef FIXED_POINT 229#ifndef FIXED_POINT
231 g = celt_exp2(lg); 230 g = celt_exp2(MIN32(32.f, lg));
232#else 231#else
233 /* Handle the integer part of the log energy */ 232 /* Handle the integer part of the log energy */
234 shift = 16-(lg>>DB_SHIFT); 233 shift = 16-(lg>>DB_SHIFT);
@@ -243,12 +242,12 @@ void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
243 /* Handle extreme gains with negative shift. */ 242 /* Handle extreme gains with negative shift. */
244 if (shift<0) 243 if (shift<0)
245 { 244 {
246 /* For shift < -2 we'd be likely to overflow, so we're capping 245 /* For shift <= -2 and g > 16384 we'd be likely to overflow, so we're
247 the gain here. This shouldn't happen unless the bitstream is 246 capping the gain here, which is equivalent to a cap of 18 on lg.
248 already corrupted. */ 247 This shouldn't trigger unless the bitstream is already corrupted. */
249 if (shift < -2) 248 if (shift <= -2)
250 { 249 {
251 g = 32767; 250 g = 16384;
252 shift = -2; 251 shift = -2;
253 } 252 }
254 do { 253 do {
@@ -268,7 +267,7 @@ void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
268/* This prevents energy collapse for transients with multiple short MDCTs */ 267/* This prevents energy collapse for transients with multiple short MDCTs */
269void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_masks, int LM, int C, int size, 268void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_masks, int LM, int C, int size,
270 int start, int end, const opus_val16 *logE, const opus_val16 *prev1logE, 269 int start, int end, const opus_val16 *logE, const opus_val16 *prev1logE,
271 const opus_val16 *prev2logE, const int *pulses, opus_uint32 seed) 270 const opus_val16 *prev2logE, const int *pulses, opus_uint32 seed, int arch)
272{ 271{
273 int c, i, j, k; 272 int c, i, j, k;
274 for (i=start;i<end;i++) 273 for (i=start;i<end;i++)
@@ -283,7 +282,7 @@ void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_mas
283 282
284 N0 = m->eBands[i+1]-m->eBands[i]; 283 N0 = m->eBands[i+1]-m->eBands[i];
285 /* depth in 1/8 bits */ 284 /* depth in 1/8 bits */
286 celt_assert(pulses[i]>=0); 285 celt_sig_assert(pulses[i]>=0);
287 depth = celt_udiv(1+pulses[i], (m->eBands[i+1]-m->eBands[i]))>>LM; 286 depth = celt_udiv(1+pulses[i], (m->eBands[i+1]-m->eBands[i]))>>LM;
288 287
289#ifdef FIXED_POINT 288#ifdef FIXED_POINT
@@ -357,11 +356,35 @@ void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_mas
357 } 356 }
358 /* We just added some energy, so we need to renormalise */ 357 /* We just added some energy, so we need to renormalise */
359 if (renormalize) 358 if (renormalize)
360 renormalise_vector(X, N0<<LM, Q15ONE); 359 renormalise_vector(X, N0<<LM, Q15ONE, arch);
361 } while (++c<C); 360 } while (++c<C);
362 } 361 }
363} 362}
364 363
364/* Compute the weights to use for optimizing normalized distortion across
365 channels. We use the amplitude to weight square distortion, which means
366 that we use the square root of the value we would have been using if we
367 wanted to minimize the MSE in the non-normalized domain. This roughly
368 corresponds to some quick-and-dirty perceptual experiments I ran to
369 measure inter-aural masking (there doesn't seem to be any published data
370 on the topic). */
371static void compute_channel_weights(celt_ener Ex, celt_ener Ey, opus_val16 w[2])
372{
373 celt_ener minE;
374#ifdef FIXED_POINT
375 int shift;
376#endif
377 minE = MIN32(Ex, Ey);
378 /* Adjustment to make the weights a bit more conservative. */
379 Ex = ADD32(Ex, minE/3);
380 Ey = ADD32(Ey, minE/3);
381#ifdef FIXED_POINT
382 shift = celt_ilog2(EPSILON+MAX32(Ex, Ey))-14;
383#endif
384 w[0] = VSHR32(Ex, shift);
385 w[1] = VSHR32(Ey, shift);
386}
387
365static void intensity_stereo(const CELTMode *m, celt_norm * OPUS_RESTRICT X, const celt_norm * OPUS_RESTRICT Y, const celt_ener *bandE, int bandID, int N) 388static void intensity_stereo(const CELTMode *m, celt_norm * OPUS_RESTRICT X, const celt_norm * OPUS_RESTRICT Y, const celt_ener *bandE, int bandID, int N)
366{ 389{
367 int i = bandID; 390 int i = bandID;
@@ -400,7 +423,7 @@ static void stereo_split(celt_norm * OPUS_RESTRICT X, celt_norm * OPUS_RESTRICT
400 } 423 }
401} 424}
402 425
403static void stereo_merge(celt_norm * OPUS_RESTRICT X, celt_norm * OPUS_RESTRICT Y, opus_val16 mid, int N) 426static void stereo_merge(celt_norm * OPUS_RESTRICT X, celt_norm * OPUS_RESTRICT Y, opus_val16 mid, int N, int arch)
404{ 427{
405 int j; 428 int j;
406 opus_val32 xp=0, side=0; 429 opus_val32 xp=0, side=0;
@@ -412,11 +435,11 @@ static void stereo_merge(celt_norm * OPUS_RESTRICT X, celt_norm * OPUS_RESTRICT
412 opus_val32 t, lgain, rgain; 435 opus_val32 t, lgain, rgain;
413 436
414 /* Compute the norm of X+Y and X-Y as |X|^2 + |Y|^2 +/- sum(xy) */ 437 /* Compute the norm of X+Y and X-Y as |X|^2 + |Y|^2 +/- sum(xy) */
415 dual_inner_prod(Y, X, Y, N, &xp, &side); 438 dual_inner_prod(Y, X, Y, N, &xp, &side, arch);
416 /* Compensating for the mid normalization */ 439 /* Compensating for the mid normalization */
417 xp = MULT16_32_Q15(mid, xp); 440 xp = MULT16_32_Q15(mid, xp);
418 /* mid and side are in Q15, not Q14 like X and Y */ 441 /* mid and side are in Q15, not Q14 like X and Y */
419 mid2 = SHR32(mid, 1); 442 mid2 = SHR16(mid, 1);
420 El = MULT16_16(mid2, mid2) + side - 2*xp; 443 El = MULT16_16(mid2, mid2) + side - 2*xp;
421 Er = MULT16_16(mid2, mid2) + side + 2*xp; 444 Er = MULT16_16(mid2, mid2) + side + 2*xp;
422 if (Er < QCONST32(6e-4f, 28) || El < QCONST32(6e-4f, 28)) 445 if (Er < QCONST32(6e-4f, 28) || El < QCONST32(6e-4f, 28))
@@ -452,11 +475,10 @@ static void stereo_merge(celt_norm * OPUS_RESTRICT X, celt_norm * OPUS_RESTRICT
452 } 475 }
453} 476}
454 477
455#if 0
456/* Decide whether we should spread the pulses in the current frame */ 478/* Decide whether we should spread the pulses in the current frame */
457int spreading_decision(const CELTMode *m, const celt_norm *X, int *average, 479int spreading_decision(const CELTMode *m, const celt_norm *X, int *average,
458 int last_decision, int *hf_average, int *tapset_decision, int update_hf, 480 int last_decision, int *hf_average, int *tapset_decision, int update_hf,
459 int end, int C, int M) 481 int end, int C, int M, const int *spread_weight)
460{ 482{
461 int i, c, N0; 483 int i, c, N0;
462 int sum = 0, nbBands=0; 484 int sum = 0, nbBands=0;
@@ -497,8 +519,8 @@ int spreading_decision(const CELTMode *m, const celt_norm *X, int *average,
497 if (i>m->nbEBands-4) 519 if (i>m->nbEBands-4)
498 hf_sum += celt_udiv(32*(tcount[1]+tcount[0]), N); 520 hf_sum += celt_udiv(32*(tcount[1]+tcount[0]), N);
499 tmp = (2*tcount[2] >= N) + (2*tcount[1] >= N) + (2*tcount[0] >= N); 521 tmp = (2*tcount[2] >= N) + (2*tcount[1] >= N) + (2*tcount[0] >= N);
500 sum += tmp*256; 522 sum += tmp*spread_weight[i];
501 nbBands++; 523 nbBands+=spread_weight[i];
502 } 524 }
503 } while (++c<C); 525 } while (++c<C);
504 526
@@ -522,7 +544,7 @@ int spreading_decision(const CELTMode *m, const celt_norm *X, int *average,
522 /*printf("%d %d %d\n", hf_sum, *hf_average, *tapset_decision);*/ 544 /*printf("%d %d %d\n", hf_sum, *hf_average, *tapset_decision);*/
523 celt_assert(nbBands>0); /* end has to be non-zero */ 545 celt_assert(nbBands>0); /* end has to be non-zero */
524 celt_assert(sum>=0); 546 celt_assert(sum>=0);
525 sum = celt_udiv(sum, nbBands); 547 sum = celt_udiv((opus_int32)sum<<8, nbBands);
526 /* Recursive averaging */ 548 /* Recursive averaging */
527 sum = (sum+*average)>>1; 549 sum = (sum+*average)>>1;
528 *average = sum; 550 *average = sum;
@@ -546,7 +568,6 @@ int spreading_decision(const CELTMode *m, const celt_norm *X, int *average,
546#endif 568#endif
547 return decision; 569 return decision;
548} 570}
549#endif
550 571
551/* Indexing table for converting from natural Hadamard to ordery Hadamard 572/* Indexing table for converting from natural Hadamard to ordery Hadamard
552 This is essentially a bit-reversed Gray, on top of which we've added 573 This is essentially a bit-reversed Gray, on top of which we've added
@@ -651,6 +672,7 @@ static int compute_qn(int N, int b, int offset, int pulse_cap, int stereo)
651 672
652struct band_ctx { 673struct band_ctx {
653 int encode; 674 int encode;
675 int resynth;
654 const CELTMode *m; 676 const CELTMode *m;
655 int i; 677 int i;
656 int intensity; 678 int intensity;
@@ -660,6 +682,10 @@ struct band_ctx {
660 opus_int32 remaining_bits; 682 opus_int32 remaining_bits;
661 const celt_ener *bandE; 683 const celt_ener *bandE;
662 opus_uint32 seed; 684 opus_uint32 seed;
685 int arch;
686 int theta_round;
687 int disable_inv;
688 int avoid_split_noise;
663}; 689};
664 690
665struct split_ctx { 691struct split_ctx {
@@ -711,14 +737,41 @@ static void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx,
711 side and mid. With just that parameter, we can re-scale both 737 side and mid. With just that parameter, we can re-scale both
712 mid and side because we know that 1) they have unit norm and 738 mid and side because we know that 1) they have unit norm and
713 2) they are orthogonal. */ 739 2) they are orthogonal. */
714 itheta = stereo_itheta(X, Y, stereo, N); 740 itheta = stereo_itheta(X, Y, stereo, N, ctx->arch);
715 } 741 }
716 tell = ec_tell_frac(ec); 742 tell = ec_tell_frac(ec);
717 if (qn!=1) 743 if (qn!=1)
718 { 744 {
719 if (encode) 745 if (encode)
720 itheta = (itheta*qn+8192)>>14; 746 {
721 747 if (!stereo || ctx->theta_round == 0)
748 {
749 itheta = (itheta*(opus_int32)qn+8192)>>14;
750 if (!stereo && ctx->avoid_split_noise && itheta > 0 && itheta < qn)
751 {
752 /* Check if the selected value of theta will cause the bit allocation
753 to inject noise on one side. If so, make sure the energy of that side
754 is zero. */
755 int unquantized = celt_udiv((opus_int32)itheta*16384, qn);
756 imid = bitexact_cos((opus_int16)unquantized);
757 iside = bitexact_cos((opus_int16)(16384-unquantized));
758 delta = FRAC_MUL16((N-1)<<7,bitexact_log2tan(iside,imid));
759 if (delta > *b)
760 itheta = qn;
761 else if (delta < -*b)
762 itheta = 0;
763 }
764 } else {
765 int down;
766 /* Bias quantization towards itheta=0 and itheta=16384. */
767 int bias = itheta > 8192 ? 32767/qn : -32767/qn;
768 down = IMIN(qn-1, IMAX(0, (itheta*(opus_int32)qn + bias)>>14));
769 if (ctx->theta_round < 0)
770 itheta = down;
771 else
772 itheta = down+1;
773 }
774 }
722 /* Entropy coding of the angle. We use a uniform pdf for the 775 /* Entropy coding of the angle. We use a uniform pdf for the
723 time split, a step for stereo, and a triangular one for the rest. */ 776 time split, a step for stereo, and a triangular one for the rest. */
724 if (stereo && N>2) 777 if (stereo && N>2)
@@ -796,7 +849,7 @@ static void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx,
796 } else if (stereo) { 849 } else if (stereo) {
797 if (encode) 850 if (encode)
798 { 851 {
799 inv = itheta > 8192; 852 inv = itheta > 8192 && !ctx->disable_inv;
800 if (inv) 853 if (inv)
801 { 854 {
802 int j; 855 int j;
@@ -813,6 +866,9 @@ static void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx,
813 inv = ec_dec_bit_logp(ec, 2); 866 inv = ec_dec_bit_logp(ec, 2);
814 } else 867 } else
815 inv = 0; 868 inv = 0;
869 /* inv flag override to avoid problems with downmixing. */
870 if (ctx->disable_inv)
871 inv = 0;
816 itheta = 0; 872 itheta = 0;
817 } 873 }
818 qalloc = ec_tell_frac(ec) - tell; 874 qalloc = ec_tell_frac(ec) - tell;
@@ -848,11 +904,6 @@ static void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx,
848static unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, int b, 904static unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, int b,
849 celt_norm *lowband_out) 905 celt_norm *lowband_out)
850{ 906{
851#ifdef RESYNTH
852 int resynth = 1;
853#else
854 int resynth = !ctx->encode;
855#endif
856 int c; 907 int c;
857 int stereo; 908 int stereo;
858 celt_norm *x = X; 909 celt_norm *x = X;
@@ -877,7 +928,7 @@ static unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y,
877 ctx->remaining_bits -= 1<<BITRES; 928 ctx->remaining_bits -= 1<<BITRES;
878 b-=1<<BITRES; 929 b-=1<<BITRES;
879 } 930 }
880 if (resynth) 931 if (ctx->resynth)
881 x[0] = sign ? -NORM_SCALING : NORM_SCALING; 932 x[0] = sign ? -NORM_SCALING : NORM_SCALING;
882 x = Y; 933 x = Y;
883 } while (++c<1+stereo); 934 } while (++c<1+stereo);
@@ -902,11 +953,6 @@ static unsigned quant_partition(struct band_ctx *ctx, celt_norm *X,
902 int B0=B; 953 int B0=B;
903 opus_val16 mid=0, side=0; 954 opus_val16 mid=0, side=0;
904 unsigned cm=0; 955 unsigned cm=0;
905#ifdef RESYNTH
906 int resynth = 1;
907#else
908 int resynth = !ctx->encode;
909#endif
910 celt_norm *Y=NULL; 956 celt_norm *Y=NULL;
911 int encode; 957 int encode;
912 const CELTMode *m; 958 const CELTMode *m;
@@ -938,8 +984,7 @@ static unsigned quant_partition(struct band_ctx *ctx, celt_norm *X,
938 fill = (fill&1)|(fill<<1); 984 fill = (fill&1)|(fill<<1);
939 B = (B+1)>>1; 985 B = (B+1)>>1;
940 986
941 compute_theta(ctx, &sctx, X, Y, N, &b, B, B0, 987 compute_theta(ctx, &sctx, X, Y, N, &b, B, B0, LM, 0, &fill);
942 LM, 0, &fill);
943 imid = sctx.imid; 988 imid = sctx.imid;
944 iside = sctx.iside; 989 iside = sctx.iside;
945 delta = sctx.delta; 990 delta = sctx.delta;
@@ -973,24 +1018,20 @@ static unsigned quant_partition(struct band_ctx *ctx, celt_norm *X,
973 rebalance = ctx->remaining_bits; 1018 rebalance = ctx->remaining_bits;
974 if (mbits >= sbits) 1019 if (mbits >= sbits)
975 { 1020 {
976 cm = quant_partition(ctx, X, N, mbits, B, 1021 cm = quant_partition(ctx, X, N, mbits, B, lowband, LM,
977 lowband, LM,
978 MULT16_16_P15(gain,mid), fill); 1022 MULT16_16_P15(gain,mid), fill);
979 rebalance = mbits - (rebalance-ctx->remaining_bits); 1023 rebalance = mbits - (rebalance-ctx->remaining_bits);
980 if (rebalance > 3<<BITRES && itheta!=0) 1024 if (rebalance > 3<<BITRES && itheta!=0)
981 sbits += rebalance - (3<<BITRES); 1025 sbits += rebalance - (3<<BITRES);
982 cm |= quant_partition(ctx, Y, N, sbits, B, 1026 cm |= quant_partition(ctx, Y, N, sbits, B, next_lowband2, LM,
983 next_lowband2, LM,
984 MULT16_16_P15(gain,side), fill>>B)<<(B0>>1); 1027 MULT16_16_P15(gain,side), fill>>B)<<(B0>>1);
985 } else { 1028 } else {
986 cm = quant_partition(ctx, Y, N, sbits, B, 1029 cm = quant_partition(ctx, Y, N, sbits, B, next_lowband2, LM,
987 next_lowband2, LM,
988 MULT16_16_P15(gain,side), fill>>B)<<(B0>>1); 1030 MULT16_16_P15(gain,side), fill>>B)<<(B0>>1);
989 rebalance = sbits - (rebalance-ctx->remaining_bits); 1031 rebalance = sbits - (rebalance-ctx->remaining_bits);
990 if (rebalance > 3<<BITRES && itheta!=16384) 1032 if (rebalance > 3<<BITRES && itheta!=16384)
991 mbits += rebalance - (3<<BITRES); 1033 mbits += rebalance - (3<<BITRES);
992 cm |= quant_partition(ctx, X, N, mbits, B, 1034 cm |= quant_partition(ctx, X, N, mbits, B, lowband, LM,
993 lowband, LM,
994 MULT16_16_P15(gain,mid), fill); 1035 MULT16_16_P15(gain,mid), fill);
995 } 1036 }
996 } else { 1037 } else {
@@ -1015,18 +1056,14 @@ static unsigned quant_partition(struct band_ctx *ctx, celt_norm *X,
1015 /* Finally do the actual quantization */ 1056 /* Finally do the actual quantization */
1016 if (encode) 1057 if (encode)
1017 { 1058 {
1018 cm = alg_quant(X, N, K, spread, B, ec 1059 cm = alg_quant(X, N, K, spread, B, ec, gain, ctx->resynth, ctx->arch);
1019#ifdef RESYNTH
1020 , gain
1021#endif
1022 );
1023 } else { 1060 } else {
1024 cm = alg_unquant(X, N, K, spread, B, ec, gain); 1061 cm = alg_unquant(X, N, K, spread, B, ec, gain);
1025 } 1062 }
1026 } else { 1063 } else {
1027 /* If there's no pulse, fill the band anyway */ 1064 /* If there's no pulse, fill the band anyway */
1028 int j; 1065 int j;
1029 if (resynth) 1066 if (ctx->resynth)
1030 { 1067 {
1031 unsigned cm_mask; 1068 unsigned cm_mask;
1032 /* B can be as large as 16, so this shift might overflow an int on a 1069 /* B can be as large as 16, so this shift might overflow an int on a
@@ -1059,7 +1096,7 @@ static unsigned quant_partition(struct band_ctx *ctx, celt_norm *X,
1059 } 1096 }
1060 cm = fill; 1097 cm = fill;
1061 } 1098 }
1062 renormalise_vector(X, N, gain); 1099 renormalise_vector(X, N, gain, ctx->arch);
1063 } 1100 }
1064 } 1101 }
1065 } 1102 }
@@ -1083,11 +1120,6 @@ static unsigned quant_band(struct band_ctx *ctx, celt_norm *X,
1083 int recombine=0; 1120 int recombine=0;
1084 int longBlocks; 1121 int longBlocks;
1085 unsigned cm=0; 1122 unsigned cm=0;
1086#ifdef RESYNTH
1087 int resynth = 1;
1088#else
1089 int resynth = !ctx->encode;
1090#endif
1091 int k; 1123 int k;
1092 int encode; 1124 int encode;
1093 int tf_change; 1125 int tf_change;
@@ -1154,11 +1186,10 @@ static unsigned quant_band(struct band_ctx *ctx, celt_norm *X,
1154 deinterleave_hadamard(lowband, N_B>>recombine, B0<<recombine, longBlocks); 1186 deinterleave_hadamard(lowband, N_B>>recombine, B0<<recombine, longBlocks);
1155 } 1187 }
1156 1188
1157 cm = quant_partition(ctx, X, N, b, B, lowband, 1189 cm = quant_partition(ctx, X, N, b, B, lowband, LM, gain, fill);
1158 LM, gain, fill);
1159 1190
1160 /* This code is used by the decoder and by the resynthesis-enabled encoder */ 1191 /* This code is used by the decoder and by the resynthesis-enabled encoder */
1161 if (resynth) 1192 if (ctx->resynth)
1162 { 1193 {
1163 /* Undo the sample reorganization going from time order to frequency order */ 1194 /* Undo the sample reorganization going from time order to frequency order */
1164 if (B0>1) 1195 if (B0>1)
@@ -1211,11 +1242,6 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm
1211 int inv = 0; 1242 int inv = 0;
1212 opus_val16 mid=0, side=0; 1243 opus_val16 mid=0, side=0;
1213 unsigned cm=0; 1244 unsigned cm=0;
1214#ifdef RESYNTH
1215 int resynth = 1;
1216#else
1217 int resynth = !ctx->encode;
1218#endif
1219 int mbits, sbits, delta; 1245 int mbits, sbits, delta;
1220 int itheta; 1246 int itheta;
1221 int qalloc; 1247 int qalloc;
@@ -1235,8 +1261,7 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm
1235 1261
1236 orig_fill = fill; 1262 orig_fill = fill;
1237 1263
1238 compute_theta(ctx, &sctx, X, Y, N, &b, B, B, 1264 compute_theta(ctx, &sctx, X, Y, N, &b, B, B, LM, 1, &fill);
1239 LM, 1, &fill);
1240 inv = sctx.inv; 1265 inv = sctx.inv;
1241 imid = sctx.imid; 1266 imid = sctx.imid;
1242 iside = sctx.iside; 1267 iside = sctx.iside;
@@ -1284,13 +1309,13 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm
1284 sign = 1-2*sign; 1309 sign = 1-2*sign;
1285 /* We use orig_fill here because we want to fold the side, but if 1310 /* We use orig_fill here because we want to fold the side, but if
1286 itheta==16384, we'll have cleared the low bits of fill. */ 1311 itheta==16384, we'll have cleared the low bits of fill. */
1287 cm = quant_band(ctx, x2, N, mbits, B, lowband, 1312 cm = quant_band(ctx, x2, N, mbits, B, lowband, LM, lowband_out, Q15ONE,
1288 LM, lowband_out, Q15ONE, lowband_scratch, orig_fill); 1313 lowband_scratch, orig_fill);
1289 /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse), 1314 /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse),
1290 and there's no need to worry about mixing with the other channel. */ 1315 and there's no need to worry about mixing with the other channel. */
1291 y2[0] = -sign*x2[1]; 1316 y2[0] = -sign*x2[1];
1292 y2[1] = sign*x2[0]; 1317 y2[1] = sign*x2[0];
1293 if (resynth) 1318 if (ctx->resynth)
1294 { 1319 {
1295 celt_norm tmp; 1320 celt_norm tmp;
1296 X[0] = MULT16_16_Q15(mid, X[0]); 1321 X[0] = MULT16_16_Q15(mid, X[0]);
@@ -1317,41 +1342,35 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm
1317 { 1342 {
1318 /* In stereo mode, we do not apply a scaling to the mid because we need the normalized 1343 /* In stereo mode, we do not apply a scaling to the mid because we need the normalized
1319 mid for folding later. */ 1344 mid for folding later. */
1320 cm = quant_band(ctx, X, N, mbits, B, 1345 cm = quant_band(ctx, X, N, mbits, B, lowband, LM, lowband_out, Q15ONE,
1321 lowband, LM, lowband_out, 1346 lowband_scratch, fill);
1322 Q15ONE, lowband_scratch, fill);
1323 rebalance = mbits - (rebalance-ctx->remaining_bits); 1347 rebalance = mbits - (rebalance-ctx->remaining_bits);
1324 if (rebalance > 3<<BITRES && itheta!=0) 1348 if (rebalance > 3<<BITRES && itheta!=0)
1325 sbits += rebalance - (3<<BITRES); 1349 sbits += rebalance - (3<<BITRES);
1326 1350
1327 /* For a stereo split, the high bits of fill are always zero, so no 1351 /* For a stereo split, the high bits of fill are always zero, so no
1328 folding will be done to the side. */ 1352 folding will be done to the side. */
1329 cm |= quant_band(ctx, Y, N, sbits, B, 1353 cm |= quant_band(ctx, Y, N, sbits, B, NULL, LM, NULL, side, NULL, fill>>B);
1330 NULL, LM, NULL,
1331 side, NULL, fill>>B);
1332 } else { 1354 } else {
1333 /* For a stereo split, the high bits of fill are always zero, so no 1355 /* For a stereo split, the high bits of fill are always zero, so no
1334 folding will be done to the side. */ 1356 folding will be done to the side. */
1335 cm = quant_band(ctx, Y, N, sbits, B, 1357 cm = quant_band(ctx, Y, N, sbits, B, NULL, LM, NULL, side, NULL, fill>>B);
1336 NULL, LM, NULL,
1337 side, NULL, fill>>B);
1338 rebalance = sbits - (rebalance-ctx->remaining_bits); 1358 rebalance = sbits - (rebalance-ctx->remaining_bits);
1339 if (rebalance > 3<<BITRES && itheta!=16384) 1359 if (rebalance > 3<<BITRES && itheta!=16384)
1340 mbits += rebalance - (3<<BITRES); 1360 mbits += rebalance - (3<<BITRES);
1341 /* In stereo mode, we do not apply a scaling to the mid because we need the normalized 1361 /* In stereo mode, we do not apply a scaling to the mid because we need the normalized
1342 mid for folding later. */ 1362 mid for folding later. */
1343 cm |= quant_band(ctx, X, N, mbits, B, 1363 cm |= quant_band(ctx, X, N, mbits, B, lowband, LM, lowband_out, Q15ONE,
1344 lowband, LM, lowband_out, 1364 lowband_scratch, fill);
1345 Q15ONE, lowband_scratch, fill);
1346 } 1365 }
1347 } 1366 }
1348 1367
1349 1368
1350 /* This code is used by the decoder and by the resynthesis-enabled encoder */ 1369 /* This code is used by the decoder and by the resynthesis-enabled encoder */
1351 if (resynth) 1370 if (ctx->resynth)
1352 { 1371 {
1353 if (N!=2) 1372 if (N!=2)
1354 stereo_merge(X, Y, mid, N); 1373 stereo_merge(X, Y, mid, N, ctx->arch);
1355 if (inv) 1374 if (inv)
1356 { 1375 {
1357 int j; 1376 int j;
@@ -1362,17 +1381,38 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm
1362 return cm; 1381 return cm;
1363} 1382}
1364 1383
1384static void special_hybrid_folding(const CELTMode *m, celt_norm *norm, celt_norm *norm2, int start, int M, int dual_stereo)
1385{
1386 int n1, n2;
1387 const opus_int16 * OPUS_RESTRICT eBands = m->eBands;
1388 n1 = M*(eBands[start+1]-eBands[start]);
1389 n2 = M*(eBands[start+2]-eBands[start+1]);
1390 /* Duplicate enough of the first band folding data to be able to fold the second band.
1391 Copies no data for CELT-only mode. */
1392 OPUS_COPY(&norm[n1], &norm[2*n1 - n2], n2-n1);
1393 if (dual_stereo)
1394 OPUS_COPY(&norm2[n1], &norm2[2*n1 - n2], n2-n1);
1395}
1365 1396
1366void quant_all_bands(int encode, const CELTMode *m, int start, int end, 1397void quant_all_bands(int encode, const CELTMode *m, int start, int end,
1367 celt_norm *X_, celt_norm *Y_, unsigned char *collapse_masks, const celt_ener *bandE, int *pulses, 1398 celt_norm *X_, celt_norm *Y_, unsigned char *collapse_masks,
1368 int shortBlocks, int spread, int dual_stereo, int intensity, int *tf_res, 1399 const celt_ener *bandE, int *pulses, int shortBlocks, int spread,
1369 opus_int32 total_bits, opus_int32 balance, ec_ctx *ec, int LM, int codedBands, opus_uint32 *seed) 1400 int dual_stereo, int intensity, int *tf_res, opus_int32 total_bits,
1401 opus_int32 balance, ec_ctx *ec, int LM, int codedBands,
1402 opus_uint32 *seed, int complexity, int arch, int disable_inv)
1370{ 1403{
1371 int i; 1404 int i;
1372 opus_int32 remaining_bits; 1405 opus_int32 remaining_bits;
1373 const opus_int16 * OPUS_RESTRICT eBands = m->eBands; 1406 const opus_int16 * OPUS_RESTRICT eBands = m->eBands;
1374 celt_norm * OPUS_RESTRICT norm, * OPUS_RESTRICT norm2; 1407 celt_norm * OPUS_RESTRICT norm, * OPUS_RESTRICT norm2;
1375 VARDECL(celt_norm, _norm); 1408 VARDECL(celt_norm, _norm);
1409 VARDECL(celt_norm, _lowband_scratch);
1410 VARDECL(celt_norm, X_save);
1411 VARDECL(celt_norm, Y_save);
1412 VARDECL(celt_norm, X_save2);
1413 VARDECL(celt_norm, Y_save2);
1414 VARDECL(celt_norm, norm_save2);
1415 int resynth_alloc;
1376 celt_norm *lowband_scratch; 1416 celt_norm *lowband_scratch;
1377 int B; 1417 int B;
1378 int M; 1418 int M;
@@ -1380,10 +1420,11 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
1380 int update_lowband = 1; 1420 int update_lowband = 1;
1381 int C = Y_ != NULL ? 2 : 1; 1421 int C = Y_ != NULL ? 2 : 1;
1382 int norm_offset; 1422 int norm_offset;
1423 int theta_rdo = encode && Y_!=NULL && !dual_stereo && complexity>=8;
1383#ifdef RESYNTH 1424#ifdef RESYNTH
1384 int resynth = 1; 1425 int resynth = 1;
1385#else 1426#else
1386 int resynth = !encode; 1427 int resynth = !encode || theta_rdo;
1387#endif 1428#endif
1388 struct band_ctx ctx; 1429 struct band_ctx ctx;
1389 SAVE_STACK; 1430 SAVE_STACK;
@@ -1396,9 +1437,24 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
1396 ALLOC(_norm, C*(M*eBands[m->nbEBands-1]-norm_offset), celt_norm); 1437 ALLOC(_norm, C*(M*eBands[m->nbEBands-1]-norm_offset), celt_norm);
1397 norm = _norm; 1438 norm = _norm;
1398 norm2 = norm + M*eBands[m->nbEBands-1]-norm_offset; 1439 norm2 = norm + M*eBands[m->nbEBands-1]-norm_offset;
1399 /* We can use the last band as scratch space because we don't need that 1440
1400 scratch space for the last band. */ 1441 /* For decoding, we can use the last band as scratch space because we don't need that
1401 lowband_scratch = X_+M*eBands[m->nbEBands-1]; 1442 scratch space for the last band and we don't care about the data there until we're
1443 decoding the last band. */
1444 if (encode && resynth)
1445 resynth_alloc = M*(eBands[m->nbEBands]-eBands[m->nbEBands-1]);
1446 else
1447 resynth_alloc = ALLOC_NONE;
1448 ALLOC(_lowband_scratch, resynth_alloc, celt_norm);
1449 if (encode && resynth)
1450 lowband_scratch = _lowband_scratch;
1451 else
1452 lowband_scratch = X_+M*eBands[m->nbEBands-1];
1453 ALLOC(X_save, resynth_alloc, celt_norm);
1454 ALLOC(Y_save, resynth_alloc, celt_norm);
1455 ALLOC(X_save2, resynth_alloc, celt_norm);
1456 ALLOC(Y_save2, resynth_alloc, celt_norm);
1457 ALLOC(norm_save2, resynth_alloc, celt_norm);
1402 1458
1403 lowband_offset = 0; 1459 lowband_offset = 0;
1404 ctx.bandE = bandE; 1460 ctx.bandE = bandE;
@@ -1408,6 +1464,12 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
1408 ctx.m = m; 1464 ctx.m = m;
1409 ctx.seed = *seed; 1465 ctx.seed = *seed;
1410 ctx.spread = spread; 1466 ctx.spread = spread;
1467 ctx.arch = arch;
1468 ctx.disable_inv = disable_inv;
1469 ctx.resynth = resynth;
1470 ctx.theta_round = 0;
1471 /* Avoid injecting noise in the first band on transients. */
1472 ctx.avoid_split_noise = B > 1;
1411 for (i=start;i<end;i++) 1473 for (i=start;i<end;i++)
1412 { 1474 {
1413 opus_int32 tell; 1475 opus_int32 tell;
@@ -1430,6 +1492,7 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
1430 else 1492 else
1431 Y = NULL; 1493 Y = NULL;
1432 N = M*eBands[i+1]-M*eBands[i]; 1494 N = M*eBands[i+1]-M*eBands[i];
1495 celt_assert(N > 0);
1433 tell = ec_tell_frac(ec); 1496 tell = ec_tell_frac(ec);
1434 1497
1435 /* Compute how many bits we want to allocate to this band */ 1498 /* Compute how many bits we want to allocate to this band */
@@ -1445,8 +1508,15 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
1445 b = 0; 1508 b = 0;
1446 } 1509 }
1447 1510
1511#ifndef DISABLE_UPDATE_DRAFT
1512 if (resynth && (M*eBands[i]-N >= M*eBands[start] || i==start+1) && (update_lowband || lowband_offset==0))
1513 lowband_offset = i;
1514 if (i == start+1)
1515 special_hybrid_folding(m, norm, norm2, start, M, dual_stereo);
1516#else
1448 if (resynth && M*eBands[i]-N >= M*eBands[start] && (update_lowband || lowband_offset==0)) 1517 if (resynth && M*eBands[i]-N >= M*eBands[start] && (update_lowband || lowband_offset==0))
1449 lowband_offset = i; 1518 lowband_offset = i;
1519#endif
1450 1520
1451 tf_change = tf_res[i]; 1521 tf_change = tf_res[i];
1452 ctx.tf_change = tf_change; 1522 ctx.tf_change = tf_change;
@@ -1457,7 +1527,7 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
1457 Y = norm; 1527 Y = norm;
1458 lowband_scratch = NULL; 1528 lowband_scratch = NULL;
1459 } 1529 }
1460 if (i==end-1) 1530 if (last && !theta_rdo)
1461 lowband_scratch = NULL; 1531 lowband_scratch = NULL;
1462 1532
1463 /* Get a conservative estimate of the collapse_mask's for the bands we're 1533 /* Get a conservative estimate of the collapse_mask's for the bands we're
@@ -1472,7 +1542,11 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
1472 fold_start = lowband_offset; 1542 fold_start = lowband_offset;
1473 while(M*eBands[--fold_start] > effective_lowband+norm_offset); 1543 while(M*eBands[--fold_start] > effective_lowband+norm_offset);
1474 fold_end = lowband_offset-1; 1544 fold_end = lowband_offset-1;
1545#ifndef DISABLE_UPDATE_DRAFT
1546 while(++fold_end < i && M*eBands[fold_end] < effective_lowband+norm_offset+N);
1547#else
1475 while(M*eBands[++fold_end] < effective_lowband+norm_offset+N); 1548 while(M*eBands[++fold_end] < effective_lowband+norm_offset+N);
1549#endif
1476 x_cm = y_cm = 0; 1550 x_cm = y_cm = 0;
1477 fold_i = fold_start; do { 1551 fold_i = fold_start; do {
1478 x_cm |= collapse_masks[fold_i*C+0]; 1552 x_cm |= collapse_masks[fold_i*C+0];
@@ -1505,13 +1579,79 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
1505 } else { 1579 } else {
1506 if (Y!=NULL) 1580 if (Y!=NULL)
1507 { 1581 {
1508 x_cm = quant_band_stereo(&ctx, X, Y, N, b, B, 1582 if (theta_rdo && i < intensity)
1509 effective_lowband != -1 ? norm+effective_lowband : NULL, LM, 1583 {
1510 last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, x_cm|y_cm); 1584 ec_ctx ec_save, ec_save2;
1585 struct band_ctx ctx_save, ctx_save2;
1586 opus_val32 dist0, dist1;
1587 unsigned cm, cm2;
1588 int nstart_bytes, nend_bytes, save_bytes;
1589 unsigned char *bytes_buf;
1590 unsigned char bytes_save[1275];
1591 opus_val16 w[2];
1592 compute_channel_weights(bandE[i], bandE[i+m->nbEBands], w);
1593 /* Make a copy. */
1594 cm = x_cm|y_cm;
1595 ec_save = *ec;
1596 ctx_save = ctx;
1597 OPUS_COPY(X_save, X, N);
1598 OPUS_COPY(Y_save, Y, N);
1599 /* Encode and round down. */
1600 ctx.theta_round = -1;
1601 x_cm = quant_band_stereo(&ctx, X, Y, N, b, B,
1602 effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
1603 last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, cm);
1604 dist0 = MULT16_32_Q15(w[0], celt_inner_prod(X_save, X, N, arch)) + MULT16_32_Q15(w[1], celt_inner_prod(Y_save, Y, N, arch));
1605
1606 /* Save first result. */
1607 cm2 = x_cm;
1608 ec_save2 = *ec;
1609 ctx_save2 = ctx;
1610 OPUS_COPY(X_save2, X, N);
1611 OPUS_COPY(Y_save2, Y, N);
1612 if (!last)
1613 OPUS_COPY(norm_save2, norm+M*eBands[i]-norm_offset, N);
1614 nstart_bytes = ec_save.offs;
1615 nend_bytes = ec_save.storage;
1616 bytes_buf = ec_save.buf+nstart_bytes;
1617 save_bytes = nend_bytes-nstart_bytes;
1618 OPUS_COPY(bytes_save, bytes_buf, save_bytes);
1619
1620 /* Restore */
1621 *ec = ec_save;
1622 ctx = ctx_save;
1623 OPUS_COPY(X, X_save, N);
1624 OPUS_COPY(Y, Y_save, N);
1625#ifndef DISABLE_UPDATE_DRAFT
1626 if (i == start+1)
1627 special_hybrid_folding(m, norm, norm2, start, M, dual_stereo);
1628#endif
1629 /* Encode and round up. */
1630 ctx.theta_round = 1;
1631 x_cm = quant_band_stereo(&ctx, X, Y, N, b, B,
1632 effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
1633 last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, cm);
1634 dist1 = MULT16_32_Q15(w[0], celt_inner_prod(X_save, X, N, arch)) + MULT16_32_Q15(w[1], celt_inner_prod(Y_save, Y, N, arch));
1635 if (dist0 >= dist1) {
1636 x_cm = cm2;
1637 *ec = ec_save2;
1638 ctx = ctx_save2;
1639 OPUS_COPY(X, X_save2, N);
1640 OPUS_COPY(Y, Y_save2, N);
1641 if (!last)
1642 OPUS_COPY(norm+M*eBands[i]-norm_offset, norm_save2, N);
1643 OPUS_COPY(bytes_buf, bytes_save, save_bytes);
1644 }
1645 } else {
1646 ctx.theta_round = 0;
1647 x_cm = quant_band_stereo(&ctx, X, Y, N, b, B,
1648 effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
1649 last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, x_cm|y_cm);
1650 }
1511 } else { 1651 } else {
1512 x_cm = quant_band(&ctx, X, N, b, B, 1652 x_cm = quant_band(&ctx, X, N, b, B,
1513 effective_lowband != -1 ? norm+effective_lowband : NULL, LM, 1653 effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
1514 last?NULL:norm+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, x_cm|y_cm); 1654 last?NULL:norm+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, x_cm|y_cm);
1515 } 1655 }
1516 y_cm = x_cm; 1656 y_cm = x_cm;
1517 } 1657 }
@@ -1521,6 +1661,9 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
1521 1661
1522 /* Update the folding position only as long as we have 1 bit/sample depth. */ 1662 /* Update the folding position only as long as we have 1 bit/sample depth. */
1523 update_lowband = b>(N<<BITRES); 1663 update_lowband = b>(N<<BITRES);
1664 /* We only need to avoid noise on a split for the first band. After that, we
1665 have folding. */
1666 ctx.avoid_split_noise = 0;
1524 } 1667 }
1525 *seed = ctx.seed; 1668 *seed = ctx.seed;
1526 1669
diff --git a/lib/rbcodec/codecs/libopus/celt/bands.h b/lib/rbcodec/codecs/libopus/celt/bands.h
index 69901b1e33..422b32cf75 100644
--- a/lib/rbcodec/codecs/libopus/celt/bands.h
+++ b/lib/rbcodec/codecs/libopus/celt/bands.h
@@ -36,12 +36,15 @@
36#include "entdec.h" 36#include "entdec.h"
37#include "rate.h" 37#include "rate.h"
38 38
39opus_int16 bitexact_cos(opus_int16 x);
40int bitexact_log2tan(int isin,int icos);
41
39/** Compute the amplitude (sqrt energy) in each of the bands 42/** Compute the amplitude (sqrt energy) in each of the bands
40 * @param m Mode data 43 * @param m Mode data
41 * @param X Spectrum 44 * @param X Spectrum
42 * @param bandE Square root of the energy for each band (returned) 45 * @param bandE Square root of the energy for each band (returned)
43 */ 46 */
44void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM); 47void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM, int arch);
45 48
46/*void compute_noise_energies(const CELTMode *m, const celt_sig *X, const opus_val16 *tonality, celt_ener *bandE);*/ 49/*void compute_noise_energies(const CELTMode *m, const celt_sig *X, const opus_val16 *tonality, celt_ener *bandE);*/
47 50
@@ -69,7 +72,7 @@ void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
69 72
70int spreading_decision(const CELTMode *m, const celt_norm *X, int *average, 73int spreading_decision(const CELTMode *m, const celt_norm *X, int *average,
71 int last_decision, int *hf_average, int *tapset_decision, int update_hf, 74 int last_decision, int *hf_average, int *tapset_decision, int update_hf,
72 int end, int C, int M); 75 int end, int C, int M, const int *spread_weight);
73 76
74#ifdef MEASURE_NORM_MSE 77#ifdef MEASURE_NORM_MSE
75void measure_norm_mse(const CELTMode *m, float *X, float *X0, float *bandE, float *bandE0, int M, int N, int C); 78void measure_norm_mse(const CELTMode *m, float *X, float *X0, float *bandE, float *bandE0, int M, int N, int C);
@@ -98,15 +101,20 @@ void haar1(celt_norm *X, int N0, int stride);
98 * @param LM log2() of the number of 2.5 subframes in the frame 101 * @param LM log2() of the number of 2.5 subframes in the frame
99 * @param codedBands Last band to receive bits + 1 102 * @param codedBands Last band to receive bits + 1
100 * @param seed Random generator seed 103 * @param seed Random generator seed
104 * @param arch Run-time architecture (see opus_select_arch())
101 */ 105 */
102void quant_all_bands(int encode, const CELTMode *m, int start, int end, 106void quant_all_bands(int encode, const CELTMode *m, int start, int end,
103 celt_norm * X, celt_norm * Y, unsigned char *collapse_masks, const celt_ener *bandE, int *pulses, 107 celt_norm * X, celt_norm * Y, unsigned char *collapse_masks,
104 int shortBlocks, int spread, int dual_stereo, int intensity, int *tf_res, 108 const celt_ener *bandE, int *pulses, int shortBlocks, int spread,
105 opus_int32 total_bits, opus_int32 balance, ec_ctx *ec, int M, int codedBands, opus_uint32 *seed); 109 int dual_stereo, int intensity, int *tf_res, opus_int32 total_bits,
106 110 opus_int32 balance, ec_ctx *ec, int M, int codedBands, opus_uint32 *seed,
107void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_masks, int LM, int C, int size, 111 int complexity, int arch, int disable_inv);
108 int start, int end, const opus_val16 *logE, const opus_val16 *prev1logE, 112
109 const opus_val16 *prev2logE, const int *pulses, opus_uint32 seed); 113void anti_collapse(const CELTMode *m, celt_norm *X_,
114 unsigned char *collapse_masks, int LM, int C, int size, int start,
115 int end, const opus_val16 *logE, const opus_val16 *prev1logE,
116 const opus_val16 *prev2logE, const int *pulses, opus_uint32 seed,
117 int arch);
110 118
111opus_uint32 celt_lcg_rand(opus_uint32 seed); 119opus_uint32 celt_lcg_rand(opus_uint32 seed);
112 120
diff --git a/lib/rbcodec/codecs/libopus/celt/celt.c b/lib/rbcodec/codecs/libopus/celt/celt.c
index c0a1e0dab9..9ce234695c 100644
--- a/lib/rbcodec/codecs/libopus/celt/celt.c
+++ b/lib/rbcodec/codecs/libopus/celt/celt.c
@@ -89,10 +89,13 @@ int resampling_factor(opus_int32 rate)
89 return ret; 89 return ret;
90} 90}
91 91
92#ifndef OVERRIDE_COMB_FILTER_CONST 92#if !defined(OVERRIDE_COMB_FILTER_CONST) || defined(NON_STATIC_COMB_FILTER_CONST_C)
93/* This version should be faster on ARM */ 93/* This version should be faster on ARM */
94#ifdef OPUS_ARM_ASM 94#ifdef OPUS_ARM_ASM
95static void comb_filter_const(opus_val32 *y, opus_val32 *x, int T, int N, 95#ifndef NON_STATIC_COMB_FILTER_CONST_C
96static
97#endif
98void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
96 opus_val16 g10, opus_val16 g11, opus_val16 g12) 99 opus_val16 g10, opus_val16 g11, opus_val16 g12)
97{ 100{
98 opus_val32 x0, x1, x2, x3, x4; 101 opus_val32 x0, x1, x2, x3, x4;
@@ -108,26 +111,31 @@ static void comb_filter_const(opus_val32 *y, opus_val32 *x, int T, int N,
108 t = MAC16_32_Q16(x[i], g10, x2); 111 t = MAC16_32_Q16(x[i], g10, x2);
109 t = MAC16_32_Q16(t, g11, ADD32(x1,x3)); 112 t = MAC16_32_Q16(t, g11, ADD32(x1,x3));
110 t = MAC16_32_Q16(t, g12, ADD32(x0,x4)); 113 t = MAC16_32_Q16(t, g12, ADD32(x0,x4));
114 t = SATURATE(t, SIG_SAT);
111 y[i] = t; 115 y[i] = t;
112 x4=SHL32(x[i-T+3],1); 116 x4=SHL32(x[i-T+3],1);
113 t = MAC16_32_Q16(x[i+1], g10, x1); 117 t = MAC16_32_Q16(x[i+1], g10, x1);
114 t = MAC16_32_Q16(t, g11, ADD32(x0,x2)); 118 t = MAC16_32_Q16(t, g11, ADD32(x0,x2));
115 t = MAC16_32_Q16(t, g12, ADD32(x4,x3)); 119 t = MAC16_32_Q16(t, g12, ADD32(x4,x3));
120 t = SATURATE(t, SIG_SAT);
116 y[i+1] = t; 121 y[i+1] = t;
117 x3=SHL32(x[i-T+4],1); 122 x3=SHL32(x[i-T+4],1);
118 t = MAC16_32_Q16(x[i+2], g10, x0); 123 t = MAC16_32_Q16(x[i+2], g10, x0);
119 t = MAC16_32_Q16(t, g11, ADD32(x4,x1)); 124 t = MAC16_32_Q16(t, g11, ADD32(x4,x1));
120 t = MAC16_32_Q16(t, g12, ADD32(x3,x2)); 125 t = MAC16_32_Q16(t, g12, ADD32(x3,x2));
126 t = SATURATE(t, SIG_SAT);
121 y[i+2] = t; 127 y[i+2] = t;
122 x2=SHL32(x[i-T+5],1); 128 x2=SHL32(x[i-T+5],1);
123 t = MAC16_32_Q16(x[i+3], g10, x4); 129 t = MAC16_32_Q16(x[i+3], g10, x4);
124 t = MAC16_32_Q16(t, g11, ADD32(x3,x0)); 130 t = MAC16_32_Q16(t, g11, ADD32(x3,x0));
125 t = MAC16_32_Q16(t, g12, ADD32(x2,x1)); 131 t = MAC16_32_Q16(t, g12, ADD32(x2,x1));
132 t = SATURATE(t, SIG_SAT);
126 y[i+3] = t; 133 y[i+3] = t;
127 x1=SHL32(x[i-T+6],1); 134 x1=SHL32(x[i-T+6],1);
128 t = MAC16_32_Q16(x[i+4], g10, x3); 135 t = MAC16_32_Q16(x[i+4], g10, x3);
129 t = MAC16_32_Q16(t, g11, ADD32(x2,x4)); 136 t = MAC16_32_Q16(t, g11, ADD32(x2,x4));
130 t = MAC16_32_Q16(t, g12, ADD32(x1,x0)); 137 t = MAC16_32_Q16(t, g12, ADD32(x1,x0));
138 t = SATURATE(t, SIG_SAT);
131 y[i+4] = t; 139 y[i+4] = t;
132 } 140 }
133#ifdef CUSTOM_MODES 141#ifdef CUSTOM_MODES
@@ -138,6 +146,7 @@ static void comb_filter_const(opus_val32 *y, opus_val32 *x, int T, int N,
138 t = MAC16_32_Q16(x[i], g10, x2); 146 t = MAC16_32_Q16(x[i], g10, x2);
139 t = MAC16_32_Q16(t, g11, ADD32(x1,x3)); 147 t = MAC16_32_Q16(t, g11, ADD32(x1,x3));
140 t = MAC16_32_Q16(t, g12, ADD32(x0,x4)); 148 t = MAC16_32_Q16(t, g12, ADD32(x0,x4));
149 t = SATURATE(t, SIG_SAT);
141 y[i] = t; 150 y[i] = t;
142 x4=x3; 151 x4=x3;
143 x3=x2; 152 x3=x2;
@@ -147,7 +156,10 @@ static void comb_filter_const(opus_val32 *y, opus_val32 *x, int T, int N,
147#endif 156#endif
148} 157}
149#else 158#else
150static void comb_filter_const(opus_val32 *y, opus_val32 *x, int T, int N, 159#ifndef NON_STATIC_COMB_FILTER_CONST_C
160static
161#endif
162void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
151 opus_val16 g10, opus_val16 g11, opus_val16 g12) 163 opus_val16 g10, opus_val16 g11, opus_val16 g12)
152{ 164{
153 opus_val32 x0, x1, x2, x3, x4; 165 opus_val32 x0, x1, x2, x3, x4;
@@ -163,6 +175,7 @@ static void comb_filter_const(opus_val32 *y, opus_val32 *x, int T, int N,
163 + MULT16_32_Q15(g10,x2) 175 + MULT16_32_Q15(g10,x2)
164 + MULT16_32_Q15(g11,ADD32(x1,x3)) 176 + MULT16_32_Q15(g11,ADD32(x1,x3))
165 + MULT16_32_Q15(g12,ADD32(x0,x4)); 177 + MULT16_32_Q15(g12,ADD32(x0,x4));
178 y[i] = SATURATE(y[i], SIG_SAT);
166 x4=x3; 179 x4=x3;
167 x3=x2; 180 x3=x2;
168 x2=x1; 181 x2=x1;
@@ -176,7 +189,7 @@ static void comb_filter_const(opus_val32 *y, opus_val32 *x, int T, int N,
176#ifndef OVERRIDE_comb_filter 189#ifndef OVERRIDE_comb_filter
177void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N, 190void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
178 opus_val16 g0, opus_val16 g1, int tapset0, int tapset1, 191 opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
179 const opus_val16 *window, int overlap) 192 const opus_val16 *window, int overlap, int arch)
180{ 193{
181 int i; 194 int i;
182 /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */ 195 /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
@@ -194,6 +207,10 @@ void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
194 OPUS_MOVE(y, x, N); 207 OPUS_MOVE(y, x, N);
195 return; 208 return;
196 } 209 }
210 /* When the gain is zero, T0 and/or T1 is set to zero. We need
211 to have then be at least 2 to avoid processing garbage data. */
212 T0 = IMAX(T0, COMBFILTER_MINPERIOD);
213 T1 = IMAX(T1, COMBFILTER_MINPERIOD);
197 g00 = MULT16_16_P15(g0, gains[tapset0][0]); 214 g00 = MULT16_16_P15(g0, gains[tapset0][0]);
198 g01 = MULT16_16_P15(g0, gains[tapset0][1]); 215 g01 = MULT16_16_P15(g0, gains[tapset0][1]);
199 g02 = MULT16_16_P15(g0, gains[tapset0][2]); 216 g02 = MULT16_16_P15(g0, gains[tapset0][2]);
@@ -219,6 +236,7 @@ void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
219 + MULT16_32_Q15(MULT16_16_Q15(f,g10),x2) 236 + MULT16_32_Q15(MULT16_16_Q15(f,g10),x2)
220 + MULT16_32_Q15(MULT16_16_Q15(f,g11),ADD32(x1,x3)) 237 + MULT16_32_Q15(MULT16_16_Q15(f,g11),ADD32(x1,x3))
221 + MULT16_32_Q15(MULT16_16_Q15(f,g12),ADD32(x0,x4)); 238 + MULT16_32_Q15(MULT16_16_Q15(f,g12),ADD32(x0,x4));
239 y[i] = SATURATE(y[i], SIG_SAT);
222 x4=x3; 240 x4=x3;
223 x3=x2; 241 x3=x2;
224 x2=x1; 242 x2=x1;
@@ -234,15 +252,20 @@ void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
234 } 252 }
235 253
236 /* Compute the part with the constant filter. */ 254 /* Compute the part with the constant filter. */
237 comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12); 255 comb_filter_const(y+i, x+i, T1, N-i, g10, g11, g12, arch);
238} 256}
239#endif /* OVERRIDE_comb_filter */ 257#endif /* OVERRIDE_comb_filter */
240 258
259/* TF change table. Positive values mean better frequency resolution (longer
260 effective window), whereas negative values mean better time resolution
261 (shorter effective window). The second index is computed as:
262 4*isTransient + 2*tf_select + per_band_flag */
241const signed char tf_select_table[4][8] = { 263const signed char tf_select_table[4][8] = {
242 {0, -1, 0, -1, 0,-1, 0,-1}, 264 /*isTransient=0 isTransient=1 */
243 {0, -1, 0, -2, 1, 0, 1,-1}, 265 {0, -1, 0, -1, 0,-1, 0,-1}, /* 2.5 ms */
244 {0, -2, 0, -3, 2, 0, 1,-1}, 266 {0, -1, 0, -2, 1, 0, 1,-1}, /* 5 ms */
245 {0, -2, 0, -3, 3, 0, 1,-1}, 267 {0, -2, 0, -3, 2, 0, 1,-1}, /* 10 ms */
268 {0, -2, 0, -3, 3, 0, 1,-1}, /* 20 ms */
246}; 269};
247 270
248 271
@@ -280,6 +303,9 @@ const char *opus_strerror(int error)
280const char *opus_get_version_string(void) 303const char *opus_get_version_string(void)
281{ 304{
282 return "libopus " PACKAGE_VERSION 305 return "libopus " PACKAGE_VERSION
306 /* Applications may rely on the presence of this substring in the version
307 string to determine if they have a fixed-point or floating-point build
308 at runtime. */
283#ifdef FIXED_POINT 309#ifdef FIXED_POINT
284 "-fixed" 310 "-fixed"
285#endif 311#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/celt.h b/lib/rbcodec/codecs/libopus/celt/celt.h
index b1967516dc..24b6b2b520 100644
--- a/lib/rbcodec/codecs/libopus/celt/celt.h
+++ b/lib/rbcodec/codecs/libopus/celt/celt.h
@@ -50,6 +50,8 @@ extern "C" {
50#define CELTDecoder OpusCustomDecoder 50#define CELTDecoder OpusCustomDecoder
51#define CELTMode OpusCustomMode 51#define CELTMode OpusCustomMode
52 52
53#define LEAK_BANDS 19
54
53typedef struct { 55typedef struct {
54 int valid; 56 int valid;
55 float tonality; 57 float tonality;
@@ -57,17 +59,27 @@ typedef struct {
57 float noisiness; 59 float noisiness;
58 float activity; 60 float activity;
59 float music_prob; 61 float music_prob;
60 int bandwidth; 62 float music_prob_min;
61}AnalysisInfo; 63 float music_prob_max;
64 int bandwidth;
65 float activity_probability;
66 float max_pitch_ratio;
67 /* Store as Q6 char to save space. */
68 unsigned char leak_boost[LEAK_BANDS];
69} AnalysisInfo;
70
71typedef struct {
72 int signalType;
73 int offset;
74} SILKInfo;
62 75
63#define __celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr))) 76#define __celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr)))
64 77
65#define __celt_check_analysis_ptr(ptr) ((ptr) + ((ptr) - (const AnalysisInfo*)(ptr))) 78#define __celt_check_analysis_ptr(ptr) ((ptr) + ((ptr) - (const AnalysisInfo*)(ptr)))
66 79
67/* Encoder/decoder Requests */ 80#define __celt_check_silkinfo_ptr(ptr) ((ptr) + ((ptr) - (const SILKInfo*)(ptr)))
68 81
69/* Expose this option again when variable framesize actually works */ 82/* Encoder/decoder Requests */
70#define OPUS_FRAMESIZE_VARIABLE 5010 /**< Optimize the frame size dynamically */
71 83
72 84
73#define CELT_SET_PREDICTION_REQUEST 10002 85#define CELT_SET_PREDICTION_REQUEST 10002
@@ -116,6 +128,9 @@ typedef struct {
116#define OPUS_SET_ENERGY_MASK_REQUEST 10026 128#define OPUS_SET_ENERGY_MASK_REQUEST 10026
117#define OPUS_SET_ENERGY_MASK(x) OPUS_SET_ENERGY_MASK_REQUEST, __opus_check_val16_ptr(x) 129#define OPUS_SET_ENERGY_MASK(x) OPUS_SET_ENERGY_MASK_REQUEST, __opus_check_val16_ptr(x)
118 130
131#define CELT_SET_SILK_INFO_REQUEST 10028
132#define CELT_SET_SILK_INFO(x) CELT_SET_SILK_INFO_REQUEST, __celt_check_silkinfo_ptr(x)
133
119/* Encoder stuff */ 134/* Encoder stuff */
120 135
121int celt_encoder_get_size(int channels); 136int celt_encoder_get_size(int channels);
@@ -194,6 +209,13 @@ static OPUS_INLINE int fromOpus(unsigned char c)
194 209
195extern const signed char tf_select_table[4][8]; 210extern const signed char tf_select_table[4][8];
196 211
212#if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)
213void validate_celt_decoder(CELTDecoder *st);
214#define VALIDATE_CELT_DECODER(st) validate_celt_decoder(st)
215#else
216#define VALIDATE_CELT_DECODER(st)
217#endif
218
197int resampling_factor(opus_int32 rate); 219int resampling_factor(opus_int32 rate);
198 220
199void celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT inp, 221void celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT inp,
@@ -201,7 +223,17 @@ void celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RES
201 223
202void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N, 224void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
203 opus_val16 g0, opus_val16 g1, int tapset0, int tapset1, 225 opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
204 const opus_val16 *window, int overlap); 226 const opus_val16 *window, int overlap, int arch);
227
228#ifdef NON_STATIC_COMB_FILTER_CONST_C
229void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
230 opus_val16 g10, opus_val16 g11, opus_val16 g12);
231#endif
232
233#ifndef OVERRIDE_COMB_FILTER_CONST
234# define comb_filter_const(y, x, T, N, g10, g11, g12, arch) \
235 ((void)(arch),comb_filter_const_c(y, x, T, N, g10, g11, g12))
236#endif
205 237
206void init_caps(const CELTMode *m,int *cap,int LM,int C); 238void init_caps(const CELTMode *m,int *cap,int LM,int C);
207 239
diff --git a/lib/rbcodec/codecs/libopus/celt/celt_decoder.c b/lib/rbcodec/codecs/libopus/celt/celt_decoder.c
index 8af96b7931..e6efce9358 100644
--- a/lib/rbcodec/codecs/libopus/celt/celt_decoder.c
+++ b/lib/rbcodec/codecs/libopus/celt/celt_decoder.c
@@ -51,6 +51,14 @@
51#include "celt_lpc.h" 51#include "celt_lpc.h"
52#include "vq.h" 52#include "vq.h"
53 53
54/* The maximum pitch lag to allow in the pitch-based PLC. It's possible to save
55 CPU time in the PLC pitch search by making this smaller than MAX_PERIOD. The
56 current value corresponds to a pitch of 66.67 Hz. */
57#define PLC_PITCH_LAG_MAX (720)
58/* The minimum pitch lag to allow in the pitch-based PLC. This corresponds to a
59 pitch of 480 Hz. */
60#define PLC_PITCH_LAG_MIN (100)
61
54#if defined(SMALL_FOOTPRINT) && defined(FIXED_POINT) 62#if defined(SMALL_FOOTPRINT) && defined(FIXED_POINT)
55#define NORM_ALIASING_HACK 63#define NORM_ALIASING_HACK
56#endif 64#endif
@@ -73,6 +81,7 @@ struct OpusCustomDecoder {
73 int downsample; 81 int downsample;
74 int start, end; 82 int start, end;
75 int signalling; 83 int signalling;
84 int disable_inv;
76 int arch; 85 int arch;
77 86
78 /* Everything beyond this point gets cleared on a reset */ 87 /* Everything beyond this point gets cleared on a reset */
@@ -82,6 +91,7 @@ struct OpusCustomDecoder {
82 int error; 91 int error;
83 int last_pitch_index; 92 int last_pitch_index;
84 int loss_count; 93 int loss_count;
94 int skip_plc;
85 int postfilter_period; 95 int postfilter_period;
86 int postfilter_period_old; 96 int postfilter_period_old;
87 opus_val16 postfilter_gain; 97 opus_val16 postfilter_gain;
@@ -99,6 +109,38 @@ struct OpusCustomDecoder {
99 /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */ 109 /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */
100}; 110};
101 111
112#if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)
113/* Make basic checks on the CELT state to ensure we don't end
114 up writing all over memory. */
115void validate_celt_decoder(CELTDecoder *st)
116{
117#ifndef CUSTOM_MODES
118 celt_assert(st->mode == opus_custom_mode_create(48000, 960, NULL));
119 celt_assert(st->overlap == 120);
120#endif
121 celt_assert(st->channels == 1 || st->channels == 2);
122 celt_assert(st->stream_channels == 1 || st->stream_channels == 2);
123 celt_assert(st->downsample > 0);
124 celt_assert(st->start == 0 || st->start == 17);
125 celt_assert(st->start < st->end);
126 celt_assert(st->end <= 21);
127#ifdef OPUS_ARCHMASK
128 celt_assert(st->arch >= 0);
129 celt_assert(st->arch <= OPUS_ARCHMASK);
130#endif
131 celt_assert(st->last_pitch_index <= PLC_PITCH_LAG_MAX);
132 celt_assert(st->last_pitch_index >= PLC_PITCH_LAG_MIN || st->last_pitch_index == 0);
133 celt_assert(st->postfilter_period < MAX_PERIOD);
134 celt_assert(st->postfilter_period >= COMBFILTER_MINPERIOD || st->postfilter_period == 0);
135 celt_assert(st->postfilter_period_old < MAX_PERIOD);
136 celt_assert(st->postfilter_period_old >= COMBFILTER_MINPERIOD || st->postfilter_period_old == 0);
137 celt_assert(st->postfilter_tapset <= 2);
138 celt_assert(st->postfilter_tapset >= 0);
139 celt_assert(st->postfilter_tapset_old <= 2);
140 celt_assert(st->postfilter_tapset_old >= 0);
141}
142#endif
143
102int celt_decoder_get_size(int channels) 144int celt_decoder_get_size(int channels)
103{ 145{
104 const CELTMode *mode = opus_custom_mode_create(48000, 960, NULL); 146 const CELTMode *mode = opus_custom_mode_create(48000, 960, NULL);
@@ -162,10 +204,13 @@ OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_init(CELTDecoder *st, const CELTMod
162 st->start = 0; 204 st->start = 0;
163 st->end = st->mode->effEBands; 205 st->end = st->mode->effEBands;
164 st->signalling = 1; 206 st->signalling = 1;
207#ifndef DISABLE_UPDATE_DRAFT
208 st->disable_inv = channels == 1;
209#else
210 st->disable_inv = 0;
211#endif
165 st->arch = opus_select_arch(); 212 st->arch = opus_select_arch();
166 213
167 st->loss_count = 0;
168
169 opus_custom_decoder_ctl(st, OPUS_RESET_STATE); 214 opus_custom_decoder_ctl(st, OPUS_RESET_STATE);
170 215
171 return OPUS_OK; 216 return OPUS_OK;
@@ -178,6 +223,36 @@ void opus_custom_decoder_destroy(CELTDecoder *st)
178} 223}
179#endif /* CUSTOM_MODES */ 224#endif /* CUSTOM_MODES */
180 225
226#ifndef CUSTOM_MODES
227/* Special case for stereo with no downsampling and no accumulation. This is
228 quite common and we can make it faster by processing both channels in the
229 same loop, reducing overhead due to the dependency loop in the IIR filter. */
230static void deemphasis_stereo_simple(celt_sig *in[], opus_val16 *pcm, int N, const opus_val16 coef0,
231 celt_sig *mem)
232{
233 celt_sig * OPUS_RESTRICT x0;
234 celt_sig * OPUS_RESTRICT x1;
235 celt_sig m0, m1;
236 int j;
237 x0=in[0];
238 x1=in[1];
239 m0 = mem[0];
240 m1 = mem[1];
241 for (j=0;j<N;j++)
242 {
243 celt_sig tmp0, tmp1;
244 /* Add VERY_SMALL to x[] first to reduce dependency chain. */
245 tmp0 = x0[j] + VERY_SMALL + m0;
246 tmp1 = x1[j] + VERY_SMALL + m1;
247 m0 = MULT16_32_Q15(coef0, tmp0);
248 m1 = MULT16_32_Q15(coef0, tmp1);
249 pcm[2*j ] = SCALEOUT(SIG2WORD16(tmp0));
250 pcm[2*j+1] = SCALEOUT(SIG2WORD16(tmp1));
251 }
252 mem[0] = m0;
253 mem[1] = m1;
254}
255#endif
181 256
182#ifndef RESYNTH 257#ifndef RESYNTH
183static 258static
@@ -191,6 +266,14 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
191 opus_val16 coef0; 266 opus_val16 coef0;
192 VARDECL(celt_sig, scratch); 267 VARDECL(celt_sig, scratch);
193 SAVE_STACK; 268 SAVE_STACK;
269#ifndef CUSTOM_MODES
270 /* Short version for common case. */
271 if (downsample == 1 && C == 2 && !accum)
272 {
273 deemphasis_stereo_simple(in, pcm, N, coef[0], mem);
274 return;
275 }
276#endif
194#ifndef FIXED_POINT 277#ifndef FIXED_POINT
195 (void)accum; 278 (void)accum;
196 celt_assert(accum==0); 279 celt_assert(accum==0);
@@ -226,7 +309,7 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
226 /* Shortcut for the standard (non-custom modes) case */ 309 /* Shortcut for the standard (non-custom modes) case */
227 for (j=0;j<N;j++) 310 for (j=0;j<N;j++)
228 { 311 {
229 celt_sig tmp = x[j] + m + VERY_SMALL; 312 celt_sig tmp = x[j] + VERY_SMALL + m;
230 m = MULT16_32_Q15(coef0, tmp); 313 m = MULT16_32_Q15(coef0, tmp);
231 scratch[j] = tmp; 314 scratch[j] = tmp;
232 } 315 }
@@ -247,7 +330,7 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
247 { 330 {
248 for (j=0;j<N;j++) 331 for (j=0;j<N;j++)
249 { 332 {
250 celt_sig tmp = x[j] + m + VERY_SMALL; 333 celt_sig tmp = x[j] + VERY_SMALL + m;
251 m = MULT16_32_Q15(coef0, tmp); 334 m = MULT16_32_Q15(coef0, tmp);
252 y[j*C] = SCALEOUT(SIG2WORD16(tmp)); 335 y[j*C] = SCALEOUT(SIG2WORD16(tmp));
253 } 336 }
@@ -278,8 +361,9 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
278static 361static
279#endif 362#endif
280void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[], 363void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
281 opus_val16 *oldBandE, int start, int effEnd, int C, int CC, int isTransient, 364 opus_val16 *oldBandE, int start, int effEnd, int C, int CC,
282 int LM, int downsample, int silence) 365 int isTransient, int LM, int downsample,
366 int silence, int arch)
283{ 367{
284 int c, i; 368 int c, i;
285 int M; 369 int M;
@@ -319,9 +403,9 @@ void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
319 freq2 = out_syn[1]+overlap/2; 403 freq2 = out_syn[1]+overlap/2;
320 OPUS_COPY(freq2, freq, N); 404 OPUS_COPY(freq2, freq, N);
321 for (b=0;b<B;b++) 405 for (b=0;b<B;b++)
322 clt_mdct_backward(&mode->mdct, &freq2[b], out_syn[0]+NB*b, mode->window, overlap, shift, B); 406 clt_mdct_backward(&mode->mdct, &freq2[b], out_syn[0]+NB*b, mode->window, overlap, shift, B, arch);
323 for (b=0;b<B;b++) 407 for (b=0;b<B;b++)
324 clt_mdct_backward(&mode->mdct, &freq[b], out_syn[1]+NB*b, mode->window, overlap, shift, B); 408 clt_mdct_backward(&mode->mdct, &freq[b], out_syn[1]+NB*b, mode->window, overlap, shift, B, arch);
325 } else if (CC==1&&C==2) 409 } else if (CC==1&&C==2)
326 { 410 {
327 /* Downmixing a stereo stream to mono */ 411 /* Downmixing a stereo stream to mono */
@@ -333,18 +417,24 @@ void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
333 denormalise_bands(mode, X+N, freq2, oldBandE+nbEBands, start, effEnd, M, 417 denormalise_bands(mode, X+N, freq2, oldBandE+nbEBands, start, effEnd, M,
334 downsample, silence); 418 downsample, silence);
335 for (i=0;i<N;i++) 419 for (i=0;i<N;i++)
336 freq[i] = HALF32(ADD32(freq[i],freq2[i])); 420 freq[i] = ADD32(HALF32(freq[i]), HALF32(freq2[i]));
337 for (b=0;b<B;b++) 421 for (b=0;b<B;b++)
338 clt_mdct_backward(&mode->mdct, &freq[b], out_syn[0]+NB*b, mode->window, overlap, shift, B); 422 clt_mdct_backward(&mode->mdct, &freq[b], out_syn[0]+NB*b, mode->window, overlap, shift, B, arch);
339 } else { 423 } else {
340 /* Normal case (mono or stereo) */ 424 /* Normal case (mono or stereo) */
341 c=0; do { 425 c=0; do {
342 denormalise_bands(mode, X+c*N, freq, oldBandE+c*nbEBands, start, effEnd, M, 426 denormalise_bands(mode, X+c*N, freq, oldBandE+c*nbEBands, start, effEnd, M,
343 downsample, silence); 427 downsample, silence);
344 for (b=0;b<B;b++) 428 for (b=0;b<B;b++)
345 clt_mdct_backward(&mode->mdct, &freq[b], out_syn[c]+NB*b, mode->window, overlap, shift, B); 429 clt_mdct_backward(&mode->mdct, &freq[b], out_syn[c]+NB*b, mode->window, overlap, shift, B, arch);
346 } while (++c<CC); 430 } while (++c<CC);
347 } 431 }
432 /* Saturate IMDCT output so that we can't overflow in the pitch postfilter
433 or in the */
434 c=0; do {
435 for (i=0;i<N;i++)
436 out_syn[c][i] = SATURATE(out_syn[c][i], SIG_SAT);
437 } while (++c<CC);
348 RESTORE_STACK; 438 RESTORE_STACK;
349} 439}
350 440
@@ -387,14 +477,6 @@ static void tf_decode(int start, int end, int isTransient, int *tf_res, int LM,
387 } 477 }
388} 478}
389 479
390/* The maximum pitch lag to allow in the pitch-based PLC. It's possible to save
391 CPU time in the PLC pitch search by making this smaller than MAX_PERIOD. The
392 current value corresponds to a pitch of 66.67 Hz. */
393#define PLC_PITCH_LAG_MAX (720)
394/* The minimum pitch lag to allow in the pitch-based PLC. This corresponds to a
395 pitch of 480 Hz. */
396#define PLC_PITCH_LAG_MIN (100)
397
398static int celt_plc_pitch_search(celt_sig *decode_mem[2], int C, int arch) 480static int celt_plc_pitch_search(celt_sig *decode_mem[2], int C, int arch)
399{ 481{
400 int pitch_index; 482 int pitch_index;
@@ -446,7 +528,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
446 528
447 loss_count = st->loss_count; 529 loss_count = st->loss_count;
448 start = st->start; 530 start = st->start;
449 noise_based = loss_count >= 5 || start != 0; 531 noise_based = loss_count >= 5 || start != 0 || st->skip_plc;
450 if (noise_based) 532 if (noise_based)
451 { 533 {
452 /* Noise-based PLC/CNG */ 534 /* Noise-based PLC/CNG */
@@ -456,10 +538,9 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
456 VARDECL(celt_norm, X); 538 VARDECL(celt_norm, X);
457#endif 539#endif
458 opus_uint32 seed; 540 opus_uint32 seed;
459 opus_val16 *plcLogE;
460 int end; 541 int end;
461 int effEnd; 542 int effEnd;
462 543 opus_val16 decay;
463 end = st->end; 544 end = st->end;
464 effEnd = IMAX(start, IMIN(end, mode->effEBands)); 545 effEnd = IMAX(start, IMIN(end, mode->effEBands));
465 546
@@ -471,19 +552,13 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
471 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ 552 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
472#endif 553#endif
473 554
474 if (loss_count >= 5) 555 /* Energy decay */
475 plcLogE = backgroundLogE; 556 decay = loss_count==0 ? QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT);
476 else { 557 c=0; do
477 /* Energy decay */ 558 {
478 opus_val16 decay = loss_count==0 ? 559 for (i=start;i<end;i++)
479 QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT); 560 oldBandE[c*nbEBands+i] = MAX16(backgroundLogE[c*nbEBands+i], oldBandE[c*nbEBands+i] - decay);
480 c=0; do 561 } while (++c<C);
481 {
482 for (i=start;i<end;i++)
483 oldBandE[c*nbEBands+i] -= decay;
484 } while (++c<C);
485 plcLogE = oldBandE;
486 }
487 seed = st->rng; 562 seed = st->rng;
488 for (c=0;c<C;c++) 563 for (c=0;c<C;c++)
489 { 564 {
@@ -499,7 +574,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
499 seed = celt_lcg_rand(seed); 574 seed = celt_lcg_rand(seed);
500 X[boffs+j] = (celt_norm)((opus_int32)seed>>20); 575 X[boffs+j] = (celt_norm)((opus_int32)seed>>20);
501 } 576 }
502 renormalise_vector(X+boffs, blen, Q15ONE); 577 renormalise_vector(X+boffs, blen, Q15ONE, st->arch);
503 } 578 }
504 } 579 }
505 st->rng = seed; 580 st->rng = seed;
@@ -509,14 +584,17 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
509 DECODE_BUFFER_SIZE-N+(overlap>>1)); 584 DECODE_BUFFER_SIZE-N+(overlap>>1));
510 } while (++c<C); 585 } while (++c<C);
511 586
512 celt_synthesis(mode, X, out_syn, plcLogE, start, effEnd, C, C, 0, LM, st->downsample, 0); 587 celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd, C, C, 0, LM, st->downsample, 0, st->arch);
513 } else { 588 } else {
589 int exc_length;
514 /* Pitch-based PLC */ 590 /* Pitch-based PLC */
515 const opus_val16 *window; 591 const opus_val16 *window;
592 opus_val16 *exc;
516 opus_val16 fade = Q15ONE; 593 opus_val16 fade = Q15ONE;
517 int pitch_index; 594 int pitch_index;
518 VARDECL(opus_val32, etmp); 595 VARDECL(opus_val32, etmp);
519 VARDECL(opus_val16, exc); 596 VARDECL(opus_val16, _exc);
597 VARDECL(opus_val16, fir_tmp);
520 598
521 if (loss_count == 0) 599 if (loss_count == 0)
522 { 600 {
@@ -526,8 +604,14 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
526 fade = QCONST16(.8f,15); 604 fade = QCONST16(.8f,15);
527 } 605 }
528 606
607 /* We want the excitation for 2 pitch periods in order to look for a
608 decaying signal, but we can't get more than MAX_PERIOD. */
609 exc_length = IMIN(2*pitch_index, MAX_PERIOD);
610
529 ALLOC(etmp, overlap, opus_val32); 611 ALLOC(etmp, overlap, opus_val32);
530 ALLOC(exc, MAX_PERIOD, opus_val16); 612 ALLOC(_exc, MAX_PERIOD+LPC_ORDER, opus_val16);
613 ALLOC(fir_tmp, exc_length, opus_val16);
614 exc = _exc+LPC_ORDER;
531 window = mode->window; 615 window = mode->window;
532 c=0; do { 616 c=0; do {
533 opus_val16 decay; 617 opus_val16 decay;
@@ -536,13 +620,11 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
536 celt_sig *buf; 620 celt_sig *buf;
537 int extrapolation_offset; 621 int extrapolation_offset;
538 int extrapolation_len; 622 int extrapolation_len;
539 int exc_length;
540 int j; 623 int j;
541 624
542 buf = decode_mem[c]; 625 buf = decode_mem[c];
543 for (i=0;i<MAX_PERIOD;i++) { 626 for (i=0;i<MAX_PERIOD+LPC_ORDER;i++)
544 exc[i] = ROUND16(buf[DECODE_BUFFER_SIZE-MAX_PERIOD+i], SIG_SHIFT); 627 exc[i-LPC_ORDER] = ROUND16(buf[DECODE_BUFFER_SIZE-MAX_PERIOD-LPC_ORDER+i], SIG_SHIFT);
545 }
546 628
547 if (loss_count == 0) 629 if (loss_count == 0)
548 { 630 {
@@ -568,22 +650,32 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
568#endif 650#endif
569 } 651 }
570 _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER); 652 _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER);
653#ifdef FIXED_POINT
654 /* For fixed-point, apply bandwidth expansion until we can guarantee that
655 no overflow can happen in the IIR filter. This means:
656 32768*sum(abs(filter)) < 2^31 */
657 while (1) {
658 opus_val16 tmp=Q15ONE;
659 opus_val32 sum=QCONST16(1., SIG_SHIFT);
660 for (i=0;i<LPC_ORDER;i++)
661 sum += ABS16(lpc[c*LPC_ORDER+i]);
662 if (sum < 65535) break;
663 for (i=0;i<LPC_ORDER;i++)
664 {
665 tmp = MULT16_16_Q15(QCONST16(.99f,15), tmp);
666 lpc[c*LPC_ORDER+i] = MULT16_16_Q15(lpc[c*LPC_ORDER+i], tmp);
667 }
668 }
669#endif
571 } 670 }
572 /* We want the excitation for 2 pitch periods in order to look for a
573 decaying signal, but we can't get more than MAX_PERIOD. */
574 exc_length = IMIN(2*pitch_index, MAX_PERIOD);
575 /* Initialize the LPC history with the samples just before the start 671 /* Initialize the LPC history with the samples just before the start
576 of the region for which we're computing the excitation. */ 672 of the region for which we're computing the excitation. */
577 { 673 {
578 opus_val16 lpc_mem[LPC_ORDER]; 674 /* Compute the excitation for exc_length samples before the loss. We need the copy
579 for (i=0;i<LPC_ORDER;i++) 675 because celt_fir() cannot filter in-place. */
580 {
581 lpc_mem[i] =
582 ROUND16(buf[DECODE_BUFFER_SIZE-exc_length-1-i], SIG_SHIFT);
583 }
584 /* Compute the excitation for exc_length samples before the loss. */
585 celt_fir(exc+MAX_PERIOD-exc_length, lpc+c*LPC_ORDER, 676 celt_fir(exc+MAX_PERIOD-exc_length, lpc+c*LPC_ORDER,
586 exc+MAX_PERIOD-exc_length, exc_length, LPC_ORDER, lpc_mem); 677 fir_tmp, exc_length, LPC_ORDER, st->arch);
678 OPUS_COPY(exc+MAX_PERIOD-exc_length, fir_tmp, exc_length);
587 } 679 }
588 680
589 /* Check if the waveform is decaying, and if so how fast. 681 /* Check if the waveform is decaying, and if so how fast.
@@ -637,9 +729,8 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
637 tmp = ROUND16( 729 tmp = ROUND16(
638 buf[DECODE_BUFFER_SIZE-MAX_PERIOD-N+extrapolation_offset+j], 730 buf[DECODE_BUFFER_SIZE-MAX_PERIOD-N+extrapolation_offset+j],
639 SIG_SHIFT); 731 SIG_SHIFT);
640 S1 += SHR32(MULT16_16(tmp, tmp), 8); 732 S1 += SHR32(MULT16_16(tmp, tmp), 10);
641 } 733 }
642
643 { 734 {
644 opus_val16 lpc_mem[LPC_ORDER]; 735 opus_val16 lpc_mem[LPC_ORDER];
645 /* Copy the last decoded samples (prior to the overlap region) to 736 /* Copy the last decoded samples (prior to the overlap region) to
@@ -650,7 +741,11 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
650 the signal domain. */ 741 the signal domain. */
651 celt_iir(buf+DECODE_BUFFER_SIZE-N, lpc+c*LPC_ORDER, 742 celt_iir(buf+DECODE_BUFFER_SIZE-N, lpc+c*LPC_ORDER,
652 buf+DECODE_BUFFER_SIZE-N, extrapolation_len, LPC_ORDER, 743 buf+DECODE_BUFFER_SIZE-N, extrapolation_len, LPC_ORDER,
653 lpc_mem); 744 lpc_mem, st->arch);
745#ifdef FIXED_POINT
746 for (i=0; i < extrapolation_len; i++)
747 buf[DECODE_BUFFER_SIZE-N+i] = SATURATE(buf[DECODE_BUFFER_SIZE-N+i], SIG_SAT);
748#endif
654 } 749 }
655 750
656 /* Check if the synthesis energy is higher than expected, which can 751 /* Check if the synthesis energy is higher than expected, which can
@@ -661,7 +756,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
661 for (i=0;i<extrapolation_len;i++) 756 for (i=0;i<extrapolation_len;i++)
662 { 757 {
663 opus_val16 tmp = ROUND16(buf[DECODE_BUFFER_SIZE-N+i], SIG_SHIFT); 758 opus_val16 tmp = ROUND16(buf[DECODE_BUFFER_SIZE-N+i], SIG_SHIFT);
664 S2 += SHR32(MULT16_16(tmp, tmp), 8); 759 S2 += SHR32(MULT16_16(tmp, tmp), 10);
665 } 760 }
666 /* This checks for an "explosion" in the synthesis. */ 761 /* This checks for an "explosion" in the synthesis. */
667#ifdef FIXED_POINT 762#ifdef FIXED_POINT
@@ -698,7 +793,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
698 comb_filter(etmp, buf+DECODE_BUFFER_SIZE, 793 comb_filter(etmp, buf+DECODE_BUFFER_SIZE,
699 st->postfilter_period, st->postfilter_period, overlap, 794 st->postfilter_period, st->postfilter_period, overlap,
700 -st->postfilter_gain, -st->postfilter_gain, 795 -st->postfilter_gain, -st->postfilter_gain,
701 st->postfilter_tapset, st->postfilter_tapset, NULL, 0); 796 st->postfilter_tapset, st->postfilter_tapset, NULL, 0, st->arch);
702 797
703 /* Simulate TDAC on the concealed audio so that it blends with the 798 /* Simulate TDAC on the concealed audio so that it blends with the
704 MDCT of the next frame. */ 799 MDCT of the next frame. */
@@ -769,6 +864,7 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
769 const opus_int16 *eBands; 864 const opus_int16 *eBands;
770 ALLOC_STACK; 865 ALLOC_STACK;
771 866
867 VALIDATE_CELT_DECODER(st);
772 mode = st->mode; 868 mode = st->mode;
773 nbEBands = mode->nbEBands; 869 nbEBands = mode->nbEBands;
774 overlap = mode->overlap; 870 overlap = mode->overlap;
@@ -838,6 +934,10 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
838 return frame_size/st->downsample; 934 return frame_size/st->downsample;
839 } 935 }
840 936
937 /* Check if there are at least two packets received consecutively before
938 * turning on the pitch-based PLC */
939 st->skip_plc = st->loss_count != 0;
940
841 if (dec == NULL) 941 if (dec == NULL)
842 { 942 {
843 ec_dec_init(&_dec,(unsigned char*)data,len); 943 ec_dec_init(&_dec,(unsigned char*)data,len);
@@ -959,7 +1059,7 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
959 ALLOC(pulses, nbEBands, int); 1059 ALLOC(pulses, nbEBands, int);
960 ALLOC(fine_priority, nbEBands, int); 1060 ALLOC(fine_priority, nbEBands, int);
961 1061
962 codedBands = compute_allocation(mode, start, end, offsets, cap, 1062 codedBands = clt_compute_allocation(mode, start, end, offsets, cap,
963 alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses, 1063 alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,
964 fine_quant, fine_priority, C, LM, dec, 0, 0, 0); 1064 fine_quant, fine_priority, C, LM, dec, 0, 0, 0);
965 1065
@@ -982,7 +1082,8 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
982 1082
983 quant_all_bands(0, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks, 1083 quant_all_bands(0, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks,
984 NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res, 1084 NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res,
985 len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng); 1085 len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng, 0,
1086 st->arch, st->disable_inv);
986 1087
987 if (anti_collapse_rsv > 0) 1088 if (anti_collapse_rsv > 0)
988 { 1089 {
@@ -994,7 +1095,7 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
994 1095
995 if (anti_collapse_on) 1096 if (anti_collapse_on)
996 anti_collapse(mode, X, collapse_masks, LM, C, N, 1097 anti_collapse(mode, X, collapse_masks, LM, C, N,
997 start, end, oldBandE, oldLogE, oldLogE2, pulses, st->rng); 1098 start, end, oldBandE, oldLogE, oldLogE2, pulses, st->rng, st->arch);
998 1099
999 if (silence) 1100 if (silence)
1000 { 1101 {
@@ -1002,18 +1103,19 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
1002 oldBandE[i] = -QCONST16(28.f,DB_SHIFT); 1103 oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
1003 } 1104 }
1004 1105
1005 celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd, C, CC, isTransient, LM, st->downsample, silence); 1106 celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd,
1107 C, CC, isTransient, LM, st->downsample, silence, st->arch);
1006 1108
1007 c=0; do { 1109 c=0; do {
1008 st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD); 1110 st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD);
1009 st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD); 1111 st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD);
1010 comb_filter(out_syn[c], out_syn[c], st->postfilter_period_old, st->postfilter_period, mode->shortMdctSize, 1112 comb_filter(out_syn[c], out_syn[c], st->postfilter_period_old, st->postfilter_period, mode->shortMdctSize,
1011 st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset, 1113 st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset,
1012 mode->window, overlap); 1114 mode->window, overlap, st->arch);
1013 if (LM!=0) 1115 if (LM!=0)
1014 comb_filter(out_syn[c]+mode->shortMdctSize, out_syn[c]+mode->shortMdctSize, st->postfilter_period, postfilter_pitch, N-mode->shortMdctSize, 1116 comb_filter(out_syn[c]+mode->shortMdctSize, out_syn[c]+mode->shortMdctSize, st->postfilter_period, postfilter_pitch, N-mode->shortMdctSize,
1015 st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset, 1117 st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset,
1016 mode->window, overlap); 1118 mode->window, overlap, st->arch);
1017 1119
1018 } while (++c<CC); 1120 } while (++c<CC);
1019 st->postfilter_period_old = st->postfilter_period; 1121 st->postfilter_period_old = st->postfilter_period;
@@ -1035,10 +1137,18 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
1035 /* In case start or end were to change */ 1137 /* In case start or end were to change */
1036 if (!isTransient) 1138 if (!isTransient)
1037 { 1139 {
1140 opus_val16 max_background_increase;
1038 OPUS_COPY(oldLogE2, oldLogE, 2*nbEBands); 1141 OPUS_COPY(oldLogE2, oldLogE, 2*nbEBands);
1039 OPUS_COPY(oldLogE, oldBandE, 2*nbEBands); 1142 OPUS_COPY(oldLogE, oldBandE, 2*nbEBands);
1143 /* In normal circumstances, we only allow the noise floor to increase by
1144 up to 2.4 dB/second, but when we're in DTX, we allow up to 6 dB
1145 increase for each update.*/
1146 if (st->loss_count < 10)
1147 max_background_increase = M*QCONST16(0.001f,DB_SHIFT);
1148 else
1149 max_background_increase = QCONST16(1.f,DB_SHIFT);
1040 for (i=0;i<2*nbEBands;i++) 1150 for (i=0;i<2*nbEBands;i++)
1041 backgroundLogE[i] = MIN16(backgroundLogE[i] + M*QCONST16(0.001f,DB_SHIFT), oldBandE[i]); 1151 backgroundLogE[i] = MIN16(backgroundLogE[i] + max_background_increase, oldBandE[i]);
1042 } else { 1152 } else {
1043 for (i=0;i<2*nbEBands;i++) 1153 for (i=0;i<2*nbEBands;i++)
1044 oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]); 1154 oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
@@ -1195,6 +1305,7 @@ int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...)
1195 ((char*)&st->DECODER_RESET_START - (char*)st)); 1305 ((char*)&st->DECODER_RESET_START - (char*)st));
1196 for (i=0;i<2*st->mode->nbEBands;i++) 1306 for (i=0;i<2*st->mode->nbEBands;i++)
1197 oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT); 1307 oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT);
1308 st->skip_plc = 1;
1198 } 1309 }
1199 break; 1310 break;
1200 case OPUS_GET_PITCH_REQUEST: 1311 case OPUS_GET_PITCH_REQUEST:
@@ -1227,6 +1338,26 @@ int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...)
1227 *value=st->rng; 1338 *value=st->rng;
1228 } 1339 }
1229 break; 1340 break;
1341 case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
1342 {
1343 opus_int32 value = va_arg(ap, opus_int32);
1344 if(value<0 || value>1)
1345 {
1346 goto bad_arg;
1347 }
1348 st->disable_inv = value;
1349 }
1350 break;
1351 case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
1352 {
1353 opus_int32 *value = va_arg(ap, opus_int32*);
1354 if (!value)
1355 {
1356 goto bad_arg;
1357 }
1358 *value = st->disable_inv;
1359 }
1360 break;
1230 default: 1361 default:
1231 goto bad_request; 1362 goto bad_request;
1232 } 1363 }
diff --git a/lib/rbcodec/codecs/libopus/celt/celt_encoder.c b/lib/rbcodec/codecs/libopus/celt/celt_encoder.c
new file mode 100644
index 0000000000..44cb0850ab
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/celt_encoder.c
@@ -0,0 +1,2607 @@
1/* Copyright (c) 2007-2008 CSIRO
2 Copyright (c) 2007-2010 Xiph.Org Foundation
3 Copyright (c) 2008 Gregory Maxwell
4 Written by Jean-Marc Valin and Gregory Maxwell */
5/*
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12
13 - Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
34#define CELT_ENCODER_C
35
36#include "cpu_support.h"
37#include "os_support.h"
38#include "mdct.h"
39#include <math.h>
40#include "celt.h"
41#include "pitch.h"
42#include "bands.h"
43#include "modes.h"
44#include "entcode.h"
45#include "quant_bands.h"
46#include "rate.h"
47#include "stack_alloc.h"
48#include "mathops.h"
49#include "float_cast.h"
50#include <stdarg.h>
51#include "celt_lpc.h"
52#include "vq.h"
53
54
55/** Encoder state
56 @brief Encoder state
57 */
58struct OpusCustomEncoder {
59 const OpusCustomMode *mode; /**< Mode used by the encoder */
60 int channels;
61 int stream_channels;
62
63 int force_intra;
64 int clip;
65 int disable_pf;
66 int complexity;
67 int upsample;
68 int start, end;
69
70 opus_int32 bitrate;
71 int vbr;
72 int signalling;
73 int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */
74 int loss_rate;
75 int lsb_depth;
76 int lfe;
77 int disable_inv;
78 int arch;
79
80 /* Everything beyond this point gets cleared on a reset */
81#define ENCODER_RESET_START rng
82
83 opus_uint32 rng;
84 int spread_decision;
85 opus_val32 delayedIntra;
86 int tonal_average;
87 int lastCodedBands;
88 int hf_average;
89 int tapset_decision;
90
91 int prefilter_period;
92 opus_val16 prefilter_gain;
93 int prefilter_tapset;
94#ifdef RESYNTH
95 int prefilter_period_old;
96 opus_val16 prefilter_gain_old;
97 int prefilter_tapset_old;
98#endif
99 int consec_transient;
100 AnalysisInfo analysis;
101 SILKInfo silk_info;
102
103 opus_val32 preemph_memE[2];
104 opus_val32 preemph_memD[2];
105
106 /* VBR-related parameters */
107 opus_int32 vbr_reservoir;
108 opus_int32 vbr_drift;
109 opus_int32 vbr_offset;
110 opus_int32 vbr_count;
111 opus_val32 overlap_max;
112 opus_val16 stereo_saving;
113 int intensity;
114 opus_val16 *energy_mask;
115 opus_val16 spec_avg;
116
117#ifdef RESYNTH
118 /* +MAX_PERIOD/2 to make space for overlap */
119 celt_sig syn_mem[2][2*MAX_PERIOD+MAX_PERIOD/2];
120#endif
121
122 celt_sig in_mem[1]; /* Size = channels*mode->overlap */
123 /* celt_sig prefilter_mem[], Size = channels*COMBFILTER_MAXPERIOD */
124 /* opus_val16 oldBandE[], Size = channels*mode->nbEBands */
125 /* opus_val16 oldLogE[], Size = channels*mode->nbEBands */
126 /* opus_val16 oldLogE2[], Size = channels*mode->nbEBands */
127 /* opus_val16 energyError[], Size = channels*mode->nbEBands */
128};
129
130int celt_encoder_get_size(int channels)
131{
132 CELTMode *mode = opus_custom_mode_create(48000, 960, NULL);
133 return opus_custom_encoder_get_size(mode, channels);
134}
135
136OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_get_size(const CELTMode *mode, int channels)
137{
138 int size = sizeof(struct CELTEncoder)
139 + (channels*mode->overlap-1)*sizeof(celt_sig) /* celt_sig in_mem[channels*mode->overlap]; */
140 + channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig) /* celt_sig prefilter_mem[channels*COMBFILTER_MAXPERIOD]; */
141 + 4*channels*mode->nbEBands*sizeof(opus_val16); /* opus_val16 oldBandE[channels*mode->nbEBands]; */
142 /* opus_val16 oldLogE[channels*mode->nbEBands]; */
143 /* opus_val16 oldLogE2[channels*mode->nbEBands]; */
144 /* opus_val16 energyError[channels*mode->nbEBands]; */
145 return size;
146}
147
148#ifdef CUSTOM_MODES
149CELTEncoder *opus_custom_encoder_create(const CELTMode *mode, int channels, int *error)
150{
151 int ret;
152 CELTEncoder *st = (CELTEncoder *)opus_alloc(opus_custom_encoder_get_size(mode, channels));
153 /* init will handle the NULL case */
154 ret = opus_custom_encoder_init(st, mode, channels);
155 if (ret != OPUS_OK)
156 {
157 opus_custom_encoder_destroy(st);
158 st = NULL;
159 }
160 if (error)
161 *error = ret;
162 return st;
163}
164#endif /* CUSTOM_MODES */
165
166static int opus_custom_encoder_init_arch(CELTEncoder *st, const CELTMode *mode,
167 int channels, int arch)
168{
169 if (channels < 0 || channels > 2)
170 return OPUS_BAD_ARG;
171
172 if (st==NULL || mode==NULL)
173 return OPUS_ALLOC_FAIL;
174
175 OPUS_CLEAR((char*)st, opus_custom_encoder_get_size(mode, channels));
176
177 st->mode = mode;
178 st->stream_channels = st->channels = channels;
179
180 st->upsample = 1;
181 st->start = 0;
182 st->end = st->mode->effEBands;
183 st->signalling = 1;
184 st->arch = arch;
185
186 st->constrained_vbr = 1;
187 st->clip = 1;
188
189 st->bitrate = OPUS_BITRATE_MAX;
190 st->vbr = 0;
191 st->force_intra = 0;
192 st->complexity = 5;
193 st->lsb_depth=24;
194
195 opus_custom_encoder_ctl(st, OPUS_RESET_STATE);
196
197 return OPUS_OK;
198}
199
200#ifdef CUSTOM_MODES
201int opus_custom_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels)
202{
203 return opus_custom_encoder_init_arch(st, mode, channels, opus_select_arch());
204}
205#endif
206
207int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels,
208 int arch)
209{
210 int ret;
211 ret = opus_custom_encoder_init_arch(st,
212 opus_custom_mode_create(48000, 960, NULL), channels, arch);
213 if (ret != OPUS_OK)
214 return ret;
215 st->upsample = resampling_factor(sampling_rate);
216 return OPUS_OK;
217}
218
219#ifdef CUSTOM_MODES
220void opus_custom_encoder_destroy(CELTEncoder *st)
221{
222 opus_free(st);
223}
224#endif /* CUSTOM_MODES */
225
226
227static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int C,
228 opus_val16 *tf_estimate, int *tf_chan, int allow_weak_transients,
229 int *weak_transient)
230{
231 int i;
232 VARDECL(opus_val16, tmp);
233 opus_val32 mem0,mem1;
234 int is_transient = 0;
235 opus_int32 mask_metric = 0;
236 int c;
237 opus_val16 tf_max;
238 int len2;
239 /* Forward masking: 6.7 dB/ms. */
240#ifdef FIXED_POINT
241 int forward_shift = 4;
242#else
243 opus_val16 forward_decay = QCONST16(.0625f,15);
244#endif
245 /* Table of 6*64/x, trained on real data to minimize the average error */
246 static const unsigned char inv_table[128] = {
247 255,255,156,110, 86, 70, 59, 51, 45, 40, 37, 33, 31, 28, 26, 25,
248 23, 22, 21, 20, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12,
249 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 9, 9, 9, 8, 8,
250 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6,
251 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5,
252 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
253 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3,
254 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2,
255 };
256 SAVE_STACK;
257 ALLOC(tmp, len, opus_val16);
258
259 *weak_transient = 0;
260 /* For lower bitrates, let's be more conservative and have a forward masking
261 decay of 3.3 dB/ms. This avoids having to code transients at very low
262 bitrate (mostly for hybrid), which can result in unstable energy and/or
263 partial collapse. */
264 if (allow_weak_transients)
265 {
266#ifdef FIXED_POINT
267 forward_shift = 5;
268#else
269 forward_decay = QCONST16(.03125f,15);
270#endif
271 }
272 len2=len/2;
273 for (c=0;c<C;c++)
274 {
275 opus_val32 mean;
276 opus_int32 unmask=0;
277 opus_val32 norm;
278 opus_val16 maxE;
279 mem0=0;
280 mem1=0;
281 /* High-pass filter: (1 - 2*z^-1 + z^-2) / (1 - z^-1 + .5*z^-2) */
282 for (i=0;i<len;i++)
283 {
284 opus_val32 x,y;
285 x = SHR32(in[i+c*len],SIG_SHIFT);
286 y = ADD32(mem0, x);
287#ifdef FIXED_POINT
288 mem0 = mem1 + y - SHL32(x,1);
289 mem1 = x - SHR32(y,1);
290#else
291 mem0 = mem1 + y - 2*x;
292 mem1 = x - .5f*y;
293#endif
294 tmp[i] = SROUND16(y, 2);
295 /*printf("%f ", tmp[i]);*/
296 }
297 /*printf("\n");*/
298 /* First few samples are bad because we don't propagate the memory */
299 OPUS_CLEAR(tmp, 12);
300
301#ifdef FIXED_POINT
302 /* Normalize tmp to max range */
303 {
304 int shift=0;
305 shift = 14-celt_ilog2(MAX16(1, celt_maxabs16(tmp, len)));
306 if (shift!=0)
307 {
308 for (i=0;i<len;i++)
309 tmp[i] = SHL16(tmp[i], shift);
310 }
311 }
312#endif
313
314 mean=0;
315 mem0=0;
316 /* Grouping by two to reduce complexity */
317 /* Forward pass to compute the post-echo threshold*/
318 for (i=0;i<len2;i++)
319 {
320 opus_val16 x2 = PSHR32(MULT16_16(tmp[2*i],tmp[2*i]) + MULT16_16(tmp[2*i+1],tmp[2*i+1]),16);
321 mean += x2;
322#ifdef FIXED_POINT
323 /* FIXME: Use PSHR16() instead */
324 tmp[i] = mem0 + PSHR32(x2-mem0,forward_shift);
325#else
326 tmp[i] = mem0 + MULT16_16_P15(forward_decay,x2-mem0);
327#endif
328 mem0 = tmp[i];
329 }
330
331 mem0=0;
332 maxE=0;
333 /* Backward pass to compute the pre-echo threshold */
334 for (i=len2-1;i>=0;i--)
335 {
336 /* Backward masking: 13.9 dB/ms. */
337#ifdef FIXED_POINT
338 /* FIXME: Use PSHR16() instead */
339 tmp[i] = mem0 + PSHR32(tmp[i]-mem0,3);
340#else
341 tmp[i] = mem0 + MULT16_16_P15(QCONST16(0.125f,15),tmp[i]-mem0);
342#endif
343 mem0 = tmp[i];
344 maxE = MAX16(maxE, mem0);
345 }
346 /*for (i=0;i<len2;i++)printf("%f ", tmp[i]/mean);printf("\n");*/
347
348 /* Compute the ratio of the "frame energy" over the harmonic mean of the energy.
349 This essentially corresponds to a bitrate-normalized temporal noise-to-mask
350 ratio */
351
352 /* As a compromise with the old transient detector, frame energy is the
353 geometric mean of the energy and half the max */
354#ifdef FIXED_POINT
355 /* Costs two sqrt() to avoid overflows */
356 mean = MULT16_16(celt_sqrt(mean), celt_sqrt(MULT16_16(maxE,len2>>1)));
357#else
358 mean = celt_sqrt(mean * maxE*.5*len2);
359#endif
360 /* Inverse of the mean energy in Q15+6 */
361 norm = SHL32(EXTEND32(len2),6+14)/ADD32(EPSILON,SHR32(mean,1));
362 /* Compute harmonic mean discarding the unreliable boundaries
363 The data is smooth, so we only take 1/4th of the samples */
364 unmask=0;
365 /* We should never see NaNs here. If we find any, then something really bad happened and we better abort
366 before it does any damage later on. If these asserts are disabled (no hardening), then the table
367 lookup a few lines below (id = ...) is likely to crash dur to an out-of-bounds read. DO NOT FIX
368 that crash on NaN since it could result in a worse issue later on. */
369 celt_assert(!celt_isnan(tmp[0]));
370 celt_assert(!celt_isnan(norm));
371 for (i=12;i<len2-5;i+=4)
372 {
373 int id;
374#ifdef FIXED_POINT
375 id = MAX32(0,MIN32(127,MULT16_32_Q15(tmp[i]+EPSILON,norm))); /* Do not round to nearest */
376#else
377 id = (int)MAX32(0,MIN32(127,floor(64*norm*(tmp[i]+EPSILON)))); /* Do not round to nearest */
378#endif
379 unmask += inv_table[id];
380 }
381 /*printf("%d\n", unmask);*/
382 /* Normalize, compensate for the 1/4th of the sample and the factor of 6 in the inverse table */
383 unmask = 64*unmask*4/(6*(len2-17));
384 if (unmask>mask_metric)
385 {
386 *tf_chan = c;
387 mask_metric = unmask;
388 }
389 }
390 is_transient = mask_metric>200;
391 /* For low bitrates, define "weak transients" that need to be
392 handled differently to avoid partial collapse. */
393 if (allow_weak_transients && is_transient && mask_metric<600) {
394 is_transient = 0;
395 *weak_transient = 1;
396 }
397 /* Arbitrary metric for VBR boost */
398 tf_max = MAX16(0,celt_sqrt(27*mask_metric)-42);
399 /* *tf_estimate = 1 + MIN16(1, sqrt(MAX16(0, tf_max-30))/20); */
400 *tf_estimate = celt_sqrt(MAX32(0, SHL32(MULT16_16(QCONST16(0.0069,14),MIN16(163,tf_max)),14)-QCONST32(0.139,28)));
401 /*printf("%d %f\n", tf_max, mask_metric);*/
402 RESTORE_STACK;
403#ifdef FUZZING
404 is_transient = rand()&0x1;
405#endif
406 /*printf("%d %f %d\n", is_transient, (float)*tf_estimate, tf_max);*/
407 return is_transient;
408}
409
410/* Looks for sudden increases of energy to decide whether we need to patch
411 the transient decision */
412static int patch_transient_decision(opus_val16 *newE, opus_val16 *oldE, int nbEBands,
413 int start, int end, int C)
414{
415 int i, c;
416 opus_val32 mean_diff=0;
417 opus_val16 spread_old[26];
418 /* Apply an aggressive (-6 dB/Bark) spreading function to the old frame to
419 avoid false detection caused by irrelevant bands */
420 if (C==1)
421 {
422 spread_old[start] = oldE[start];
423 for (i=start+1;i<end;i++)
424 spread_old[i] = MAX16(spread_old[i-1]-QCONST16(1.0f, DB_SHIFT), oldE[i]);
425 } else {
426 spread_old[start] = MAX16(oldE[start],oldE[start+nbEBands]);
427 for (i=start+1;i<end;i++)
428 spread_old[i] = MAX16(spread_old[i-1]-QCONST16(1.0f, DB_SHIFT),
429 MAX16(oldE[i],oldE[i+nbEBands]));
430 }
431 for (i=end-2;i>=start;i--)
432 spread_old[i] = MAX16(spread_old[i], spread_old[i+1]-QCONST16(1.0f, DB_SHIFT));
433 /* Compute mean increase */
434 c=0; do {
435 for (i=IMAX(2,start);i<end-1;i++)
436 {
437 opus_val16 x1, x2;
438 x1 = MAX16(0, newE[i + c*nbEBands]);
439 x2 = MAX16(0, spread_old[i]);
440 mean_diff = ADD32(mean_diff, EXTEND32(MAX16(0, SUB16(x1, x2))));
441 }
442 } while (++c<C);
443 mean_diff = DIV32(mean_diff, C*(end-1-IMAX(2,start)));
444 /*printf("%f %f %d\n", mean_diff, max_diff, count);*/
445 return mean_diff > QCONST16(1.f, DB_SHIFT);
446}
447
448/** Apply window and compute the MDCT for all sub-frames and
449 all channels in a frame */
450static void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig * OPUS_RESTRICT in,
451 celt_sig * OPUS_RESTRICT out, int C, int CC, int LM, int upsample,
452 int arch)
453{
454 const int overlap = mode->overlap;
455 int N;
456 int B;
457 int shift;
458 int i, b, c;
459 if (shortBlocks)
460 {
461 B = shortBlocks;
462 N = mode->shortMdctSize;
463 shift = mode->maxLM;
464 } else {
465 B = 1;
466 N = mode->shortMdctSize<<LM;
467 shift = mode->maxLM-LM;
468 }
469 c=0; do {
470 for (b=0;b<B;b++)
471 {
472 /* Interleaving the sub-frames while doing the MDCTs */
473 clt_mdct_forward(&mode->mdct, in+c*(B*N+overlap)+b*N,
474 &out[b+c*N*B], mode->window, overlap, shift, B,
475 arch);
476 }
477 } while (++c<CC);
478 if (CC==2&&C==1)
479 {
480 for (i=0;i<B*N;i++)
481 out[i] = ADD32(HALF32(out[i]), HALF32(out[B*N+i]));
482 }
483 if (upsample != 1)
484 {
485 c=0; do
486 {
487 int bound = B*N/upsample;
488 for (i=0;i<bound;i++)
489 out[c*B*N+i] *= upsample;
490 OPUS_CLEAR(&out[c*B*N+bound], B*N-bound);
491 } while (++c<C);
492 }
493}
494
495
496void celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT inp,
497 int N, int CC, int upsample, const opus_val16 *coef, celt_sig *mem, int clip)
498{
499 int i;
500 opus_val16 coef0;
501 celt_sig m;
502 int Nu;
503
504 coef0 = coef[0];
505 m = *mem;
506
507 /* Fast path for the normal 48kHz case and no clipping */
508 if (coef[1] == 0 && upsample == 1 && !clip)
509 {
510 for (i=0;i<N;i++)
511 {
512 opus_val16 x;
513 x = SCALEIN(pcmp[CC*i]);
514 /* Apply pre-emphasis */
515 inp[i] = SHL32(x, SIG_SHIFT) - m;
516 m = SHR32(MULT16_16(coef0, x), 15-SIG_SHIFT);
517 }
518 *mem = m;
519 return;
520 }
521
522 Nu = N/upsample;
523 if (upsample!=1)
524 {
525 OPUS_CLEAR(inp, N);
526 }
527 for (i=0;i<Nu;i++)
528 inp[i*upsample] = SCALEIN(pcmp[CC*i]);
529
530#ifndef FIXED_POINT
531 if (clip)
532 {
533 /* Clip input to avoid encoding non-portable files */
534 for (i=0;i<Nu;i++)
535 inp[i*upsample] = MAX32(-65536.f, MIN32(65536.f,inp[i*upsample]));
536 }
537#else
538 (void)clip; /* Avoids a warning about clip being unused. */
539#endif
540#ifdef CUSTOM_MODES
541 if (coef[1] != 0)
542 {
543 opus_val16 coef1 = coef[1];
544 opus_val16 coef2 = coef[2];
545 for (i=0;i<N;i++)
546 {
547 celt_sig x, tmp;
548 x = inp[i];
549 /* Apply pre-emphasis */
550 tmp = MULT16_16(coef2, x);
551 inp[i] = tmp + m;
552 m = MULT16_32_Q15(coef1, inp[i]) - MULT16_32_Q15(coef0, tmp);
553 }
554 } else
555#endif
556 {
557 for (i=0;i<N;i++)
558 {
559 opus_val16 x;
560 x = inp[i];
561 /* Apply pre-emphasis */
562 inp[i] = SHL32(x, SIG_SHIFT) - m;
563 m = SHR32(MULT16_16(coef0, x), 15-SIG_SHIFT);
564 }
565 }
566 *mem = m;
567}
568
569
570
571static opus_val32 l1_metric(const celt_norm *tmp, int N, int LM, opus_val16 bias)
572{
573 int i;
574 opus_val32 L1;
575 L1 = 0;
576 for (i=0;i<N;i++)
577 L1 += EXTEND32(ABS16(tmp[i]));
578 /* When in doubt, prefer good freq resolution */
579 L1 = MAC16_32_Q15(L1, LM*bias, L1);
580 return L1;
581
582}
583
584static int tf_analysis(const CELTMode *m, int len, int isTransient,
585 int *tf_res, int lambda, celt_norm *X, int N0, int LM,
586 opus_val16 tf_estimate, int tf_chan, int *importance)
587{
588 int i;
589 VARDECL(int, metric);
590 int cost0;
591 int cost1;
592 VARDECL(int, path0);
593 VARDECL(int, path1);
594 VARDECL(celt_norm, tmp);
595 VARDECL(celt_norm, tmp_1);
596 int sel;
597 int selcost[2];
598 int tf_select=0;
599 opus_val16 bias;
600
601 SAVE_STACK;
602 bias = MULT16_16_Q14(QCONST16(.04f,15), MAX16(-QCONST16(.25f,14), QCONST16(.5f,14)-tf_estimate));
603 /*printf("%f ", bias);*/
604
605 ALLOC(metric, len, int);
606 ALLOC(tmp, (m->eBands[len]-m->eBands[len-1])<<LM, celt_norm);
607 ALLOC(tmp_1, (m->eBands[len]-m->eBands[len-1])<<LM, celt_norm);
608 ALLOC(path0, len, int);
609 ALLOC(path1, len, int);
610
611 for (i=0;i<len;i++)
612 {
613 int k, N;
614 int narrow;
615 opus_val32 L1, best_L1;
616 int best_level=0;
617 N = (m->eBands[i+1]-m->eBands[i])<<LM;
618 /* band is too narrow to be split down to LM=-1 */
619 narrow = (m->eBands[i+1]-m->eBands[i])==1;
620 OPUS_COPY(tmp, &X[tf_chan*N0 + (m->eBands[i]<<LM)], N);
621 /* Just add the right channel if we're in stereo */
622 /*if (C==2)
623 for (j=0;j<N;j++)
624 tmp[j] = ADD16(SHR16(tmp[j], 1),SHR16(X[N0+j+(m->eBands[i]<<LM)], 1));*/
625 L1 = l1_metric(tmp, N, isTransient ? LM : 0, bias);
626 best_L1 = L1;
627 /* Check the -1 case for transients */
628 if (isTransient && !narrow)
629 {
630 OPUS_COPY(tmp_1, tmp, N);
631 haar1(tmp_1, N>>LM, 1<<LM);
632 L1 = l1_metric(tmp_1, N, LM+1, bias);
633 if (L1<best_L1)
634 {
635 best_L1 = L1;
636 best_level = -1;
637 }
638 }
639 /*printf ("%f ", L1);*/
640 for (k=0;k<LM+!(isTransient||narrow);k++)
641 {
642 int B;
643
644 if (isTransient)
645 B = (LM-k-1);
646 else
647 B = k+1;
648
649 haar1(tmp, N>>k, 1<<k);
650
651 L1 = l1_metric(tmp, N, B, bias);
652
653 if (L1 < best_L1)
654 {
655 best_L1 = L1;
656 best_level = k+1;
657 }
658 }
659 /*printf ("%d ", isTransient ? LM-best_level : best_level);*/
660 /* metric is in Q1 to be able to select the mid-point (-0.5) for narrower bands */
661 if (isTransient)
662 metric[i] = 2*best_level;
663 else
664 metric[i] = -2*best_level;
665 /* For bands that can't be split to -1, set the metric to the half-way point to avoid
666 biasing the decision */
667 if (narrow && (metric[i]==0 || metric[i]==-2*LM))
668 metric[i]-=1;
669 /*printf("%d ", metric[i]/2 + (!isTransient)*LM);*/
670 }
671 /*printf("\n");*/
672 /* Search for the optimal tf resolution, including tf_select */
673 tf_select = 0;
674 for (sel=0;sel<2;sel++)
675 {
676 cost0 = importance[0]*abs(metric[0]-2*tf_select_table[LM][4*isTransient+2*sel+0]);
677 cost1 = importance[0]*abs(metric[0]-2*tf_select_table[LM][4*isTransient+2*sel+1]) + (isTransient ? 0 : lambda);
678 for (i=1;i<len;i++)
679 {
680 int curr0, curr1;
681 curr0 = IMIN(cost0, cost1 + lambda);
682 curr1 = IMIN(cost0 + lambda, cost1);
683 cost0 = curr0 + importance[i]*abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*sel+0]);
684 cost1 = curr1 + importance[i]*abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*sel+1]);
685 }
686 cost0 = IMIN(cost0, cost1);
687 selcost[sel]=cost0;
688 }
689 /* For now, we're conservative and only allow tf_select=1 for transients.
690 * If tests confirm it's useful for non-transients, we could allow it. */
691 if (selcost[1]<selcost[0] && isTransient)
692 tf_select=1;
693 cost0 = importance[0]*abs(metric[0]-2*tf_select_table[LM][4*isTransient+2*tf_select+0]);
694 cost1 = importance[0]*abs(metric[0]-2*tf_select_table[LM][4*isTransient+2*tf_select+1]) + (isTransient ? 0 : lambda);
695 /* Viterbi forward pass */
696 for (i=1;i<len;i++)
697 {
698 int curr0, curr1;
699 int from0, from1;
700
701 from0 = cost0;
702 from1 = cost1 + lambda;
703 if (from0 < from1)
704 {
705 curr0 = from0;
706 path0[i]= 0;
707 } else {
708 curr0 = from1;
709 path0[i]= 1;
710 }
711
712 from0 = cost0 + lambda;
713 from1 = cost1;
714 if (from0 < from1)
715 {
716 curr1 = from0;
717 path1[i]= 0;
718 } else {
719 curr1 = from1;
720 path1[i]= 1;
721 }
722 cost0 = curr0 + importance[i]*abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*tf_select+0]);
723 cost1 = curr1 + importance[i]*abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*tf_select+1]);
724 }
725 tf_res[len-1] = cost0 < cost1 ? 0 : 1;
726 /* Viterbi backward pass to check the decisions */
727 for (i=len-2;i>=0;i--)
728 {
729 if (tf_res[i+1] == 1)
730 tf_res[i] = path1[i+1];
731 else
732 tf_res[i] = path0[i+1];
733 }
734 /*printf("%d %f\n", *tf_sum, tf_estimate);*/
735 RESTORE_STACK;
736#ifdef FUZZING
737 tf_select = rand()&0x1;
738 tf_res[0] = rand()&0x1;
739 for (i=1;i<len;i++)
740 tf_res[i] = tf_res[i-1] ^ ((rand()&0xF) == 0);
741#endif
742 return tf_select;
743}
744
745static void tf_encode(int start, int end, int isTransient, int *tf_res, int LM, int tf_select, ec_enc *enc)
746{
747 int curr, i;
748 int tf_select_rsv;
749 int tf_changed;
750 int logp;
751 opus_uint32 budget;
752 opus_uint32 tell;
753 budget = enc->storage*8;
754 tell = ec_tell(enc);
755 logp = isTransient ? 2 : 4;
756 /* Reserve space to code the tf_select decision. */
757 tf_select_rsv = LM>0 && tell+logp+1 <= budget;
758 budget -= tf_select_rsv;
759 curr = tf_changed = 0;
760 for (i=start;i<end;i++)
761 {
762 if (tell+logp<=budget)
763 {
764 ec_enc_bit_logp(enc, tf_res[i] ^ curr, logp);
765 tell = ec_tell(enc);
766 curr = tf_res[i];
767 tf_changed |= curr;
768 }
769 else
770 tf_res[i] = curr;
771 logp = isTransient ? 4 : 5;
772 }
773 /* Only code tf_select if it would actually make a difference. */
774 if (tf_select_rsv &&
775 tf_select_table[LM][4*isTransient+0+tf_changed]!=
776 tf_select_table[LM][4*isTransient+2+tf_changed])
777 ec_enc_bit_logp(enc, tf_select, 1);
778 else
779 tf_select = 0;
780 for (i=start;i<end;i++)
781 tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
782 /*for(i=0;i<end;i++)printf("%d ", isTransient ? tf_res[i] : LM+tf_res[i]);printf("\n");*/
783}
784
785
786static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X,
787 const opus_val16 *bandLogE, int end, int LM, int C, int N0,
788 AnalysisInfo *analysis, opus_val16 *stereo_saving, opus_val16 tf_estimate,
789 int intensity, opus_val16 surround_trim, opus_int32 equiv_rate, int arch)
790{
791 int i;
792 opus_val32 diff=0;
793 int c;
794 int trim_index;
795 opus_val16 trim = QCONST16(5.f, 8);
796 opus_val16 logXC, logXC2;
797 /* At low bitrate, reducing the trim seems to help. At higher bitrates, it's less
798 clear what's best, so we're keeping it as it was before, at least for now. */
799 if (equiv_rate < 64000) {
800 trim = QCONST16(4.f, 8);
801 } else if (equiv_rate < 80000) {
802 opus_int32 frac = (equiv_rate-64000) >> 10;
803 trim = QCONST16(4.f, 8) + QCONST16(1.f/16.f, 8)*frac;
804 }
805 if (C==2)
806 {
807 opus_val16 sum = 0; /* Q10 */
808 opus_val16 minXC; /* Q10 */
809 /* Compute inter-channel correlation for low frequencies */
810 for (i=0;i<8;i++)
811 {
812 opus_val32 partial;
813 partial = celt_inner_prod(&X[m->eBands[i]<<LM], &X[N0+(m->eBands[i]<<LM)],
814 (m->eBands[i+1]-m->eBands[i])<<LM, arch);
815 sum = ADD16(sum, EXTRACT16(SHR32(partial, 18)));
816 }
817 sum = MULT16_16_Q15(QCONST16(1.f/8, 15), sum);
818 sum = MIN16(QCONST16(1.f, 10), ABS16(sum));
819 minXC = sum;
820 for (i=8;i<intensity;i++)
821 {
822 opus_val32 partial;
823 partial = celt_inner_prod(&X[m->eBands[i]<<LM], &X[N0+(m->eBands[i]<<LM)],
824 (m->eBands[i+1]-m->eBands[i])<<LM, arch);
825 minXC = MIN16(minXC, ABS16(EXTRACT16(SHR32(partial, 18))));
826 }
827 minXC = MIN16(QCONST16(1.f, 10), ABS16(minXC));
828 /*printf ("%f\n", sum);*/
829 /* mid-side savings estimations based on the LF average*/
830 logXC = celt_log2(QCONST32(1.001f, 20)-MULT16_16(sum, sum));
831 /* mid-side savings estimations based on min correlation */
832 logXC2 = MAX16(HALF16(logXC), celt_log2(QCONST32(1.001f, 20)-MULT16_16(minXC, minXC)));
833#ifdef FIXED_POINT
834 /* Compensate for Q20 vs Q14 input and convert output to Q8 */
835 logXC = PSHR32(logXC-QCONST16(6.f, DB_SHIFT),DB_SHIFT-8);
836 logXC2 = PSHR32(logXC2-QCONST16(6.f, DB_SHIFT),DB_SHIFT-8);
837#endif
838
839 trim += MAX16(-QCONST16(4.f, 8), MULT16_16_Q15(QCONST16(.75f,15),logXC));
840 *stereo_saving = MIN16(*stereo_saving + QCONST16(0.25f, 8), -HALF16(logXC2));
841 }
842
843 /* Estimate spectral tilt */
844 c=0; do {
845 for (i=0;i<end-1;i++)
846 {
847 diff += bandLogE[i+c*m->nbEBands]*(opus_int32)(2+2*i-end);
848 }
849 } while (++c<C);
850 diff /= C*(end-1);
851 /*printf("%f\n", diff);*/
852 trim -= MAX32(-QCONST16(2.f, 8), MIN32(QCONST16(2.f, 8), SHR32(diff+QCONST16(1.f, DB_SHIFT),DB_SHIFT-8)/6 ));
853 trim -= SHR16(surround_trim, DB_SHIFT-8);
854 trim -= 2*SHR16(tf_estimate, 14-8);
855#ifndef DISABLE_FLOAT_API
856 if (analysis->valid)
857 {
858 trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8),
859 (opus_val16)(QCONST16(2.f, 8)*(analysis->tonality_slope+.05f))));
860 }
861#else
862 (void)analysis;
863#endif
864
865#ifdef FIXED_POINT
866 trim_index = PSHR32(trim, 8);
867#else
868 trim_index = (int)floor(.5f+trim);
869#endif
870 trim_index = IMAX(0, IMIN(10, trim_index));
871 /*printf("%d\n", trim_index);*/
872#ifdef FUZZING
873 trim_index = rand()%11;
874#endif
875 return trim_index;
876}
877
878static int stereo_analysis(const CELTMode *m, const celt_norm *X,
879 int LM, int N0)
880{
881 int i;
882 int thetas;
883 opus_val32 sumLR = EPSILON, sumMS = EPSILON;
884
885 /* Use the L1 norm to model the entropy of the L/R signal vs the M/S signal */
886 for (i=0;i<13;i++)
887 {
888 int j;
889 for (j=m->eBands[i]<<LM;j<m->eBands[i+1]<<LM;j++)
890 {
891 opus_val32 L, R, M, S;
892 /* We cast to 32-bit first because of the -32768 case */
893 L = EXTEND32(X[j]);
894 R = EXTEND32(X[N0+j]);
895 M = ADD32(L, R);
896 S = SUB32(L, R);
897 sumLR = ADD32(sumLR, ADD32(ABS32(L), ABS32(R)));
898 sumMS = ADD32(sumMS, ADD32(ABS32(M), ABS32(S)));
899 }
900 }
901 sumMS = MULT16_32_Q15(QCONST16(0.707107f, 15), sumMS);
902 thetas = 13;
903 /* We don't need thetas for lower bands with LM<=1 */
904 if (LM<=1)
905 thetas -= 8;
906 return MULT16_32_Q15((m->eBands[13]<<(LM+1))+thetas, sumMS)
907 > MULT16_32_Q15(m->eBands[13]<<(LM+1), sumLR);
908}
909
910#define MSWAP(a,b) do {opus_val16 tmp = a;a=b;b=tmp;} while(0)
911static opus_val16 median_of_5(const opus_val16 *x)
912{
913 opus_val16 t0, t1, t2, t3, t4;
914 t2 = x[2];
915 if (x[0] > x[1])
916 {
917 t0 = x[1];
918 t1 = x[0];
919 } else {
920 t0 = x[0];
921 t1 = x[1];
922 }
923 if (x[3] > x[4])
924 {
925 t3 = x[4];
926 t4 = x[3];
927 } else {
928 t3 = x[3];
929 t4 = x[4];
930 }
931 if (t0 > t3)
932 {
933 MSWAP(t0, t3);
934 MSWAP(t1, t4);
935 }
936 if (t2 > t1)
937 {
938 if (t1 < t3)
939 return MIN16(t2, t3);
940 else
941 return MIN16(t4, t1);
942 } else {
943 if (t2 < t3)
944 return MIN16(t1, t3);
945 else
946 return MIN16(t2, t4);
947 }
948}
949
950static opus_val16 median_of_3(const opus_val16 *x)
951{
952 opus_val16 t0, t1, t2;
953 if (x[0] > x[1])
954 {
955 t0 = x[1];
956 t1 = x[0];
957 } else {
958 t0 = x[0];
959 t1 = x[1];
960 }
961 t2 = x[2];
962 if (t1 < t2)
963 return t1;
964 else if (t0 < t2)
965 return t2;
966 else
967 return t0;
968}
969
970static opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16 *bandLogE2,
971 int nbEBands, int start, int end, int C, int *offsets, int lsb_depth, const opus_int16 *logN,
972 int isTransient, int vbr, int constrained_vbr, const opus_int16 *eBands, int LM,
973 int effectiveBytes, opus_int32 *tot_boost_, int lfe, opus_val16 *surround_dynalloc,
974 AnalysisInfo *analysis, int *importance, int *spread_weight)
975{
976 int i, c;
977 opus_int32 tot_boost=0;
978 opus_val16 maxDepth;
979 VARDECL(opus_val16, follower);
980 VARDECL(opus_val16, noise_floor);
981 SAVE_STACK;
982 ALLOC(follower, C*nbEBands, opus_val16);
983 ALLOC(noise_floor, C*nbEBands, opus_val16);
984 OPUS_CLEAR(offsets, nbEBands);
985 /* Dynamic allocation code */
986 maxDepth=-QCONST16(31.9f, DB_SHIFT);
987 for (i=0;i<end;i++)
988 {
989 /* Noise floor must take into account eMeans, the depth, the width of the bands
990 and the preemphasis filter (approx. square of bark band ID) */
991 noise_floor[i] = MULT16_16(QCONST16(0.0625f, DB_SHIFT),logN[i])
992 +QCONST16(.5f,DB_SHIFT)+SHL16(9-lsb_depth,DB_SHIFT)-SHL16(eMeans[i],6)
993 +MULT16_16(QCONST16(.0062,DB_SHIFT),(i+5)*(i+5));
994 }
995 c=0;do
996 {
997 for (i=0;i<end;i++)
998 maxDepth = MAX16(maxDepth, bandLogE[c*nbEBands+i]-noise_floor[i]);
999 } while (++c<C);
1000 {
1001 /* Compute a really simple masking model to avoid taking into account completely masked
1002 bands when computing the spreading decision. */
1003 VARDECL(opus_val16, mask);
1004 VARDECL(opus_val16, sig);
1005 ALLOC(mask, nbEBands, opus_val16);
1006 ALLOC(sig, nbEBands, opus_val16);
1007 for (i=0;i<end;i++)
1008 mask[i] = bandLogE[i]-noise_floor[i];
1009 if (C==2)
1010 {
1011 for (i=0;i<end;i++)
1012 mask[i] = MAX16(mask[i], bandLogE[nbEBands+i]-noise_floor[i]);
1013 }
1014 OPUS_COPY(sig, mask, end);
1015 for (i=1;i<end;i++)
1016 mask[i] = MAX16(mask[i], mask[i-1] - QCONST16(2.f, DB_SHIFT));
1017 for (i=end-2;i>=0;i--)
1018 mask[i] = MAX16(mask[i], mask[i+1] - QCONST16(3.f, DB_SHIFT));
1019 for (i=0;i<end;i++)
1020 {
1021 /* Compute SMR: Mask is never more than 72 dB below the peak and never below the noise floor.*/
1022 opus_val16 smr = sig[i]-MAX16(MAX16(0, maxDepth-QCONST16(12.f, DB_SHIFT)), mask[i]);
1023 /* Clamp SMR to make sure we're not shifting by something negative or too large. */
1024#ifdef FIXED_POINT
1025 /* FIXME: Use PSHR16() instead */
1026 int shift = -PSHR32(MAX16(-QCONST16(5.f, DB_SHIFT), MIN16(0, smr)), DB_SHIFT);
1027#else
1028 int shift = IMIN(5, IMAX(0, -(int)floor(.5f + smr)));
1029#endif
1030 spread_weight[i] = 32 >> shift;
1031 }
1032 /*for (i=0;i<end;i++)
1033 printf("%d ", spread_weight[i]);
1034 printf("\n");*/
1035 }
1036 /* Make sure that dynamic allocation can't make us bust the budget */
1037 if (effectiveBytes > 50 && LM>=1 && !lfe)
1038 {
1039 int last=0;
1040 c=0;do
1041 {
1042 opus_val16 offset;
1043 opus_val16 tmp;
1044 opus_val16 *f;
1045 f = &follower[c*nbEBands];
1046 f[0] = bandLogE2[c*nbEBands];
1047 for (i=1;i<end;i++)
1048 {
1049 /* The last band to be at least 3 dB higher than the previous one
1050 is the last we'll consider. Otherwise, we run into problems on
1051 bandlimited signals. */
1052 if (bandLogE2[c*nbEBands+i] > bandLogE2[c*nbEBands+i-1]+QCONST16(.5f,DB_SHIFT))
1053 last=i;
1054 f[i] = MIN16(f[i-1]+QCONST16(1.5f,DB_SHIFT), bandLogE2[c*nbEBands+i]);
1055 }
1056 for (i=last-1;i>=0;i--)
1057 f[i] = MIN16(f[i], MIN16(f[i+1]+QCONST16(2.f,DB_SHIFT), bandLogE2[c*nbEBands+i]));
1058
1059 /* Combine with a median filter to avoid dynalloc triggering unnecessarily.
1060 The "offset" value controls how conservative we are -- a higher offset
1061 reduces the impact of the median filter and makes dynalloc use more bits. */
1062 offset = QCONST16(1.f, DB_SHIFT);
1063 for (i=2;i<end-2;i++)
1064 f[i] = MAX16(f[i], median_of_5(&bandLogE2[c*nbEBands+i-2])-offset);
1065 tmp = median_of_3(&bandLogE2[c*nbEBands])-offset;
1066 f[0] = MAX16(f[0], tmp);
1067 f[1] = MAX16(f[1], tmp);
1068 tmp = median_of_3(&bandLogE2[c*nbEBands+end-3])-offset;
1069 f[end-2] = MAX16(f[end-2], tmp);
1070 f[end-1] = MAX16(f[end-1], tmp);
1071
1072 for (i=0;i<end;i++)
1073 f[i] = MAX16(f[i], noise_floor[i]);
1074 } while (++c<C);
1075 if (C==2)
1076 {
1077 for (i=start;i<end;i++)
1078 {
1079 /* Consider 24 dB "cross-talk" */
1080 follower[nbEBands+i] = MAX16(follower[nbEBands+i], follower[ i]-QCONST16(4.f,DB_SHIFT));
1081 follower[ i] = MAX16(follower[ i], follower[nbEBands+i]-QCONST16(4.f,DB_SHIFT));
1082 follower[i] = HALF16(MAX16(0, bandLogE[i]-follower[i]) + MAX16(0, bandLogE[nbEBands+i]-follower[nbEBands+i]));
1083 }
1084 } else {
1085 for (i=start;i<end;i++)
1086 {
1087 follower[i] = MAX16(0, bandLogE[i]-follower[i]);
1088 }
1089 }
1090 for (i=start;i<end;i++)
1091 follower[i] = MAX16(follower[i], surround_dynalloc[i]);
1092 for (i=start;i<end;i++)
1093 {
1094#ifdef FIXED_POINT
1095 importance[i] = PSHR32(13*celt_exp2(MIN16(follower[i], QCONST16(4.f, DB_SHIFT))), 16);
1096#else
1097 importance[i] = (int)floor(.5f+13*celt_exp2(MIN16(follower[i], QCONST16(4.f, DB_SHIFT))));
1098#endif
1099 }
1100 /* For non-transient CBR/CVBR frames, halve the dynalloc contribution */
1101 if ((!vbr || constrained_vbr)&&!isTransient)
1102 {
1103 for (i=start;i<end;i++)
1104 follower[i] = HALF16(follower[i]);
1105 }
1106 for (i=start;i<end;i++)
1107 {
1108 if (i<8)
1109 follower[i] *= 2;
1110 if (i>=12)
1111 follower[i] = HALF16(follower[i]);
1112 }
1113#ifdef DISABLE_FLOAT_API
1114 (void)analysis;
1115#else
1116 if (analysis->valid)
1117 {
1118 for (i=start;i<IMIN(LEAK_BANDS, end);i++)
1119 follower[i] = follower[i] + QCONST16(1.f/64.f, DB_SHIFT)*analysis->leak_boost[i];
1120 }
1121#endif
1122 for (i=start;i<end;i++)
1123 {
1124 int width;
1125 int boost;
1126 int boost_bits;
1127
1128 follower[i] = MIN16(follower[i], QCONST16(4, DB_SHIFT));
1129
1130 width = C*(eBands[i+1]-eBands[i])<<LM;
1131 if (width<6)
1132 {
1133 boost = (int)SHR32(EXTEND32(follower[i]),DB_SHIFT);
1134 boost_bits = boost*width<<BITRES;
1135 } else if (width > 48) {
1136 boost = (int)SHR32(EXTEND32(follower[i])*8,DB_SHIFT);
1137 boost_bits = (boost*width<<BITRES)/8;
1138 } else {
1139 boost = (int)SHR32(EXTEND32(follower[i])*width/6,DB_SHIFT);
1140 boost_bits = boost*6<<BITRES;
1141 }
1142 /* For CBR and non-transient CVBR frames, limit dynalloc to 2/3 of the bits */
1143 if ((!vbr || (constrained_vbr&&!isTransient))
1144 && (tot_boost+boost_bits)>>BITRES>>3 > 2*effectiveBytes/3)
1145 {
1146 opus_int32 cap = ((2*effectiveBytes/3)<<BITRES<<3);
1147 offsets[i] = cap-tot_boost;
1148 tot_boost = cap;
1149 break;
1150 } else {
1151 offsets[i] = boost;
1152 tot_boost += boost_bits;
1153 }
1154 }
1155 } else {
1156 for (i=start;i<end;i++)
1157 importance[i] = 13;
1158 }
1159 *tot_boost_ = tot_boost;
1160 RESTORE_STACK;
1161 return maxDepth;
1162}
1163
1164
1165static int run_prefilter(CELTEncoder *st, celt_sig *in, celt_sig *prefilter_mem, int CC, int N,
1166 int prefilter_tapset, int *pitch, opus_val16 *gain, int *qgain, int enabled, int nbAvailableBytes, AnalysisInfo *analysis)
1167{
1168 int c;
1169 VARDECL(celt_sig, _pre);
1170 celt_sig *pre[2];
1171 const CELTMode *mode;
1172 int pitch_index;
1173 opus_val16 gain1;
1174 opus_val16 pf_threshold;
1175 int pf_on;
1176 int qg;
1177 int overlap;
1178 SAVE_STACK;
1179
1180 mode = st->mode;
1181 overlap = mode->overlap;
1182 ALLOC(_pre, CC*(N+COMBFILTER_MAXPERIOD), celt_sig);
1183
1184 pre[0] = _pre;
1185 pre[1] = _pre + (N+COMBFILTER_MAXPERIOD);
1186
1187
1188 c=0; do {
1189 OPUS_COPY(pre[c], prefilter_mem+c*COMBFILTER_MAXPERIOD, COMBFILTER_MAXPERIOD);
1190 OPUS_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+overlap)+overlap, N);
1191 } while (++c<CC);
1192
1193 if (enabled)
1194 {
1195 VARDECL(opus_val16, pitch_buf);
1196 ALLOC(pitch_buf, (COMBFILTER_MAXPERIOD+N)>>1, opus_val16);
1197
1198 pitch_downsample(pre, pitch_buf, COMBFILTER_MAXPERIOD+N, CC, st->arch);
1199 /* Don't search for the fir last 1.5 octave of the range because
1200 there's too many false-positives due to short-term correlation */
1201 pitch_search(pitch_buf+(COMBFILTER_MAXPERIOD>>1), pitch_buf, N,
1202 COMBFILTER_MAXPERIOD-3*COMBFILTER_MINPERIOD, &pitch_index,
1203 st->arch);
1204 pitch_index = COMBFILTER_MAXPERIOD-pitch_index;
1205
1206 gain1 = remove_doubling(pitch_buf, COMBFILTER_MAXPERIOD, COMBFILTER_MINPERIOD,
1207 N, &pitch_index, st->prefilter_period, st->prefilter_gain, st->arch);
1208 if (pitch_index > COMBFILTER_MAXPERIOD-2)
1209 pitch_index = COMBFILTER_MAXPERIOD-2;
1210 gain1 = MULT16_16_Q15(QCONST16(.7f,15),gain1);
1211 /*printf("%d %d %f %f\n", pitch_change, pitch_index, gain1, st->analysis.tonality);*/
1212 if (st->loss_rate>2)
1213 gain1 = HALF32(gain1);
1214 if (st->loss_rate>4)
1215 gain1 = HALF32(gain1);
1216 if (st->loss_rate>8)
1217 gain1 = 0;
1218 } else {
1219 gain1 = 0;
1220 pitch_index = COMBFILTER_MINPERIOD;
1221 }
1222#ifndef DISABLE_FLOAT_API
1223 if (analysis->valid)
1224 gain1 = (opus_val16)(gain1 * analysis->max_pitch_ratio);
1225#else
1226 (void)analysis;
1227#endif
1228 /* Gain threshold for enabling the prefilter/postfilter */
1229 pf_threshold = QCONST16(.2f,15);
1230
1231 /* Adjusting the threshold based on rate and continuity */
1232 if (abs(pitch_index-st->prefilter_period)*10>pitch_index)
1233 pf_threshold += QCONST16(.2f,15);
1234 if (nbAvailableBytes<25)
1235 pf_threshold += QCONST16(.1f,15);
1236 if (nbAvailableBytes<35)
1237 pf_threshold += QCONST16(.1f,15);
1238 if (st->prefilter_gain > QCONST16(.4f,15))
1239 pf_threshold -= QCONST16(.1f,15);
1240 if (st->prefilter_gain > QCONST16(.55f,15))
1241 pf_threshold -= QCONST16(.1f,15);
1242
1243 /* Hard threshold at 0.2 */
1244 pf_threshold = MAX16(pf_threshold, QCONST16(.2f,15));
1245 if (gain1<pf_threshold)
1246 {
1247 gain1 = 0;
1248 pf_on = 0;
1249 qg = 0;
1250 } else {
1251 /*This block is not gated by a total bits check only because
1252 of the nbAvailableBytes check above.*/
1253 if (ABS16(gain1-st->prefilter_gain)<QCONST16(.1f,15))
1254 gain1=st->prefilter_gain;
1255
1256#ifdef FIXED_POINT
1257 qg = ((gain1+1536)>>10)/3-1;
1258#else
1259 qg = (int)floor(.5f+gain1*32/3)-1;
1260#endif
1261 qg = IMAX(0, IMIN(7, qg));
1262 gain1 = QCONST16(0.09375f,15)*(qg+1);
1263 pf_on = 1;
1264 }
1265 /*printf("%d %f\n", pitch_index, gain1);*/
1266
1267 c=0; do {
1268 int offset = mode->shortMdctSize-overlap;
1269 st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD);
1270 OPUS_COPY(in+c*(N+overlap), st->in_mem+c*(overlap), overlap);
1271 if (offset)
1272 comb_filter(in+c*(N+overlap)+overlap, pre[c]+COMBFILTER_MAXPERIOD,
1273 st->prefilter_period, st->prefilter_period, offset, -st->prefilter_gain, -st->prefilter_gain,
1274 st->prefilter_tapset, st->prefilter_tapset, NULL, 0, st->arch);
1275
1276 comb_filter(in+c*(N+overlap)+overlap+offset, pre[c]+COMBFILTER_MAXPERIOD+offset,
1277 st->prefilter_period, pitch_index, N-offset, -st->prefilter_gain, -gain1,
1278 st->prefilter_tapset, prefilter_tapset, mode->window, overlap, st->arch);
1279 OPUS_COPY(st->in_mem+c*(overlap), in+c*(N+overlap)+N, overlap);
1280
1281 if (N>COMBFILTER_MAXPERIOD)
1282 {
1283 OPUS_COPY(prefilter_mem+c*COMBFILTER_MAXPERIOD, pre[c]+N, COMBFILTER_MAXPERIOD);
1284 } else {
1285 OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, prefilter_mem+c*COMBFILTER_MAXPERIOD+N, COMBFILTER_MAXPERIOD-N);
1286 OPUS_COPY(prefilter_mem+c*COMBFILTER_MAXPERIOD+COMBFILTER_MAXPERIOD-N, pre[c]+COMBFILTER_MAXPERIOD, N);
1287 }
1288 } while (++c<CC);
1289
1290 RESTORE_STACK;
1291 *gain = gain1;
1292 *pitch = pitch_index;
1293 *qgain = qg;
1294 return pf_on;
1295}
1296
1297static int compute_vbr(const CELTMode *mode, AnalysisInfo *analysis, opus_int32 base_target,
1298 int LM, opus_int32 bitrate, int lastCodedBands, int C, int intensity,
1299 int constrained_vbr, opus_val16 stereo_saving, int tot_boost,
1300 opus_val16 tf_estimate, int pitch_change, opus_val16 maxDepth,
1301 int lfe, int has_surround_mask, opus_val16 surround_masking,
1302 opus_val16 temporal_vbr)
1303{
1304 /* The target rate in 8th bits per frame */
1305 opus_int32 target;
1306 int coded_bins;
1307 int coded_bands;
1308 opus_val16 tf_calibration;
1309 int nbEBands;
1310 const opus_int16 *eBands;
1311
1312 nbEBands = mode->nbEBands;
1313 eBands = mode->eBands;
1314
1315 coded_bands = lastCodedBands ? lastCodedBands : nbEBands;
1316 coded_bins = eBands[coded_bands]<<LM;
1317 if (C==2)
1318 coded_bins += eBands[IMIN(intensity, coded_bands)]<<LM;
1319
1320 target = base_target;
1321
1322 /*printf("%f %f %f %f %d %d ", st->analysis.activity, st->analysis.tonality, tf_estimate, st->stereo_saving, tot_boost, coded_bands);*/
1323#ifndef DISABLE_FLOAT_API
1324 if (analysis->valid && analysis->activity<.4)
1325 target -= (opus_int32)((coded_bins<<BITRES)*(.4f-analysis->activity));
1326#endif
1327 /* Stereo savings */
1328 if (C==2)
1329 {
1330 int coded_stereo_bands;
1331 int coded_stereo_dof;
1332 opus_val16 max_frac;
1333 coded_stereo_bands = IMIN(intensity, coded_bands);
1334 coded_stereo_dof = (eBands[coded_stereo_bands]<<LM)-coded_stereo_bands;
1335 /* Maximum fraction of the bits we can save if the signal is mono. */
1336 max_frac = DIV32_16(MULT16_16(QCONST16(0.8f, 15), coded_stereo_dof), coded_bins);
1337 stereo_saving = MIN16(stereo_saving, QCONST16(1.f, 8));
1338 /*printf("%d %d %d ", coded_stereo_dof, coded_bins, tot_boost);*/
1339 target -= (opus_int32)MIN32(MULT16_32_Q15(max_frac,target),
1340 SHR32(MULT16_16(stereo_saving-QCONST16(0.1f,8),(coded_stereo_dof<<BITRES)),8));
1341 }
1342 /* Boost the rate according to dynalloc (minus the dynalloc average for calibration). */
1343 target += tot_boost-(19<<LM);
1344 /* Apply transient boost, compensating for average boost. */
1345 tf_calibration = QCONST16(0.044f,14);
1346 target += (opus_int32)SHL32(MULT16_32_Q15(tf_estimate-tf_calibration, target),1);
1347
1348#ifndef DISABLE_FLOAT_API
1349 /* Apply tonality boost */
1350 if (analysis->valid && !lfe)
1351 {
1352 opus_int32 tonal_target;
1353 float tonal;
1354
1355 /* Tonality boost (compensating for the average). */
1356 tonal = MAX16(0.f,analysis->tonality-.15f)-0.12f;
1357 tonal_target = target + (opus_int32)((coded_bins<<BITRES)*1.2f*tonal);
1358 if (pitch_change)
1359 tonal_target += (opus_int32)((coded_bins<<BITRES)*.8f);
1360 /*printf("%f %f ", analysis->tonality, tonal);*/
1361 target = tonal_target;
1362 }
1363#else
1364 (void)analysis;
1365 (void)pitch_change;
1366#endif
1367
1368 if (has_surround_mask&&!lfe)
1369 {
1370 opus_int32 surround_target = target + (opus_int32)SHR32(MULT16_16(surround_masking,coded_bins<<BITRES), DB_SHIFT);
1371 /*printf("%f %d %d %d %d %d %d ", surround_masking, coded_bins, st->end, st->intensity, surround_target, target, st->bitrate);*/
1372 target = IMAX(target/4, surround_target);
1373 }
1374
1375 {
1376 opus_int32 floor_depth;
1377 int bins;
1378 bins = eBands[nbEBands-2]<<LM;
1379 /*floor_depth = SHR32(MULT16_16((C*bins<<BITRES),celt_log2(SHL32(MAX16(1,sample_max),13))), DB_SHIFT);*/
1380 floor_depth = (opus_int32)SHR32(MULT16_16((C*bins<<BITRES),maxDepth), DB_SHIFT);
1381 floor_depth = IMAX(floor_depth, target>>2);
1382 target = IMIN(target, floor_depth);
1383 /*printf("%f %d\n", maxDepth, floor_depth);*/
1384 }
1385
1386 /* Make VBR less aggressive for constrained VBR because we can't keep a higher bitrate
1387 for long. Needs tuning. */
1388 if ((!has_surround_mask||lfe) && constrained_vbr)
1389 {
1390 target = base_target + (opus_int32)MULT16_32_Q15(QCONST16(0.67f, 15), target-base_target);
1391 }
1392
1393 if (!has_surround_mask && tf_estimate < QCONST16(.2f, 14))
1394 {
1395 opus_val16 amount;
1396 opus_val16 tvbr_factor;
1397 amount = MULT16_16_Q15(QCONST16(.0000031f, 30), IMAX(0, IMIN(32000, 96000-bitrate)));
1398 tvbr_factor = SHR32(MULT16_16(temporal_vbr, amount), DB_SHIFT);
1399 target += (opus_int32)MULT16_32_Q15(tvbr_factor, target);
1400 }
1401
1402 /* Don't allow more than doubling the rate */
1403 target = IMIN(2*base_target, target);
1404
1405 return target;
1406}
1407
1408int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc)
1409{
1410 int i, c, N;
1411 opus_int32 bits;
1412 ec_enc _enc;
1413 VARDECL(celt_sig, in);
1414 VARDECL(celt_sig, freq);
1415 VARDECL(celt_norm, X);
1416 VARDECL(celt_ener, bandE);
1417 VARDECL(opus_val16, bandLogE);
1418 VARDECL(opus_val16, bandLogE2);
1419 VARDECL(int, fine_quant);
1420 VARDECL(opus_val16, error);
1421 VARDECL(int, pulses);
1422 VARDECL(int, cap);
1423 VARDECL(int, offsets);
1424 VARDECL(int, importance);
1425 VARDECL(int, spread_weight);
1426 VARDECL(int, fine_priority);
1427 VARDECL(int, tf_res);
1428 VARDECL(unsigned char, collapse_masks);
1429 celt_sig *prefilter_mem;
1430 opus_val16 *oldBandE, *oldLogE, *oldLogE2, *energyError;
1431 int shortBlocks=0;
1432 int isTransient=0;
1433 const int CC = st->channels;
1434 const int C = st->stream_channels;
1435 int LM, M;
1436 int tf_select;
1437 int nbFilledBytes, nbAvailableBytes;
1438 int start;
1439 int end;
1440 int effEnd;
1441 int codedBands;
1442 int alloc_trim;
1443 int pitch_index=COMBFILTER_MINPERIOD;
1444 opus_val16 gain1 = 0;
1445 int dual_stereo=0;
1446 int effectiveBytes;
1447 int dynalloc_logp;
1448 opus_int32 vbr_rate;
1449 opus_int32 total_bits;
1450 opus_int32 total_boost;
1451 opus_int32 balance;
1452 opus_int32 tell;
1453 opus_int32 tell0_frac;
1454 int prefilter_tapset=0;
1455 int pf_on;
1456 int anti_collapse_rsv;
1457 int anti_collapse_on=0;
1458 int silence=0;
1459 int tf_chan = 0;
1460 opus_val16 tf_estimate;
1461 int pitch_change=0;
1462 opus_int32 tot_boost;
1463 opus_val32 sample_max;
1464 opus_val16 maxDepth;
1465 const OpusCustomMode *mode;
1466 int nbEBands;
1467 int overlap;
1468 const opus_int16 *eBands;
1469 int secondMdct;
1470 int signalBandwidth;
1471 int transient_got_disabled=0;
1472 opus_val16 surround_masking=0;
1473 opus_val16 temporal_vbr=0;
1474 opus_val16 surround_trim = 0;
1475 opus_int32 equiv_rate;
1476 int hybrid;
1477 int weak_transient = 0;
1478 int enable_tf_analysis;
1479 VARDECL(opus_val16, surround_dynalloc);
1480 ALLOC_STACK;
1481
1482 mode = st->mode;
1483 nbEBands = mode->nbEBands;
1484 overlap = mode->overlap;
1485 eBands = mode->eBands;
1486 start = st->start;
1487 end = st->end;
1488 hybrid = start != 0;
1489 tf_estimate = 0;
1490 if (nbCompressedBytes<2 || pcm==NULL)
1491 {
1492 RESTORE_STACK;
1493 return OPUS_BAD_ARG;
1494 }
1495
1496 frame_size *= st->upsample;
1497 for (LM=0;LM<=mode->maxLM;LM++)
1498 if (mode->shortMdctSize<<LM==frame_size)
1499 break;
1500 if (LM>mode->maxLM)
1501 {
1502 RESTORE_STACK;
1503 return OPUS_BAD_ARG;
1504 }
1505 M=1<<LM;
1506 N = M*mode->shortMdctSize;
1507
1508 prefilter_mem = st->in_mem+CC*(overlap);
1509 oldBandE = (opus_val16*)(st->in_mem+CC*(overlap+COMBFILTER_MAXPERIOD));
1510 oldLogE = oldBandE + CC*nbEBands;
1511 oldLogE2 = oldLogE + CC*nbEBands;
1512 energyError = oldLogE2 + CC*nbEBands;
1513
1514 if (enc==NULL)
1515 {
1516 tell0_frac=tell=1;
1517 nbFilledBytes=0;
1518 } else {
1519 tell0_frac=ec_tell_frac(enc);
1520 tell=ec_tell(enc);
1521 nbFilledBytes=(tell+4)>>3;
1522 }
1523
1524#ifdef CUSTOM_MODES
1525 if (st->signalling && enc==NULL)
1526 {
1527 int tmp = (mode->effEBands-end)>>1;
1528 end = st->end = IMAX(1, mode->effEBands-tmp);
1529 compressed[0] = tmp<<5;
1530 compressed[0] |= LM<<3;
1531 compressed[0] |= (C==2)<<2;
1532 /* Convert "standard mode" to Opus header */
1533 if (mode->Fs==48000 && mode->shortMdctSize==120)
1534 {
1535 int c0 = toOpus(compressed[0]);
1536 if (c0<0)
1537 {
1538 RESTORE_STACK;
1539 return OPUS_BAD_ARG;
1540 }
1541 compressed[0] = c0;
1542 }
1543 compressed++;
1544 nbCompressedBytes--;
1545 }
1546#else
1547 celt_assert(st->signalling==0);
1548#endif
1549
1550 /* Can't produce more than 1275 output bytes */
1551 nbCompressedBytes = IMIN(nbCompressedBytes,1275);
1552 nbAvailableBytes = nbCompressedBytes - nbFilledBytes;
1553
1554 if (st->vbr && st->bitrate!=OPUS_BITRATE_MAX)
1555 {
1556 opus_int32 den=mode->Fs>>BITRES;
1557 vbr_rate=(st->bitrate*frame_size+(den>>1))/den;
1558#ifdef CUSTOM_MODES
1559 if (st->signalling)
1560 vbr_rate -= 8<<BITRES;
1561#endif
1562 effectiveBytes = vbr_rate>>(3+BITRES);
1563 } else {
1564 opus_int32 tmp;
1565 vbr_rate = 0;
1566 tmp = st->bitrate*frame_size;
1567 if (tell>1)
1568 tmp += tell;
1569 if (st->bitrate!=OPUS_BITRATE_MAX)
1570 nbCompressedBytes = IMAX(2, IMIN(nbCompressedBytes,
1571 (tmp+4*mode->Fs)/(8*mode->Fs)-!!st->signalling));
1572 effectiveBytes = nbCompressedBytes - nbFilledBytes;
1573 }
1574 equiv_rate = ((opus_int32)nbCompressedBytes*8*50 >> (3-LM)) - (40*C+20)*((400>>LM) - 50);
1575 if (st->bitrate != OPUS_BITRATE_MAX)
1576 equiv_rate = IMIN(equiv_rate, st->bitrate - (40*C+20)*((400>>LM) - 50));
1577
1578 if (enc==NULL)
1579 {
1580 ec_enc_init(&_enc, compressed, nbCompressedBytes);
1581 enc = &_enc;
1582 }
1583
1584 if (vbr_rate>0)
1585 {
1586 /* Computes the max bit-rate allowed in VBR mode to avoid violating the
1587 target rate and buffering.
1588 We must do this up front so that bust-prevention logic triggers
1589 correctly if we don't have enough bits. */
1590 if (st->constrained_vbr)
1591 {
1592 opus_int32 vbr_bound;
1593 opus_int32 max_allowed;
1594 /* We could use any multiple of vbr_rate as bound (depending on the
1595 delay).
1596 This is clamped to ensure we use at least two bytes if the encoder
1597 was entirely empty, but to allow 0 in hybrid mode. */
1598 vbr_bound = vbr_rate;
1599 max_allowed = IMIN(IMAX(tell==1?2:0,
1600 (vbr_rate+vbr_bound-st->vbr_reservoir)>>(BITRES+3)),
1601 nbAvailableBytes);
1602 if(max_allowed < nbAvailableBytes)
1603 {
1604 nbCompressedBytes = nbFilledBytes+max_allowed;
1605 nbAvailableBytes = max_allowed;
1606 ec_enc_shrink(enc, nbCompressedBytes);
1607 }
1608 }
1609 }
1610 total_bits = nbCompressedBytes*8;
1611
1612 effEnd = end;
1613 if (effEnd > mode->effEBands)
1614 effEnd = mode->effEBands;
1615
1616 ALLOC(in, CC*(N+overlap), celt_sig);
1617
1618 sample_max=MAX32(st->overlap_max, celt_maxabs16(pcm, C*(N-overlap)/st->upsample));
1619 st->overlap_max=celt_maxabs16(pcm+C*(N-overlap)/st->upsample, C*overlap/st->upsample);
1620 sample_max=MAX32(sample_max, st->overlap_max);
1621#ifdef FIXED_POINT
1622 silence = (sample_max==0);
1623#else
1624 silence = (sample_max <= (opus_val16)1/(1<<st->lsb_depth));
1625#endif
1626#ifdef FUZZING
1627 if ((rand()&0x3F)==0)
1628 silence = 1;
1629#endif
1630 if (tell==1)
1631 ec_enc_bit_logp(enc, silence, 15);
1632 else
1633 silence=0;
1634 if (silence)
1635 {
1636 /*In VBR mode there is no need to send more than the minimum. */
1637 if (vbr_rate>0)
1638 {
1639 effectiveBytes=nbCompressedBytes=IMIN(nbCompressedBytes, nbFilledBytes+2);
1640 total_bits=nbCompressedBytes*8;
1641 nbAvailableBytes=2;
1642 ec_enc_shrink(enc, nbCompressedBytes);
1643 }
1644 /* Pretend we've filled all the remaining bits with zeros
1645 (that's what the initialiser did anyway) */
1646 tell = nbCompressedBytes*8;
1647 enc->nbits_total+=tell-ec_tell(enc);
1648 }
1649 c=0; do {
1650 int need_clip=0;
1651#ifndef FIXED_POINT
1652 need_clip = st->clip && sample_max>65536.f;
1653#endif
1654 celt_preemphasis(pcm+c, in+c*(N+overlap)+overlap, N, CC, st->upsample,
1655 mode->preemph, st->preemph_memE+c, need_clip);
1656 } while (++c<CC);
1657
1658
1659
1660 /* Find pitch period and gain */
1661 {
1662 int enabled;
1663 int qg;
1664 enabled = ((st->lfe&&nbAvailableBytes>3) || nbAvailableBytes>12*C) && !hybrid && !silence && !st->disable_pf
1665 && st->complexity >= 5;
1666
1667 prefilter_tapset = st->tapset_decision;
1668 pf_on = run_prefilter(st, in, prefilter_mem, CC, N, prefilter_tapset, &pitch_index, &gain1, &qg, enabled, nbAvailableBytes, &st->analysis);
1669 if ((gain1 > QCONST16(.4f,15) || st->prefilter_gain > QCONST16(.4f,15)) && (!st->analysis.valid || st->analysis.tonality > .3)
1670 && (pitch_index > 1.26*st->prefilter_period || pitch_index < .79*st->prefilter_period))
1671 pitch_change = 1;
1672 if (pf_on==0)
1673 {
1674 if(!hybrid && tell+16<=total_bits)
1675 ec_enc_bit_logp(enc, 0, 1);
1676 } else {
1677 /*This block is not gated by a total bits check only because
1678 of the nbAvailableBytes check above.*/
1679 int octave;
1680 ec_enc_bit_logp(enc, 1, 1);
1681 pitch_index += 1;
1682 octave = EC_ILOG(pitch_index)-5;
1683 ec_enc_uint(enc, octave, 6);
1684 ec_enc_bits(enc, pitch_index-(16<<octave), 4+octave);
1685 pitch_index -= 1;
1686 ec_enc_bits(enc, qg, 3);
1687 ec_enc_icdf(enc, prefilter_tapset, tapset_icdf, 2);
1688 }
1689 }
1690
1691 isTransient = 0;
1692 shortBlocks = 0;
1693 if (st->complexity >= 1 && !st->lfe)
1694 {
1695 /* Reduces the likelihood of energy instability on fricatives at low bitrate
1696 in hybrid mode. It seems like we still want to have real transients on vowels
1697 though (small SILK quantization offset value). */
1698 int allow_weak_transients = hybrid && effectiveBytes<15 && st->silk_info.signalType != 2;
1699 isTransient = transient_analysis(in, N+overlap, CC,
1700 &tf_estimate, &tf_chan, allow_weak_transients, &weak_transient);
1701 }
1702 if (LM>0 && ec_tell(enc)+3<=total_bits)
1703 {
1704 if (isTransient)
1705 shortBlocks = M;
1706 } else {
1707 isTransient = 0;
1708 transient_got_disabled=1;
1709 }
1710
1711 ALLOC(freq, CC*N, celt_sig); /**< Interleaved signal MDCTs */
1712 ALLOC(bandE,nbEBands*CC, celt_ener);
1713 ALLOC(bandLogE,nbEBands*CC, opus_val16);
1714
1715 secondMdct = shortBlocks && st->complexity>=8;
1716 ALLOC(bandLogE2, C*nbEBands, opus_val16);
1717 if (secondMdct)
1718 {
1719 compute_mdcts(mode, 0, in, freq, C, CC, LM, st->upsample, st->arch);
1720 compute_band_energies(mode, freq, bandE, effEnd, C, LM, st->arch);
1721 amp2Log2(mode, effEnd, end, bandE, bandLogE2, C);
1722 for (i=0;i<C*nbEBands;i++)
1723 bandLogE2[i] += HALF16(SHL16(LM, DB_SHIFT));
1724 }
1725
1726 compute_mdcts(mode, shortBlocks, in, freq, C, CC, LM, st->upsample, st->arch);
1727 /* This should catch any NaN in the CELT input. Since we're not supposed to see any (they're filtered
1728 at the Opus layer), just abort. */
1729 celt_assert(!celt_isnan(freq[0]) && (C==1 || !celt_isnan(freq[N])));
1730 if (CC==2&&C==1)
1731 tf_chan = 0;
1732 compute_band_energies(mode, freq, bandE, effEnd, C, LM, st->arch);
1733
1734 if (st->lfe)
1735 {
1736 for (i=2;i<end;i++)
1737 {
1738 bandE[i] = IMIN(bandE[i], MULT16_32_Q15(QCONST16(1e-4f,15),bandE[0]));
1739 bandE[i] = MAX32(bandE[i], EPSILON);
1740 }
1741 }
1742 amp2Log2(mode, effEnd, end, bandE, bandLogE, C);
1743
1744 ALLOC(surround_dynalloc, C*nbEBands, opus_val16);
1745 OPUS_CLEAR(surround_dynalloc, end);
1746 /* This computes how much masking takes place between surround channels */
1747 if (!hybrid&&st->energy_mask&&!st->lfe)
1748 {
1749 int mask_end;
1750 int midband;
1751 int count_dynalloc;
1752 opus_val32 mask_avg=0;
1753 opus_val32 diff=0;
1754 int count=0;
1755 mask_end = IMAX(2,st->lastCodedBands);
1756 for (c=0;c<C;c++)
1757 {
1758 for(i=0;i<mask_end;i++)
1759 {
1760 opus_val16 mask;
1761 mask = MAX16(MIN16(st->energy_mask[nbEBands*c+i],
1762 QCONST16(.25f, DB_SHIFT)), -QCONST16(2.0f, DB_SHIFT));
1763 if (mask > 0)
1764 mask = HALF16(mask);
1765 mask_avg += MULT16_16(mask, eBands[i+1]-eBands[i]);
1766 count += eBands[i+1]-eBands[i];
1767 diff += MULT16_16(mask, 1+2*i-mask_end);
1768 }
1769 }
1770 celt_assert(count>0);
1771 mask_avg = DIV32_16(mask_avg,count);
1772 mask_avg += QCONST16(.2f, DB_SHIFT);
1773 diff = diff*6/(C*(mask_end-1)*(mask_end+1)*mask_end);
1774 /* Again, being conservative */
1775 diff = HALF32(diff);
1776 diff = MAX32(MIN32(diff, QCONST32(.031f, DB_SHIFT)), -QCONST32(.031f, DB_SHIFT));
1777 /* Find the band that's in the middle of the coded spectrum */
1778 for (midband=0;eBands[midband+1] < eBands[mask_end]/2;midband++);
1779 count_dynalloc=0;
1780 for(i=0;i<mask_end;i++)
1781 {
1782 opus_val32 lin;
1783 opus_val16 unmask;
1784 lin = mask_avg + diff*(i-midband);
1785 if (C==2)
1786 unmask = MAX16(st->energy_mask[i], st->energy_mask[nbEBands+i]);
1787 else
1788 unmask = st->energy_mask[i];
1789 unmask = MIN16(unmask, QCONST16(.0f, DB_SHIFT));
1790 unmask -= lin;
1791 if (unmask > QCONST16(.25f, DB_SHIFT))
1792 {
1793 surround_dynalloc[i] = unmask - QCONST16(.25f, DB_SHIFT);
1794 count_dynalloc++;
1795 }
1796 }
1797 if (count_dynalloc>=3)
1798 {
1799 /* If we need dynalloc in many bands, it's probably because our
1800 initial masking rate was too low. */
1801 mask_avg += QCONST16(.25f, DB_SHIFT);
1802 if (mask_avg>0)
1803 {
1804 /* Something went really wrong in the original calculations,
1805 disabling masking. */
1806 mask_avg = 0;
1807 diff = 0;
1808 OPUS_CLEAR(surround_dynalloc, mask_end);
1809 } else {
1810 for(i=0;i<mask_end;i++)
1811 surround_dynalloc[i] = MAX16(0, surround_dynalloc[i]-QCONST16(.25f, DB_SHIFT));
1812 }
1813 }
1814 mask_avg += QCONST16(.2f, DB_SHIFT);
1815 /* Convert to 1/64th units used for the trim */
1816 surround_trim = 64*diff;
1817 /*printf("%d %d ", mask_avg, surround_trim);*/
1818 surround_masking = mask_avg;
1819 }
1820 /* Temporal VBR (but not for LFE) */
1821 if (!st->lfe)
1822 {
1823 opus_val16 follow=-QCONST16(10.0f,DB_SHIFT);
1824 opus_val32 frame_avg=0;
1825 opus_val16 offset = shortBlocks?HALF16(SHL16(LM, DB_SHIFT)):0;
1826 for(i=start;i<end;i++)
1827 {
1828 follow = MAX16(follow-QCONST16(1.f, DB_SHIFT), bandLogE[i]-offset);
1829 if (C==2)
1830 follow = MAX16(follow, bandLogE[i+nbEBands]-offset);
1831 frame_avg += follow;
1832 }
1833 frame_avg /= (end-start);
1834 temporal_vbr = SUB16(frame_avg,st->spec_avg);
1835 temporal_vbr = MIN16(QCONST16(3.f, DB_SHIFT), MAX16(-QCONST16(1.5f, DB_SHIFT), temporal_vbr));
1836 st->spec_avg += MULT16_16_Q15(QCONST16(.02f, 15), temporal_vbr);
1837 }
1838 /*for (i=0;i<21;i++)
1839 printf("%f ", bandLogE[i]);
1840 printf("\n");*/
1841
1842 if (!secondMdct)
1843 {
1844 OPUS_COPY(bandLogE2, bandLogE, C*nbEBands);
1845 }
1846
1847 /* Last chance to catch any transient we might have missed in the
1848 time-domain analysis */
1849 if (LM>0 && ec_tell(enc)+3<=total_bits && !isTransient && st->complexity>=5 && !st->lfe && !hybrid)
1850 {
1851 if (patch_transient_decision(bandLogE, oldBandE, nbEBands, start, end, C))
1852 {
1853 isTransient = 1;
1854 shortBlocks = M;
1855 compute_mdcts(mode, shortBlocks, in, freq, C, CC, LM, st->upsample, st->arch);
1856 compute_band_energies(mode, freq, bandE, effEnd, C, LM, st->arch);
1857 amp2Log2(mode, effEnd, end, bandE, bandLogE, C);
1858 /* Compensate for the scaling of short vs long mdcts */
1859 for (i=0;i<C*nbEBands;i++)
1860 bandLogE2[i] += HALF16(SHL16(LM, DB_SHIFT));
1861 tf_estimate = QCONST16(.2f,14);
1862 }
1863 }
1864
1865 if (LM>0 && ec_tell(enc)+3<=total_bits)
1866 ec_enc_bit_logp(enc, isTransient, 3);
1867
1868 ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */
1869
1870 /* Band normalisation */
1871 normalise_bands(mode, freq, X, bandE, effEnd, C, M);
1872
1873 enable_tf_analysis = effectiveBytes>=15*C && !hybrid && st->complexity>=2 && !st->lfe;
1874
1875 ALLOC(offsets, nbEBands, int);
1876 ALLOC(importance, nbEBands, int);
1877 ALLOC(spread_weight, nbEBands, int);
1878
1879 maxDepth = dynalloc_analysis(bandLogE, bandLogE2, nbEBands, start, end, C, offsets,
1880 st->lsb_depth, mode->logN, isTransient, st->vbr, st->constrained_vbr,
1881 eBands, LM, effectiveBytes, &tot_boost, st->lfe, surround_dynalloc, &st->analysis, importance, spread_weight);
1882
1883 ALLOC(tf_res, nbEBands, int);
1884 /* Disable variable tf resolution for hybrid and at very low bitrate */
1885 if (enable_tf_analysis)
1886 {
1887 int lambda;
1888 lambda = IMAX(80, 20480/effectiveBytes + 2);
1889 tf_select = tf_analysis(mode, effEnd, isTransient, tf_res, lambda, X, N, LM, tf_estimate, tf_chan, importance);
1890 for (i=effEnd;i<end;i++)
1891 tf_res[i] = tf_res[effEnd-1];
1892 } else if (hybrid && weak_transient)
1893 {
1894 /* For weak transients, we rely on the fact that improving time resolution using
1895 TF on a long window is imperfect and will not result in an energy collapse at
1896 low bitrate. */
1897 for (i=0;i<end;i++)
1898 tf_res[i] = 1;
1899 tf_select=0;
1900 } else if (hybrid && effectiveBytes<15 && st->silk_info.signalType != 2)
1901 {
1902 /* For low bitrate hybrid, we force temporal resolution to 5 ms rather than 2.5 ms. */
1903 for (i=0;i<end;i++)
1904 tf_res[i] = 0;
1905 tf_select=isTransient;
1906 } else {
1907 for (i=0;i<end;i++)
1908 tf_res[i] = isTransient;
1909 tf_select=0;
1910 }
1911
1912 ALLOC(error, C*nbEBands, opus_val16);
1913 c=0;
1914 do {
1915 for (i=start;i<end;i++)
1916 {
1917 /* When the energy is stable, slightly bias energy quantization towards
1918 the previous error to make the gain more stable (a constant offset is
1919 better than fluctuations). */
1920 if (ABS32(SUB32(bandLogE[i+c*nbEBands], oldBandE[i+c*nbEBands])) < QCONST16(2.f, DB_SHIFT))
1921 {
1922 bandLogE[i+c*nbEBands] -= MULT16_16_Q15(energyError[i+c*nbEBands], QCONST16(0.25f, 15));
1923 }
1924 }
1925 } while (++c < C);
1926 quant_coarse_energy(mode, start, end, effEnd, bandLogE,
1927 oldBandE, total_bits, error, enc,
1928 C, LM, nbAvailableBytes, st->force_intra,
1929 &st->delayedIntra, st->complexity >= 4, st->loss_rate, st->lfe);
1930
1931 tf_encode(start, end, isTransient, tf_res, LM, tf_select, enc);
1932
1933 if (ec_tell(enc)+4<=total_bits)
1934 {
1935 if (st->lfe)
1936 {
1937 st->tapset_decision = 0;
1938 st->spread_decision = SPREAD_NORMAL;
1939 } else if (hybrid)
1940 {
1941 if (st->complexity == 0)
1942 st->spread_decision = SPREAD_NONE;
1943 else if (isTransient)
1944 st->spread_decision = SPREAD_NORMAL;
1945 else
1946 st->spread_decision = SPREAD_AGGRESSIVE;
1947 } else if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C)
1948 {
1949 if (st->complexity == 0)
1950 st->spread_decision = SPREAD_NONE;
1951 else
1952 st->spread_decision = SPREAD_NORMAL;
1953 } else {
1954 /* Disable new spreading+tapset estimator until we can show it works
1955 better than the old one. So far it seems like spreading_decision()
1956 works best. */
1957#if 0
1958 if (st->analysis.valid)
1959 {
1960 static const opus_val16 spread_thresholds[3] = {-QCONST16(.6f, 15), -QCONST16(.2f, 15), -QCONST16(.07f, 15)};
1961 static const opus_val16 spread_histeresis[3] = {QCONST16(.15f, 15), QCONST16(.07f, 15), QCONST16(.02f, 15)};
1962 static const opus_val16 tapset_thresholds[2] = {QCONST16(.0f, 15), QCONST16(.15f, 15)};
1963 static const opus_val16 tapset_histeresis[2] = {QCONST16(.1f, 15), QCONST16(.05f, 15)};
1964 st->spread_decision = hysteresis_decision(-st->analysis.tonality, spread_thresholds, spread_histeresis, 3, st->spread_decision);
1965 st->tapset_decision = hysteresis_decision(st->analysis.tonality_slope, tapset_thresholds, tapset_histeresis, 2, st->tapset_decision);
1966 } else
1967#endif
1968 {
1969 st->spread_decision = spreading_decision(mode, X,
1970 &st->tonal_average, st->spread_decision, &st->hf_average,
1971 &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M, spread_weight);
1972 }
1973 /*printf("%d %d\n", st->tapset_decision, st->spread_decision);*/
1974 /*printf("%f %d %f %d\n\n", st->analysis.tonality, st->spread_decision, st->analysis.tonality_slope, st->tapset_decision);*/
1975 }
1976 ec_enc_icdf(enc, st->spread_decision, spread_icdf, 5);
1977 }
1978
1979 /* For LFE, everything interesting is in the first band */
1980 if (st->lfe)
1981 offsets[0] = IMIN(8, effectiveBytes/3);
1982 ALLOC(cap, nbEBands, int);
1983 init_caps(mode,cap,LM,C);
1984
1985 dynalloc_logp = 6;
1986 total_bits<<=BITRES;
1987 total_boost = 0;
1988 tell = ec_tell_frac(enc);
1989 for (i=start;i<end;i++)
1990 {
1991 int width, quanta;
1992 int dynalloc_loop_logp;
1993 int boost;
1994 int j;
1995 width = C*(eBands[i+1]-eBands[i])<<LM;
1996 /* quanta is 6 bits, but no more than 1 bit/sample
1997 and no less than 1/8 bit/sample */
1998 quanta = IMIN(width<<BITRES, IMAX(6<<BITRES, width));
1999 dynalloc_loop_logp = dynalloc_logp;
2000 boost = 0;
2001 for (j = 0; tell+(dynalloc_loop_logp<<BITRES) < total_bits-total_boost
2002 && boost < cap[i]; j++)
2003 {
2004 int flag;
2005 flag = j<offsets[i];
2006 ec_enc_bit_logp(enc, flag, dynalloc_loop_logp);
2007 tell = ec_tell_frac(enc);
2008 if (!flag)
2009 break;
2010 boost += quanta;
2011 total_boost += quanta;
2012 dynalloc_loop_logp = 1;
2013 }
2014 /* Making dynalloc more likely */
2015 if (j)
2016 dynalloc_logp = IMAX(2, dynalloc_logp-1);
2017 offsets[i] = boost;
2018 }
2019
2020 if (C==2)
2021 {
2022 static const opus_val16 intensity_thresholds[21]=
2023 /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 off*/
2024 { 1, 2, 3, 4, 5, 6, 7, 8,16,24,36,44,50,56,62,67,72,79,88,106,134};
2025 static const opus_val16 intensity_histeresis[21]=
2026 { 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 5, 6, 8, 8};
2027
2028 /* Always use MS for 2.5 ms frames until we can do a better analysis */
2029 if (LM!=0)
2030 dual_stereo = stereo_analysis(mode, X, LM, N);
2031
2032 st->intensity = hysteresis_decision((opus_val16)(equiv_rate/1000),
2033 intensity_thresholds, intensity_histeresis, 21, st->intensity);
2034 st->intensity = IMIN(end,IMAX(start, st->intensity));
2035 }
2036
2037 alloc_trim = 5;
2038 if (tell+(6<<BITRES) <= total_bits - total_boost)
2039 {
2040 if (start > 0 || st->lfe)
2041 {
2042 st->stereo_saving = 0;
2043 alloc_trim = 5;
2044 } else {
2045 alloc_trim = alloc_trim_analysis(mode, X, bandLogE,
2046 end, LM, C, N, &st->analysis, &st->stereo_saving, tf_estimate,
2047 st->intensity, surround_trim, equiv_rate, st->arch);
2048 }
2049 ec_enc_icdf(enc, alloc_trim, trim_icdf, 7);
2050 tell = ec_tell_frac(enc);
2051 }
2052
2053 /* Variable bitrate */
2054 if (vbr_rate>0)
2055 {
2056 opus_val16 alpha;
2057 opus_int32 delta;
2058 /* The target rate in 8th bits per frame */
2059 opus_int32 target, base_target;
2060 opus_int32 min_allowed;
2061 int lm_diff = mode->maxLM - LM;
2062
2063 /* Don't attempt to use more than 510 kb/s, even for frames smaller than 20 ms.
2064 The CELT allocator will just not be able to use more than that anyway. */
2065 nbCompressedBytes = IMIN(nbCompressedBytes,1275>>(3-LM));
2066 if (!hybrid)
2067 {
2068 base_target = vbr_rate - ((40*C+20)<<BITRES);
2069 } else {
2070 base_target = IMAX(0, vbr_rate - ((9*C+4)<<BITRES));
2071 }
2072
2073 if (st->constrained_vbr)
2074 base_target += (st->vbr_offset>>lm_diff);
2075
2076 if (!hybrid)
2077 {
2078 target = compute_vbr(mode, &st->analysis, base_target, LM, equiv_rate,
2079 st->lastCodedBands, C, st->intensity, st->constrained_vbr,
2080 st->stereo_saving, tot_boost, tf_estimate, pitch_change, maxDepth,
2081 st->lfe, st->energy_mask!=NULL, surround_masking,
2082 temporal_vbr);
2083 } else {
2084 target = base_target;
2085 /* Tonal frames (offset<100) need more bits than noisy (offset>100) ones. */
2086 if (st->silk_info.offset < 100) target += 12 << BITRES >> (3-LM);
2087 if (st->silk_info.offset > 100) target -= 18 << BITRES >> (3-LM);
2088 /* Boosting bitrate on transients and vowels with significant temporal
2089 spikes. */
2090 target += (opus_int32)MULT16_16_Q14(tf_estimate-QCONST16(.25f,14), (50<<BITRES));
2091 /* If we have a strong transient, let's make sure it has enough bits to code
2092 the first two bands, so that it can use folding rather than noise. */
2093 if (tf_estimate > QCONST16(.7f,14))
2094 target = IMAX(target, 50<<BITRES);
2095 }
2096 /* The current offset is removed from the target and the space used
2097 so far is added*/
2098 target=target+tell;
2099 /* In VBR mode the frame size must not be reduced so much that it would
2100 result in the encoder running out of bits.
2101 The margin of 2 bytes ensures that none of the bust-prevention logic
2102 in the decoder will have triggered so far. */
2103 min_allowed = ((tell+total_boost+(1<<(BITRES+3))-1)>>(BITRES+3)) + 2;
2104 /* Take into account the 37 bits we need to have left in the packet to
2105 signal a redundant frame in hybrid mode. Creating a shorter packet would
2106 create an entropy coder desync. */
2107 if (hybrid)
2108 min_allowed = IMAX(min_allowed, (tell0_frac+(37<<BITRES)+total_boost+(1<<(BITRES+3))-1)>>(BITRES+3));
2109
2110 nbAvailableBytes = (target+(1<<(BITRES+2)))>>(BITRES+3);
2111 nbAvailableBytes = IMAX(min_allowed,nbAvailableBytes);
2112 nbAvailableBytes = IMIN(nbCompressedBytes,nbAvailableBytes);
2113
2114 /* By how much did we "miss" the target on that frame */
2115 delta = target - vbr_rate;
2116
2117 target=nbAvailableBytes<<(BITRES+3);
2118
2119 /*If the frame is silent we don't adjust our drift, otherwise
2120 the encoder will shoot to very high rates after hitting a
2121 span of silence, but we do allow the bitres to refill.
2122 This means that we'll undershoot our target in CVBR/VBR modes
2123 on files with lots of silence. */
2124 if(silence)
2125 {
2126 nbAvailableBytes = 2;
2127 target = 2*8<<BITRES;
2128 delta = 0;
2129 }
2130
2131 if (st->vbr_count < 970)
2132 {
2133 st->vbr_count++;
2134 alpha = celt_rcp(SHL32(EXTEND32(st->vbr_count+20),16));
2135 } else
2136 alpha = QCONST16(.001f,15);
2137 /* How many bits have we used in excess of what we're allowed */
2138 if (st->constrained_vbr)
2139 st->vbr_reservoir += target - vbr_rate;
2140 /*printf ("%d\n", st->vbr_reservoir);*/
2141
2142 /* Compute the offset we need to apply in order to reach the target */
2143 if (st->constrained_vbr)
2144 {
2145 st->vbr_drift += (opus_int32)MULT16_32_Q15(alpha,(delta*(1<<lm_diff))-st->vbr_offset-st->vbr_drift);
2146 st->vbr_offset = -st->vbr_drift;
2147 }
2148 /*printf ("%d\n", st->vbr_drift);*/
2149
2150 if (st->constrained_vbr && st->vbr_reservoir < 0)
2151 {
2152 /* We're under the min value -- increase rate */
2153 int adjust = (-st->vbr_reservoir)/(8<<BITRES);
2154 /* Unless we're just coding silence */
2155 nbAvailableBytes += silence?0:adjust;
2156 st->vbr_reservoir = 0;
2157 /*printf ("+%d\n", adjust);*/
2158 }
2159 nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes);
2160 /*printf("%d\n", nbCompressedBytes*50*8);*/
2161 /* This moves the raw bits to take into account the new compressed size */
2162 ec_enc_shrink(enc, nbCompressedBytes);
2163 }
2164
2165 /* Bit allocation */
2166 ALLOC(fine_quant, nbEBands, int);
2167 ALLOC(pulses, nbEBands, int);
2168 ALLOC(fine_priority, nbEBands, int);
2169
2170 /* bits = packet size - where we are - safety*/
2171 bits = (((opus_int32)nbCompressedBytes*8)<<BITRES) - ec_tell_frac(enc) - 1;
2172 anti_collapse_rsv = isTransient&&LM>=2&&bits>=((LM+2)<<BITRES) ? (1<<BITRES) : 0;
2173 bits -= anti_collapse_rsv;
2174 signalBandwidth = end-1;
2175#ifndef DISABLE_FLOAT_API
2176 if (st->analysis.valid)
2177 {
2178 int min_bandwidth;
2179 if (equiv_rate < (opus_int32)32000*C)
2180 min_bandwidth = 13;
2181 else if (equiv_rate < (opus_int32)48000*C)
2182 min_bandwidth = 16;
2183 else if (equiv_rate < (opus_int32)60000*C)
2184 min_bandwidth = 18;
2185 else if (equiv_rate < (opus_int32)80000*C)
2186 min_bandwidth = 19;
2187 else
2188 min_bandwidth = 20;
2189 signalBandwidth = IMAX(st->analysis.bandwidth, min_bandwidth);
2190 }
2191#endif
2192 if (st->lfe)
2193 signalBandwidth = 1;
2194 codedBands = clt_compute_allocation(mode, start, end, offsets, cap,
2195 alloc_trim, &st->intensity, &dual_stereo, bits, &balance, pulses,
2196 fine_quant, fine_priority, C, LM, enc, 1, st->lastCodedBands, signalBandwidth);
2197 if (st->lastCodedBands)
2198 st->lastCodedBands = IMIN(st->lastCodedBands+1,IMAX(st->lastCodedBands-1,codedBands));
2199 else
2200 st->lastCodedBands = codedBands;
2201
2202 quant_fine_energy(mode, start, end, oldBandE, error, fine_quant, enc, C);
2203
2204 /* Residual quantisation */
2205 ALLOC(collapse_masks, C*nbEBands, unsigned char);
2206 quant_all_bands(1, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks,
2207 bandE, pulses, shortBlocks, st->spread_decision,
2208 dual_stereo, st->intensity, tf_res, nbCompressedBytes*(8<<BITRES)-anti_collapse_rsv,
2209 balance, enc, LM, codedBands, &st->rng, st->complexity, st->arch, st->disable_inv);
2210
2211 if (anti_collapse_rsv > 0)
2212 {
2213 anti_collapse_on = st->consec_transient<2;
2214#ifdef FUZZING
2215 anti_collapse_on = rand()&0x1;
2216#endif
2217 ec_enc_bits(enc, anti_collapse_on, 1);
2218 }
2219 quant_energy_finalise(mode, start, end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_tell(enc), enc, C);
2220 OPUS_CLEAR(energyError, nbEBands*CC);
2221 c=0;
2222 do {
2223 for (i=start;i<end;i++)
2224 {
2225 energyError[i+c*nbEBands] = MAX16(-QCONST16(0.5f, 15), MIN16(QCONST16(0.5f, 15), error[i+c*nbEBands]));
2226 }
2227 } while (++c < C);
2228
2229 if (silence)
2230 {
2231 for (i=0;i<C*nbEBands;i++)
2232 oldBandE[i] = -QCONST16(28.f,DB_SHIFT);
2233 }
2234
2235#ifdef RESYNTH
2236 /* Re-synthesis of the coded audio if required */
2237 {
2238 celt_sig *out_mem[2];
2239
2240 if (anti_collapse_on)
2241 {
2242 anti_collapse(mode, X, collapse_masks, LM, C, N,
2243 start, end, oldBandE, oldLogE, oldLogE2, pulses, st->rng);
2244 }
2245
2246 c=0; do {
2247 OPUS_MOVE(st->syn_mem[c], st->syn_mem[c]+N, 2*MAX_PERIOD-N+overlap/2);
2248 } while (++c<CC);
2249
2250 c=0; do {
2251 out_mem[c] = st->syn_mem[c]+2*MAX_PERIOD-N;
2252 } while (++c<CC);
2253
2254 celt_synthesis(mode, X, out_mem, oldBandE, start, effEnd,
2255 C, CC, isTransient, LM, st->upsample, silence, st->arch);
2256
2257 c=0; do {
2258 st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD);
2259 st->prefilter_period_old=IMAX(st->prefilter_period_old, COMBFILTER_MINPERIOD);
2260 comb_filter(out_mem[c], out_mem[c], st->prefilter_period_old, st->prefilter_period, mode->shortMdctSize,
2261 st->prefilter_gain_old, st->prefilter_gain, st->prefilter_tapset_old, st->prefilter_tapset,
2262 mode->window, overlap);
2263 if (LM!=0)
2264 comb_filter(out_mem[c]+mode->shortMdctSize, out_mem[c]+mode->shortMdctSize, st->prefilter_period, pitch_index, N-mode->shortMdctSize,
2265 st->prefilter_gain, gain1, st->prefilter_tapset, prefilter_tapset,
2266 mode->window, overlap);
2267 } while (++c<CC);
2268
2269 /* We reuse freq[] as scratch space for the de-emphasis */
2270 deemphasis(out_mem, (opus_val16*)pcm, N, CC, st->upsample, mode->preemph, st->preemph_memD);
2271 st->prefilter_period_old = st->prefilter_period;
2272 st->prefilter_gain_old = st->prefilter_gain;
2273 st->prefilter_tapset_old = st->prefilter_tapset;
2274 }
2275#endif
2276
2277 st->prefilter_period = pitch_index;
2278 st->prefilter_gain = gain1;
2279 st->prefilter_tapset = prefilter_tapset;
2280#ifdef RESYNTH
2281 if (LM!=0)
2282 {
2283 st->prefilter_period_old = st->prefilter_period;
2284 st->prefilter_gain_old = st->prefilter_gain;
2285 st->prefilter_tapset_old = st->prefilter_tapset;
2286 }
2287#endif
2288
2289 if (CC==2&&C==1) {
2290 OPUS_COPY(&oldBandE[nbEBands], oldBandE, nbEBands);
2291 }
2292
2293 if (!isTransient)
2294 {
2295 OPUS_COPY(oldLogE2, oldLogE, CC*nbEBands);
2296 OPUS_COPY(oldLogE, oldBandE, CC*nbEBands);
2297 } else {
2298 for (i=0;i<CC*nbEBands;i++)
2299 oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]);
2300 }
2301 /* In case start or end were to change */
2302 c=0; do
2303 {
2304 for (i=0;i<start;i++)
2305 {
2306 oldBandE[c*nbEBands+i]=0;
2307 oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
2308 }
2309 for (i=end;i<nbEBands;i++)
2310 {
2311 oldBandE[c*nbEBands+i]=0;
2312 oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT);
2313 }
2314 } while (++c<CC);
2315
2316 if (isTransient || transient_got_disabled)
2317 st->consec_transient++;
2318 else
2319 st->consec_transient=0;
2320 st->rng = enc->rng;
2321
2322 /* If there's any room left (can only happen for very high rates),
2323 it's already filled with zeros */
2324 ec_enc_done(enc);
2325
2326#ifdef CUSTOM_MODES
2327 if (st->signalling)
2328 nbCompressedBytes++;
2329#endif
2330
2331 RESTORE_STACK;
2332 if (ec_get_error(enc))
2333 return OPUS_INTERNAL_ERROR;
2334 else
2335 return nbCompressedBytes;
2336}
2337
2338
2339#ifdef CUSTOM_MODES
2340
2341#ifdef FIXED_POINT
2342int opus_custom_encode(CELTEncoder * OPUS_RESTRICT st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
2343{
2344 return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL);
2345}
2346
2347#ifndef DISABLE_FLOAT_API
2348int opus_custom_encode_float(CELTEncoder * OPUS_RESTRICT st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
2349{
2350 int j, ret, C, N;
2351 VARDECL(opus_int16, in);
2352 ALLOC_STACK;
2353
2354 if (pcm==NULL)
2355 return OPUS_BAD_ARG;
2356
2357 C = st->channels;
2358 N = frame_size;
2359 ALLOC(in, C*N, opus_int16);
2360
2361 for (j=0;j<C*N;j++)
2362 in[j] = FLOAT2INT16(pcm[j]);
2363
2364 ret=celt_encode_with_ec(st,in,frame_size,compressed,nbCompressedBytes, NULL);
2365#ifdef RESYNTH
2366 for (j=0;j<C*N;j++)
2367 ((float*)pcm)[j]=in[j]*(1.f/32768.f);
2368#endif
2369 RESTORE_STACK;
2370 return ret;
2371}
2372#endif /* DISABLE_FLOAT_API */
2373#else
2374
2375int opus_custom_encode(CELTEncoder * OPUS_RESTRICT st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
2376{
2377 int j, ret, C, N;
2378 VARDECL(celt_sig, in);
2379 ALLOC_STACK;
2380
2381 if (pcm==NULL)
2382 return OPUS_BAD_ARG;
2383
2384 C=st->channels;
2385 N=frame_size;
2386 ALLOC(in, C*N, celt_sig);
2387 for (j=0;j<C*N;j++) {
2388 in[j] = SCALEOUT(pcm[j]);
2389 }
2390
2391 ret = celt_encode_with_ec(st,in,frame_size,compressed,nbCompressedBytes, NULL);
2392#ifdef RESYNTH
2393 for (j=0;j<C*N;j++)
2394 ((opus_int16*)pcm)[j] = FLOAT2INT16(in[j]);
2395#endif
2396 RESTORE_STACK;
2397 return ret;
2398}
2399
2400int opus_custom_encode_float(CELTEncoder * OPUS_RESTRICT st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes)
2401{
2402 return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL);
2403}
2404
2405#endif
2406
2407#endif /* CUSTOM_MODES */
2408
2409int opus_custom_encoder_ctl(CELTEncoder * OPUS_RESTRICT st, int request, ...)
2410{
2411 va_list ap;
2412
2413 va_start(ap, request);
2414 switch (request)
2415 {
2416 case OPUS_SET_COMPLEXITY_REQUEST:
2417 {
2418 int value = va_arg(ap, opus_int32);
2419 if (value<0 || value>10)
2420 goto bad_arg;
2421 st->complexity = value;
2422 }
2423 break;
2424 case CELT_SET_START_BAND_REQUEST:
2425 {
2426 opus_int32 value = va_arg(ap, opus_int32);
2427 if (value<0 || value>=st->mode->nbEBands)
2428 goto bad_arg;
2429 st->start = value;
2430 }
2431 break;
2432 case CELT_SET_END_BAND_REQUEST:
2433 {
2434 opus_int32 value = va_arg(ap, opus_int32);
2435 if (value<1 || value>st->mode->nbEBands)
2436 goto bad_arg;
2437 st->end = value;
2438 }
2439 break;
2440 case CELT_SET_PREDICTION_REQUEST:
2441 {
2442 int value = va_arg(ap, opus_int32);
2443 if (value<0 || value>2)
2444 goto bad_arg;
2445 st->disable_pf = value<=1;
2446 st->force_intra = value==0;
2447 }
2448 break;
2449 case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
2450 {
2451 int value = va_arg(ap, opus_int32);
2452 if (value<0 || value>100)
2453 goto bad_arg;
2454 st->loss_rate = value;
2455 }
2456 break;
2457 case OPUS_SET_VBR_CONSTRAINT_REQUEST:
2458 {
2459 opus_int32 value = va_arg(ap, opus_int32);
2460 st->constrained_vbr = value;
2461 }
2462 break;
2463 case OPUS_SET_VBR_REQUEST:
2464 {
2465 opus_int32 value = va_arg(ap, opus_int32);
2466 st->vbr = value;
2467 }
2468 break;
2469 case OPUS_SET_BITRATE_REQUEST:
2470 {
2471 opus_int32 value = va_arg(ap, opus_int32);
2472 if (value<=500 && value!=OPUS_BITRATE_MAX)
2473 goto bad_arg;
2474 value = IMIN(value, 260000*st->channels);
2475 st->bitrate = value;
2476 }
2477 break;
2478 case CELT_SET_CHANNELS_REQUEST:
2479 {
2480 opus_int32 value = va_arg(ap, opus_int32);
2481 if (value<1 || value>2)
2482 goto bad_arg;
2483 st->stream_channels = value;
2484 }
2485 break;
2486 case OPUS_SET_LSB_DEPTH_REQUEST:
2487 {
2488 opus_int32 value = va_arg(ap, opus_int32);
2489 if (value<8 || value>24)
2490 goto bad_arg;
2491 st->lsb_depth=value;
2492 }
2493 break;
2494 case OPUS_GET_LSB_DEPTH_REQUEST:
2495 {
2496 opus_int32 *value = va_arg(ap, opus_int32*);
2497 *value=st->lsb_depth;
2498 }
2499 break;
2500 case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
2501 {
2502 opus_int32 value = va_arg(ap, opus_int32);
2503 if(value<0 || value>1)
2504 {
2505 goto bad_arg;
2506 }
2507 st->disable_inv = value;
2508 }
2509 break;
2510 case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
2511 {
2512 opus_int32 *value = va_arg(ap, opus_int32*);
2513 if (!value)
2514 {
2515 goto bad_arg;
2516 }
2517 *value = st->disable_inv;
2518 }
2519 break;
2520 case OPUS_RESET_STATE:
2521 {
2522 int i;
2523 opus_val16 *oldBandE, *oldLogE, *oldLogE2;
2524 oldBandE = (opus_val16*)(st->in_mem+st->channels*(st->mode->overlap+COMBFILTER_MAXPERIOD));
2525 oldLogE = oldBandE + st->channels*st->mode->nbEBands;
2526 oldLogE2 = oldLogE + st->channels*st->mode->nbEBands;
2527 OPUS_CLEAR((char*)&st->ENCODER_RESET_START,
2528 opus_custom_encoder_get_size(st->mode, st->channels)-
2529 ((char*)&st->ENCODER_RESET_START - (char*)st));
2530 for (i=0;i<st->channels*st->mode->nbEBands;i++)
2531 oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT);
2532 st->vbr_offset = 0;
2533 st->delayedIntra = 1;
2534 st->spread_decision = SPREAD_NORMAL;
2535 st->tonal_average = 256;
2536 st->hf_average = 0;
2537 st->tapset_decision = 0;
2538 }
2539 break;
2540#ifdef CUSTOM_MODES
2541 case CELT_SET_INPUT_CLIPPING_REQUEST:
2542 {
2543 opus_int32 value = va_arg(ap, opus_int32);
2544 st->clip = value;
2545 }
2546 break;
2547#endif
2548 case CELT_SET_SIGNALLING_REQUEST:
2549 {
2550 opus_int32 value = va_arg(ap, opus_int32);
2551 st->signalling = value;
2552 }
2553 break;
2554 case CELT_SET_ANALYSIS_REQUEST:
2555 {
2556 AnalysisInfo *info = va_arg(ap, AnalysisInfo *);
2557 if (info)
2558 OPUS_COPY(&st->analysis, info, 1);
2559 }
2560 break;
2561 case CELT_SET_SILK_INFO_REQUEST:
2562 {
2563 SILKInfo *info = va_arg(ap, SILKInfo *);
2564 if (info)
2565 OPUS_COPY(&st->silk_info, info, 1);
2566 }
2567 break;
2568 case CELT_GET_MODE_REQUEST:
2569 {
2570 const CELTMode ** value = va_arg(ap, const CELTMode**);
2571 if (value==0)
2572 goto bad_arg;
2573 *value=st->mode;
2574 }
2575 break;
2576 case OPUS_GET_FINAL_RANGE_REQUEST:
2577 {
2578 opus_uint32 * value = va_arg(ap, opus_uint32 *);
2579 if (value==0)
2580 goto bad_arg;
2581 *value=st->rng;
2582 }
2583 break;
2584 case OPUS_SET_LFE_REQUEST:
2585 {
2586 opus_int32 value = va_arg(ap, opus_int32);
2587 st->lfe = value;
2588 }
2589 break;
2590 case OPUS_SET_ENERGY_MASK_REQUEST:
2591 {
2592 opus_val16 *value = va_arg(ap, opus_val16*);
2593 st->energy_mask = value;
2594 }
2595 break;
2596 default:
2597 goto bad_request;
2598 }
2599 va_end(ap);
2600 return OPUS_OK;
2601bad_arg:
2602 va_end(ap);
2603 return OPUS_BAD_ARG;
2604bad_request:
2605 va_end(ap);
2606 return OPUS_UNIMPLEMENTED;
2607}
diff --git a/lib/rbcodec/codecs/libopus/celt/celt_lpc.c b/lib/rbcodec/codecs/libopus/celt/celt_lpc.c
index fa29d626ea..8ecb693ee9 100644
--- a/lib/rbcodec/codecs/libopus/celt/celt_lpc.c
+++ b/lib/rbcodec/codecs/libopus/celt/celt_lpc.c
@@ -49,8 +49,7 @@ int p
49 float *lpc = _lpc; 49 float *lpc = _lpc;
50#endif 50#endif
51 51
52 for (i = 0; i < p; i++) 52 OPUS_CLEAR(lpc, p);
53 lpc[i] = 0;
54 if (ac[0] != 0) 53 if (ac[0] != 0)
55 { 54 {
56 for (i = 0; i < p; i++) { 55 for (i = 0; i < p; i++) {
@@ -88,56 +87,42 @@ int p
88#endif 87#endif
89} 88}
90 89
91void celt_fir(const opus_val16 *_x, 90
91void celt_fir_c(
92 const opus_val16 *x,
92 const opus_val16 *num, 93 const opus_val16 *num,
93 opus_val16 *_y, 94 opus_val16 *y,
94 int N, 95 int N,
95 int ord, 96 int ord,
96 opus_val16 *mem) 97 int arch)
97{ 98{
98 int i,j; 99 int i,j;
99 VARDECL(opus_val16, rnum); 100 VARDECL(opus_val16, rnum);
100 VARDECL(opus_val16, x);
101 SAVE_STACK; 101 SAVE_STACK;
102 102 celt_assert(x != y);
103 ALLOC(rnum, ord, opus_val16); 103 ALLOC(rnum, ord, opus_val16);
104 ALLOC(x, N+ord, opus_val16);
105 for(i=0;i<ord;i++) 104 for(i=0;i<ord;i++)
106 rnum[i] = num[ord-i-1]; 105 rnum[i] = num[ord-i-1];
107 for(i=0;i<ord;i++)
108 x[i] = mem[ord-i-1];
109 for (i=0;i<N;i++)
110 x[i+ord]=_x[i];
111 for(i=0;i<ord;i++)
112 mem[i] = _x[N-i-1];
113#ifdef SMALL_FOOTPRINT
114 for (i=0;i<N;i++)
115 {
116 opus_val32 sum = SHL32(EXTEND32(_x[i]), SIG_SHIFT);
117 for (j=0;j<ord;j++)
118 {
119 sum = MAC16_16(sum,rnum[j],x[i+j]);
120 }
121 _y[i] = SATURATE16(PSHR32(sum, SIG_SHIFT));
122 }
123#else
124 for (i=0;i<N-3;i+=4) 106 for (i=0;i<N-3;i+=4)
125 { 107 {
126 opus_val32 sum[4]={0,0,0,0}; 108 opus_val32 sum[4];
127 xcorr_kernel(rnum, x+i, sum, ord); 109 sum[0] = SHL32(EXTEND32(x[i ]), SIG_SHIFT);
128 _y[i ] = SATURATE16(ADD32(EXTEND32(_x[i ]), PSHR32(sum[0], SIG_SHIFT))); 110 sum[1] = SHL32(EXTEND32(x[i+1]), SIG_SHIFT);
129 _y[i+1] = SATURATE16(ADD32(EXTEND32(_x[i+1]), PSHR32(sum[1], SIG_SHIFT))); 111 sum[2] = SHL32(EXTEND32(x[i+2]), SIG_SHIFT);
130 _y[i+2] = SATURATE16(ADD32(EXTEND32(_x[i+2]), PSHR32(sum[2], SIG_SHIFT))); 112 sum[3] = SHL32(EXTEND32(x[i+3]), SIG_SHIFT);
131 _y[i+3] = SATURATE16(ADD32(EXTEND32(_x[i+3]), PSHR32(sum[3], SIG_SHIFT))); 113 xcorr_kernel(rnum, x+i-ord, sum, ord, arch);
114 y[i ] = ROUND16(sum[0], SIG_SHIFT);
115 y[i+1] = ROUND16(sum[1], SIG_SHIFT);
116 y[i+2] = ROUND16(sum[2], SIG_SHIFT);
117 y[i+3] = ROUND16(sum[3], SIG_SHIFT);
132 } 118 }
133 for (;i<N;i++) 119 for (;i<N;i++)
134 { 120 {
135 opus_val32 sum = 0; 121 opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);
136 for (j=0;j<ord;j++) 122 for (j=0;j<ord;j++)
137 sum = MAC16_16(sum,rnum[j],x[i+j]); 123 sum = MAC16_16(sum,rnum[j],x[i+j-ord]);
138 _y[i] = SATURATE16(ADD32(EXTEND32(_x[i]), PSHR32(sum, SIG_SHIFT))); 124 y[i] = ROUND16(sum, SIG_SHIFT);
139 } 125 }
140#endif
141 RESTORE_STACK; 126 RESTORE_STACK;
142} 127}
143 128
@@ -146,10 +131,12 @@ void celt_iir(const opus_val32 *_x,
146 opus_val32 *_y, 131 opus_val32 *_y,
147 int N, 132 int N,
148 int ord, 133 int ord,
149 opus_val16 *mem) 134 opus_val16 *mem,
135 int arch)
150{ 136{
151#ifdef SMALL_FOOTPRINT 137#ifdef SMALL_FOOTPRINT
152 int i,j; 138 int i,j;
139 (void)arch;
153 for (i=0;i<N;i++) 140 for (i=0;i<N;i++)
154 { 141 {
155 opus_val32 sum = _x[i]; 142 opus_val32 sum = _x[i];
@@ -161,7 +148,7 @@ void celt_iir(const opus_val32 *_x,
161 { 148 {
162 mem[j]=mem[j-1]; 149 mem[j]=mem[j-1];
163 } 150 }
164 mem[0] = ROUND16(sum,SIG_SHIFT); 151 mem[0] = SROUND16(sum, SIG_SHIFT);
165 _y[i] = sum; 152 _y[i] = sum;
166 } 153 }
167#else 154#else
@@ -187,23 +174,23 @@ void celt_iir(const opus_val32 *_x,
187 sum[1]=_x[i+1]; 174 sum[1]=_x[i+1];
188 sum[2]=_x[i+2]; 175 sum[2]=_x[i+2];
189 sum[3]=_x[i+3]; 176 sum[3]=_x[i+3];
190 xcorr_kernel(rden, y+i, sum, ord); 177 xcorr_kernel(rden, y+i, sum, ord, arch);
191 178
192 /* Patch up the result to compensate for the fact that this is an IIR */ 179 /* Patch up the result to compensate for the fact that this is an IIR */
193 y[i+ord ] = -ROUND16(sum[0],SIG_SHIFT); 180 y[i+ord ] = -SROUND16(sum[0],SIG_SHIFT);
194 _y[i ] = sum[0]; 181 _y[i ] = sum[0];
195 sum[1] = MAC16_16(sum[1], y[i+ord ], den[0]); 182 sum[1] = MAC16_16(sum[1], y[i+ord ], den[0]);
196 y[i+ord+1] = -ROUND16(sum[1],SIG_SHIFT); 183 y[i+ord+1] = -SROUND16(sum[1],SIG_SHIFT);
197 _y[i+1] = sum[1]; 184 _y[i+1] = sum[1];
198 sum[2] = MAC16_16(sum[2], y[i+ord+1], den[0]); 185 sum[2] = MAC16_16(sum[2], y[i+ord+1], den[0]);
199 sum[2] = MAC16_16(sum[2], y[i+ord ], den[1]); 186 sum[2] = MAC16_16(sum[2], y[i+ord ], den[1]);
200 y[i+ord+2] = -ROUND16(sum[2],SIG_SHIFT); 187 y[i+ord+2] = -SROUND16(sum[2],SIG_SHIFT);
201 _y[i+2] = sum[2]; 188 _y[i+2] = sum[2];
202 189
203 sum[3] = MAC16_16(sum[3], y[i+ord+2], den[0]); 190 sum[3] = MAC16_16(sum[3], y[i+ord+2], den[0]);
204 sum[3] = MAC16_16(sum[3], y[i+ord+1], den[1]); 191 sum[3] = MAC16_16(sum[3], y[i+ord+1], den[1]);
205 sum[3] = MAC16_16(sum[3], y[i+ord ], den[2]); 192 sum[3] = MAC16_16(sum[3], y[i+ord ], den[2]);
206 y[i+ord+3] = -ROUND16(sum[3],SIG_SHIFT); 193 y[i+ord+3] = -SROUND16(sum[3],SIG_SHIFT);
207 _y[i+3] = sum[3]; 194 _y[i+3] = sum[3];
208 } 195 }
209 for (;i<N;i++) 196 for (;i<N;i++)
@@ -211,7 +198,7 @@ void celt_iir(const opus_val32 *_x,
211 opus_val32 sum = _x[i]; 198 opus_val32 sum = _x[i];
212 for (j=0;j<ord;j++) 199 for (j=0;j<ord;j++)
213 sum -= MULT16_16(rden[j],y[i+j]); 200 sum -= MULT16_16(rden[j],y[i+j]);
214 y[i+ord] = ROUND16(sum,SIG_SHIFT); 201 y[i+ord] = SROUND16(sum,SIG_SHIFT);
215 _y[i] = sum; 202 _y[i] = sum;
216 } 203 }
217 for(i=0;i<ord;i++) 204 for(i=0;i<ord;i++)
diff --git a/lib/rbcodec/codecs/libopus/celt/celt_lpc.h b/lib/rbcodec/codecs/libopus/celt/celt_lpc.h
index dc2a0a3d26..a4c5fd6ea5 100644
--- a/lib/rbcodec/codecs/libopus/celt/celt_lpc.h
+++ b/lib/rbcodec/codecs/libopus/celt/celt_lpc.h
@@ -29,24 +29,36 @@
29#define PLC_H 29#define PLC_H
30 30
31#include "arch.h" 31#include "arch.h"
32#include "cpu_support.h"
33
34#if defined(OPUS_X86_MAY_HAVE_SSE4_1)
35#include "x86/celt_lpc_sse.h"
36#endif
32 37
33#define LPC_ORDER 24 38#define LPC_ORDER 24
34 39
35void _celt_lpc(opus_val16 *_lpc, const opus_val32 *ac, int p); 40void _celt_lpc(opus_val16 *_lpc, const opus_val32 *ac, int p);
36 41
37void celt_fir(const opus_val16 *x, 42void celt_fir_c(
43 const opus_val16 *x,
38 const opus_val16 *num, 44 const opus_val16 *num,
39 opus_val16 *y, 45 opus_val16 *y,
40 int N, 46 int N,
41 int ord, 47 int ord,
42 opus_val16 *mem); 48 int arch);
49
50#if !defined(OVERRIDE_CELT_FIR)
51#define celt_fir(x, num, y, N, ord, arch) \
52 (celt_fir_c(x, num, y, N, ord, arch))
53#endif
43 54
44void celt_iir(const opus_val32 *x, 55void celt_iir(const opus_val32 *x,
45 const opus_val16 *den, 56 const opus_val16 *den,
46 opus_val32 *y, 57 opus_val32 *y,
47 int N, 58 int N,
48 int ord, 59 int ord,
49 opus_val16 *mem); 60 opus_val16 *mem,
61 int arch);
50 62
51int _celt_autocorr(const opus_val16 *x, opus_val32 *ac, 63int _celt_autocorr(const opus_val16 *x, opus_val32 *ac,
52 const opus_val16 *window, int overlap, int lag, int n, int arch); 64 const opus_val16 *window, int overlap, int lag, int n, int arch);
diff --git a/lib/rbcodec/codecs/libopus/celt/cpu_support.h b/lib/rbcodec/codecs/libopus/celt/cpu_support.h
index d68dbe62c5..68fc60678f 100644
--- a/lib/rbcodec/codecs/libopus/celt/cpu_support.h
+++ b/lib/rbcodec/codecs/libopus/celt/cpu_support.h
@@ -31,7 +31,8 @@
31#include "opus_types.h" 31#include "opus_types.h"
32#include "opus_defines.h" 32#include "opus_defines.h"
33 33
34#if defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_ASM) 34#if defined(OPUS_HAVE_RTCD) && \
35 (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
35#include "arm/armcpu.h" 36#include "arm/armcpu.h"
36 37
37/* We currently support 4 ARM variants: 38/* We currently support 4 ARM variants:
@@ -42,6 +43,22 @@
42 */ 43 */
43#define OPUS_ARCHMASK 3 44#define OPUS_ARCHMASK 3
44 45
46#elif (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(OPUS_X86_PRESUME_SSE)) || \
47 (defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(OPUS_X86_PRESUME_SSE2)) || \
48 (defined(OPUS_X86_MAY_HAVE_SSE4_1) && !defined(OPUS_X86_PRESUME_SSE4_1)) || \
49 (defined(OPUS_X86_MAY_HAVE_AVX) && !defined(OPUS_X86_PRESUME_AVX))
50
51#include "x86/x86cpu.h"
52/* We currently support 5 x86 variants:
53 * arch[0] -> non-sse
54 * arch[1] -> sse
55 * arch[2] -> sse2
56 * arch[3] -> sse4.1
57 * arch[4] -> avx
58 */
59#define OPUS_ARCHMASK 7
60int opus_select_arch(void);
61
45#else 62#else
46#define OPUS_ARCHMASK 0 63#define OPUS_ARCHMASK 0
47 64
@@ -50,5 +67,4 @@ static OPUS_INLINE int opus_select_arch(void)
50 return 0; 67 return 0;
51} 68}
52#endif 69#endif
53
54#endif 70#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/cwrs.c b/lib/rbcodec/codecs/libopus/celt/cwrs.c
index 031a875995..a552e4f0fb 100644
--- a/lib/rbcodec/codecs/libopus/celt/cwrs.c
+++ b/lib/rbcodec/codecs/libopus/celt/cwrs.c
@@ -74,7 +74,7 @@ int log2_frac(opus_uint32 val, int frac)
74/*Although derived separately, the pulse vector coding scheme is equivalent to 74/*Although derived separately, the pulse vector coding scheme is equivalent to
75 a Pyramid Vector Quantizer \cite{Fis86}. 75 a Pyramid Vector Quantizer \cite{Fis86}.
76 Some additional notes about an early version appear at 76 Some additional notes about an early version appear at
77 http://people.xiph.org/~tterribe/notes/cwrs.html, but the codebook ordering 77 https://people.xiph.org/~tterribe/notes/cwrs.html, but the codebook ordering
78 and the definitions of some terms have evolved since that was written. 78 and the definitions of some terms have evolved since that was written.
79 79
80 The conversion from a pulse vector to an integer index (encoding) and back 80 The conversion from a pulse vector to an integer index (encoding) and back
@@ -210,7 +210,7 @@ int log2_frac(opus_uint32 val, int frac)
210#if defined(CUSTOM_MODES) 210#if defined(CUSTOM_MODES)
211static const opus_uint32 CELT_PVQ_U_DATA[1488]={ 211static const opus_uint32 CELT_PVQ_U_DATA[1488]={
212#else 212#else
213static const opus_uint32 CELT_PVQ_U_DATA[1272] ICONST_ATTR ={ 213static const opus_uint32 CELT_PVQ_U_DATA[1272]={
214#endif 214#endif
215 /*N=0, K=0...176:*/ 215 /*N=0, K=0...176:*/
216 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, 216 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,
@@ -418,7 +418,7 @@ static const opus_uint32 *const CELT_PVQ_U_ROW[15]={
418 CELT_PVQ_U_DATA+1464,CELT_PVQ_U_DATA+1470,CELT_PVQ_U_DATA+1473 418 CELT_PVQ_U_DATA+1464,CELT_PVQ_U_DATA+1470,CELT_PVQ_U_DATA+1473
419}; 419};
420#else 420#else
421static const opus_uint32 *const CELT_PVQ_U_ROW[15] ICONST_ATTR ={ 421static const opus_uint32 *const CELT_PVQ_U_ROW[15]={
422 CELT_PVQ_U_DATA+ 0,CELT_PVQ_U_DATA+ 176,CELT_PVQ_U_DATA+ 351, 422 CELT_PVQ_U_DATA+ 0,CELT_PVQ_U_DATA+ 176,CELT_PVQ_U_DATA+ 351,
423 CELT_PVQ_U_DATA+ 525,CELT_PVQ_U_DATA+ 698,CELT_PVQ_U_DATA+ 870, 423 CELT_PVQ_U_DATA+ 525,CELT_PVQ_U_DATA+ 698,CELT_PVQ_U_DATA+ 870,
424 CELT_PVQ_U_DATA+1041,CELT_PVQ_U_DATA+1131,CELT_PVQ_U_DATA+1178, 424 CELT_PVQ_U_DATA+1041,CELT_PVQ_U_DATA+1131,CELT_PVQ_U_DATA+1178,
@@ -482,7 +482,7 @@ static opus_val32 cwrsi(int _n,int _k,opus_uint32 _i,int *_y){
482 k0=_k; 482 k0=_k;
483 q=row[_n]; 483 q=row[_n];
484 if(q>_i){ 484 if(q>_i){
485 celt_assert(p>q); 485 celt_sig_assert(p>q);
486 _k=_n; 486 _k=_n;
487 do p=CELT_PVQ_U_ROW[--_k][_n]; 487 do p=CELT_PVQ_U_ROW[--_k][_n];
488 while(p>_i); 488 while(p>_i);
diff --git a/lib/rbcodec/codecs/libopus/celt/dump_modes/Makefile b/lib/rbcodec/codecs/libopus/celt/dump_modes/Makefile
new file mode 100644
index 0000000000..93f599fb5b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/dump_modes/Makefile
@@ -0,0 +1,32 @@
1
2CFLAGS=-O2 -Wall -Wextra -DHAVE_CONFIG_H
3INCLUDES=-I. -I../ -I../.. -I../../include
4
5SOURCES = dump_modes.c \
6 ../modes.c \
7 ../cwrs.c \
8 ../rate.c \
9 ../entcode.c \
10 ../entenc.c \
11 ../entdec.c \
12 ../mathops.c \
13 ../mdct.c \
14 ../kiss_fft.c
15
16ifdef HAVE_ARM_NE10
17CC = gcc
18CFLAGS += -mfpu=neon
19INCLUDES += -I$(NE10_INCDIR) -DHAVE_ARM_NE10 -DOPUS_ARM_PRESUME_NEON_INTR
20LIBS = -L$(NE10_LIBDIR) -lNE10
21SOURCES += ../arm/celt_ne10_fft.c \
22 dump_modes_arm_ne10.c \
23 ../arm/armcpu.c
24endif
25
26all: dump_modes
27
28dump_modes:
29 $(PREFIX)$(CC) $(CFLAGS) $(INCLUDES) -DCUSTOM_MODES_ONLY -DCUSTOM_MODES $(SOURCES) -o $@ $(LIBS) -lm
30
31clean:
32 rm -f dump_modes
diff --git a/lib/rbcodec/codecs/libopus/celt/dump_modes/dump_modes.c b/lib/rbcodec/codecs/libopus/celt/dump_modes/dump_modes.c
new file mode 100644
index 0000000000..9105a5344e
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/dump_modes/dump_modes.c
@@ -0,0 +1,353 @@
1/* Copyright (c) 2008 CSIRO
2 Copyright (c) 2008-2009 Xiph.Org Foundation
3 Written by Jean-Marc Valin */
4/*
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include <stdlib.h>
34#include <stdio.h>
35#include "modes.h"
36#include "celt.h"
37#include "rate.h"
38#include "dump_modes_arch.h"
39
40#define INT16 "%d"
41#define INT32 "%d"
42#define FLOAT "%#0.8gf"
43
44#ifdef FIXED_POINT
45#define WORD16 INT16
46#define WORD32 INT32
47#else
48#define WORD16 FLOAT
49#define WORD32 FLOAT
50#endif
51
52void dump_modes(FILE *file, CELTMode **modes, int nb_modes)
53{
54 int i, j, k;
55 int mdct_twiddles_size;
56 fprintf(file, "/* The contents of this file was automatically generated by dump_modes.c\n");
57 fprintf(file, " with arguments:");
58 for (i=0;i<nb_modes;i++)
59 {
60 CELTMode *mode = modes[i];
61 fprintf(file, " %d %d",mode->Fs,mode->shortMdctSize*mode->nbShortMdcts);
62 }
63 fprintf(file, "\n It contains static definitions for some pre-defined modes. */\n");
64 fprintf(file, "#include \"modes.h\"\n");
65 fprintf(file, "#include \"rate.h\"\n");
66 fprintf(file, "\n#ifdef HAVE_ARM_NE10\n");
67 fprintf(file, "#define OVERRIDE_FFT 1\n");
68 fprintf(file, "#include \"%s\"\n", ARM_NE10_ARCH_FILE_NAME);
69 fprintf(file, "#endif\n");
70
71 fprintf(file, "\n");
72
73 for (i=0;i<nb_modes;i++)
74 {
75 CELTMode *mode = modes[i];
76 int mdctSize;
77 int standard, framerate;
78
79 mdctSize = mode->shortMdctSize*mode->nbShortMdcts;
80 standard = (mode->Fs == 400*(opus_int32)mode->shortMdctSize);
81 framerate = mode->Fs/mode->shortMdctSize;
82
83 if (!standard)
84 {
85 fprintf(file, "#ifndef DEF_EBANDS%d_%d\n", mode->Fs, mdctSize);
86 fprintf(file, "#define DEF_EBANDS%d_%d\n", mode->Fs, mdctSize);
87 fprintf (file, "static const opus_int16 eBands%d_%d[%d] = {\n", mode->Fs, mdctSize, mode->nbEBands+2);
88 for (j=0;j<mode->nbEBands+2;j++)
89 fprintf (file, "%d, ", mode->eBands[j]);
90 fprintf (file, "};\n");
91 fprintf(file, "#endif\n");
92 fprintf(file, "\n");
93 }
94
95 fprintf(file, "#ifndef DEF_WINDOW%d\n", mode->overlap);
96 fprintf(file, "#define DEF_WINDOW%d\n", mode->overlap);
97 fprintf (file, "static const opus_val16 window%d[%d] = {\n", mode->overlap, mode->overlap);
98 for (j=0;j<mode->overlap;j++)
99 fprintf (file, WORD16 ",%c", mode->window[j],(j+6)%5==0?'\n':' ');
100 fprintf (file, "};\n");
101 fprintf(file, "#endif\n");
102 fprintf(file, "\n");
103
104 if (!standard)
105 {
106 fprintf(file, "#ifndef DEF_ALLOC_VECTORS%d_%d\n", mode->Fs, mdctSize);
107 fprintf(file, "#define DEF_ALLOC_VECTORS%d_%d\n", mode->Fs, mdctSize);
108 fprintf (file, "static const unsigned char allocVectors%d_%d[%d] = {\n", mode->Fs, mdctSize, mode->nbEBands*mode->nbAllocVectors);
109 for (j=0;j<mode->nbAllocVectors;j++)
110 {
111 for (k=0;k<mode->nbEBands;k++)
112 fprintf (file, "%2d, ", mode->allocVectors[j*mode->nbEBands+k]);
113 fprintf (file, "\n");
114 }
115 fprintf (file, "};\n");
116 fprintf(file, "#endif\n");
117 fprintf(file, "\n");
118 }
119
120 fprintf(file, "#ifndef DEF_LOGN%d\n", framerate);
121 fprintf(file, "#define DEF_LOGN%d\n", framerate);
122 fprintf (file, "static const opus_int16 logN%d[%d] = {\n", framerate, mode->nbEBands);
123 for (j=0;j<mode->nbEBands;j++)
124 fprintf (file, "%d, ", mode->logN[j]);
125 fprintf (file, "};\n");
126 fprintf(file, "#endif\n");
127 fprintf(file, "\n");
128
129 /* Pulse cache */
130 fprintf(file, "#ifndef DEF_PULSE_CACHE%d\n", mode->Fs/mdctSize);
131 fprintf(file, "#define DEF_PULSE_CACHE%d\n", mode->Fs/mdctSize);
132 fprintf (file, "static const opus_int16 cache_index%d[%d] = {\n", mode->Fs/mdctSize, (mode->maxLM+2)*mode->nbEBands);
133 for (j=0;j<mode->nbEBands*(mode->maxLM+2);j++)
134 fprintf (file, "%d,%c", mode->cache.index[j],(j+16)%15==0?'\n':' ');
135 fprintf (file, "};\n");
136 fprintf (file, "static const unsigned char cache_bits%d[%d] = {\n", mode->Fs/mdctSize, mode->cache.size);
137 for (j=0;j<mode->cache.size;j++)
138 fprintf (file, "%d,%c", mode->cache.bits[j],(j+16)%15==0?'\n':' ');
139 fprintf (file, "};\n");
140 fprintf (file, "static const unsigned char cache_caps%d[%d] = {\n", mode->Fs/mdctSize, (mode->maxLM+1)*2*mode->nbEBands);
141 for (j=0;j<(mode->maxLM+1)*2*mode->nbEBands;j++)
142 fprintf (file, "%d,%c", mode->cache.caps[j],(j+16)%15==0?'\n':' ');
143 fprintf (file, "};\n");
144
145 fprintf(file, "#endif\n");
146 fprintf(file, "\n");
147
148 /* FFT twiddles */
149 fprintf(file, "#ifndef FFT_TWIDDLES%d_%d\n", mode->Fs, mdctSize);
150 fprintf(file, "#define FFT_TWIDDLES%d_%d\n", mode->Fs, mdctSize);
151 fprintf (file, "static const kiss_twiddle_cpx fft_twiddles%d_%d[%d] = {\n",
152 mode->Fs, mdctSize, mode->mdct.kfft[0]->nfft);
153 for (j=0;j<mode->mdct.kfft[0]->nfft;j++)
154 fprintf (file, "{" WORD16 ", " WORD16 "},%c", mode->mdct.kfft[0]->twiddles[j].r, mode->mdct.kfft[0]->twiddles[j].i,(j+3)%2==0?'\n':' ');
155 fprintf (file, "};\n");
156
157#ifdef OVERRIDE_FFT
158 dump_mode_arch(mode);
159#endif
160 /* FFT Bitrev tables */
161 for (k=0;k<=mode->mdct.maxshift;k++)
162 {
163 fprintf(file, "#ifndef FFT_BITREV%d\n", mode->mdct.kfft[k]->nfft);
164 fprintf(file, "#define FFT_BITREV%d\n", mode->mdct.kfft[k]->nfft);
165 fprintf (file, "static const opus_int16 fft_bitrev%d[%d] = {\n",
166 mode->mdct.kfft[k]->nfft, mode->mdct.kfft[k]->nfft);
167 for (j=0;j<mode->mdct.kfft[k]->nfft;j++)
168 fprintf (file, "%d,%c", mode->mdct.kfft[k]->bitrev[j],(j+16)%15==0?'\n':' ');
169 fprintf (file, "};\n");
170
171 fprintf(file, "#endif\n");
172 fprintf(file, "\n");
173 }
174
175 /* FFT States */
176 for (k=0;k<=mode->mdct.maxshift;k++)
177 {
178 fprintf(file, "#ifndef FFT_STATE%d_%d_%d\n", mode->Fs, mdctSize, k);
179 fprintf(file, "#define FFT_STATE%d_%d_%d\n", mode->Fs, mdctSize, k);
180 fprintf (file, "static const kiss_fft_state fft_state%d_%d_%d = {\n",
181 mode->Fs, mdctSize, k);
182 fprintf (file, "%d, /* nfft */\n", mode->mdct.kfft[k]->nfft);
183 fprintf (file, WORD16 ", /* scale */\n", mode->mdct.kfft[k]->scale);
184#ifdef FIXED_POINT
185 fprintf (file, "%d, /* scale_shift */\n", mode->mdct.kfft[k]->scale_shift);
186#endif
187 fprintf (file, "%d, /* shift */\n", mode->mdct.kfft[k]->shift);
188 fprintf (file, "{");
189 for (j=0;j<2*MAXFACTORS;j++)
190 fprintf (file, "%d, ", mode->mdct.kfft[k]->factors[j]);
191 fprintf (file, "}, /* factors */\n");
192 fprintf (file, "fft_bitrev%d, /* bitrev */\n", mode->mdct.kfft[k]->nfft);
193 fprintf (file, "fft_twiddles%d_%d, /* bitrev */\n", mode->Fs, mdctSize);
194
195 fprintf (file, "#ifdef OVERRIDE_FFT\n");
196 fprintf (file, "(arch_fft_state *)&cfg_arch_%d,\n", mode->mdct.kfft[k]->nfft);
197 fprintf (file, "#else\n");
198 fprintf (file, "NULL,\n");
199 fprintf(file, "#endif\n");
200
201 fprintf (file, "};\n");
202
203 fprintf(file, "#endif\n");
204 fprintf(file, "\n");
205 }
206
207 fprintf(file, "#endif\n");
208 fprintf(file, "\n");
209
210 /* MDCT twiddles */
211 mdct_twiddles_size = mode->mdct.n-(mode->mdct.n/2>>mode->mdct.maxshift);
212 fprintf(file, "#ifndef MDCT_TWIDDLES%d\n", mdctSize);
213 fprintf(file, "#define MDCT_TWIDDLES%d\n", mdctSize);
214 fprintf (file, "static const opus_val16 mdct_twiddles%d[%d] = {\n",
215 mdctSize, mdct_twiddles_size);
216 for (j=0;j<mdct_twiddles_size;j++)
217 fprintf (file, WORD16 ",%c", mode->mdct.trig[j],(j+6)%5==0?'\n':' ');
218 fprintf (file, "};\n");
219
220 fprintf(file, "#endif\n");
221 fprintf(file, "\n");
222
223
224 /* Print the actual mode data */
225 fprintf(file, "static const CELTMode mode%d_%d_%d = {\n", mode->Fs, mdctSize, mode->overlap);
226 fprintf(file, INT32 ", /* Fs */\n", mode->Fs);
227 fprintf(file, "%d, /* overlap */\n", mode->overlap);
228 fprintf(file, "%d, /* nbEBands */\n", mode->nbEBands);
229 fprintf(file, "%d, /* effEBands */\n", mode->effEBands);
230 fprintf(file, "{");
231 for (j=0;j<4;j++)
232 fprintf(file, WORD16 ", ", mode->preemph[j]);
233 fprintf(file, "}, /* preemph */\n");
234 if (standard)
235 fprintf(file, "eband5ms, /* eBands */\n");
236 else
237 fprintf(file, "eBands%d_%d, /* eBands */\n", mode->Fs, mdctSize);
238
239 fprintf(file, "%d, /* maxLM */\n", mode->maxLM);
240 fprintf(file, "%d, /* nbShortMdcts */\n", mode->nbShortMdcts);
241 fprintf(file, "%d, /* shortMdctSize */\n", mode->shortMdctSize);
242
243 fprintf(file, "%d, /* nbAllocVectors */\n", mode->nbAllocVectors);
244 if (standard)
245 fprintf(file, "band_allocation, /* allocVectors */\n");
246 else
247 fprintf(file, "allocVectors%d_%d, /* allocVectors */\n", mode->Fs, mdctSize);
248
249 fprintf(file, "logN%d, /* logN */\n", framerate);
250 fprintf(file, "window%d, /* window */\n", mode->overlap);
251 fprintf(file, "{%d, %d, {", mode->mdct.n, mode->mdct.maxshift);
252 for (k=0;k<=mode->mdct.maxshift;k++)
253 fprintf(file, "&fft_state%d_%d_%d, ", mode->Fs, mdctSize, k);
254 fprintf (file, "}, mdct_twiddles%d}, /* mdct */\n", mdctSize);
255
256 fprintf(file, "{%d, cache_index%d, cache_bits%d, cache_caps%d}, /* cache */\n",
257 mode->cache.size, mode->Fs/mdctSize, mode->Fs/mdctSize, mode->Fs/mdctSize);
258 fprintf(file, "};\n");
259 }
260 fprintf(file, "\n");
261 fprintf(file, "/* List of all the available modes */\n");
262 fprintf(file, "#define TOTAL_MODES %d\n", nb_modes);
263 fprintf(file, "static const CELTMode * const static_mode_list[TOTAL_MODES] = {\n");
264 for (i=0;i<nb_modes;i++)
265 {
266 CELTMode *mode = modes[i];
267 int mdctSize;
268 mdctSize = mode->shortMdctSize*mode->nbShortMdcts;
269 fprintf(file, "&mode%d_%d_%d,\n", mode->Fs, mdctSize, mode->overlap);
270 }
271 fprintf(file, "};\n");
272}
273
274void dump_header(FILE *file, CELTMode **modes, int nb_modes)
275{
276 int i;
277 int channels = 0;
278 int frame_size = 0;
279 int overlap = 0;
280 fprintf (file, "/* This header file is generated automatically*/\n");
281 for (i=0;i<nb_modes;i++)
282 {
283 CELTMode *mode = modes[i];
284 if (frame_size==0)
285 frame_size = mode->shortMdctSize*mode->nbShortMdcts;
286 else if (frame_size != mode->shortMdctSize*mode->nbShortMdcts)
287 frame_size = -1;
288 if (overlap==0)
289 overlap = mode->overlap;
290 else if (overlap != mode->overlap)
291 overlap = -1;
292 }
293 if (channels>0)
294 {
295 fprintf (file, "#define CHANNELS(mode) %d\n", channels);
296 if (channels==1)
297 fprintf (file, "#define DISABLE_STEREO\n");
298 }
299 if (frame_size>0)
300 {
301 fprintf (file, "#define FRAMESIZE(mode) %d\n", frame_size);
302 }
303 if (overlap>0)
304 {
305 fprintf (file, "#define OVERLAP(mode) %d\n", overlap);
306 }
307}
308
309#ifdef FIXED_POINT
310#define BASENAME "static_modes_fixed"
311#else
312#define BASENAME "static_modes_float"
313#endif
314
315int main(int argc, char **argv)
316{
317 int i, nb;
318 FILE *file;
319 CELTMode **m;
320 if (argc%2 != 1 || argc<3)
321 {
322 fprintf (stderr, "Usage: %s rate frame_size [rate frame_size] [rate frame_size]...\n",argv[0]);
323 return 1;
324 }
325 nb = (argc-1)/2;
326 m = malloc(nb*sizeof(CELTMode*));
327 for (i=0;i<nb;i++)
328 {
329 int Fs, frame;
330 Fs = atoi(argv[2*i+1]);
331 frame = atoi(argv[2*i+2]);
332 m[i] = opus_custom_mode_create(Fs, frame, NULL);
333 if (m[i]==NULL)
334 {
335 fprintf(stderr,"Error creating mode with Fs=%s, frame_size=%s\n",
336 argv[2*i+1],argv[2*i+2]);
337 return EXIT_FAILURE;
338 }
339 }
340 file = fopen(BASENAME ".h", "w");
341#ifdef OVERRIDE_FFT
342 dump_modes_arch_init(m, nb);
343#endif
344 dump_modes(file, m, nb);
345 fclose(file);
346#ifdef OVERRIDE_FFT
347 dump_modes_arch_finalize();
348#endif
349 for (i=0;i<nb;i++)
350 opus_custom_mode_destroy(m[i]);
351 free(m);
352 return 0;
353}
diff --git a/lib/rbcodec/codecs/libopus/celt/dump_modes/dump_modes_arch.h b/lib/rbcodec/codecs/libopus/celt/dump_modes/dump_modes_arch.h
new file mode 100644
index 0000000000..cc0d4be1ec
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/dump_modes/dump_modes_arch.h
@@ -0,0 +1,45 @@
1/* Copyright (c) 2015 Xiph.Org Foundation
2 Written by Viswanath Puttagunta */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifndef DUMP_MODE_ARCH_H
29#define DUMP_MODE_ARCH_H
30
31void dump_modes_arch_init();
32void dump_mode_arch(CELTMode *mode);
33void dump_modes_arch_finalize();
34
35#if !defined(FIXED_POINT)
36#define ARM_NE10_ARCH_FILE_NAME "static_modes_float_arm_ne10.h"
37#else
38#define ARM_NE10_ARCH_FILE_NAME "static_modes_fixed_arm_ne10.h"
39#endif
40
41#if defined(HAVE_ARM_NE10)
42#define OVERRIDE_FFT (1)
43#endif
44
45#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/dump_modes/dump_modes_arm_ne10.c b/lib/rbcodec/codecs/libopus/celt/dump_modes/dump_modes_arm_ne10.c
new file mode 100644
index 0000000000..828e7b9fff
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/dump_modes/dump_modes_arm_ne10.c
@@ -0,0 +1,152 @@
1/* Copyright (c) 2015 Xiph.Org Foundation
2 Written by Viswanath Puttagunta */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#if defined(HAVE_CONFIG_H)
29# include "config.h"
30#endif
31
32#include <stdio.h>
33#include <stdlib.h>
34#include "modes.h"
35#include "dump_modes_arch.h"
36#include <NE10_dsp.h>
37
38#if !defined(FIXED_POINT)
39# define NE10_FFT_CFG_TYPE_T ne10_fft_cfg_float32_t
40# define NE10_FFT_CPX_TYPE_T_STR "ne10_fft_cpx_float32_t"
41# define NE10_FFT_STATE_TYPE_T_STR "ne10_fft_state_float32_t"
42#else
43# define NE10_FFT_CFG_TYPE_T ne10_fft_cfg_int32_t
44# define NE10_FFT_CPX_TYPE_T_STR "ne10_fft_cpx_int32_t"
45# define NE10_FFT_STATE_TYPE_T_STR "ne10_fft_state_int32_t"
46#endif
47
48static FILE *file;
49
50void dump_modes_arch_init(CELTMode **modes, int nb_modes)
51{
52 int i;
53
54 file = fopen(ARM_NE10_ARCH_FILE_NAME, "w");
55 fprintf(file, "/* The contents of this file was automatically generated by\n");
56 fprintf(file, " * dump_mode_arm_ne10.c with arguments:");
57 for (i=0;i<nb_modes;i++)
58 {
59 CELTMode *mode = modes[i];
60 fprintf(file, " %d %d",mode->Fs,mode->shortMdctSize*mode->nbShortMdcts);
61 }
62 fprintf(file, "\n * It contains static definitions for some pre-defined modes. */\n");
63 fprintf(file, "#include <NE10_types.h>\n\n");
64}
65
66void dump_modes_arch_finalize()
67{
68 fclose(file);
69}
70
71void dump_mode_arch(CELTMode *mode)
72{
73 int k, j;
74 int mdctSize;
75
76 mdctSize = mode->shortMdctSize*mode->nbShortMdcts;
77
78 fprintf(file, "#ifndef NE10_FFT_PARAMS%d_%d\n", mode->Fs, mdctSize);
79 fprintf(file, "#define NE10_FFT_PARAMS%d_%d\n", mode->Fs, mdctSize);
80 /* cfg->factors */
81 for(k=0;k<=mode->mdct.maxshift;k++) {
82 NE10_FFT_CFG_TYPE_T cfg;
83 cfg = (NE10_FFT_CFG_TYPE_T)mode->mdct.kfft[k]->arch_fft->priv;
84 if (!cfg)
85 continue;
86 fprintf(file, "static const ne10_int32_t ne10_factors_%d[%d] = {\n",
87 mode->mdct.kfft[k]->nfft, (NE10_MAXFACTORS * 2));
88 for(j=0;j<(NE10_MAXFACTORS * 2);j++) {
89 fprintf(file, "%d,%c", cfg->factors[j],(j+16)%15==0?'\n':' ');
90 }
91 fprintf (file, "};\n");
92 }
93
94 /* cfg->twiddles */
95 for(k=0;k<=mode->mdct.maxshift;k++) {
96 NE10_FFT_CFG_TYPE_T cfg;
97 cfg = (NE10_FFT_CFG_TYPE_T)mode->mdct.kfft[k]->arch_fft->priv;
98 if (!cfg)
99 continue;
100 fprintf(file, "static const %s ne10_twiddles_%d[%d] = {\n",
101 NE10_FFT_CPX_TYPE_T_STR, mode->mdct.kfft[k]->nfft,
102 mode->mdct.kfft[k]->nfft);
103 for(j=0;j<mode->mdct.kfft[k]->nfft;j++) {
104#if !defined(FIXED_POINT)
105 fprintf(file, "{%#0.8gf,%#0.8gf},%c",
106 cfg->twiddles[j].r, cfg->twiddles[j].i,(j+4)%3==0?'\n':' ');
107#else
108 fprintf(file, "{%d,%d},%c",
109 cfg->twiddles[j].r, cfg->twiddles[j].i,(j+4)%3==0?'\n':' ');
110#endif
111 }
112 fprintf (file, "};\n");
113 }
114
115 for(k=0;k<=mode->mdct.maxshift;k++) {
116 NE10_FFT_CFG_TYPE_T cfg;
117 cfg = (NE10_FFT_CFG_TYPE_T)mode->mdct.kfft[k]->arch_fft->priv;
118 if (!cfg) {
119 fprintf(file, "/* Ne10 does not support scaled FFT for length = %d */\n",
120 mode->mdct.kfft[k]->nfft);
121 fprintf(file, "static const arch_fft_state cfg_arch_%d = {\n", mode->mdct.kfft[k]->nfft);
122 fprintf(file, "0,\n");
123 fprintf(file, "NULL\n");
124 fprintf(file, "};\n");
125 continue;
126 }
127 fprintf(file, "static const %s %s_%d = {\n", NE10_FFT_STATE_TYPE_T_STR,
128 NE10_FFT_STATE_TYPE_T_STR, mode->mdct.kfft[k]->nfft);
129 fprintf(file, "%d,\n", cfg->nfft);
130 fprintf(file, "(ne10_int32_t *)ne10_factors_%d,\n", mode->mdct.kfft[k]->nfft);
131 fprintf(file, "(%s *)ne10_twiddles_%d,\n",
132 NE10_FFT_CPX_TYPE_T_STR, mode->mdct.kfft[k]->nfft);
133 fprintf(file, "NULL,\n"); /* buffer */
134 fprintf(file, "(%s *)&ne10_twiddles_%d[%d],\n",
135 NE10_FFT_CPX_TYPE_T_STR, mode->mdct.kfft[k]->nfft, cfg->nfft);
136#if !defined(FIXED_POINT)
137 fprintf(file, "/* is_forward_scaled = true */\n");
138 fprintf(file, "(ne10_int32_t) 1,\n");
139 fprintf(file, "/* is_backward_scaled = false */\n");
140 fprintf(file, "(ne10_int32_t) 0,\n");
141#endif
142 fprintf(file, "};\n");
143
144 fprintf(file, "static const arch_fft_state cfg_arch_%d = {\n",
145 mode->mdct.kfft[k]->nfft);
146 fprintf(file, "1,\n");
147 fprintf(file, "(void *)&%s_%d,\n",
148 NE10_FFT_STATE_TYPE_T_STR, mode->mdct.kfft[k]->nfft);
149 fprintf(file, "};\n\n");
150 }
151 fprintf(file, "#endif /* end NE10_FFT_PARAMS%d_%d */\n", mode->Fs, mdctSize);
152}
diff --git a/lib/rbcodec/codecs/libopus/celt/entcode.c b/lib/rbcodec/codecs/libopus/celt/entcode.c
index 461a36dd55..70f32016ec 100644
--- a/lib/rbcodec/codecs/libopus/celt/entcode.c
+++ b/lib/rbcodec/codecs/libopus/celt/entcode.c
@@ -116,7 +116,7 @@ opus_uint32 ec_tell_frac(ec_ctx *_this){
116 116
117#ifdef USE_SMALL_DIV_TABLE 117#ifdef USE_SMALL_DIV_TABLE
118/* Result of 2^32/(2*i+1), except for i=0. */ 118/* Result of 2^32/(2*i+1), except for i=0. */
119const opus_uint32 SMALL_DIV_TABLE[129] ICONST_ATTR = { 119const opus_uint32 SMALL_DIV_TABLE[129] = {
120 0xFFFFFFFF, 0x55555555, 0x33333333, 0x24924924, 120 0xFFFFFFFF, 0x55555555, 0x33333333, 0x24924924,
121 0x1C71C71C, 0x1745D174, 0x13B13B13, 0x11111111, 121 0x1C71C71C, 0x1745D174, 0x13B13B13, 0x11111111,
122 0x0F0F0F0F, 0x0D79435E, 0x0C30C30C, 0x0B21642C, 122 0x0F0F0F0F, 0x0D79435E, 0x0C30C30C, 0x0B21642C,
diff --git a/lib/rbcodec/codecs/libopus/celt/entcode.h b/lib/rbcodec/codecs/libopus/celt/entcode.h
index 13d6c84ef0..3763e3f284 100644
--- a/lib/rbcodec/codecs/libopus/celt/entcode.h
+++ b/lib/rbcodec/codecs/libopus/celt/entcode.h
@@ -122,7 +122,7 @@ opus_uint32 ec_tell_frac(ec_ctx *_this);
122 122
123/* Tested exhaustively for all n and for 1<=d<=256 */ 123/* Tested exhaustively for all n and for 1<=d<=256 */
124static OPUS_INLINE opus_uint32 celt_udiv(opus_uint32 n, opus_uint32 d) { 124static OPUS_INLINE opus_uint32 celt_udiv(opus_uint32 n, opus_uint32 d) {
125 celt_assert(d>0); 125 celt_sig_assert(d>0);
126#ifdef USE_SMALL_DIV_TABLE 126#ifdef USE_SMALL_DIV_TABLE
127 if (d>256) 127 if (d>256)
128 return n/d; 128 return n/d;
@@ -138,7 +138,7 @@ static OPUS_INLINE opus_uint32 celt_udiv(opus_uint32 n, opus_uint32 d) {
138} 138}
139 139
140static OPUS_INLINE opus_int32 celt_sudiv(opus_int32 n, opus_int32 d) { 140static OPUS_INLINE opus_int32 celt_sudiv(opus_int32 n, opus_int32 d) {
141 celt_assert(d>0); 141 celt_sig_assert(d>0);
142#ifdef USE_SMALL_DIV_TABLE 142#ifdef USE_SMALL_DIV_TABLE
143 if (n<0) 143 if (n<0)
144 return -(opus_int32)celt_udiv(-n, d); 144 return -(opus_int32)celt_udiv(-n, d);
diff --git a/lib/rbcodec/codecs/libopus/celt/entdec.h b/lib/rbcodec/codecs/libopus/celt/entdec.h
index d8ab318730..025fc1870d 100644
--- a/lib/rbcodec/codecs/libopus/celt/entdec.h
+++ b/lib/rbcodec/codecs/libopus/celt/entdec.h
@@ -85,7 +85,7 @@ int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb);
85 The bits must have been encoded with ec_enc_uint(). 85 The bits must have been encoded with ec_enc_uint().
86 No call to ec_dec_update() is necessary after this call. 86 No call to ec_dec_update() is necessary after this call.
87 _ft: The number of integers that can be decoded (one more than the max). 87 _ft: The number of integers that can be decoded (one more than the max).
88 This must be at least one, and no more than 2**32-1. 88 This must be at least 2, and no more than 2**32-1.
89 Return: The decoded bits.*/ 89 Return: The decoded bits.*/
90opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft); 90opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft);
91 91
diff --git a/lib/rbcodec/codecs/libopus/celt/entenc.c b/lib/rbcodec/codecs/libopus/celt/entenc.c
index 271e4d30c5..f1750d25b8 100644
--- a/lib/rbcodec/codecs/libopus/celt/entenc.c
+++ b/lib/rbcodec/codecs/libopus/celt/entenc.c
@@ -98,7 +98,7 @@ static void ec_enc_carry_out(ec_enc *_this,int _c){
98 else _this->ext++; 98 else _this->ext++;
99} 99}
100 100
101static void ec_enc_normalize(ec_enc *_this){ 101static OPUS_INLINE void ec_enc_normalize(ec_enc *_this){
102 /*If the range is too small, output some bits and rescale it.*/ 102 /*If the range is too small, output some bits and rescale it.*/
103 while(_this->rng<=EC_CODE_BOT){ 103 while(_this->rng<=EC_CODE_BOT){
104 ec_enc_carry_out(_this,(int)(_this->val>>EC_CODE_SHIFT)); 104 ec_enc_carry_out(_this,(int)(_this->val>>EC_CODE_SHIFT));
diff --git a/lib/rbcodec/codecs/libopus/celt/entenc.h b/lib/rbcodec/codecs/libopus/celt/entenc.h
index 796bc4d572..f502eaf662 100644
--- a/lib/rbcodec/codecs/libopus/celt/entenc.h
+++ b/lib/rbcodec/codecs/libopus/celt/entenc.h
@@ -67,7 +67,7 @@ void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb);
67/*Encodes a raw unsigned integer in the stream. 67/*Encodes a raw unsigned integer in the stream.
68 _fl: The integer to encode. 68 _fl: The integer to encode.
69 _ft: The number of integers that can be encoded (one more than the max). 69 _ft: The number of integers that can be encoded (one more than the max).
70 This must be at least one, and no more than 2**32-1.*/ 70 This must be at least 2, and no more than 2**32-1.*/
71void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft); 71void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft);
72 72
73/*Encodes a sequence of raw bits in the stream. 73/*Encodes a sequence of raw bits in the stream.
diff --git a/lib/rbcodec/codecs/libopus/celt/fixed_c5x.h b/lib/rbcodec/codecs/libopus/celt/fixed_c5x.h
new file mode 100644
index 0000000000..ea95a998c3
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/fixed_c5x.h
@@ -0,0 +1,79 @@
1/* Copyright (C) 2003 Jean-Marc Valin */
2/**
3 @file fixed_c5x.h
4 @brief Fixed-point operations for the TI C5x DSP family
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
22 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*/
30
31#ifndef FIXED_C5X_H
32#define FIXED_C5X_H
33
34#include "dsplib.h"
35
36#undef IMUL32
37static OPUS_INLINE long IMUL32(long i, long j)
38{
39 long ac0, ac1;
40 ac0 = _lmpy(i>>16,j);
41 ac1 = ac0 + _lmpy(i,j>>16);
42 return _lmpyu(i,j) + (ac1<<16);
43}
44
45#undef MAX16
46#define MAX16(a,b) _max(a,b)
47
48#undef MIN16
49#define MIN16(a,b) _min(a,b)
50
51#undef MAX32
52#define MAX32(a,b) _lmax(a,b)
53
54#undef MIN32
55#define MIN32(a,b) _lmin(a,b)
56
57#undef VSHR32
58#define VSHR32(a, shift) _lshl(a,-(shift))
59
60#undef MULT16_16_Q15
61#define MULT16_16_Q15(a,b) (_smpy(a,b))
62
63#undef MULT16_16SU
64#define MULT16_16SU(a,b) _lmpysu(a,b)
65
66#undef MULT_16_16
67#define MULT_16_16(a,b) _lmpy(a,b)
68
69/* FIXME: This is technically incorrect and is bound to cause problems. Is there any cleaner solution? */
70#undef MULT16_32_Q15
71#define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),(b)),15))
72
73#define celt_ilog2(x) (30 - _lnorm(x))
74#define OVERRIDE_CELT_ILOG2
75
76#define celt_maxabs16(x, len) MAX32(EXTEND32(maxval((DATA *)x, len)),-EXTEND32(minval((DATA *)x, len)))
77#define OVERRIDE_CELT_MAXABS16
78
79#endif /* FIXED_C5X_H */
diff --git a/lib/rbcodec/codecs/libopus/celt/fixed_c6x.h b/lib/rbcodec/codecs/libopus/celt/fixed_c6x.h
new file mode 100644
index 0000000000..bb6ad92780
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/fixed_c6x.h
@@ -0,0 +1,70 @@
1/* Copyright (C) 2008 CSIRO */
2/**
3 @file fixed_c6x.h
4 @brief Fixed-point operations for the TI C6x DSP family
5*/
6/*
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
22 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*/
30
31#ifndef FIXED_C6X_H
32#define FIXED_C6X_H
33
34#undef MULT16_16SU
35#define MULT16_16SU(a,b) _mpysu(a,b)
36
37#undef MULT_16_16
38#define MULT_16_16(a,b) _mpy(a,b)
39
40#define celt_ilog2(x) (30 - _norm(x))
41#define OVERRIDE_CELT_ILOG2
42
43#undef MULT16_32_Q15
44#define MULT16_32_Q15(a,b) (_mpylill(a, b) >> 15)
45
46#if 0
47#include "dsplib.h"
48
49#undef MAX16
50#define MAX16(a,b) _max(a,b)
51
52#undef MIN16
53#define MIN16(a,b) _min(a,b)
54
55#undef MAX32
56#define MAX32(a,b) _lmax(a,b)
57
58#undef MIN32
59#define MIN32(a,b) _lmin(a,b)
60
61#undef VSHR32
62#define VSHR32(a, shift) _lshl(a,-(shift))
63
64#undef MULT16_16_Q15
65#define MULT16_16_Q15(a,b) (_smpy(a,b))
66
67#define celt_maxabs16(x, len) MAX32(EXTEND32(maxval((DATA *)x, len)),-EXTEND32(minval((DATA *)x, len)))
68#define OVERRIDE_CELT_MAXABS16
69
70#endif /* FIXED_C6X_H */
diff --git a/lib/rbcodec/codecs/libopus/celt/fixed_debug.h b/lib/rbcodec/codecs/libopus/celt/fixed_debug.h
new file mode 100644
index 0000000000..f435295234
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/fixed_debug.h
@@ -0,0 +1,791 @@
1/* Copyright (C) 2003-2008 Jean-Marc Valin
2 Copyright (C) 2007-2012 Xiph.Org Foundation */
3/**
4 @file fixed_debug.h
5 @brief Fixed-point operations with debugging
6*/
7/*
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions
10 are met:
11
12 - Redistributions of source code must retain the above copyright
13 notice, this list of conditions and the following disclaimer.
14
15 - Redistributions in binary form must reproduce the above copyright
16 notice, this list of conditions and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
23 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*/
31
32#ifndef FIXED_DEBUG_H
33#define FIXED_DEBUG_H
34
35#include <stdio.h>
36#include "opus_defines.h"
37
38#ifdef CELT_C
39OPUS_EXPORT opus_int64 celt_mips=0;
40#else
41extern opus_int64 celt_mips;
42#endif
43
44#define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b))
45#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))
46
47/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
48#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR32((b),16)), SHR32(MULT16_16SU((a),((b)&0x0000ffff)),16))
49
50#define MULT16_32_P16(a,b) MULT16_32_PX(a,b,16)
51
52#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))
53#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits))))
54
55#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
56#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
57#define VERIFY_UINT(x) ((x)<=(2147483647LLU<<1))
58
59#define SHR(a,b) SHR32(a,b)
60#define PSHR(a,b) PSHR32(a,b)
61
62/** Add two 32-bit values, ignore any overflows */
63#define ADD32_ovflw(a,b) (celt_mips+=2,(opus_val32)((opus_uint32)(a)+(opus_uint32)(b)))
64/** Subtract two 32-bit values, ignore any overflows */
65#define SUB32_ovflw(a,b) (celt_mips+=2,(opus_val32)((opus_uint32)(a)-(opus_uint32)(b)))
66/* Avoid MSVC warning C4146: unary minus operator applied to unsigned type */
67/** Negate 32-bit value, ignore any overflows */
68#define NEG32_ovflw(a) (celt_mips+=2,(opus_val32)(0-(opus_uint32)(a)))
69
70static OPUS_INLINE short NEG16(int x)
71{
72 int res;
73 if (!VERIFY_SHORT(x))
74 {
75 fprintf (stderr, "NEG16: input is not short: %d\n", (int)x);
76#ifdef FIXED_DEBUG_ASSERT
77 celt_assert(0);
78#endif
79 }
80 res = -x;
81 if (!VERIFY_SHORT(res))
82 {
83 fprintf (stderr, "NEG16: output is not short: %d\n", (int)res);
84#ifdef FIXED_DEBUG_ASSERT
85 celt_assert(0);
86#endif
87 }
88 celt_mips++;
89 return res;
90}
91static OPUS_INLINE int NEG32(opus_int64 x)
92{
93 opus_int64 res;
94 if (!VERIFY_INT(x))
95 {
96 fprintf (stderr, "NEG16: input is not int: %d\n", (int)x);
97#ifdef FIXED_DEBUG_ASSERT
98 celt_assert(0);
99#endif
100 }
101 res = -x;
102 if (!VERIFY_INT(res))
103 {
104 fprintf (stderr, "NEG16: output is not int: %d\n", (int)res);
105#ifdef FIXED_DEBUG_ASSERT
106 celt_assert(0);
107#endif
108 }
109 celt_mips+=2;
110 return res;
111}
112
113#define EXTRACT16(x) EXTRACT16_(x, __FILE__, __LINE__)
114static OPUS_INLINE short EXTRACT16_(int x, char *file, int line)
115{
116 int res;
117 if (!VERIFY_SHORT(x))
118 {
119 fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line);
120#ifdef FIXED_DEBUG_ASSERT
121 celt_assert(0);
122#endif
123 }
124 res = x;
125 celt_mips++;
126 return res;
127}
128
129#define EXTEND32(x) EXTEND32_(x, __FILE__, __LINE__)
130static OPUS_INLINE int EXTEND32_(int x, char *file, int line)
131{
132 int res;
133 if (!VERIFY_SHORT(x))
134 {
135 fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line);
136#ifdef FIXED_DEBUG_ASSERT
137 celt_assert(0);
138#endif
139 }
140 res = x;
141 celt_mips++;
142 return res;
143}
144
145#define SHR16(a, shift) SHR16_(a, shift, __FILE__, __LINE__)
146static OPUS_INLINE short SHR16_(int a, int shift, char *file, int line)
147{
148 int res;
149 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
150 {
151 fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line);
152#ifdef FIXED_DEBUG_ASSERT
153 celt_assert(0);
154#endif
155 }
156 res = a>>shift;
157 if (!VERIFY_SHORT(res))
158 {
159 fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line);
160#ifdef FIXED_DEBUG_ASSERT
161 celt_assert(0);
162#endif
163 }
164 celt_mips++;
165 return res;
166}
167#define SHL16(a, shift) SHL16_(a, shift, __FILE__, __LINE__)
168static OPUS_INLINE short SHL16_(int a, int shift, char *file, int line)
169{
170 int res;
171 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
172 {
173 fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line);
174#ifdef FIXED_DEBUG_ASSERT
175 celt_assert(0);
176#endif
177 }
178 res = a<<shift;
179 if (!VERIFY_SHORT(res))
180 {
181 fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line);
182#ifdef FIXED_DEBUG_ASSERT
183 celt_assert(0);
184#endif
185 }
186 celt_mips++;
187 return res;
188}
189
190static OPUS_INLINE int SHR32(opus_int64 a, int shift)
191{
192 opus_int64 res;
193 if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
194 {
195 fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift);
196#ifdef FIXED_DEBUG_ASSERT
197 celt_assert(0);
198#endif
199 }
200 res = a>>shift;
201 if (!VERIFY_INT(res))
202 {
203 fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
204#ifdef FIXED_DEBUG_ASSERT
205 celt_assert(0);
206#endif
207 }
208 celt_mips+=2;
209 return res;
210}
211#define SHL32(a, shift) SHL32_(a, shift, __FILE__, __LINE__)
212static OPUS_INLINE int SHL32_(opus_int64 a, int shift, char *file, int line)
213{
214 opus_int64 res;
215 if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
216 {
217 fprintf (stderr, "SHL32: inputs are not int: %lld %d in %s: line %d\n", a, shift, file, line);
218#ifdef FIXED_DEBUG_ASSERT
219 celt_assert(0);
220#endif
221 }
222 res = a<<shift;
223 if (!VERIFY_INT(res))
224 {
225 fprintf (stderr, "SHL32: output is not int: %lld<<%d = %lld in %s: line %d\n", a, shift, res, file, line);
226#ifdef FIXED_DEBUG_ASSERT
227 celt_assert(0);
228#endif
229 }
230 celt_mips+=2;
231 return res;
232}
233
234#define PSHR32(a,shift) (celt_mips--,SHR32(ADD32((a),(((opus_val32)(1)<<((shift))>>1))),shift))
235#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
236
237#define ROUND16(x,a) (celt_mips--,EXTRACT16(PSHR32((x),(a))))
238#define SROUND16(x,a) (celt_mips--,EXTRACT16(SATURATE(PSHR32(x,a), 32767)));
239
240#define HALF16(x) (SHR16(x,1))
241#define HALF32(x) (SHR32(x,1))
242
243#define ADD16(a, b) ADD16_(a, b, __FILE__, __LINE__)
244static OPUS_INLINE short ADD16_(int a, int b, char *file, int line)
245{
246 int res;
247 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
248 {
249 fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
250#ifdef FIXED_DEBUG_ASSERT
251 celt_assert(0);
252#endif
253 }
254 res = a+b;
255 if (!VERIFY_SHORT(res))
256 {
257 fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line);
258#ifdef FIXED_DEBUG_ASSERT
259 celt_assert(0);
260#endif
261 }
262 celt_mips++;
263 return res;
264}
265
266#define SUB16(a, b) SUB16_(a, b, __FILE__, __LINE__)
267static OPUS_INLINE short SUB16_(int a, int b, char *file, int line)
268{
269 int res;
270 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
271 {
272 fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
273#ifdef FIXED_DEBUG_ASSERT
274 celt_assert(0);
275#endif
276 }
277 res = a-b;
278 if (!VERIFY_SHORT(res))
279 {
280 fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line);
281#ifdef FIXED_DEBUG_ASSERT
282 celt_assert(0);
283#endif
284 }
285 celt_mips++;
286 return res;
287}
288
289#define ADD32(a, b) ADD32_(a, b, __FILE__, __LINE__)
290static OPUS_INLINE int ADD32_(opus_int64 a, opus_int64 b, char *file, int line)
291{
292 opus_int64 res;
293 if (!VERIFY_INT(a) || !VERIFY_INT(b))
294 {
295 fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
296#ifdef FIXED_DEBUG_ASSERT
297 celt_assert(0);
298#endif
299 }
300 res = a+b;
301 if (!VERIFY_INT(res))
302 {
303 fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line);
304#ifdef FIXED_DEBUG_ASSERT
305 celt_assert(0);
306#endif
307 }
308 celt_mips+=2;
309 return res;
310}
311
312#define SUB32(a, b) SUB32_(a, b, __FILE__, __LINE__)
313static OPUS_INLINE int SUB32_(opus_int64 a, opus_int64 b, char *file, int line)
314{
315 opus_int64 res;
316 if (!VERIFY_INT(a) || !VERIFY_INT(b))
317 {
318 fprintf (stderr, "SUB32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
319#ifdef FIXED_DEBUG_ASSERT
320 celt_assert(0);
321#endif
322 }
323 res = a-b;
324 if (!VERIFY_INT(res))
325 {
326 fprintf (stderr, "SUB32: output is not int: %d in %s: line %d\n", (int)res, file, line);
327#ifdef FIXED_DEBUG_ASSERT
328 celt_assert(0);
329#endif
330 }
331 celt_mips+=2;
332 return res;
333}
334
335#undef UADD32
336#define UADD32(a, b) UADD32_(a, b, __FILE__, __LINE__)
337static OPUS_INLINE unsigned int UADD32_(opus_uint64 a, opus_uint64 b, char *file, int line)
338{
339 opus_uint64 res;
340 if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
341 {
342 fprintf (stderr, "UADD32: inputs are not uint32: %llu %llu in %s: line %d\n", a, b, file, line);
343#ifdef FIXED_DEBUG_ASSERT
344 celt_assert(0);
345#endif
346 }
347 res = a+b;
348 if (!VERIFY_UINT(res))
349 {
350 fprintf (stderr, "UADD32: output is not uint32: %llu in %s: line %d\n", res, file, line);
351#ifdef FIXED_DEBUG_ASSERT
352 celt_assert(0);
353#endif
354 }
355 celt_mips+=2;
356 return res;
357}
358
359#undef USUB32
360#define USUB32(a, b) USUB32_(a, b, __FILE__, __LINE__)
361static OPUS_INLINE unsigned int USUB32_(opus_uint64 a, opus_uint64 b, char *file, int line)
362{
363 opus_uint64 res;
364 if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
365 {
366 fprintf (stderr, "USUB32: inputs are not uint32: %llu %llu in %s: line %d\n", a, b, file, line);
367#ifdef FIXED_DEBUG_ASSERT
368 celt_assert(0);
369#endif
370 }
371 if (a<b)
372 {
373 fprintf (stderr, "USUB32: inputs underflow: %llu < %llu in %s: line %d\n", a, b, file, line);
374#ifdef FIXED_DEBUG_ASSERT
375 celt_assert(0);
376#endif
377 }
378 res = a-b;
379 if (!VERIFY_UINT(res))
380 {
381 fprintf (stderr, "USUB32: output is not uint32: %llu - %llu = %llu in %s: line %d\n", a, b, res, file, line);
382#ifdef FIXED_DEBUG_ASSERT
383 celt_assert(0);
384#endif
385 }
386 celt_mips+=2;
387 return res;
388}
389
390/* result fits in 16 bits */
391static OPUS_INLINE short MULT16_16_16(int a, int b)
392{
393 int res;
394 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
395 {
396 fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b);
397#ifdef FIXED_DEBUG_ASSERT
398 celt_assert(0);
399#endif
400 }
401 res = a*b;
402 if (!VERIFY_SHORT(res))
403 {
404 fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
405#ifdef FIXED_DEBUG_ASSERT
406 celt_assert(0);
407#endif
408 }
409 celt_mips++;
410 return res;
411}
412
413#define MULT16_16(a, b) MULT16_16_(a, b, __FILE__, __LINE__)
414static OPUS_INLINE int MULT16_16_(int a, int b, char *file, int line)
415{
416 opus_int64 res;
417 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
418 {
419 fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
420#ifdef FIXED_DEBUG_ASSERT
421 celt_assert(0);
422#endif
423 }
424 res = ((opus_int64)a)*b;
425 if (!VERIFY_INT(res))
426 {
427 fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line);
428#ifdef FIXED_DEBUG_ASSERT
429 celt_assert(0);
430#endif
431 }
432 celt_mips++;
433 return res;
434}
435
436#define MAC16_16(c,a,b) (celt_mips-=2,ADD32((c),MULT16_16((a),(b))))
437
438#define MULT16_32_QX(a, b, Q) MULT16_32_QX_(a, b, Q, __FILE__, __LINE__)
439static OPUS_INLINE int MULT16_32_QX_(int a, opus_int64 b, int Q, char *file, int line)
440{
441 opus_int64 res;
442 if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
443 {
444 fprintf (stderr, "MULT16_32_Q%d: inputs are not short+int: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
445#ifdef FIXED_DEBUG_ASSERT
446 celt_assert(0);
447#endif
448 }
449 if (ABS32(b)>=((opus_val32)(1)<<(15+Q)))
450 {
451 fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
452#ifdef FIXED_DEBUG_ASSERT
453 celt_assert(0);
454#endif
455 }
456 res = (((opus_int64)a)*(opus_int64)b) >> Q;
457 if (!VERIFY_INT(res))
458 {
459 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);
460#ifdef FIXED_DEBUG_ASSERT
461 celt_assert(0);
462#endif
463 }
464 if (Q==15)
465 celt_mips+=3;
466 else
467 celt_mips+=4;
468 return res;
469}
470
471#define MULT16_32_PX(a, b, Q) MULT16_32_PX_(a, b, Q, __FILE__, __LINE__)
472static OPUS_INLINE int MULT16_32_PX_(int a, opus_int64 b, int Q, char *file, int line)
473{
474 opus_int64 res;
475 if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
476 {
477 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);
478#ifdef FIXED_DEBUG_ASSERT
479 celt_assert(0);
480#endif
481 }
482 if (ABS32(b)>=((opus_int64)(1)<<(15+Q)))
483 {
484 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);
485#ifdef FIXED_DEBUG_ASSERT
486 celt_assert(0);
487#endif
488 }
489 res = ((((opus_int64)a)*(opus_int64)b) + (((opus_val32)(1)<<Q)>>1))>> Q;
490 if (!VERIFY_INT(res))
491 {
492 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);
493#ifdef FIXED_DEBUG_ASSERT
494 celt_assert(0);
495#endif
496 }
497 if (Q==15)
498 celt_mips+=4;
499 else
500 celt_mips+=5;
501 return res;
502}
503
504#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
505#define MAC16_32_Q15(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q15((a),(b))))
506#define MAC16_32_Q16(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q16((a),(b))))
507
508static OPUS_INLINE int SATURATE(int a, int b)
509{
510 if (a>b)
511 a=b;
512 if (a<-b)
513 a = -b;
514 celt_mips+=3;
515 return a;
516}
517
518static OPUS_INLINE opus_int16 SATURATE16(opus_int32 a)
519{
520 celt_mips+=3;
521 if (a>32767)
522 return 32767;
523 else if (a<-32768)
524 return -32768;
525 else return a;
526}
527
528static OPUS_INLINE int MULT16_16_Q11_32(int a, int b)
529{
530 opus_int64 res;
531 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
532 {
533 fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
534#ifdef FIXED_DEBUG_ASSERT
535 celt_assert(0);
536#endif
537 }
538 res = ((opus_int64)a)*b;
539 res >>= 11;
540 if (!VERIFY_INT(res))
541 {
542 fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res);
543#ifdef FIXED_DEBUG_ASSERT
544 celt_assert(0);
545#endif
546 }
547 celt_mips+=3;
548 return res;
549}
550static OPUS_INLINE short MULT16_16_Q13(int a, int b)
551{
552 opus_int64 res;
553 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
554 {
555 fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
556#ifdef FIXED_DEBUG_ASSERT
557 celt_assert(0);
558#endif
559 }
560 res = ((opus_int64)a)*b;
561 res >>= 13;
562 if (!VERIFY_SHORT(res))
563 {
564 fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res);
565#ifdef FIXED_DEBUG_ASSERT
566 celt_assert(0);
567#endif
568 }
569 celt_mips+=3;
570 return res;
571}
572static OPUS_INLINE short MULT16_16_Q14(int a, int b)
573{
574 opus_int64 res;
575 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
576 {
577 fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
578#ifdef FIXED_DEBUG_ASSERT
579 celt_assert(0);
580#endif
581 }
582 res = ((opus_int64)a)*b;
583 res >>= 14;
584 if (!VERIFY_SHORT(res))
585 {
586 fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res);
587#ifdef FIXED_DEBUG_ASSERT
588 celt_assert(0);
589#endif
590 }
591 celt_mips+=3;
592 return res;
593}
594
595#define MULT16_16_Q15(a, b) MULT16_16_Q15_(a, b, __FILE__, __LINE__)
596static OPUS_INLINE short MULT16_16_Q15_(int a, int b, char *file, int line)
597{
598 opus_int64 res;
599 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
600 {
601 fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
602#ifdef FIXED_DEBUG_ASSERT
603 celt_assert(0);
604#endif
605 }
606 res = ((opus_int64)a)*b;
607 res >>= 15;
608 if (!VERIFY_SHORT(res))
609 {
610 fprintf (stderr, "MULT16_16_Q15: output is not short: %d in %s: line %d\n", (int)res, file, line);
611#ifdef FIXED_DEBUG_ASSERT
612 celt_assert(0);
613#endif
614 }
615 celt_mips+=1;
616 return res;
617}
618
619static OPUS_INLINE short MULT16_16_P13(int a, int b)
620{
621 opus_int64 res;
622 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
623 {
624 fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
625#ifdef FIXED_DEBUG_ASSERT
626 celt_assert(0);
627#endif
628 }
629 res = ((opus_int64)a)*b;
630 res += 4096;
631 if (!VERIFY_INT(res))
632 {
633 fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res);
634#ifdef FIXED_DEBUG_ASSERT
635 celt_assert(0);
636#endif
637 }
638 res >>= 13;
639 if (!VERIFY_SHORT(res))
640 {
641 fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res);
642#ifdef FIXED_DEBUG_ASSERT
643 celt_assert(0);
644#endif
645 }
646 celt_mips+=4;
647 return res;
648}
649static OPUS_INLINE short MULT16_16_P14(int a, int b)
650{
651 opus_int64 res;
652 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
653 {
654 fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
655#ifdef FIXED_DEBUG_ASSERT
656 celt_assert(0);
657#endif
658 }
659 res = ((opus_int64)a)*b;
660 res += 8192;
661 if (!VERIFY_INT(res))
662 {
663 fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res);
664#ifdef FIXED_DEBUG_ASSERT
665 celt_assert(0);
666#endif
667 }
668 res >>= 14;
669 if (!VERIFY_SHORT(res))
670 {
671 fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res);
672#ifdef FIXED_DEBUG_ASSERT
673 celt_assert(0);
674#endif
675 }
676 celt_mips+=4;
677 return res;
678}
679static OPUS_INLINE short MULT16_16_P15(int a, int b)
680{
681 opus_int64 res;
682 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
683 {
684 fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
685#ifdef FIXED_DEBUG_ASSERT
686 celt_assert(0);
687#endif
688 }
689 res = ((opus_int64)a)*b;
690 res += 16384;
691 if (!VERIFY_INT(res))
692 {
693 fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res);
694#ifdef FIXED_DEBUG_ASSERT
695 celt_assert(0);
696#endif
697 }
698 res >>= 15;
699 if (!VERIFY_SHORT(res))
700 {
701 fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res);
702#ifdef FIXED_DEBUG_ASSERT
703 celt_assert(0);
704#endif
705 }
706 celt_mips+=2;
707 return res;
708}
709
710#define DIV32_16(a, b) DIV32_16_(a, b, __FILE__, __LINE__)
711
712static OPUS_INLINE int DIV32_16_(opus_int64 a, opus_int64 b, char *file, int line)
713{
714 opus_int64 res;
715 if (b==0)
716 {
717 fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
718#ifdef FIXED_DEBUG_ASSERT
719 celt_assert(0);
720#endif
721 return 0;
722 }
723 if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
724 {
725 fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
726#ifdef FIXED_DEBUG_ASSERT
727 celt_assert(0);
728#endif
729 }
730 res = a/b;
731 if (!VERIFY_SHORT(res))
732 {
733 fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line);
734 if (res>32767)
735 res = 32767;
736 if (res<-32768)
737 res = -32768;
738#ifdef FIXED_DEBUG_ASSERT
739 celt_assert(0);
740#endif
741 }
742 celt_mips+=35;
743 return res;
744}
745
746#define DIV32(a, b) DIV32_(a, b, __FILE__, __LINE__)
747static OPUS_INLINE int DIV32_(opus_int64 a, opus_int64 b, char *file, int line)
748{
749 opus_int64 res;
750 if (b==0)
751 {
752 fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
753#ifdef FIXED_DEBUG_ASSERT
754 celt_assert(0);
755#endif
756 return 0;
757 }
758
759 if (!VERIFY_INT(a) || !VERIFY_INT(b))
760 {
761 fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
762#ifdef FIXED_DEBUG_ASSERT
763 celt_assert(0);
764#endif
765 }
766 res = a/b;
767 if (!VERIFY_INT(res))
768 {
769 fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line);
770#ifdef FIXED_DEBUG_ASSERT
771 celt_assert(0);
772#endif
773 }
774 celt_mips+=70;
775 return res;
776}
777
778static OPUS_INLINE opus_val16 SIG2WORD16_generic(celt_sig x)
779{
780 x = PSHR32(x, SIG_SHIFT);
781 x = MAX32(x, -32768);
782 x = MIN32(x, 32767);
783 return EXTRACT16(x);
784}
785#define SIG2WORD16(x) (SIG2WORD16_generic(x))
786
787
788#undef PRINT_MIPS
789#define PRINT_MIPS(file) do {fprintf (file, "total complexity = %llu MIPS\n", celt_mips);} while (0);
790
791#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/fixed_generic.h b/lib/rbcodec/codecs/libopus/celt/fixed_generic.h
index ac67d37ce8..5f4abda76e 100644
--- a/lib/rbcodec/codecs/libopus/celt/fixed_generic.h
+++ b/lib/rbcodec/codecs/libopus/celt/fixed_generic.h
@@ -37,16 +37,32 @@
37#define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b)) 37#define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b))
38 38
39/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */ 39/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
40#if OPUS_FAST_INT64
41#define MULT16_32_Q16(a,b) ((opus_val32)SHR((opus_int64)((opus_val16)(a))*(b),16))
42#else
40#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR((b),16)), SHR(MULT16_16SU((a),((b)&0x0000ffff)),16)) 43#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR((b),16)), SHR(MULT16_16SU((a),((b)&0x0000ffff)),16))
44#endif
41 45
42/** 16x32 multiplication, followed by a 16-bit shift right (round-to-nearest). Results fits in 32 bits */ 46/** 16x32 multiplication, followed by a 16-bit shift right (round-to-nearest). Results fits in 32 bits */
47#if OPUS_FAST_INT64
48#define MULT16_32_P16(a,b) ((opus_val32)PSHR((opus_int64)((opus_val16)(a))*(b),16))
49#else
43#define MULT16_32_P16(a,b) ADD32(MULT16_16((a),SHR((b),16)), PSHR(MULT16_16SU((a),((b)&0x0000ffff)),16)) 50#define MULT16_32_P16(a,b) ADD32(MULT16_16((a),SHR((b),16)), PSHR(MULT16_16SU((a),((b)&0x0000ffff)),16))
51#endif
44 52
45/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */ 53/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */
54#if OPUS_FAST_INT64
55#define MULT16_32_Q15(a,b) ((opus_val32)SHR((opus_int64)((opus_val16)(a))*(b),15))
56#else
46#define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),((b)&0x0000ffff)),15)) 57#define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),((b)&0x0000ffff)),15))
58#endif
47 59
48/** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */ 60/** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */
61#if OPUS_FAST_INT64
62#define MULT32_32_Q31(a,b) ((opus_val32)SHR((opus_int64)(a)*(opus_int64)(b),31))
63#else
49#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)) 64#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))
65#endif
50 66
51/** Compile-time conversion of float constant to 16-bit value */ 67/** Compile-time conversion of float constant to 16-bit value */
52#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits)))) 68#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))
@@ -88,6 +104,9 @@
88 104
89/** Shift by a and round-to-neareast 32-bit value. Result is a 16-bit value */ 105/** Shift by a and round-to-neareast 32-bit value. Result is a 16-bit value */
90#define ROUND16(x,a) (EXTRACT16(PSHR32((x),(a)))) 106#define ROUND16(x,a) (EXTRACT16(PSHR32((x),(a))))
107/** Shift by a and round-to-neareast 32-bit value. Result is a saturated 16-bit value */
108#define SROUND16(x,a) EXTRACT16(SATURATE(PSHR32(x,a), 32767));
109
91/** Divide by two */ 110/** Divide by two */
92#define HALF16(x) (SHR16(x,1)) 111#define HALF16(x) (SHR16(x,1))
93#define HALF32(x) (SHR32(x,1)) 112#define HALF32(x) (SHR32(x,1))
@@ -101,6 +120,14 @@
101/** Subtract two 32-bit values */ 120/** Subtract two 32-bit values */
102#define SUB32(a,b) ((opus_val32)(a)-(opus_val32)(b)) 121#define SUB32(a,b) ((opus_val32)(a)-(opus_val32)(b))
103 122
123/** Add two 32-bit values, ignore any overflows */
124#define ADD32_ovflw(a,b) ((opus_val32)((opus_uint32)(a)+(opus_uint32)(b)))
125/** Subtract two 32-bit values, ignore any overflows */
126#define SUB32_ovflw(a,b) ((opus_val32)((opus_uint32)(a)-(opus_uint32)(b)))
127/* Avoid MSVC warning C4146: unary minus operator applied to unsigned type */
128/** Negate 32-bit value, ignore any overflows */
129#define NEG32_ovflw(a) ((opus_val32)(0-(opus_uint32)(a)))
130
104/** 16x16 multiplication where the result fits in 16 bits */ 131/** 16x16 multiplication where the result fits in 16 bits */
105#define MULT16_16_16(a,b) ((((opus_val16)(a))*((opus_val16)(b)))) 132#define MULT16_16_16(a,b) ((((opus_val16)(a))*((opus_val16)(b))))
106 133
diff --git a/lib/rbcodec/codecs/libopus/celt/float_cast.h b/lib/rbcodec/codecs/libopus/celt/float_cast.h
index ede6574860..889dae965f 100644
--- a/lib/rbcodec/codecs/libopus/celt/float_cast.h
+++ b/lib/rbcodec/codecs/libopus/celt/float_cast.h
@@ -61,7 +61,13 @@
61** the config.h file. 61** the config.h file.
62*/ 62*/
63 63
64#if (HAVE_LRINTF) 64/* With GCC, when SSE is available, the fastest conversion is cvtss2si. */
65#if defined(__GNUC__) && defined(__SSE__)
66
67#include <xmmintrin.h>
68static OPUS_INLINE opus_int32 float2int(float x) {return _mm_cvt_ss2si(_mm_set_ss(x));}
69
70#elif defined(HAVE_LRINTF)
65 71
66/* These defines enable functionality introduced with the 1999 ISO C 72/* These defines enable functionality introduced with the 1999 ISO C
67** standard. They must be defined before the inclusion of math.h to 73** standard. They must be defined before the inclusion of math.h to
@@ -90,21 +96,21 @@
90#include <math.h> 96#include <math.h>
91#define float2int(x) lrint(x) 97#define float2int(x) lrint(x)
92 98
93#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined (WIN64) || defined (_WIN64)) 99#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1))
94 #include <xmmintrin.h> 100 #include <xmmintrin.h>
95 101
96 __inline long int float2int(float value) 102 static __inline long int float2int(float value)
97 { 103 {
98 return _mm_cvtss_si32(_mm_load_ss(&value)); 104 return _mm_cvtss_si32(_mm_load_ss(&value));
99 } 105 }
100#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined (WIN32) || defined (_WIN32)) 106#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && defined (_M_IX86)
101 #include <math.h> 107 #include <math.h>
102 108
103 /* Win32 doesn't seem to have these functions. 109 /* Win32 doesn't seem to have these functions.
104 ** Therefore implement OPUS_INLINE versions of these functions here. 110 ** Therefore implement OPUS_INLINE versions of these functions here.
105 */ 111 */
106 112
107 __inline long int 113 static __inline long int
108 float2int (float flt) 114 float2int (float flt)
109 { int intgr; 115 { int intgr;
110 116
diff --git a/lib/rbcodec/codecs/libopus/celt/kiss_fft.c b/lib/rbcodec/codecs/libopus/celt/kiss_fft.c
index 833ef5a71f..83775165d8 100644
--- a/lib/rbcodec/codecs/libopus/celt/kiss_fft.c
+++ b/lib/rbcodec/codecs/libopus/celt/kiss_fft.c
@@ -82,8 +82,8 @@ static void kf_bfly2(
82 C_SUB( Fout2[0] , Fout[0] , t ); 82 C_SUB( Fout2[0] , Fout[0] , t );
83 C_ADDTO( Fout[0] , t ); 83 C_ADDTO( Fout[0] , t );
84 84
85 t.r = S_MUL(Fout2[1].r+Fout2[1].i, tw); 85 t.r = S_MUL(ADD32_ovflw(Fout2[1].r, Fout2[1].i), tw);
86 t.i = S_MUL(Fout2[1].i-Fout2[1].r, tw); 86 t.i = S_MUL(SUB32_ovflw(Fout2[1].i, Fout2[1].r), tw);
87 C_SUB( Fout2[1] , Fout[1] , t ); 87 C_SUB( Fout2[1] , Fout[1] , t );
88 C_ADDTO( Fout[1] , t ); 88 C_ADDTO( Fout[1] , t );
89 89
@@ -92,8 +92,8 @@ static void kf_bfly2(
92 C_SUB( Fout2[2] , Fout[2] , t ); 92 C_SUB( Fout2[2] , Fout[2] , t );
93 C_ADDTO( Fout[2] , t ); 93 C_ADDTO( Fout[2] , t );
94 94
95 t.r = S_MUL(Fout2[3].i-Fout2[3].r, tw); 95 t.r = S_MUL(SUB32_ovflw(Fout2[3].i, Fout2[3].r), tw);
96 t.i = S_MUL(-Fout2[3].i-Fout2[3].r, tw); 96 t.i = S_MUL(NEG32_ovflw(ADD32_ovflw(Fout2[3].i, Fout2[3].r)), tw);
97 C_SUB( Fout2[3] , Fout[3] , t ); 97 C_SUB( Fout2[3] , Fout[3] , t );
98 C_ADDTO( Fout[3] , t ); 98 C_ADDTO( Fout[3] , t );
99 Fout += 8; 99 Fout += 8;
@@ -126,10 +126,10 @@ static void kf_bfly4(
126 C_ADDTO( *Fout , scratch1 ); 126 C_ADDTO( *Fout , scratch1 );
127 C_SUB( scratch1 , Fout[1] , Fout[3] ); 127 C_SUB( scratch1 , Fout[1] , Fout[3] );
128 128
129 Fout[1].r = scratch0.r + scratch1.i; 129 Fout[1].r = ADD32_ovflw(scratch0.r, scratch1.i);
130 Fout[1].i = scratch0.i - scratch1.r; 130 Fout[1].i = SUB32_ovflw(scratch0.i, scratch1.r);
131 Fout[3].r = scratch0.r - scratch1.i; 131 Fout[3].r = SUB32_ovflw(scratch0.r, scratch1.i);
132 Fout[3].i = scratch0.i + scratch1.r; 132 Fout[3].i = ADD32_ovflw(scratch0.i, scratch1.r);
133 Fout+=4; 133 Fout+=4;
134 } 134 }
135 } else { 135 } else {
@@ -160,10 +160,10 @@ static void kf_bfly4(
160 tw3 += fstride*3; 160 tw3 += fstride*3;
161 C_ADDTO( *Fout , scratch[3] ); 161 C_ADDTO( *Fout , scratch[3] );
162 162
163 Fout[m].r = scratch[5].r + scratch[4].i; 163 Fout[m].r = ADD32_ovflw(scratch[5].r, scratch[4].i);
164 Fout[m].i = scratch[5].i - scratch[4].r; 164 Fout[m].i = SUB32_ovflw(scratch[5].i, scratch[4].r);
165 Fout[m3].r = scratch[5].r - scratch[4].i; 165 Fout[m3].r = SUB32_ovflw(scratch[5].r, scratch[4].i);
166 Fout[m3].i = scratch[5].i + scratch[4].r; 166 Fout[m3].i = ADD32_ovflw(scratch[5].i, scratch[4].r);
167 ++Fout; 167 ++Fout;
168 } 168 }
169 } 169 }
@@ -191,7 +191,7 @@ static void kf_bfly3(
191 191
192 kiss_fft_cpx * Fout_beg = Fout; 192 kiss_fft_cpx * Fout_beg = Fout;
193#ifdef FIXED_POINT 193#ifdef FIXED_POINT
194 epi3.r = -16384; 194 /*epi3.r = -16384;*/ /* Unused */
195 epi3.i = -28378; 195 epi3.i = -28378;
196#else 196#else
197 epi3 = st->twiddles[fstride*m]; 197 epi3 = st->twiddles[fstride*m];
@@ -212,18 +212,18 @@ static void kf_bfly3(
212 tw1 += fstride; 212 tw1 += fstride;
213 tw2 += fstride*2; 213 tw2 += fstride*2;
214 214
215 Fout[m].r = Fout->r - HALF_OF(scratch[3].r); 215 Fout[m].r = SUB32_ovflw(Fout->r, HALF_OF(scratch[3].r));
216 Fout[m].i = Fout->i - HALF_OF(scratch[3].i); 216 Fout[m].i = SUB32_ovflw(Fout->i, HALF_OF(scratch[3].i));
217 217
218 C_MULBYSCALAR( scratch[0] , epi3.i ); 218 C_MULBYSCALAR( scratch[0] , epi3.i );
219 219
220 C_ADDTO(*Fout,scratch[3]); 220 C_ADDTO(*Fout,scratch[3]);
221 221
222 Fout[m2].r = Fout[m].r + scratch[0].i; 222 Fout[m2].r = ADD32_ovflw(Fout[m].r, scratch[0].i);
223 Fout[m2].i = Fout[m].i - scratch[0].r; 223 Fout[m2].i = SUB32_ovflw(Fout[m].i, scratch[0].r);
224 224
225 Fout[m].r -= scratch[0].i; 225 Fout[m].r = SUB32_ovflw(Fout[m].r, scratch[0].i);
226 Fout[m].i += scratch[0].r; 226 Fout[m].i = ADD32_ovflw(Fout[m].i, scratch[0].r);
227 227
228 ++Fout; 228 ++Fout;
229 } while(--k); 229 } while(--k);
@@ -282,22 +282,22 @@ static void kf_bfly5(
282 C_ADD( scratch[8],scratch[2],scratch[3]); 282 C_ADD( scratch[8],scratch[2],scratch[3]);
283 C_SUB( scratch[9],scratch[2],scratch[3]); 283 C_SUB( scratch[9],scratch[2],scratch[3]);
284 284
285 Fout0->r += scratch[7].r + scratch[8].r; 285 Fout0->r = ADD32_ovflw(Fout0->r, ADD32_ovflw(scratch[7].r, scratch[8].r));
286 Fout0->i += scratch[7].i + scratch[8].i; 286 Fout0->i = ADD32_ovflw(Fout0->i, ADD32_ovflw(scratch[7].i, scratch[8].i));
287 287
288 scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); 288 scratch[5].r = ADD32_ovflw(scratch[0].r, ADD32_ovflw(S_MUL(scratch[7].r,ya.r), S_MUL(scratch[8].r,yb.r)));
289 scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); 289 scratch[5].i = ADD32_ovflw(scratch[0].i, ADD32_ovflw(S_MUL(scratch[7].i,ya.r), S_MUL(scratch[8].i,yb.r)));
290 290
291 scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i); 291 scratch[6].r = ADD32_ovflw(S_MUL(scratch[10].i,ya.i), S_MUL(scratch[9].i,yb.i));
292 scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i); 292 scratch[6].i = NEG32_ovflw(ADD32_ovflw(S_MUL(scratch[10].r,ya.i), S_MUL(scratch[9].r,yb.i)));
293 293
294 C_SUB(*Fout1,scratch[5],scratch[6]); 294 C_SUB(*Fout1,scratch[5],scratch[6]);
295 C_ADD(*Fout4,scratch[5],scratch[6]); 295 C_ADD(*Fout4,scratch[5],scratch[6]);
296 296
297 scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); 297 scratch[11].r = ADD32_ovflw(scratch[0].r, ADD32_ovflw(S_MUL(scratch[7].r,yb.r), S_MUL(scratch[8].r,ya.r)));
298 scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); 298 scratch[11].i = ADD32_ovflw(scratch[0].i, ADD32_ovflw(S_MUL(scratch[7].i,yb.r), S_MUL(scratch[8].i,ya.r)));
299 scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i); 299 scratch[12].r = SUB32_ovflw(S_MUL(scratch[9].i,ya.i), S_MUL(scratch[10].i,yb.i));
300 scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i); 300 scratch[12].i = SUB32_ovflw(S_MUL(scratch[10].r,yb.i), S_MUL(scratch[9].r,ya.i));
301 301
302 C_ADD(*Fout2,scratch[11],scratch[12]); 302 C_ADD(*Fout2,scratch[11],scratch[12]);
303 C_SUB(*Fout3,scratch[11],scratch[12]); 303 C_SUB(*Fout3,scratch[11],scratch[12]);
@@ -423,13 +423,19 @@ static void compute_twiddles(kiss_twiddle_cpx *twiddles, int nfft)
423#endif 423#endif
424} 424}
425 425
426int opus_fft_alloc_arch_c(kiss_fft_state *st) {
427 (void)st;
428 return 0;
429}
430
426/* 431/*
427 * 432 *
428 * Allocates all necessary storage space for the fft and ifft. 433 * Allocates all necessary storage space for the fft and ifft.
429 * The return value is a contiguous block of memory. As such, 434 * The return value is a contiguous block of memory. As such,
430 * It can be freed with free(). 435 * It can be freed with free().
431 * */ 436 * */
432kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, const kiss_fft_state *base) 437kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem,
438 const kiss_fft_state *base, int arch)
433{ 439{
434 kiss_fft_state *st=NULL; 440 kiss_fft_state *st=NULL;
435 size_t memneeded = sizeof(struct kiss_fft_state); /* twiddle factors*/ 441 size_t memneeded = sizeof(struct kiss_fft_state); /* twiddle factors*/
@@ -478,22 +484,31 @@ kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, co
478 if (st->bitrev==NULL) 484 if (st->bitrev==NULL)
479 goto fail; 485 goto fail;
480 compute_bitrev_table(0, bitrev, 1,1, st->factors,st); 486 compute_bitrev_table(0, bitrev, 1,1, st->factors,st);
487
488 /* Initialize architecture specific fft parameters */
489 if (opus_fft_alloc_arch(st, arch))
490 goto fail;
481 } 491 }
482 return st; 492 return st;
483fail: 493fail:
484 opus_fft_free(st); 494 opus_fft_free(st, arch);
485 return NULL; 495 return NULL;
486} 496}
487 497
488kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem ) 498kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem, int arch)
489{ 499{
490 return opus_fft_alloc_twiddles(nfft, mem, lenmem, NULL); 500 return opus_fft_alloc_twiddles(nfft, mem, lenmem, NULL, arch);
491} 501}
492 502
493void opus_fft_free(const kiss_fft_state *cfg) 503void opus_fft_free_arch_c(kiss_fft_state *st) {
504 (void)st;
505}
506
507void opus_fft_free(const kiss_fft_state *cfg, int arch)
494{ 508{
495 if (cfg) 509 if (cfg)
496 { 510 {
511 opus_fft_free_arch((kiss_fft_state *)cfg, arch);
497 opus_free((opus_int16*)cfg->bitrev); 512 opus_free((opus_int16*)cfg->bitrev);
498 if (cfg->shift < 0) 513 if (cfg->shift < 0)
499 opus_free((kiss_twiddle_cpx*)cfg->twiddles); 514 opus_free((kiss_twiddle_cpx*)cfg->twiddles);
@@ -551,8 +566,7 @@ void opus_fft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout)
551 } 566 }
552} 567}
553 568
554#if 0 569void opus_fft_c(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
555void opus_fft(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
556{ 570{
557 int i; 571 int i;
558 opus_val16 scale; 572 opus_val16 scale;
@@ -573,11 +587,9 @@ void opus_fft(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fou
573 } 587 }
574 opus_fft_impl(st, fout); 588 opus_fft_impl(st, fout);
575} 589}
576#endif
577 590
578 591
579#ifdef TEST_UNIT_DFT_C 592void opus_ifft_c(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
580void opus_ifft(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout)
581{ 593{
582 int i; 594 int i;
583 celt_assert2 (fin != fout, "In-place FFT not supported"); 595 celt_assert2 (fin != fout, "In-place FFT not supported");
@@ -590,4 +602,3 @@ void opus_ifft(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fo
590 for (i=0;i<st->nfft;i++) 602 for (i=0;i<st->nfft;i++)
591 fout[i].i = -fout[i].i; 603 fout[i].i = -fout[i].i;
592} 604}
593#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/kiss_fft.h b/lib/rbcodec/codecs/libopus/celt/kiss_fft.h
index 390b54d948..bffa2bfad6 100644
--- a/lib/rbcodec/codecs/libopus/celt/kiss_fft.h
+++ b/lib/rbcodec/codecs/libopus/celt/kiss_fft.h
@@ -32,6 +32,7 @@
32#include <stdlib.h> 32#include <stdlib.h>
33#include <math.h> 33#include <math.h>
34#include "arch.h" 34#include "arch.h"
35#include "cpu_support.h"
35 36
36#ifdef __cplusplus 37#ifdef __cplusplus
37extern "C" { 38extern "C" {
@@ -77,6 +78,11 @@ typedef struct {
77 4*4*4*2 78 4*4*4*2
78 */ 79 */
79 80
81typedef struct arch_fft_state{
82 int is_supported;
83 void *priv;
84} arch_fft_state;
85
80typedef struct kiss_fft_state{ 86typedef struct kiss_fft_state{
81 int nfft; 87 int nfft;
82 opus_val16 scale; 88 opus_val16 scale;
@@ -87,8 +93,13 @@ typedef struct kiss_fft_state{
87 opus_int16 factors[2*MAXFACTORS]; 93 opus_int16 factors[2*MAXFACTORS];
88 const opus_int16 *bitrev; 94 const opus_int16 *bitrev;
89 const kiss_twiddle_cpx *twiddles; 95 const kiss_twiddle_cpx *twiddles;
96 arch_fft_state *arch_fft;
90} kiss_fft_state; 97} kiss_fft_state;
91 98
99#if defined(HAVE_ARM_NE10)
100#include "arm/fft_arm.h"
101#endif
102
92/*typedef struct kiss_fft_state* kiss_fft_cfg;*/ 103/*typedef struct kiss_fft_state* kiss_fft_cfg;*/
93 104
94/** 105/**
@@ -114,9 +125,9 @@ typedef struct kiss_fft_state{
114 * buffer size in *lenmem. 125 * buffer size in *lenmem.
115 * */ 126 * */
116 127
117kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, const kiss_fft_state *base); 128kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, const kiss_fft_state *base, int arch);
118 129
119kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem); 130kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem, int arch);
120 131
121/** 132/**
122 * opus_fft(cfg,in_out_buf) 133 * opus_fft(cfg,in_out_buf)
@@ -128,13 +139,59 @@ kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem);
128 * Note that each element is complex and can be accessed like 139 * Note that each element is complex and can be accessed like
129 f[k].r and f[k].i 140 f[k].r and f[k].i
130 * */ 141 * */
131void opus_fft(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); 142void opus_fft_c(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
132void opus_ifft(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); 143void opus_ifft_c(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout);
133 144
134void opus_fft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout); 145void opus_fft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout);
135void opus_ifft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout); 146void opus_ifft_impl(const kiss_fft_state *st,kiss_fft_cpx *fout);
136 147
137void opus_fft_free(const kiss_fft_state *cfg); 148void opus_fft_free(const kiss_fft_state *cfg, int arch);
149
150
151void opus_fft_free_arch_c(kiss_fft_state *st);
152int opus_fft_alloc_arch_c(kiss_fft_state *st);
153
154#if !defined(OVERRIDE_OPUS_FFT)
155/* Is run-time CPU detection enabled on this platform? */
156#if defined(OPUS_HAVE_RTCD) && (defined(HAVE_ARM_NE10))
157
158extern int (*const OPUS_FFT_ALLOC_ARCH_IMPL[OPUS_ARCHMASK+1])(
159 kiss_fft_state *st);
160
161#define opus_fft_alloc_arch(_st, arch) \
162 ((*OPUS_FFT_ALLOC_ARCH_IMPL[(arch)&OPUS_ARCHMASK])(_st))
163
164extern void (*const OPUS_FFT_FREE_ARCH_IMPL[OPUS_ARCHMASK+1])(
165 kiss_fft_state *st);
166#define opus_fft_free_arch(_st, arch) \
167 ((*OPUS_FFT_FREE_ARCH_IMPL[(arch)&OPUS_ARCHMASK])(_st))
168
169extern void (*const OPUS_FFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg,
170 const kiss_fft_cpx *fin, kiss_fft_cpx *fout);
171#define opus_fft(_cfg, _fin, _fout, arch) \
172 ((*OPUS_FFT[(arch)&OPUS_ARCHMASK])(_cfg, _fin, _fout))
173
174extern void (*const OPUS_IFFT[OPUS_ARCHMASK+1])(const kiss_fft_state *cfg,
175 const kiss_fft_cpx *fin, kiss_fft_cpx *fout);
176#define opus_ifft(_cfg, _fin, _fout, arch) \
177 ((*OPUS_IFFT[(arch)&OPUS_ARCHMASK])(_cfg, _fin, _fout))
178
179#else /* else for if defined(OPUS_HAVE_RTCD) && (defined(HAVE_ARM_NE10)) */
180
181#define opus_fft_alloc_arch(_st, arch) \
182 ((void)(arch), opus_fft_alloc_arch_c(_st))
183
184#define opus_fft_free_arch(_st, arch) \
185 ((void)(arch), opus_fft_free_arch_c(_st))
186
187#define opus_fft(_cfg, _fin, _fout, arch) \
188 ((void)(arch), opus_fft_c(_cfg, _fin, _fout))
189
190#define opus_ifft(_cfg, _fin, _fout, arch) \
191 ((void)(arch), opus_ifft_c(_cfg, _fin, _fout))
192
193#endif /* end if defined(OPUS_HAVE_RTCD) && (defined(HAVE_ARM_NE10)) */
194#endif /* end if !defined(OVERRIDE_OPUS_FFT) */
138 195
139#ifdef __cplusplus 196#ifdef __cplusplus
140} 197}
diff --git a/lib/rbcodec/codecs/libopus/celt/mathops.c b/lib/rbcodec/codecs/libopus/celt/mathops.c
index 3f8c5dcc0e..6ee9b9e101 100644
--- a/lib/rbcodec/codecs/libopus/celt/mathops.c
+++ b/lib/rbcodec/codecs/libopus/celt/mathops.c
@@ -38,7 +38,8 @@
38#include "mathops.h" 38#include "mathops.h"
39 39
40/*Compute floor(sqrt(_val)) with exact arithmetic. 40/*Compute floor(sqrt(_val)) with exact arithmetic.
41 This has been tested on all possible 32-bit inputs.*/ 41 _val must be greater than 0.
42 This has been tested on all possible 32-bit inputs greater than 0.*/
42unsigned isqrt32(opus_uint32 _val){ 43unsigned isqrt32(opus_uint32 _val){
43 unsigned b; 44 unsigned b;
44 unsigned g; 45 unsigned g;
@@ -164,7 +165,7 @@ opus_val16 celt_cos_norm(opus_val32 x)
164 { 165 {
165 return _celt_cos_pi_2(EXTRACT16(x)); 166 return _celt_cos_pi_2(EXTRACT16(x));
166 } else { 167 } else {
167 return NEG32(_celt_cos_pi_2(EXTRACT16(65536-x))); 168 return NEG16(_celt_cos_pi_2(EXTRACT16(65536-x)));
168 } 169 }
169 } else { 170 } else {
170 if (x&0x0000ffff) 171 if (x&0x0000ffff)
@@ -182,7 +183,7 @@ opus_val32 celt_rcp(opus_val32 x)
182 int i; 183 int i;
183 opus_val16 n; 184 opus_val16 n;
184 opus_val16 r; 185 opus_val16 r;
185 celt_assert2(x>0, "celt_rcp() only defined for positive values"); 186 celt_sig_assert(x>0);
186 i = celt_ilog2(x); 187 i = celt_ilog2(x);
187 /* n is Q15 with range [0,1). */ 188 /* n is Q15 with range [0,1). */
188 n = VSHR32(x,i-15)-32768; 189 n = VSHR32(x,i-15)-32768;
diff --git a/lib/rbcodec/codecs/libopus/celt/mathops.h b/lib/rbcodec/codecs/libopus/celt/mathops.h
index a0525a9610..f3e5246a39 100644
--- a/lib/rbcodec/codecs/libopus/celt/mathops.h
+++ b/lib/rbcodec/codecs/libopus/celt/mathops.h
@@ -38,11 +38,48 @@
38#include "entcode.h" 38#include "entcode.h"
39#include "os_support.h" 39#include "os_support.h"
40 40
41#define PI 3.141592653f
42
43#ifndef ABS
44#define ABS(a)(((a) < 0) ? - (a) :(a))
45#endif
46
41/* Multiplies two 16-bit fractional values. Bit-exactness of this macro is important */ 47/* Multiplies two 16-bit fractional values. Bit-exactness of this macro is important */
42#define FRAC_MUL16(a,b) ((16384+((opus_int32)(opus_int16)(a)*(opus_int16)(b)))>>15) 48#define FRAC_MUL16(a,b) ((16384+((opus_int32)(opus_int16)(a)*(opus_int16)(b)))>>15)
43 49
44unsigned isqrt32(opus_uint32 _val); 50unsigned isqrt32(opus_uint32 _val);
45 51
52/* CELT doesn't need it for fixed-point, by analysis.c does. */
53#if !defined(FIXED_POINT) || defined(ANALYSIS_C)
54#define cA 0.43157974f
55#define cB 0.67848403f
56#define cC 0.08595542f
57#define cE ((float)PI/2)
58static OPUS_INLINE float fast_atan2f(float y, float x) {
59 float x2, y2;
60 x2 = x*x;
61 y2 = y*y;
62 /* For very small values, we don't care about the answer, so
63 we can just return 0. */
64 if (x2 + y2 < 1e-18f)
65 {
66 return 0;
67 }
68 if(x2<y2){
69 float den = (y2 + cB*x2) * (y2 + cC*x2);
70 return -x*y*(y2 + cA*x2) / den + (y<0 ? -cE : cE);
71 }else{
72 float den = (x2 + cB*y2) * (x2 + cC*y2);
73 return x*y*(x2 + cA*y2) / den + (y<0 ? -cE : cE) - (x*y<0 ? -cE : cE);
74 }
75}
76#undef cA
77#undef cB
78#undef cC
79#undef cE
80#endif
81
82
46#ifndef OVERRIDE_CELT_MAXABS16 83#ifndef OVERRIDE_CELT_MAXABS16
47static OPUS_INLINE opus_val32 celt_maxabs16(const opus_val16 *x, int len) 84static OPUS_INLINE opus_val32 celt_maxabs16(const opus_val16 *x, int len)
48{ 85{
@@ -80,7 +117,6 @@ static OPUS_INLINE opus_val32 celt_maxabs32(const opus_val32 *x, int len)
80 117
81#ifndef FIXED_POINT 118#ifndef FIXED_POINT
82 119
83#define PI 3.141592653f
84#define celt_sqrt(x) ((float)sqrt(x)) 120#define celt_sqrt(x) ((float)sqrt(x))
85#define celt_rsqrt(x) (1.f/celt_sqrt(x)) 121#define celt_rsqrt(x) (1.f/celt_sqrt(x))
86#define celt_rsqrt_norm(x) (celt_rsqrt(x)) 122#define celt_rsqrt_norm(x) (celt_rsqrt(x))
@@ -147,7 +183,7 @@ static OPUS_INLINE float celt_exp2(float x)
147/** Integer log in base2. Undefined for zero and negative numbers */ 183/** Integer log in base2. Undefined for zero and negative numbers */
148static OPUS_INLINE opus_int16 celt_ilog2(opus_int32 x) 184static OPUS_INLINE opus_int16 celt_ilog2(opus_int32 x)
149{ 185{
150 celt_assert2(x>0, "celt_ilog2() only defined for strictly positive numbers"); 186 celt_sig_assert(x>0);
151 return EC_ILOG(x)-1; 187 return EC_ILOG(x)-1;
152} 188}
153#endif 189#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/mdct.c b/lib/rbcodec/codecs/libopus/celt/mdct.c
index 7fa8eaf6bf..5c6dab5b75 100644
--- a/lib/rbcodec/codecs/libopus/celt/mdct.c
+++ b/lib/rbcodec/codecs/libopus/celt/mdct.c
@@ -60,7 +60,7 @@
60 60
61#ifdef CUSTOM_MODES 61#ifdef CUSTOM_MODES
62 62
63int clt_mdct_init(mdct_lookup *l,int N, int maxshift) 63int clt_mdct_init(mdct_lookup *l,int N, int maxshift, int arch)
64{ 64{
65 int i; 65 int i;
66 kiss_twiddle_scalar *trig; 66 kiss_twiddle_scalar *trig;
@@ -71,9 +71,9 @@ int clt_mdct_init(mdct_lookup *l,int N, int maxshift)
71 for (i=0;i<=maxshift;i++) 71 for (i=0;i<=maxshift;i++)
72 { 72 {
73 if (i==0) 73 if (i==0)
74 l->kfft[i] = opus_fft_alloc(N>>2>>i, 0, 0); 74 l->kfft[i] = opus_fft_alloc(N>>2>>i, 0, 0, arch);
75 else 75 else
76 l->kfft[i] = opus_fft_alloc_twiddles(N>>2>>i, 0, 0, l->kfft[0]); 76 l->kfft[i] = opus_fft_alloc_twiddles(N>>2>>i, 0, 0, l->kfft[0], arch);
77#ifndef ENABLE_TI_DSPLIB55 77#ifndef ENABLE_TI_DSPLIB55
78 if (l->kfft[i]==NULL) 78 if (l->kfft[i]==NULL)
79 return 0; 79 return 0;
@@ -104,21 +104,20 @@ int clt_mdct_init(mdct_lookup *l,int N, int maxshift)
104 return 1; 104 return 1;
105} 105}
106 106
107void clt_mdct_clear(mdct_lookup *l) 107void clt_mdct_clear(mdct_lookup *l, int arch)
108{ 108{
109 int i; 109 int i;
110 for (i=0;i<=l->maxshift;i++) 110 for (i=0;i<=l->maxshift;i++)
111 opus_fft_free(l->kfft[i]); 111 opus_fft_free(l->kfft[i], arch);
112 opus_free((kiss_twiddle_scalar*)l->trig); 112 opus_free((kiss_twiddle_scalar*)l->trig);
113} 113}
114 114
115#endif /* CUSTOM_MODES */ 115#endif /* CUSTOM_MODES */
116 116
117#if 0
118/* Forward MDCT trashes the input array */ 117/* Forward MDCT trashes the input array */
119#ifndef OVERRIDE_clt_mdct_forward 118#ifndef OVERRIDE_clt_mdct_forward
120void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, 119void clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,
121 const opus_val16 *window, int overlap, int shift, int stride) 120 const opus_val16 *window, int overlap, int shift, int stride, int arch)
122{ 121{
123 int i; 122 int i;
124 int N, N2, N4; 123 int N, N2, N4;
@@ -133,6 +132,7 @@ void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar
133 int scale_shift = st->scale_shift-1; 132 int scale_shift = st->scale_shift-1;
134#endif 133#endif
135 SAVE_STACK; 134 SAVE_STACK;
135 (void)arch;
136 scale = st->scale; 136 scale = st->scale;
137 137
138 N = l->n; 138 N = l->n;
@@ -237,15 +237,15 @@ void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar
237 RESTORE_STACK; 237 RESTORE_STACK;
238} 238}
239#endif /* OVERRIDE_clt_mdct_forward */ 239#endif /* OVERRIDE_clt_mdct_forward */
240#endif
241 240
242#ifndef OVERRIDE_clt_mdct_backward 241#ifndef OVERRIDE_clt_mdct_backward
243void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, 242void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,
244 const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride) 243 const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride, int arch)
245{ 244{
246 int i; 245 int i;
247 int N, N2, N4; 246 int N, N2, N4;
248 const kiss_twiddle_scalar *trig; 247 const kiss_twiddle_scalar *trig;
248 (void) arch;
249 249
250 N = l->n; 250 N = l->n;
251 trig = l->trig; 251 trig = l->trig;
@@ -270,8 +270,8 @@ void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scala
270 int rev; 270 int rev;
271 kiss_fft_scalar yr, yi; 271 kiss_fft_scalar yr, yi;
272 rev = *bitrev++; 272 rev = *bitrev++;
273 yr = S_MUL(*xp2, t[i]) + S_MUL(*xp1, t[N4+i]); 273 yr = ADD32_ovflw(S_MUL(*xp2, t[i]), S_MUL(*xp1, t[N4+i]));
274 yi = S_MUL(*xp1, t[i]) - S_MUL(*xp2, t[N4+i]); 274 yi = SUB32_ovflw(S_MUL(*xp1, t[i]), S_MUL(*xp2, t[N4+i]));
275 /* We swap real and imag because we use an FFT instead of an IFFT. */ 275 /* We swap real and imag because we use an FFT instead of an IFFT. */
276 yp[2*rev+1] = yr; 276 yp[2*rev+1] = yr;
277 yp[2*rev] = yi; 277 yp[2*rev] = yi;
@@ -301,8 +301,8 @@ void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scala
301 t0 = t[i]; 301 t0 = t[i];
302 t1 = t[N4+i]; 302 t1 = t[N4+i];
303 /* We'd scale up by 2 here, but instead it's done when mixing the windows */ 303 /* We'd scale up by 2 here, but instead it's done when mixing the windows */
304 yr = S_MUL(re,t0) + S_MUL(im,t1); 304 yr = ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1));
305 yi = S_MUL(re,t1) - S_MUL(im,t0); 305 yi = SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0));
306 /* We swap real and imag because we're using an FFT instead of an IFFT. */ 306 /* We swap real and imag because we're using an FFT instead of an IFFT. */
307 re = yp1[1]; 307 re = yp1[1];
308 im = yp1[0]; 308 im = yp1[0];
@@ -312,8 +312,8 @@ void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scala
312 t0 = t[(N4-i-1)]; 312 t0 = t[(N4-i-1)];
313 t1 = t[(N2-i-1)]; 313 t1 = t[(N2-i-1)];
314 /* We'd scale up by 2 here, but instead it's done when mixing the windows */ 314 /* We'd scale up by 2 here, but instead it's done when mixing the windows */
315 yr = S_MUL(re,t0) + S_MUL(im,t1); 315 yr = ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1));
316 yi = S_MUL(re,t1) - S_MUL(im,t0); 316 yi = SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0));
317 yp1[0] = yr; 317 yp1[0] = yr;
318 yp0[1] = yi; 318 yp0[1] = yi;
319 yp0 += 2; 319 yp0 += 2;
@@ -333,8 +333,8 @@ void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scala
333 kiss_fft_scalar x1, x2; 333 kiss_fft_scalar x1, x2;
334 x1 = *xp1; 334 x1 = *xp1;
335 x2 = *yp1; 335 x2 = *yp1;
336 *yp1++ = MULT16_32_Q15(*wp2, x2) - MULT16_32_Q15(*wp1, x1); 336 *yp1++ = SUB32_ovflw(MULT16_32_Q15(*wp2, x2), MULT16_32_Q15(*wp1, x1));
337 *xp1-- = MULT16_32_Q15(*wp1, x2) + MULT16_32_Q15(*wp2, x1); 337 *xp1-- = ADD32_ovflw(MULT16_32_Q15(*wp1, x2), MULT16_32_Q15(*wp2, x1));
338 wp1++; 338 wp1++;
339 wp2--; 339 wp2--;
340 } 340 }
diff --git a/lib/rbcodec/codecs/libopus/celt/mdct.h b/lib/rbcodec/codecs/libopus/celt/mdct.h
index d72182138a..160ae4e0f3 100644
--- a/lib/rbcodec/codecs/libopus/celt/mdct.h
+++ b/lib/rbcodec/codecs/libopus/celt/mdct.h
@@ -53,18 +53,60 @@ typedef struct {
53 const kiss_twiddle_scalar * OPUS_RESTRICT trig; 53 const kiss_twiddle_scalar * OPUS_RESTRICT trig;
54} mdct_lookup; 54} mdct_lookup;
55 55
56int clt_mdct_init(mdct_lookup *l,int N, int maxshift); 56#if defined(HAVE_ARM_NE10)
57void clt_mdct_clear(mdct_lookup *l); 57#include "arm/mdct_arm.h"
58#endif
59
60
61int clt_mdct_init(mdct_lookup *l,int N, int maxshift, int arch);
62void clt_mdct_clear(mdct_lookup *l, int arch);
58 63
59/** Compute a forward MDCT and scale by 4/N, trashes the input array */ 64/** Compute a forward MDCT and scale by 4/N, trashes the input array */
60void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, 65void clt_mdct_forward_c(const mdct_lookup *l, kiss_fft_scalar *in,
61 kiss_fft_scalar * OPUS_RESTRICT out, 66 kiss_fft_scalar * OPUS_RESTRICT out,
62 const opus_val16 *window, int overlap, int shift, int stride); 67 const opus_val16 *window, int overlap,
68 int shift, int stride, int arch);
63 69
64/** Compute a backward MDCT (no scaling) and performs weighted overlap-add 70/** Compute a backward MDCT (no scaling) and performs weighted overlap-add
65 (scales implicitly by 1/2) */ 71 (scales implicitly by 1/2) */
66void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, 72void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in,
67 kiss_fft_scalar * OPUS_RESTRICT out, 73 kiss_fft_scalar * OPUS_RESTRICT out,
68 const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride); 74 const opus_val16 * OPUS_RESTRICT window,
75 int overlap, int shift, int stride, int arch);
76
77#if !defined(OVERRIDE_OPUS_MDCT)
78/* Is run-time CPU detection enabled on this platform? */
79#if defined(OPUS_HAVE_RTCD) && defined(HAVE_ARM_NE10)
80
81extern void (*const CLT_MDCT_FORWARD_IMPL[OPUS_ARCHMASK+1])(
82 const mdct_lookup *l, kiss_fft_scalar *in,
83 kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window,
84 int overlap, int shift, int stride, int arch);
85
86#define clt_mdct_forward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \
87 ((*CLT_MDCT_FORWARD_IMPL[(arch)&OPUS_ARCHMASK])(_l, _in, _out, \
88 _window, _overlap, _shift, \
89 _stride, _arch))
90
91extern void (*const CLT_MDCT_BACKWARD_IMPL[OPUS_ARCHMASK+1])(
92 const mdct_lookup *l, kiss_fft_scalar *in,
93 kiss_fft_scalar * OPUS_RESTRICT out, const opus_val16 *window,
94 int overlap, int shift, int stride, int arch);
95
96#define clt_mdct_backward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \
97 (*CLT_MDCT_BACKWARD_IMPL[(arch)&OPUS_ARCHMASK])(_l, _in, _out, \
98 _window, _overlap, _shift, \
99 _stride, _arch)
100
101#else /* if defined(OPUS_HAVE_RTCD) && defined(HAVE_ARM_NE10) */
102
103#define clt_mdct_forward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \
104 clt_mdct_forward_c(_l, _in, _out, _window, _overlap, _shift, _stride, _arch)
105
106#define clt_mdct_backward(_l, _in, _out, _window, _overlap, _shift, _stride, _arch) \
107 clt_mdct_backward_c(_l, _in, _out, _window, _overlap, _shift, _stride, _arch)
108
109#endif /* end if defined(OPUS_HAVE_RTCD) && defined(HAVE_ARM_NE10) && !defined(FIXED_POINT) */
110#endif /* end if !defined(OVERRIDE_OPUS_MDCT) */
69 111
70#endif 112#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/mips/celt_mipsr1.h b/lib/rbcodec/codecs/libopus/celt/mips/celt_mipsr1.h
new file mode 100644
index 0000000000..e85661a661
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/mips/celt_mipsr1.h
@@ -0,0 +1,151 @@
1/* Copyright (c) 2007-2008 CSIRO
2 Copyright (c) 2007-2010 Xiph.Org Foundation
3 Copyright (c) 2008 Gregory Maxwell
4 Written by Jean-Marc Valin and Gregory Maxwell */
5/*
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions
8 are met:
9
10 - Redistributions of source code must retain the above copyright
11 notice, this list of conditions and the following disclaimer.
12
13 - Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30#ifndef __CELT_MIPSR1_H__
31#define __CELT_MIPSR1_H__
32
33#ifdef HAVE_CONFIG_H
34#include "config.h"
35#endif
36
37#define CELT_C
38
39#include "os_support.h"
40#include "mdct.h"
41#include <math.h>
42#include "celt.h"
43#include "pitch.h"
44#include "bands.h"
45#include "modes.h"
46#include "entcode.h"
47#include "quant_bands.h"
48#include "rate.h"
49#include "stack_alloc.h"
50#include "mathops.h"
51#include "float_cast.h"
52#include <stdarg.h>
53#include "celt_lpc.h"
54#include "vq.h"
55
56#define OVERRIDE_comb_filter
57void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
58 opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
59 const opus_val16 *window, int overlap, int arch)
60{
61 int i;
62 opus_val32 x0, x1, x2, x3, x4;
63
64 (void)arch;
65
66 /* printf ("%d %d %f %f\n", T0, T1, g0, g1); */
67 opus_val16 g00, g01, g02, g10, g11, g12;
68 static const opus_val16 gains[3][3] = {
69 {QCONST16(0.3066406250f, 15), QCONST16(0.2170410156f, 15), QCONST16(0.1296386719f, 15)},
70 {QCONST16(0.4638671875f, 15), QCONST16(0.2680664062f, 15), QCONST16(0.f, 15)},
71 {QCONST16(0.7998046875f, 15), QCONST16(0.1000976562f, 15), QCONST16(0.f, 15)}};
72
73 if (g0==0 && g1==0)
74 {
75 /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
76 if (x!=y)
77 OPUS_MOVE(y, x, N);
78 return;
79 }
80
81 g00 = MULT16_16_P15(g0, gains[tapset0][0]);
82 g01 = MULT16_16_P15(g0, gains[tapset0][1]);
83 g02 = MULT16_16_P15(g0, gains[tapset0][2]);
84 g10 = MULT16_16_P15(g1, gains[tapset1][0]);
85 g11 = MULT16_16_P15(g1, gains[tapset1][1]);
86 g12 = MULT16_16_P15(g1, gains[tapset1][2]);
87 x1 = x[-T1+1];
88 x2 = x[-T1 ];
89 x3 = x[-T1-1];
90 x4 = x[-T1-2];
91 /* If the filter didn't change, we don't need the overlap */
92 if (g0==g1 && T0==T1 && tapset0==tapset1)
93 overlap=0;
94
95 for (i=0;i<overlap;i++)
96 {
97 opus_val16 f;
98 opus_val32 res;
99 f = MULT16_16_Q15(window[i],window[i]);
100 x0= x[i-T1+2];
101
102 asm volatile("MULT $ac1, %0, %1" : : "r" ((int)MULT16_16_Q15((Q15ONE-f),g00)), "r" ((int)x[i-T0]));
103
104 asm volatile("MADD $ac1, %0, %1" : : "r" ((int)MULT16_16_Q15((Q15ONE-f),g01)), "r" ((int)ADD32(x[i-T0-1],x[i-T0+1])));
105 asm volatile("MADD $ac1, %0, %1" : : "r" ((int)MULT16_16_Q15((Q15ONE-f),g02)), "r" ((int)ADD32(x[i-T0-2],x[i-T0+2])));
106 asm volatile("MADD $ac1, %0, %1" : : "r" ((int)MULT16_16_Q15(f,g10)), "r" ((int)x2));
107 asm volatile("MADD $ac1, %0, %1" : : "r" ((int)MULT16_16_Q15(f,g11)), "r" ((int)ADD32(x3,x1)));
108 asm volatile("MADD $ac1, %0, %1" : : "r" ((int)MULT16_16_Q15(f,g12)), "r" ((int)ADD32(x4,x0)));
109
110 asm volatile("EXTR.W %0,$ac1, %1" : "=r" (res): "i" (15));
111
112 y[i] = x[i] + res;
113
114 x4=x3;
115 x3=x2;
116 x2=x1;
117 x1=x0;
118 }
119
120 x4 = x[i-T1-2];
121 x3 = x[i-T1-1];
122 x2 = x[i-T1];
123 x1 = x[i-T1+1];
124
125 if (g1==0)
126 {
127 /* OPT: Happens to work without the OPUS_MOVE(), but only because the current encoder already copies x to y */
128 if (x!=y)
129 OPUS_MOVE(y+overlap, x+overlap, N-overlap);
130 return;
131 }
132
133 for (i=overlap;i<N;i++)
134 {
135 opus_val32 res;
136 x0=x[i-T1+2];
137
138 asm volatile("MULT $ac1, %0, %1" : : "r" ((int)g10), "r" ((int)x2));
139
140 asm volatile("MADD $ac1, %0, %1" : : "r" ((int)g11), "r" ((int)ADD32(x3,x1)));
141 asm volatile("MADD $ac1, %0, %1" : : "r" ((int)g12), "r" ((int)ADD32(x4,x0)));
142 asm volatile("EXTR.W %0,$ac1, %1" : "=r" (res): "i" (15));
143 y[i] = x[i] + res;
144 x4=x3;
145 x3=x2;
146 x2=x1;
147 x1=x0;
148 }
149}
150
151#endif /* __CELT_MIPSR1_H__ */
diff --git a/lib/rbcodec/codecs/libopus/celt/mips/fixed_generic_mipsr1.h b/lib/rbcodec/codecs/libopus/celt/mips/fixed_generic_mipsr1.h
new file mode 100644
index 0000000000..4a05efbf85
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/mips/fixed_generic_mipsr1.h
@@ -0,0 +1,126 @@
1/* Copyright (C) 2007-2009 Xiph.Org Foundation
2 Copyright (C) 2003-2008 Jean-Marc Valin
3 Copyright (C) 2007-2008 CSIRO */
4/**
5 @file fixed_generic.h
6 @brief Generic fixed-point operations
7*/
8/*
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions
11 are met:
12
13 - Redistributions of source code must retain the above copyright
14 notice, this list of conditions and the following disclaimer.
15
16 - Redistributions in binary form must reproduce the above copyright
17 notice, this list of conditions and the following disclaimer in the
18 documentation and/or other materials provided with the distribution.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
24 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#ifndef CELT_FIXED_GENERIC_MIPSR1_H
34#define CELT_FIXED_GENERIC_MIPSR1_H
35
36#undef MULT16_32_Q15_ADD
37static inline int MULT16_32_Q15_ADD(int a, int b, int c, int d) {
38 int m;
39 asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
40 asm volatile("madd $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
41 asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
42 return m;
43}
44
45#undef MULT16_32_Q15_SUB
46static inline int MULT16_32_Q15_SUB(int a, int b, int c, int d) {
47 int m;
48 asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
49 asm volatile("msub $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
50 asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
51 return m;
52}
53
54#undef MULT16_16_Q15_ADD
55static inline int MULT16_16_Q15_ADD(int a, int b, int c, int d) {
56 int m;
57 asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
58 asm volatile("madd $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
59 asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
60 return m;
61}
62
63#undef MULT16_16_Q15_SUB
64static inline int MULT16_16_Q15_SUB(int a, int b, int c, int d) {
65 int m;
66 asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
67 asm volatile("msub $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
68 asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
69 return m;
70}
71
72
73#undef MULT16_32_Q16
74static inline int MULT16_32_Q16(int a, int b)
75{
76 int c;
77 asm volatile("MULT $ac1,%0, %1" : : "r" (a), "r" (b));
78 asm volatile("EXTR.W %0,$ac1, %1" : "=r" (c): "i" (16));
79 return c;
80}
81
82#undef MULT16_32_P16
83static inline int MULT16_32_P16(int a, int b)
84{
85 int c;
86 asm volatile("MULT $ac1, %0, %1" : : "r" (a), "r" (b));
87 asm volatile("EXTR_R.W %0,$ac1, %1" : "=r" (c): "i" (16));
88 return c;
89}
90
91#undef MULT16_32_Q15
92static inline int MULT16_32_Q15(int a, int b)
93{
94 int c;
95 asm volatile("MULT $ac1, %0, %1" : : "r" (a), "r" (b));
96 asm volatile("EXTR.W %0,$ac1, %1" : "=r" (c): "i" (15));
97 return c;
98}
99
100#undef MULT32_32_Q31
101static inline int MULT32_32_Q31(int a, int b)
102{
103 int r;
104 asm volatile("MULT $ac1, %0, %1" : : "r" (a), "r" (b));
105 asm volatile("EXTR.W %0,$ac1, %1" : "=r" (r): "i" (31));
106 return r;
107}
108
109#undef PSHR32
110static inline int PSHR32(int a, int shift)
111{
112 int r;
113 asm volatile ("SHRAV_R.W %0, %1, %2" :"=r" (r): "r" (a), "r" (shift));
114 return r;
115}
116
117#undef MULT16_16_P15
118static inline int MULT16_16_P15(int a, int b)
119{
120 int r;
121 asm volatile ("mul %0, %1, %2" :"=r" (r): "r" (a), "r" (b));
122 asm volatile ("SHRA_R.W %0, %1, %2" : "+r" (r): "0" (r), "i"(15));
123 return r;
124}
125
126#endif /* CELT_FIXED_GENERIC_MIPSR1_H */
diff --git a/lib/rbcodec/codecs/libopus/celt/mips/kiss_fft_mipsr1.h b/lib/rbcodec/codecs/libopus/celt/mips/kiss_fft_mipsr1.h
new file mode 100644
index 0000000000..400ca4de9c
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/mips/kiss_fft_mipsr1.h
@@ -0,0 +1,167 @@
1/*Copyright (c) 2013, Xiph.Org Foundation and contributors.
2
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright notice,
11 this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 POSSIBILITY OF SUCH DAMAGE.*/
25
26#ifndef KISS_FFT_MIPSR1_H
27#define KISS_FFT_MIPSR1_H
28
29#if !defined(KISS_FFT_GUTS_H)
30#error "This file should only be included from _kiss_fft_guts.h"
31#endif
32
33#ifdef FIXED_POINT
34
35#define S_MUL_ADD(a, b, c, d) (S_MUL(a,b)+S_MUL(c,d))
36#define S_MUL_SUB(a, b, c, d) (S_MUL(a,b)-S_MUL(c,d))
37
38#undef S_MUL_ADD
39static inline int S_MUL_ADD(int a, int b, int c, int d) {
40 int m;
41 asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
42 asm volatile("madd $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
43 asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
44 return m;
45}
46
47#undef S_MUL_SUB
48static inline int S_MUL_SUB(int a, int b, int c, int d) {
49 int m;
50 asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a), "r" ((int)b));
51 asm volatile("msub $ac1, %0, %1" : : "r" ((int)c), "r" ((int)d));
52 asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m): "i" (15));
53 return m;
54}
55
56#undef C_MUL
57# define C_MUL(m,a,b) (m=C_MUL_fun(a,b))
58static inline kiss_fft_cpx C_MUL_fun(kiss_fft_cpx a, kiss_twiddle_cpx b) {
59 kiss_fft_cpx m;
60
61 asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a.r), "r" ((int)b.r));
62 asm volatile("msub $ac1, %0, %1" : : "r" ((int)a.i), "r" ((int)b.i));
63 asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m.r): "i" (15));
64 asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a.r), "r" ((int)b.i));
65 asm volatile("madd $ac1, %0, %1" : : "r" ((int)a.i), "r" ((int)b.r));
66 asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m.i): "i" (15));
67
68 return m;
69}
70#undef C_MULC
71# define C_MULC(m,a,b) (m=C_MULC_fun(a,b))
72static inline kiss_fft_cpx C_MULC_fun(kiss_fft_cpx a, kiss_twiddle_cpx b) {
73 kiss_fft_cpx m;
74
75 asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a.r), "r" ((int)b.r));
76 asm volatile("madd $ac1, %0, %1" : : "r" ((int)a.i), "r" ((int)b.i));
77 asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m.r): "i" (15));
78 asm volatile("MULT $ac1, %0, %1" : : "r" ((int)a.i), "r" ((int)b.r));
79 asm volatile("msub $ac1, %0, %1" : : "r" ((int)a.r), "r" ((int)b.i));
80 asm volatile("EXTR.W %0,$ac1, %1" : "=r" (m.i): "i" (15));
81
82 return m;
83}
84
85#endif /* FIXED_POINT */
86
87#define OVERRIDE_kf_bfly5
88static void kf_bfly5(
89 kiss_fft_cpx * Fout,
90 const size_t fstride,
91 const kiss_fft_state *st,
92 int m,
93 int N,
94 int mm
95 )
96{
97 kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;
98 int i, u;
99 kiss_fft_cpx scratch[13];
100
101 const kiss_twiddle_cpx *tw;
102 kiss_twiddle_cpx ya,yb;
103 kiss_fft_cpx * Fout_beg = Fout;
104
105#ifdef FIXED_POINT
106 ya.r = 10126;
107 ya.i = -31164;
108 yb.r = -26510;
109 yb.i = -19261;
110#else
111 ya = st->twiddles[fstride*m];
112 yb = st->twiddles[fstride*2*m];
113#endif
114
115 tw=st->twiddles;
116
117 for (i=0;i<N;i++)
118 {
119 Fout = Fout_beg + i*mm;
120 Fout0=Fout;
121 Fout1=Fout0+m;
122 Fout2=Fout0+2*m;
123 Fout3=Fout0+3*m;
124 Fout4=Fout0+4*m;
125
126 /* For non-custom modes, m is guaranteed to be a multiple of 4. */
127 for ( u=0; u<m; ++u ) {
128 scratch[0] = *Fout0;
129
130
131 C_MUL(scratch[1] ,*Fout1, tw[u*fstride]);
132 C_MUL(scratch[2] ,*Fout2, tw[2*u*fstride]);
133 C_MUL(scratch[3] ,*Fout3, tw[3*u*fstride]);
134 C_MUL(scratch[4] ,*Fout4, tw[4*u*fstride]);
135
136 C_ADD( scratch[7],scratch[1],scratch[4]);
137 C_SUB( scratch[10],scratch[1],scratch[4]);
138 C_ADD( scratch[8],scratch[2],scratch[3]);
139 C_SUB( scratch[9],scratch[2],scratch[3]);
140
141 Fout0->r += scratch[7].r + scratch[8].r;
142 Fout0->i += scratch[7].i + scratch[8].i;
143 scratch[5].r = scratch[0].r + S_MUL_ADD(scratch[7].r,ya.r,scratch[8].r,yb.r);
144 scratch[5].i = scratch[0].i + S_MUL_ADD(scratch[7].i,ya.r,scratch[8].i,yb.r);
145
146 scratch[6].r = S_MUL_ADD(scratch[10].i,ya.i,scratch[9].i,yb.i);
147 scratch[6].i = -S_MUL_ADD(scratch[10].r,ya.i,scratch[9].r,yb.i);
148
149 C_SUB(*Fout1,scratch[5],scratch[6]);
150 C_ADD(*Fout4,scratch[5],scratch[6]);
151
152 scratch[11].r = scratch[0].r + S_MUL_ADD(scratch[7].r,yb.r,scratch[8].r,ya.r);
153 scratch[11].i = scratch[0].i + S_MUL_ADD(scratch[7].i,yb.r,scratch[8].i,ya.r);
154
155 scratch[12].r = S_MUL_SUB(scratch[9].i,ya.i,scratch[10].i,yb.i);
156 scratch[12].i = S_MUL_SUB(scratch[10].r,yb.i,scratch[9].r,ya.i);
157
158 C_ADD(*Fout2,scratch[11],scratch[12]);
159 C_SUB(*Fout3,scratch[11],scratch[12]);
160
161 ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;
162 }
163 }
164}
165
166
167#endif /* KISS_FFT_MIPSR1_H */
diff --git a/lib/rbcodec/codecs/libopus/celt/mips/mdct_mipsr1.h b/lib/rbcodec/codecs/libopus/celt/mips/mdct_mipsr1.h
new file mode 100644
index 0000000000..2934dab776
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/mips/mdct_mipsr1.h
@@ -0,0 +1,288 @@
1/* Copyright (c) 2007-2008 CSIRO
2 Copyright (c) 2007-2008 Xiph.Org Foundation
3 Written by Jean-Marc Valin */
4/*
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
28
29/* This is a simple MDCT implementation that uses a N/4 complex FFT
30 to do most of the work. It should be relatively straightforward to
31 plug in pretty much and FFT here.
32
33 This replaces the Vorbis FFT (and uses the exact same API), which
34 was a bit too messy and that was ending up duplicating code
35 (might as well use the same FFT everywhere).
36
37 The algorithm is similar to (and inspired from) Fabrice Bellard's
38 MDCT implementation in FFMPEG, but has differences in signs, ordering
39 and scaling in many places.
40*/
41#ifndef __MDCT_MIPSR1_H__
42#define __MDCT_MIPSR1_H__
43
44#ifndef SKIP_CONFIG_H
45#ifdef HAVE_CONFIG_H
46#include "config.h"
47#endif
48#endif
49
50#include "mdct.h"
51#include "kiss_fft.h"
52#include "_kiss_fft_guts.h"
53#include <math.h>
54#include "os_support.h"
55#include "mathops.h"
56#include "stack_alloc.h"
57
58/* Forward MDCT trashes the input array */
59#define OVERRIDE_clt_mdct_forward
60void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,
61 const opus_val16 *window, int overlap, int shift, int stride, int arch)
62{
63 int i;
64 int N, N2, N4;
65 VARDECL(kiss_fft_scalar, f);
66 VARDECL(kiss_fft_cpx, f2);
67 const kiss_fft_state *st = l->kfft[shift];
68 const kiss_twiddle_scalar *trig;
69 opus_val16 scale;
70#ifdef FIXED_POINT
71 /* Allows us to scale with MULT16_32_Q16(), which is faster than
72 MULT16_32_Q15() on ARM. */
73 int scale_shift = st->scale_shift-1;
74#endif
75
76 (void)arch;
77
78 SAVE_STACK;
79 scale = st->scale;
80
81 N = l->n;
82 trig = l->trig;
83 for (i=0;i<shift;i++)
84 {
85 N >>= 1;
86 trig += N;
87 }
88 N2 = N>>1;
89 N4 = N>>2;
90
91 ALLOC(f, N2, kiss_fft_scalar);
92 ALLOC(f2, N4, kiss_fft_cpx);
93
94 /* Consider the input to be composed of four blocks: [a, b, c, d] */
95 /* Window, shuffle, fold */
96 {
97 /* Temp pointers to make it really clear to the compiler what we're doing */
98 const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1);
99 const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1);
100 kiss_fft_scalar * OPUS_RESTRICT yp = f;
101 const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1);
102 const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1;
103 for(i=0;i<((overlap+3)>>2);i++)
104 {
105 /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/
106 *yp++ = S_MUL_ADD(*wp2, xp1[N2],*wp1,*xp2);
107 *yp++ = S_MUL_SUB(*wp1, *xp1,*wp2, xp2[-N2]);
108 xp1+=2;
109 xp2-=2;
110 wp1+=2;
111 wp2-=2;
112 }
113 wp1 = window;
114 wp2 = window+overlap-1;
115 for(;i<N4-((overlap+3)>>2);i++)
116 {
117 /* Real part arranged as a-bR, Imag part arranged as -c-dR */
118 *yp++ = *xp2;
119 *yp++ = *xp1;
120 xp1+=2;
121 xp2-=2;
122 }
123 for(;i<N4;i++)
124 {
125 /* Real part arranged as a-bR, Imag part arranged as -c-dR */
126 *yp++ = S_MUL_SUB(*wp2, *xp2, *wp1, xp1[-N2]);
127 *yp++ = S_MUL_ADD(*wp2, *xp1, *wp1, xp2[N2]);
128 xp1+=2;
129 xp2-=2;
130 wp1+=2;
131 wp2-=2;
132 }
133 }
134 /* Pre-rotation */
135 {
136 kiss_fft_scalar * OPUS_RESTRICT yp = f;
137 const kiss_twiddle_scalar *t = &trig[0];
138 for(i=0;i<N4;i++)
139 {
140 kiss_fft_cpx yc;
141 kiss_twiddle_scalar t0, t1;
142 kiss_fft_scalar re, im, yr, yi;
143 t0 = t[i];
144 t1 = t[N4+i];
145 re = *yp++;
146 im = *yp++;
147
148 yr = S_MUL_SUB(re,t0,im,t1);
149 yi = S_MUL_ADD(im,t0,re,t1);
150
151 yc.r = yr;
152 yc.i = yi;
153 yc.r = PSHR32(MULT16_32_Q16(scale, yc.r), scale_shift);
154 yc.i = PSHR32(MULT16_32_Q16(scale, yc.i), scale_shift);
155 f2[st->bitrev[i]] = yc;
156 }
157 }
158
159 /* N/4 complex FFT, does not downscale anymore */
160 opus_fft_impl(st, f2);
161
162 /* Post-rotate */
163 {
164 /* Temp pointers to make it really clear to the compiler what we're doing */
165 const kiss_fft_cpx * OPUS_RESTRICT fp = f2;
166 kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
167 kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1);
168 const kiss_twiddle_scalar *t = &trig[0];
169 /* Temp pointers to make it really clear to the compiler what we're doing */
170 for(i=0;i<N4;i++)
171 {
172 kiss_fft_scalar yr, yi;
173 yr = S_MUL_SUB(fp->i,t[N4+i] , fp->r,t[i]);
174 yi = S_MUL_ADD(fp->r,t[N4+i] ,fp->i,t[i]);
175 *yp1 = yr;
176 *yp2 = yi;
177 fp++;
178 yp1 += 2*stride;
179 yp2 -= 2*stride;
180 }
181 }
182 RESTORE_STACK;
183}
184
185#define OVERRIDE_clt_mdct_backward
186void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out,
187 const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride, int arch)
188{
189 int i;
190 int N, N2, N4;
191 const kiss_twiddle_scalar *trig;
192
193 (void)arch;
194
195 N = l->n;
196 trig = l->trig;
197 for (i=0;i<shift;i++)
198 {
199 N >>= 1;
200 trig += N;
201 }
202 N2 = N>>1;
203 N4 = N>>2;
204
205 /* Pre-rotate */
206 {
207 /* Temp pointers to make it really clear to the compiler what we're doing */
208 const kiss_fft_scalar * OPUS_RESTRICT xp1 = in;
209 const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1);
210 kiss_fft_scalar * OPUS_RESTRICT yp = out+(overlap>>1);
211 const kiss_twiddle_scalar * OPUS_RESTRICT t = &trig[0];
212 const opus_int16 * OPUS_RESTRICT bitrev = l->kfft[shift]->bitrev;
213 for(i=0;i<N4;i++)
214 {
215 int rev;
216 kiss_fft_scalar yr, yi;
217 rev = *bitrev++;
218 yr = S_MUL_ADD(*xp2, t[i] , *xp1, t[N4+i]);
219 yi = S_MUL_SUB(*xp1, t[i] , *xp2, t[N4+i]);
220 /* We swap real and imag because we use an FFT instead of an IFFT. */
221 yp[2*rev+1] = yr;
222 yp[2*rev] = yi;
223 /* Storing the pre-rotation directly in the bitrev order. */
224 xp1+=2*stride;
225 xp2-=2*stride;
226 }
227 }
228
229 opus_fft_impl(l->kfft[shift], (kiss_fft_cpx*)(out+(overlap>>1)));
230
231 /* Post-rotate and de-shuffle from both ends of the buffer at once to make
232 it in-place. */
233 {
234 kiss_fft_scalar * OPUS_RESTRICT yp0 = out+(overlap>>1);
235 kiss_fft_scalar * OPUS_RESTRICT yp1 = out+(overlap>>1)+N2-2;
236 const kiss_twiddle_scalar *t = &trig[0];
237 /* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the
238 middle pair will be computed twice. */
239 for(i=0;i<(N4+1)>>1;i++)
240 {
241 kiss_fft_scalar re, im, yr, yi;
242 kiss_twiddle_scalar t0, t1;
243 /* We swap real and imag because we're using an FFT instead of an IFFT. */
244 re = yp0[1];
245 im = yp0[0];
246 t0 = t[i];
247 t1 = t[N4+i];
248 /* We'd scale up by 2 here, but instead it's done when mixing the windows */
249 yr = S_MUL_ADD(re,t0 , im,t1);
250 yi = S_MUL_SUB(re,t1 , im,t0);
251 /* We swap real and imag because we're using an FFT instead of an IFFT. */
252 re = yp1[1];
253 im = yp1[0];
254 yp0[0] = yr;
255 yp1[1] = yi;
256
257 t0 = t[(N4-i-1)];
258 t1 = t[(N2-i-1)];
259 /* We'd scale up by 2 here, but instead it's done when mixing the windows */
260 yr = S_MUL_ADD(re,t0,im,t1);
261 yi = S_MUL_SUB(re,t1,im,t0);
262 yp1[0] = yr;
263 yp0[1] = yi;
264 yp0 += 2;
265 yp1 -= 2;
266 }
267 }
268
269 /* Mirror on both sides for TDAC */
270 {
271 kiss_fft_scalar * OPUS_RESTRICT xp1 = out+overlap-1;
272 kiss_fft_scalar * OPUS_RESTRICT yp1 = out;
273 const opus_val16 * OPUS_RESTRICT wp1 = window;
274 const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1;
275
276 for(i = 0; i < overlap/2; i++)
277 {
278 kiss_fft_scalar x1, x2;
279 x1 = *xp1;
280 x2 = *yp1;
281 *yp1++ = MULT16_32_Q15(*wp2, x2) - MULT16_32_Q15(*wp1, x1);
282 *xp1-- = MULT16_32_Q15(*wp1, x2) + MULT16_32_Q15(*wp2, x1);
283 wp1++;
284 wp2--;
285 }
286 }
287}
288#endif /* __MDCT_MIPSR1_H__ */
diff --git a/lib/rbcodec/codecs/libopus/celt/mips/pitch_mipsr1.h b/lib/rbcodec/codecs/libopus/celt/mips/pitch_mipsr1.h
new file mode 100644
index 0000000000..a9500aff58
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/mips/pitch_mipsr1.h
@@ -0,0 +1,161 @@
1/* Copyright (c) 2007-2008 CSIRO
2 Copyright (c) 2007-2009 Xiph.Org Foundation
3 Written by Jean-Marc Valin */
4/**
5 @file pitch.h
6 @brief Pitch analysis
7 */
8
9/*
10 Redistribution and use in source and binary forms, with or without
11 modification, are permitted provided that the following conditions
12 are met:
13
14 - Redistributions of source code must retain the above copyright
15 notice, this list of conditions and the following disclaimer.
16
17 - Redistributions in binary form must reproduce the above copyright
18 notice, this list of conditions and the following disclaimer in the
19 documentation and/or other materials provided with the distribution.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
25 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32*/
33
34#ifndef PITCH_MIPSR1_H
35#define PITCH_MIPSR1_H
36
37#define OVERRIDE_DUAL_INNER_PROD
38static inline void dual_inner_prod(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
39 int N, opus_val32 *xy1, opus_val32 *xy2, int arch)
40{
41 int j;
42 opus_val32 xy01=0;
43 opus_val32 xy02=0;
44
45 (void)arch;
46
47 asm volatile("MULT $ac1, $0, $0");
48 asm volatile("MULT $ac2, $0, $0");
49 /* Compute the norm of X+Y and X-Y as |X|^2 + |Y|^2 +/- sum(xy) */
50 for (j=0;j<N;j++)
51 {
52 asm volatile("MADD $ac1, %0, %1" : : "r" ((int)x[j]), "r" ((int)y01[j]));
53 asm volatile("MADD $ac2, %0, %1" : : "r" ((int)x[j]), "r" ((int)y02[j]));
54 ++j;
55 asm volatile("MADD $ac1, %0, %1" : : "r" ((int)x[j]), "r" ((int)y01[j]));
56 asm volatile("MADD $ac2, %0, %1" : : "r" ((int)x[j]), "r" ((int)y02[j]));
57 }
58 asm volatile ("mflo %0, $ac1": "=r"(xy01));
59 asm volatile ("mflo %0, $ac2": "=r"(xy02));
60 *xy1 = xy01;
61 *xy2 = xy02;
62}
63
64static inline void xcorr_kernel_mips(const opus_val16 * x,
65 const opus_val16 * y, opus_val32 sum[4], int len)
66{
67 int j;
68 opus_val16 y_0, y_1, y_2, y_3;
69
70 opus_int64 sum_0, sum_1, sum_2, sum_3;
71 sum_0 = (opus_int64)sum[0];
72 sum_1 = (opus_int64)sum[1];
73 sum_2 = (opus_int64)sum[2];
74 sum_3 = (opus_int64)sum[3];
75
76 y_3=0; /* gcc doesn't realize that y_3 can't be used uninitialized */
77 y_0=*y++;
78 y_1=*y++;
79 y_2=*y++;
80 for (j=0;j<len-3;j+=4)
81 {
82 opus_val16 tmp;
83 tmp = *x++;
84 y_3=*y++;
85
86 sum_0 = __builtin_mips_madd( sum_0, tmp, y_0);
87 sum_1 = __builtin_mips_madd( sum_1, tmp, y_1);
88 sum_2 = __builtin_mips_madd( sum_2, tmp, y_2);
89 sum_3 = __builtin_mips_madd( sum_3, tmp, y_3);
90
91 tmp=*x++;
92 y_0=*y++;
93
94 sum_0 = __builtin_mips_madd( sum_0, tmp, y_1 );
95 sum_1 = __builtin_mips_madd( sum_1, tmp, y_2 );
96 sum_2 = __builtin_mips_madd( sum_2, tmp, y_3);
97 sum_3 = __builtin_mips_madd( sum_3, tmp, y_0);
98
99 tmp=*x++;
100 y_1=*y++;
101
102 sum_0 = __builtin_mips_madd( sum_0, tmp, y_2 );
103 sum_1 = __builtin_mips_madd( sum_1, tmp, y_3 );
104 sum_2 = __builtin_mips_madd( sum_2, tmp, y_0);
105 sum_3 = __builtin_mips_madd( sum_3, tmp, y_1);
106
107
108 tmp=*x++;
109 y_2=*y++;
110
111 sum_0 = __builtin_mips_madd( sum_0, tmp, y_3 );
112 sum_1 = __builtin_mips_madd( sum_1, tmp, y_0 );
113 sum_2 = __builtin_mips_madd( sum_2, tmp, y_1);
114 sum_3 = __builtin_mips_madd( sum_3, tmp, y_2);
115
116 }
117 if (j++<len)
118 {
119 opus_val16 tmp = *x++;
120 y_3=*y++;
121
122 sum_0 = __builtin_mips_madd( sum_0, tmp, y_0 );
123 sum_1 = __builtin_mips_madd( sum_1, tmp, y_1 );
124 sum_2 = __builtin_mips_madd( sum_2, tmp, y_2);
125 sum_3 = __builtin_mips_madd( sum_3, tmp, y_3);
126 }
127
128 if (j++<len)
129 {
130 opus_val16 tmp=*x++;
131 y_0=*y++;
132
133 sum_0 = __builtin_mips_madd( sum_0, tmp, y_1 );
134 sum_1 = __builtin_mips_madd( sum_1, tmp, y_2 );
135 sum_2 = __builtin_mips_madd( sum_2, tmp, y_3);
136 sum_3 = __builtin_mips_madd( sum_3, tmp, y_0);
137 }
138
139 if (j<len)
140 {
141 opus_val16 tmp=*x++;
142 y_1=*y++;
143
144 sum_0 = __builtin_mips_madd( sum_0, tmp, y_2 );
145 sum_1 = __builtin_mips_madd( sum_1, tmp, y_3 );
146 sum_2 = __builtin_mips_madd( sum_2, tmp, y_0);
147 sum_3 = __builtin_mips_madd( sum_3, tmp, y_1);
148
149 }
150
151 sum[0] = (opus_val32)sum_0;
152 sum[1] = (opus_val32)sum_1;
153 sum[2] = (opus_val32)sum_2;
154 sum[3] = (opus_val32)sum_3;
155}
156
157#define OVERRIDE_XCORR_KERNEL
158#define xcorr_kernel(x, y, sum, len, arch) \
159 ((void)(arch), xcorr_kernel_mips(x, y, sum, len))
160
161#endif /* PITCH_MIPSR1_H */
diff --git a/lib/rbcodec/codecs/libopus/celt/mips/vq_mipsr1.h b/lib/rbcodec/codecs/libopus/celt/mips/vq_mipsr1.h
new file mode 100644
index 0000000000..fd18eab7a9
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/mips/vq_mipsr1.h
@@ -0,0 +1,122 @@
1/* Copyright (c) 2007-2008 CSIRO
2 Copyright (c) 2007-2009 Xiph.Org Foundation
3 Written by Jean-Marc Valin */
4/*
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
28
29#ifndef __VQ_MIPSR1_H__
30#define __VQ_MIPSR1_H__
31
32#ifdef HAVE_CONFIG_H
33#include "config.h"
34#endif
35
36#include "mathops.h"
37#include "arch.h"
38
39static void renormalise_vector_mips(celt_norm *X, int N, opus_val16 gain, int arch);
40
41#define OVERRIDE_vq_exp_rotation1
42static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_val16 s)
43{
44 int i;
45 opus_val16 ms;
46 celt_norm *Xptr;
47 Xptr = X;
48 ms = NEG16(s);
49 for (i=0;i<len-stride;i++)
50 {
51 celt_norm x1, x2;
52 x1 = Xptr[0];
53 x2 = Xptr[stride];
54 Xptr[stride] = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x2), s, x1), 15));
55 *Xptr++ = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x1), ms, x2), 15));
56 }
57 Xptr = &X[len-2*stride-1];
58 for (i=len-2*stride-1;i>=0;i--)
59 {
60 celt_norm x1, x2;
61 x1 = Xptr[0];
62 x2 = Xptr[stride];
63 Xptr[stride] = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x2), s, x1), 15));
64 *Xptr-- = EXTRACT16(PSHR32(MAC16_16(MULT16_16(c, x1), ms, x2), 15));
65 }
66}
67
68#define OVERRIDE_renormalise_vector
69
70#define renormalise_vector(X, N, gain, arch) \
71 (renormalise_vector_mips(X, N, gain, arch))
72
73void renormalise_vector_mips(celt_norm *X, int N, opus_val16 gain, int arch)
74{
75 int i;
76#ifdef FIXED_POINT
77 int k;
78#endif
79 opus_val32 E = EPSILON;
80 opus_val16 g;
81 opus_val32 t;
82 celt_norm *xptr = X;
83 int X0, X1;
84
85 (void)arch;
86
87 asm volatile("mult $ac1, $0, $0");
88 asm volatile("MTLO %0, $ac1" : :"r" (E));
89 /*if(N %4)
90 printf("error");*/
91 for (i=0;i<N-2;i+=2)
92 {
93 X0 = (int)*xptr++;
94 asm volatile("MADD $ac1, %0, %1" : : "r" (X0), "r" (X0));
95
96 X1 = (int)*xptr++;
97 asm volatile("MADD $ac1, %0, %1" : : "r" (X1), "r" (X1));
98 }
99
100 for (;i<N;i++)
101 {
102 X0 = (int)*xptr++;
103 asm volatile("MADD $ac1, %0, %1" : : "r" (X0), "r" (X0));
104 }
105
106 asm volatile("MFLO %0, $ac1" : "=r" (E));
107#ifdef FIXED_POINT
108 k = celt_ilog2(E)>>1;
109#endif
110 t = VSHR32(E, 2*(k-7));
111 g = MULT16_16_P15(celt_rsqrt_norm(t),gain);
112
113 xptr = X;
114 for (i=0;i<N;i++)
115 {
116 *xptr = EXTRACT16(PSHR32(MULT16_16(g, *xptr), k+1));
117 xptr++;
118 }
119 /*return celt_sqrt(E);*/
120}
121
122#endif /* __VQ_MIPSR1_H__ */
diff --git a/lib/rbcodec/codecs/libopus/celt/modes.c b/lib/rbcodec/codecs/libopus/celt/modes.c
index 42e68e1cb7..390c5e8aeb 100644
--- a/lib/rbcodec/codecs/libopus/celt/modes.c
+++ b/lib/rbcodec/codecs/libopus/celt/modes.c
@@ -37,6 +37,7 @@
37#include "os_support.h" 37#include "os_support.h"
38#include "stack_alloc.h" 38#include "stack_alloc.h"
39#include "quant_bands.h" 39#include "quant_bands.h"
40#include "cpu_support.h"
40 41
41static const opus_int16 eband5ms[] = { 42static const opus_int16 eband5ms[] = {
42/*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 */ 43/*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 */
@@ -229,6 +230,7 @@ CELTMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error)
229 opus_val16 *window; 230 opus_val16 *window;
230 opus_int16 *logN; 231 opus_int16 *logN;
231 int LM; 232 int LM;
233 int arch = opus_select_arch();
232 ALLOC_STACK; 234 ALLOC_STACK;
233#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA) 235#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA)
234 if (global_stack==NULL) 236 if (global_stack==NULL)
@@ -389,7 +391,7 @@ CELTMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error)
389 compute_pulse_cache(mode, mode->maxLM); 391 compute_pulse_cache(mode, mode->maxLM);
390 392
391 if (clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts, 393 if (clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts,
392 mode->maxLM) == 0) 394 mode->maxLM, arch) == 0)
393 goto failure; 395 goto failure;
394 396
395 if (error) 397 if (error)
@@ -408,6 +410,8 @@ failure:
408#ifdef CUSTOM_MODES 410#ifdef CUSTOM_MODES
409void opus_custom_mode_destroy(CELTMode *mode) 411void opus_custom_mode_destroy(CELTMode *mode)
410{ 412{
413 int arch = opus_select_arch();
414
411 if (mode == NULL) 415 if (mode == NULL)
412 return; 416 return;
413#ifndef CUSTOM_MODES_ONLY 417#ifndef CUSTOM_MODES_ONLY
@@ -423,7 +427,7 @@ void opus_custom_mode_destroy(CELTMode *mode)
423 } 427 }
424#endif /* CUSTOM_MODES_ONLY */ 428#endif /* CUSTOM_MODES_ONLY */
425 opus_free((opus_int16*)mode->eBands); 429 opus_free((opus_int16*)mode->eBands);
426 opus_free((opus_int16*)mode->allocVectors); 430 opus_free((unsigned char*)mode->allocVectors);
427 431
428 opus_free((opus_val16*)mode->window); 432 opus_free((opus_val16*)mode->window);
429 opus_free((opus_int16*)mode->logN); 433 opus_free((opus_int16*)mode->logN);
@@ -431,7 +435,7 @@ void opus_custom_mode_destroy(CELTMode *mode)
431 opus_free((opus_int16*)mode->cache.index); 435 opus_free((opus_int16*)mode->cache.index);
432 opus_free((unsigned char*)mode->cache.bits); 436 opus_free((unsigned char*)mode->cache.bits);
433 opus_free((unsigned char*)mode->cache.caps); 437 opus_free((unsigned char*)mode->cache.caps);
434 clt_mdct_clear(&mode->mdct); 438 clt_mdct_clear(&mode->mdct, arch);
435 439
436 opus_free((CELTMode *)mode); 440 opus_free((CELTMode *)mode);
437} 441}
diff --git a/lib/rbcodec/codecs/libopus/celt/opus_custom_demo.c b/lib/rbcodec/codecs/libopus/celt/opus_custom_demo.c
new file mode 100644
index 0000000000..ae41c0de5a
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/opus_custom_demo.c
@@ -0,0 +1,210 @@
1/* Copyright (c) 2007-2008 CSIRO
2 Copyright (c) 2007-2009 Xiph.Org Foundation
3 Written by Jean-Marc Valin */
4/*
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include "opus_custom.h"
34#include "arch.h"
35#include <stdio.h>
36#include <stdlib.h>
37#include <math.h>
38#include <string.h>
39
40#define MAX_PACKET 1275
41
42int main(int argc, char *argv[])
43{
44 int err;
45 char *inFile, *outFile;
46 FILE *fin, *fout;
47 OpusCustomMode *mode=NULL;
48 OpusCustomEncoder *enc;
49 OpusCustomDecoder *dec;
50 int len;
51 opus_int32 frame_size, channels, rate;
52 int bytes_per_packet;
53 unsigned char data[MAX_PACKET];
54 int complexity;
55#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH)
56 int i;
57 double rmsd = 0;
58#endif
59 int count = 0;
60 opus_int32 skip;
61 opus_int16 *in, *out;
62 if (argc != 9 && argc != 8 && argc != 7)
63 {
64 fprintf (stderr, "Usage: test_opus_custom <rate> <channels> <frame size> "
65 " <bytes per packet> [<complexity> [packet loss rate]] "
66 "<input> <output>\n");
67 return 1;
68 }
69
70 rate = (opus_int32)atol(argv[1]);
71 channels = atoi(argv[2]);
72 frame_size = atoi(argv[3]);
73 mode = opus_custom_mode_create(rate, frame_size, NULL);
74 if (mode == NULL)
75 {
76 fprintf(stderr, "failed to create a mode\n");
77 return 1;
78 }
79
80 bytes_per_packet = atoi(argv[4]);
81 if (bytes_per_packet < 0 || bytes_per_packet > MAX_PACKET)
82 {
83 fprintf (stderr, "bytes per packet must be between 0 and %d\n",
84 MAX_PACKET);
85 return 1;
86 }
87
88 inFile = argv[argc-2];
89 fin = fopen(inFile, "rb");
90 if (!fin)
91 {
92 fprintf (stderr, "Could not open input file %s\n", argv[argc-2]);
93 return 1;
94 }
95 outFile = argv[argc-1];
96 fout = fopen(outFile, "wb+");
97 if (!fout)
98 {
99 fprintf (stderr, "Could not open output file %s\n", argv[argc-1]);
100 fclose(fin);
101 return 1;
102 }
103
104 enc = opus_custom_encoder_create(mode, channels, &err);
105 if (err != 0)
106 {
107 fprintf(stderr, "Failed to create the encoder: %s\n", opus_strerror(err));
108 fclose(fin);
109 fclose(fout);
110 return 1;
111 }
112 dec = opus_custom_decoder_create(mode, channels, &err);
113 if (err != 0)
114 {
115 fprintf(stderr, "Failed to create the decoder: %s\n", opus_strerror(err));
116 fclose(fin);
117 fclose(fout);
118 return 1;
119 }
120 opus_custom_decoder_ctl(dec, OPUS_GET_LOOKAHEAD(&skip));
121
122 if (argc>7)
123 {
124 complexity=atoi(argv[5]);
125 opus_custom_encoder_ctl(enc,OPUS_SET_COMPLEXITY(complexity));
126 }
127
128 in = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16));
129 out = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16));
130
131 while (!feof(fin))
132 {
133 int ret;
134 err = fread(in, sizeof(short), frame_size*channels, fin);
135 if (feof(fin))
136 break;
137 len = opus_custom_encode(enc, in, frame_size, data, bytes_per_packet);
138 if (len <= 0)
139 fprintf (stderr, "opus_custom_encode() failed: %s\n", opus_strerror(len));
140
141 /* This is for simulating bit errors */
142#if 0
143 int errors = 0;
144 int eid = 0;
145 /* This simulates random bit error */
146 for (i=0;i<len*8;i++)
147 {
148 if (rand()%atoi(argv[8])==0)
149 {
150 if (i<64)
151 {
152 errors++;
153 eid = i;
154 }
155 data[i/8] ^= 1<<(7-(i%8));
156 }
157 }
158 if (errors == 1)
159 data[eid/8] ^= 1<<(7-(eid%8));
160 else if (errors%2 == 1)
161 data[rand()%8] ^= 1<<rand()%8;
162#endif
163
164#if 1 /* Set to zero to use the encoder's output instead */
165 /* This is to simulate packet loss */
166 if (argc==9 && rand()%1000<atoi(argv[argc-3]))
167 /*if (errors && (errors%2==0))*/
168 ret = opus_custom_decode(dec, NULL, len, out, frame_size);
169 else
170 ret = opus_custom_decode(dec, data, len, out, frame_size);
171 if (ret < 0)
172 fprintf(stderr, "opus_custom_decode() failed: %s\n", opus_strerror(ret));
173#else
174 for (i=0;i<ret*channels;i++)
175 out[i] = in[i];
176#endif
177#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH)
178 for (i=0;i<ret*channels;i++)
179 {
180 rmsd += (in[i]-out[i])*1.0*(in[i]-out[i]);
181 /*out[i] -= in[i];*/
182 }
183#endif
184 count++;
185 fwrite(out+skip*channels, sizeof(short), (ret-skip)*channels, fout);
186 skip = 0;
187 }
188 PRINT_MIPS(stderr);
189
190 opus_custom_encoder_destroy(enc);
191 opus_custom_decoder_destroy(dec);
192 fclose(fin);
193 fclose(fout);
194 opus_custom_mode_destroy(mode);
195 free(in);
196 free(out);
197#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH)
198 if (rmsd > 0)
199 {
200 rmsd = sqrt(rmsd/(1.0*frame_size*channels*count));
201 fprintf (stderr, "Error: encoder doesn't match decoder\n");
202 fprintf (stderr, "RMS mismatch is %f\n", rmsd);
203 return 1;
204 } else {
205 fprintf (stderr, "Encoder matches decoder!!\n");
206 }
207#endif
208 return 0;
209}
210
diff --git a/lib/rbcodec/codecs/libopus/celt/os_support.h b/lib/rbcodec/codecs/libopus/celt/os_support.h
index 5e47e3cff9..a2171971e9 100644
--- a/lib/rbcodec/codecs/libopus/celt/os_support.h
+++ b/lib/rbcodec/codecs/libopus/celt/os_support.h
@@ -67,18 +67,18 @@ static OPUS_INLINE void opus_free (void *ptr)
67} 67}
68#endif 68#endif
69 69
70/** Copy n bytes of memory from src to dst. The 0* term provides compile-time type checking */ 70/** Copy n elements from src to dst. The 0* term provides compile-time type checking */
71#ifndef OVERRIDE_OPUS_COPY 71#ifndef OVERRIDE_OPUS_COPY
72#define OPUS_COPY(dst, src, n) (memcpy((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) )) 72#define OPUS_COPY(dst, src, n) (memcpy((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))
73#endif 73#endif
74 74
75/** Copy n bytes of memory from src to dst, allowing overlapping regions. The 0* term 75/** Copy n elements from src to dst, allowing overlapping regions. The 0* term
76 provides compile-time type checking */ 76 provides compile-time type checking */
77#ifndef OVERRIDE_OPUS_MOVE 77#ifndef OVERRIDE_OPUS_MOVE
78#define OPUS_MOVE(dst, src, n) (memmove((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) )) 78#define OPUS_MOVE(dst, src, n) (memmove((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) ))
79#endif 79#endif
80 80
81/** Set n elements of dst to zero, starting at address s */ 81/** Set n elements of dst to zero */
82#ifndef OVERRIDE_OPUS_CLEAR 82#ifndef OVERRIDE_OPUS_CLEAR
83#define OPUS_CLEAR(dst, n) (memset((dst), 0, (n)*sizeof(*(dst)))) 83#define OPUS_CLEAR(dst, n) (memset((dst), 0, (n)*sizeof(*(dst))))
84#endif 84#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/pitch.c b/lib/rbcodec/codecs/libopus/celt/pitch.c
index ee56a434f0..872582a48a 100644
--- a/lib/rbcodec/codecs/libopus/celt/pitch.c
+++ b/lib/rbcodec/codecs/libopus/celt/pitch.c
@@ -102,11 +102,9 @@ static void find_best_pitch(opus_val32 *xcorr, opus_val16 *y, int len,
102 } 102 }
103} 103}
104 104
105static void celt_fir5(const opus_val16 *x, 105static void celt_fir5(opus_val16 *x,
106 const opus_val16 *num, 106 const opus_val16 *num,
107 opus_val16 *y, 107 int N)
108 int N,
109 opus_val16 *mem)
110{ 108{
111 int i; 109 int i;
112 opus_val16 num0, num1, num2, num3, num4; 110 opus_val16 num0, num1, num2, num3, num4;
@@ -116,11 +114,11 @@ static void celt_fir5(const opus_val16 *x,
116 num2=num[2]; 114 num2=num[2];
117 num3=num[3]; 115 num3=num[3];
118 num4=num[4]; 116 num4=num[4];
119 mem0=mem[0]; 117 mem0=0;
120 mem1=mem[1]; 118 mem1=0;
121 mem2=mem[2]; 119 mem2=0;
122 mem3=mem[3]; 120 mem3=0;
123 mem4=mem[4]; 121 mem4=0;
124 for (i=0;i<N;i++) 122 for (i=0;i<N;i++)
125 { 123 {
126 opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT); 124 opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);
@@ -134,13 +132,8 @@ static void celt_fir5(const opus_val16 *x,
134 mem2 = mem1; 132 mem2 = mem1;
135 mem1 = mem0; 133 mem1 = mem0;
136 mem0 = x[i]; 134 mem0 = x[i];
137 y[i] = ROUND16(sum, SIG_SHIFT); 135 x[i] = ROUND16(sum, SIG_SHIFT);
138 } 136 }
139 mem[0]=mem0;
140 mem[1]=mem1;
141 mem[2]=mem2;
142 mem[3]=mem3;
143 mem[4]=mem4;
144} 137}
145 138
146 139
@@ -150,7 +143,7 @@ void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x
150 int i; 143 int i;
151 opus_val32 ac[5]; 144 opus_val32 ac[5];
152 opus_val16 tmp=Q15ONE; 145 opus_val16 tmp=Q15ONE;
153 opus_val16 lpc[4], mem[5]={0,0,0,0,0}; 146 opus_val16 lpc[4];
154 opus_val16 lpc2[5]; 147 opus_val16 lpc2[5];
155 opus_val16 c1 = QCONST16(.8f,15); 148 opus_val16 c1 = QCONST16(.8f,15);
156#ifdef FIXED_POINT 149#ifdef FIXED_POINT
@@ -211,28 +204,33 @@ void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x
211 lpc2[2] = lpc[2] + MULT16_16_Q15(c1,lpc[1]); 204 lpc2[2] = lpc[2] + MULT16_16_Q15(c1,lpc[1]);
212 lpc2[3] = lpc[3] + MULT16_16_Q15(c1,lpc[2]); 205 lpc2[3] = lpc[3] + MULT16_16_Q15(c1,lpc[2]);
213 lpc2[4] = MULT16_16_Q15(c1,lpc[3]); 206 lpc2[4] = MULT16_16_Q15(c1,lpc[3]);
214 celt_fir5(x_lp, lpc2, x_lp, len>>1, mem); 207 celt_fir5(x_lp, lpc2, len>>1);
215} 208}
216 209
217#if 0 /* This is a simple version of the pitch correlation that should work 210/* Pure C implementation. */
218 well on DSPs like Blackfin and TI C5x/C6x */
219
220#ifdef FIXED_POINT 211#ifdef FIXED_POINT
221opus_val32 212opus_val32
222#else 213#else
223void 214void
224#endif 215#endif
225celt_pitch_xcorr(opus_val16 *x, opus_val16 *y, opus_val32 *xcorr, int len, int max_pitch) 216celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y,
217 opus_val32 *xcorr, int len, int max_pitch, int arch)
226{ 218{
219
220#if 0 /* This is a simple version of the pitch correlation that should work
221 well on DSPs like Blackfin and TI C5x/C6x */
227 int i, j; 222 int i, j;
228#ifdef FIXED_POINT 223#ifdef FIXED_POINT
229 opus_val32 maxcorr=1; 224 opus_val32 maxcorr=1;
230#endif 225#endif
226#if !defined(OVERRIDE_PITCH_XCORR)
227 (void)arch;
228#endif
231 for (i=0;i<max_pitch;i++) 229 for (i=0;i<max_pitch;i++)
232 { 230 {
233 opus_val32 sum = 0; 231 opus_val32 sum = 0;
234 for (j=0;j<len;j++) 232 for (j=0;j<len;j++)
235 sum = MAC16_16(sum, x[j],y[i+j]); 233 sum = MAC16_16(sum, _x[j], _y[i+j]);
236 xcorr[i] = sum; 234 xcorr[i] = sum;
237#ifdef FIXED_POINT 235#ifdef FIXED_POINT
238 maxcorr = MAX32(maxcorr, sum); 236 maxcorr = MAX32(maxcorr, sum);
@@ -241,17 +239,8 @@ celt_pitch_xcorr(opus_val16 *x, opus_val16 *y, opus_val32 *xcorr, int len, int m
241#ifdef FIXED_POINT 239#ifdef FIXED_POINT
242 return maxcorr; 240 return maxcorr;
243#endif 241#endif
244}
245 242
246#else /* Unrolled version of the pitch correlation -- runs faster on x86 and ARM */ 243#else /* Unrolled version of the pitch correlation -- runs faster on x86 and ARM */
247
248#ifdef FIXED_POINT
249opus_val32
250#else
251void
252#endif
253celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y, opus_val32 *xcorr, int len, int max_pitch)
254{
255 int i; 244 int i;
256 /*The EDSP version requires that max_pitch is at least 1, and that _x is 245 /*The EDSP version requires that max_pitch is at least 1, and that _x is
257 32-bit aligned. 246 32-bit aligned.
@@ -260,11 +249,11 @@ celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y, opus_val32 *xcorr
260 opus_val32 maxcorr=1; 249 opus_val32 maxcorr=1;
261#endif 250#endif
262 celt_assert(max_pitch>0); 251 celt_assert(max_pitch>0);
263 celt_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0); 252 celt_sig_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0);
264 for (i=0;i<max_pitch-3;i+=4) 253 for (i=0;i<max_pitch-3;i+=4)
265 { 254 {
266 opus_val32 sum[4]={0,0,0,0}; 255 opus_val32 sum[4]={0,0,0,0};
267 xcorr_kernel(_x, _y+i, sum, len); 256 xcorr_kernel(_x, _y+i, sum, len, arch);
268 xcorr[i]=sum[0]; 257 xcorr[i]=sum[0];
269 xcorr[i+1]=sum[1]; 258 xcorr[i+1]=sum[1];
270 xcorr[i+2]=sum[2]; 259 xcorr[i+2]=sum[2];
@@ -280,7 +269,7 @@ celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y, opus_val32 *xcorr
280 for (;i<max_pitch;i++) 269 for (;i<max_pitch;i++)
281 { 270 {
282 opus_val32 sum; 271 opus_val32 sum;
283 sum = celt_inner_prod(_x, _y+i, len); 272 sum = celt_inner_prod(_x, _y+i, len, arch);
284 xcorr[i] = sum; 273 xcorr[i] = sum;
285#ifdef FIXED_POINT 274#ifdef FIXED_POINT
286 maxcorr = MAX32(maxcorr, sum); 275 maxcorr = MAX32(maxcorr, sum);
@@ -289,9 +278,9 @@ celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y, opus_val32 *xcorr
289#ifdef FIXED_POINT 278#ifdef FIXED_POINT
290 return maxcorr; 279 return maxcorr;
291#endif 280#endif
281#endif
292} 282}
293 283
294#endif
295void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTRICT y, 284void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTRICT y,
296 int len, int max_pitch, int *pitch, int arch) 285 int len, int max_pitch, int *pitch, int arch)
297{ 286{
@@ -369,7 +358,7 @@ void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTR
369 for (j=0;j<len>>1;j++) 358 for (j=0;j<len>>1;j++)
370 sum += SHR32(MULT16_16(x_lp[j],y[i+j]), shift); 359 sum += SHR32(MULT16_16(x_lp[j],y[i+j]), shift);
371#else 360#else
372 sum = celt_inner_prod(x_lp, y+i, len>>1); 361 sum = celt_inner_prod(x_lp, y+i, len>>1, arch);
373#endif 362#endif
374 xcorr[i] = MAX32(-1, sum); 363 xcorr[i] = MAX32(-1, sum);
375#ifdef FIXED_POINT 364#ifdef FIXED_POINT
@@ -403,10 +392,44 @@ void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTR
403 RESTORE_STACK; 392 RESTORE_STACK;
404} 393}
405 394
406#if 0 395#ifdef FIXED_POINT
396static opus_val16 compute_pitch_gain(opus_val32 xy, opus_val32 xx, opus_val32 yy)
397{
398 opus_val32 x2y2;
399 int sx, sy, shift;
400 opus_val32 g;
401 opus_val16 den;
402 if (xy == 0 || xx == 0 || yy == 0)
403 return 0;
404 sx = celt_ilog2(xx)-14;
405 sy = celt_ilog2(yy)-14;
406 shift = sx + sy;
407 x2y2 = SHR32(MULT16_16(VSHR32(xx, sx), VSHR32(yy, sy)), 14);
408 if (shift & 1) {
409 if (x2y2 < 32768)
410 {
411 x2y2 <<= 1;
412 shift--;
413 } else {
414 x2y2 >>= 1;
415 shift++;
416 }
417 }
418 den = celt_rsqrt_norm(x2y2);
419 g = MULT16_32_Q15(den, xy);
420 g = VSHR32(g, (shift>>1)-1);
421 return EXTRACT16(MIN32(g, Q15ONE));
422}
423#else
424static opus_val16 compute_pitch_gain(opus_val32 xy, opus_val32 xx, opus_val32 yy)
425{
426 return xy/celt_sqrt(1+xx*yy);
427}
428#endif
429
407static const int second_check[16] = {0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2}; 430static const int second_check[16] = {0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2};
408opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod, 431opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
409 int N, int *T0_, int prev_period, opus_val16 prev_gain) 432 int N, int *T0_, int prev_period, opus_val16 prev_gain, int arch)
410{ 433{
411 int k, i, T, T0; 434 int k, i, T, T0;
412 opus_val16 g, g0; 435 opus_val16 g, g0;
@@ -431,7 +454,7 @@ opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
431 454
432 T = T0 = *T0_; 455 T = T0 = *T0_;
433 ALLOC(yy_lookup, maxperiod+1, opus_val32); 456 ALLOC(yy_lookup, maxperiod+1, opus_val32);
434 dual_inner_prod(x, x, x-T0, N, &xx, &xy); 457 dual_inner_prod(x, x, x-T0, N, &xx, &xy, arch);
435 yy_lookup[0] = xx; 458 yy_lookup[0] = xx;
436 yy=xx; 459 yy=xx;
437 for (i=1;i<=maxperiod;i++) 460 for (i=1;i<=maxperiod;i++)
@@ -442,18 +465,7 @@ opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
442 yy = yy_lookup[T0]; 465 yy = yy_lookup[T0];
443 best_xy = xy; 466 best_xy = xy;
444 best_yy = yy; 467 best_yy = yy;
445#ifdef FIXED_POINT 468 g = g0 = compute_pitch_gain(xy, xx, yy);
446 {
447 opus_val32 x2y2;
448 int sh, t;
449 x2y2 = 1+HALF32(MULT32_32_Q31(xx,yy));
450 sh = celt_ilog2(x2y2)>>1;
451 t = VSHR32(x2y2, 2*(sh-7));
452 g = g0 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1);
453 }
454#else
455 g = g0 = xy/celt_sqrt(1+xx*yy);
456#endif
457 /* Look for any pitch at T/k */ 469 /* Look for any pitch at T/k */
458 for (k=2;k<=15;k++) 470 for (k=2;k<=15;k++)
459 { 471 {
@@ -475,25 +487,14 @@ opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
475 { 487 {
476 T1b = celt_udiv(2*second_check[k]*T0+k, 2*k); 488 T1b = celt_udiv(2*second_check[k]*T0+k, 2*k);
477 } 489 }
478 dual_inner_prod(x, &x[-T1], &x[-T1b], N, &xy, &xy2); 490 dual_inner_prod(x, &x[-T1], &x[-T1b], N, &xy, &xy2, arch);
479 xy += xy2; 491 xy = HALF32(xy + xy2);
480 yy = yy_lookup[T1] + yy_lookup[T1b]; 492 yy = HALF32(yy_lookup[T1] + yy_lookup[T1b]);
481#ifdef FIXED_POINT 493 g1 = compute_pitch_gain(xy, xx, yy);
482 {
483 opus_val32 x2y2;
484 int sh, t;
485 x2y2 = 1+MULT32_32_Q31(xx,yy);
486 sh = celt_ilog2(x2y2)>>1;
487 t = VSHR32(x2y2, 2*(sh-7));
488 g1 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1);
489 }
490#else
491 g1 = xy/celt_sqrt(1+2.f*xx*1.f*yy);
492#endif
493 if (abs(T1-prev_period)<=1) 494 if (abs(T1-prev_period)<=1)
494 cont = prev_gain; 495 cont = prev_gain;
495 else if (abs(T1-prev_period)<=2 && 5*k*k < T0) 496 else if (abs(T1-prev_period)<=2 && 5*k*k < T0)
496 cont = HALF32(prev_gain); 497 cont = HALF16(prev_gain);
497 else 498 else
498 cont = 0; 499 cont = 0;
499 thresh = MAX16(QCONST16(.3f,15), MULT16_16_Q15(QCONST16(.7f,15),g0)-cont); 500 thresh = MAX16(QCONST16(.3f,15), MULT16_16_Q15(QCONST16(.7f,15),g0)-cont);
@@ -518,7 +519,7 @@ opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
518 pg = SHR32(frac_div32(best_xy,best_yy+1),16); 519 pg = SHR32(frac_div32(best_xy,best_yy+1),16);
519 520
520 for (k=0;k<3;k++) 521 for (k=0;k<3;k++)
521 xcorr[k] = celt_inner_prod(x, x-(T+k-1), N); 522 xcorr[k] = celt_inner_prod(x, x-(T+k-1), N, arch);
522 if ((xcorr[2]-xcorr[0]) > MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[0])) 523 if ((xcorr[2]-xcorr[0]) > MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[0]))
523 offset = 1; 524 offset = 1;
524 else if ((xcorr[0]-xcorr[2]) > MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[2])) 525 else if ((xcorr[0]-xcorr[2]) > MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[2]))
@@ -534,4 +535,3 @@ opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
534 RESTORE_STACK; 535 RESTORE_STACK;
535 return pg; 536 return pg;
536} 537}
537#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/pitch.h b/lib/rbcodec/codecs/libopus/celt/pitch.h
index 96dbc0d794..e425f56aea 100644
--- a/lib/rbcodec/codecs/libopus/celt/pitch.h
+++ b/lib/rbcodec/codecs/libopus/celt/pitch.h
@@ -37,7 +37,8 @@
37#include "modes.h" 37#include "modes.h"
38#include "cpu_support.h" 38#include "cpu_support.h"
39 39
40#if defined(__SSE__) && !defined(FIXED_POINT) 40#if (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT)) \
41 || ((defined(OPUS_X86_MAY_HAVE_SSE4_1) || defined(OPUS_X86_MAY_HAVE_SSE2)) && defined(FIXED_POINT))
41#include "x86/pitch_sse.h" 42#include "x86/pitch_sse.h"
42#endif 43#endif
43 44
@@ -45,8 +46,8 @@
45#include "mips/pitch_mipsr1.h" 46#include "mips/pitch_mipsr1.h"
46#endif 47#endif
47 48
48#if defined(OPUS_ARM_ASM) && defined(FIXED_POINT) 49#if (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
49//# include "arm/pitch_arm.h" 50# include "arm/pitch_arm.h"
50#endif 51#endif
51 52
52void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x_lp, 53void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x_lp,
@@ -56,12 +57,12 @@ void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTR
56 int len, int max_pitch, int *pitch, int arch); 57 int len, int max_pitch, int *pitch, int arch);
57 58
58opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod, 59opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
59 int N, int *T0, int prev_period, opus_val16 prev_gain); 60 int N, int *T0, int prev_period, opus_val16 prev_gain, int arch);
61
60 62
61/* OPT: This is the kernel you really want to optimize. It gets used a lot 63/* OPT: This is the kernel you really want to optimize. It gets used a lot
62 by the prefilter and by the PLC. */ 64 by the prefilter and by the PLC. */
63#ifndef OVERRIDE_XCORR_KERNEL 65static OPUS_INLINE void xcorr_kernel_c(const opus_val16 * x, const opus_val16 * y, opus_val32 sum[4], int len)
64static OPUS_INLINE void xcorr_kernel(const opus_val16 * x, const opus_val16 * y, opus_val32 sum[4], int len)
65{ 66{
66 int j; 67 int j;
67 opus_val16 y_0, y_1, y_2, y_3; 68 opus_val16 y_0, y_1, y_2, y_3;
@@ -126,10 +127,14 @@ static OPUS_INLINE void xcorr_kernel(const opus_val16 * x, const opus_val16 * y,
126 sum[3] = MAC16_16(sum[3],tmp,y_1); 127 sum[3] = MAC16_16(sum[3],tmp,y_1);
127 } 128 }
128} 129}
130
131#ifndef OVERRIDE_XCORR_KERNEL
132#define xcorr_kernel(x, y, sum, len, arch) \
133 ((void)(arch),xcorr_kernel_c(x, y, sum, len))
129#endif /* OVERRIDE_XCORR_KERNEL */ 134#endif /* OVERRIDE_XCORR_KERNEL */
130 135
131#ifndef OVERRIDE_DUAL_INNER_PROD 136
132static OPUS_INLINE void dual_inner_prod(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02, 137static OPUS_INLINE void dual_inner_prod_c(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
133 int N, opus_val32 *xy1, opus_val32 *xy2) 138 int N, opus_val32 *xy1, opus_val32 *xy2)
134{ 139{
135 int i; 140 int i;
@@ -143,11 +148,16 @@ static OPUS_INLINE void dual_inner_prod(const opus_val16 *x, const opus_val16 *y
143 *xy1 = xy01; 148 *xy1 = xy01;
144 *xy2 = xy02; 149 *xy2 = xy02;
145} 150}
151
152#ifndef OVERRIDE_DUAL_INNER_PROD
153# define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) \
154 ((void)(arch),dual_inner_prod_c(x, y01, y02, N, xy1, xy2))
146#endif 155#endif
147 156
148#ifndef OVERRIDE_CELT_INNER_PROD 157/*We make sure a C version is always available for cases where the overhead of
149static OPUS_INLINE opus_val32 celt_inner_prod(const opus_val16 *x, const opus_val16 *y, 158 vectorization and passing around an arch flag aren't worth it.*/
150 int N) 159static OPUS_INLINE opus_val32 celt_inner_prod_c(const opus_val16 *x,
160 const opus_val16 *y, int N)
151{ 161{
152 int i; 162 int i;
153 opus_val32 xy=0; 163 opus_val32 xy=0;
@@ -155,35 +165,28 @@ static OPUS_INLINE opus_val32 celt_inner_prod(const opus_val16 *x, const opus_va
155 xy = MAC16_16(xy, x[i], y[i]); 165 xy = MAC16_16(xy, x[i], y[i]);
156 return xy; 166 return xy;
157} 167}
168
169#if !defined(OVERRIDE_CELT_INNER_PROD)
170# define celt_inner_prod(x, y, N, arch) \
171 ((void)(arch),celt_inner_prod_c(x, y, N))
172#endif
173
174#ifdef NON_STATIC_COMB_FILTER_CONST_C
175void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
176 opus_val16 g10, opus_val16 g11, opus_val16 g12);
158#endif 177#endif
159 178
179
160#ifdef FIXED_POINT 180#ifdef FIXED_POINT
161opus_val32 181opus_val32
162#else 182#else
163void 183void
164#endif 184#endif
165celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y, 185celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y,
166 opus_val32 *xcorr, int len, int max_pitch); 186 opus_val32 *xcorr, int len, int max_pitch, int arch);
167 187
168#if !defined(OVERRIDE_PITCH_XCORR) 188#ifndef OVERRIDE_PITCH_XCORR
169/*Is run-time CPU detection enabled on this platform?*/ 189# define celt_pitch_xcorr celt_pitch_xcorr_c
170# if defined(OPUS_HAVE_RTCD)
171extern
172# if defined(FIXED_POINT)
173opus_val32
174# else
175void
176# endif
177(*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
178 const opus_val16 *, opus_val32 *, int, int);
179
180# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
181 ((*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])(_x, _y, \
182 xcorr, len, max_pitch))
183# else
184# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
185 ((void)(arch),celt_pitch_xcorr_c(_x, _y, xcorr, len, max_pitch))
186# endif
187#endif 190#endif
188 191
189#endif 192#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/quant_bands.c b/lib/rbcodec/codecs/libopus/celt/quant_bands.c
index ac6952c266..39a221eda5 100644
--- a/lib/rbcodec/codecs/libopus/celt/quant_bands.c
+++ b/lib/rbcodec/codecs/libopus/celt/quant_bands.c
@@ -292,7 +292,7 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
292#endif 292#endif
293 } 293 }
294 if (lfe) 294 if (lfe)
295 max_decay=3; 295 max_decay = QCONST16(3.f,DB_SHIFT);
296 enc_start_state = *enc; 296 enc_start_state = *enc;
297 297
298 ALLOC(oldEBands_intra, C*m->nbEBands, opus_val16); 298 ALLOC(oldEBands_intra, C*m->nbEBands, opus_val16);
@@ -418,6 +418,7 @@ void quant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *ol
418 offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384); 418 offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);
419#endif 419#endif
420 oldEBands[i+c*m->nbEBands] += offset; 420 oldEBands[i+c*m->nbEBands] += offset;
421 error[i+c*m->nbEBands] -= offset;
421 bits_left--; 422 bits_left--;
422 } while (++c < C); 423 } while (++c < C);
423 } 424 }
@@ -456,7 +457,7 @@ void unquant_coarse_energy(const CELTMode *m, int start, int end, opus_val16 *ol
456 /* It would be better to express this invariant as a 457 /* It would be better to express this invariant as a
457 test on C at function entry, but that isn't enough 458 test on C at function entry, but that isn't enough
458 to make the static analyzer happy. */ 459 to make the static analyzer happy. */
459 celt_assert(c<2); 460 celt_sig_assert(c<2);
460 tell = ec_tell(dec); 461 tell = ec_tell(dec);
461 if(budget-tell>=15) 462 if(budget-tell>=15)
462 { 463 {
@@ -547,9 +548,15 @@ void amp2Log2(const CELTMode *m, int effEnd, int end,
547 c=0; 548 c=0;
548 do { 549 do {
549 for (i=0;i<effEnd;i++) 550 for (i=0;i<effEnd;i++)
551 {
550 bandLogE[i+c*m->nbEBands] = 552 bandLogE[i+c*m->nbEBands] =
551 celt_log2(SHL32(bandE[i+c*m->nbEBands],2)) 553 celt_log2(bandE[i+c*m->nbEBands])
552 - SHL16((opus_val16)eMeans[i],6); 554 - SHL16((opus_val16)eMeans[i],6);
555#ifdef FIXED_POINT
556 /* Compensate for bandE[] being Q12 but celt_log2() taking a Q14 input. */
557 bandLogE[i+c*m->nbEBands] += QCONST16(2.f, DB_SHIFT);
558#endif
559 }
553 for (i=effEnd;i<end;i++) 560 for (i=effEnd;i<end;i++)
554 bandLogE[c*m->nbEBands+i] = -QCONST16(14.f,DB_SHIFT); 561 bandLogE[c*m->nbEBands+i] = -QCONST16(14.f,DB_SHIFT);
555 } while (++c < C); 562 } while (++c < C);
diff --git a/lib/rbcodec/codecs/libopus/celt/rate.c b/lib/rbcodec/codecs/libopus/celt/rate.c
index f85c3ee63c..465e1ba26c 100644
--- a/lib/rbcodec/codecs/libopus/celt/rate.c
+++ b/lib/rbcodec/codecs/libopus/celt/rate.c
@@ -131,7 +131,7 @@ void compute_pulse_cache(CELTMode *m, int LM)
131 for (i=0;i<nbEntries;i++) 131 for (i=0;i<nbEntries;i++)
132 { 132 {
133 unsigned char *ptr = bits+entryI[i]; 133 unsigned char *ptr = bits+entryI[i];
134 opus_int16 tmp[MAX_PULSES+1]; 134 opus_int16 tmp[CELT_MAX_PULSES+1];
135 get_required_bits(tmp, entryN[i], get_pulses(entryK[i]), BITRES); 135 get_required_bits(tmp, entryN[i], get_pulses(entryK[i]), BITRES);
136 for (j=1;j<=entryK[i];j++) 136 for (j=1;j<=entryK[i];j++)
137 ptr[j] = tmp[get_pulses(j)]-1; 137 ptr[j] = tmp[get_pulses(j)]-1;
@@ -296,7 +296,7 @@ static OPUS_INLINE int interp_bits2pulses(const CELTMode *m, int start, int end,
296 done = 0; 296 done = 0;
297 for (j=end;j-->start;) 297 for (j=end;j-->start;)
298 { 298 {
299 int tmp = bits1[j] + (lo*bits2[j]>>ALLOC_STEPS); 299 int tmp = bits1[j] + ((opus_int32)lo*bits2[j]>>ALLOC_STEPS);
300 if (tmp < thresh[j] && !done) 300 if (tmp < thresh[j] && !done)
301 { 301 {
302 if (tmp >= alloc_floor) 302 if (tmp >= alloc_floor)
@@ -348,12 +348,17 @@ static OPUS_INLINE int interp_bits2pulses(const CELTMode *m, int start, int end,
348 /*This if() block is the only part of the allocation function that 348 /*This if() block is the only part of the allocation function that
349 is not a mandatory part of the bitstream: any bands we choose to 349 is not a mandatory part of the bitstream: any bands we choose to
350 skip here must be explicitly signaled.*/ 350 skip here must be explicitly signaled.*/
351 /*Choose a threshold with some hysteresis to keep bands from 351 int depth_threshold;
352 fluctuating in and out.*/ 352 /*We choose a threshold with some hysteresis to keep bands from
353 fluctuating in and out, but we try not to fold below a certain point. */
354 if (codedBands > 17)
355 depth_threshold = j<prev ? 7 : 9;
356 else
357 depth_threshold = 0;
353#ifdef FUZZING 358#ifdef FUZZING
354 if ((rand()&0x1) == 0) 359 if ((rand()&0x1) == 0)
355#else 360#else
356 if (codedBands<=start+2 || (band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4 && j<=signalBandwidth)) 361 if (codedBands<=start+2 || (band_bits > (depth_threshold*band_width<<LM<<BITRES)>>4 && j<=signalBandwidth))
357#endif 362#endif
358 { 363 {
359 ec_enc_bit_logp(ec, 1, 1); 364 ec_enc_bit_logp(ec, 1, 1);
@@ -524,7 +529,7 @@ static OPUS_INLINE int interp_bits2pulses(const CELTMode *m, int start, int end,
524 return codedBands; 529 return codedBands;
525} 530}
526 531
527int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stereo, 532int clt_compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stereo,
528 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) 533 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)
529{ 534{
530 int lo, hi, len, j; 535 int lo, hi, len, j;
diff --git a/lib/rbcodec/codecs/libopus/celt/rate.h b/lib/rbcodec/codecs/libopus/celt/rate.h
index f1e0661129..852b9d6f60 100644
--- a/lib/rbcodec/codecs/libopus/celt/rate.h
+++ b/lib/rbcodec/codecs/libopus/celt/rate.h
@@ -32,7 +32,7 @@
32#define MAX_PSEUDO 40 32#define MAX_PSEUDO 40
33#define LOG_MAX_PSEUDO 6 33#define LOG_MAX_PSEUDO 6
34 34
35#define MAX_PULSES 128 35#define CELT_MAX_PULSES 128
36 36
37#define MAX_FINE_BITS 8 37#define MAX_FINE_BITS 8
38 38
@@ -95,7 +95,7 @@ static OPUS_INLINE int pulses2bits(const CELTMode *m, int band, int LM, int puls
95 @param pulses Number of pulses per band (returned) 95 @param pulses Number of pulses per band (returned)
96 @return Total number of bits allocated 96 @return Total number of bits allocated
97*/ 97*/
98int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stero, 98int clt_compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stero,
99 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); 99 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);
100 100
101#endif 101#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/static_modes_fixed.h b/lib/rbcodec/codecs/libopus/celt/static_modes_fixed.h
index 1f13497c69..8717d626cb 100644
--- a/lib/rbcodec/codecs/libopus/celt/static_modes_fixed.h
+++ b/lib/rbcodec/codecs/libopus/celt/static_modes_fixed.h
@@ -4,9 +4,14 @@
4#include "modes.h" 4#include "modes.h"
5#include "rate.h" 5#include "rate.h"
6 6
7#ifdef HAVE_ARM_NE10
8#define OVERRIDE_FFT 1
9#include "static_modes_fixed_arm_ne10.h"
10#endif
11
7#ifndef DEF_WINDOW120 12#ifndef DEF_WINDOW120
8#define DEF_WINDOW120 13#define DEF_WINDOW120
9static const opus_val16 window120[120] ICONST_ATTR = { 14static const opus_val16 window120[120] = {
102, 20, 55, 108, 178, 152, 20, 55, 108, 178,
11266, 372, 494, 635, 792, 16266, 372, 494, 635, 792,
12966, 1157, 1365, 1590, 1831, 17966, 1157, 1365, 1590, 1831,
@@ -36,13 +41,13 @@ static const opus_val16 window120[120] ICONST_ATTR = {
36 41
37#ifndef DEF_LOGN400 42#ifndef DEF_LOGN400
38#define DEF_LOGN400 43#define DEF_LOGN400
39static const opus_int16 logN400[21] ICONST_ATTR = { 44static const opus_int16 logN400[21] = {
400, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 21, 21, 24, 29, 34, 36, }; 450, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 21, 21, 24, 29, 34, 36, };
41#endif 46#endif
42 47
43#ifndef DEF_PULSE_CACHE50 48#ifndef DEF_PULSE_CACHE50
44#define DEF_PULSE_CACHE50 49#define DEF_PULSE_CACHE50
45static const opus_int16 cache_index50[105] ICONST_ATTR = { 50static const opus_int16 cache_index50[105] = {
46-1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 41, 41, 41, 51-1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 41, 41, 41,
4782, 82, 123, 164, 200, 222, 0, 0, 0, 0, 0, 0, 0, 0, 41, 5282, 82, 123, 164, 200, 222, 0, 0, 0, 0, 0, 0, 0, 0, 41,
4841, 41, 41, 123, 123, 123, 164, 164, 240, 266, 283, 295, 41, 41, 41, 5341, 41, 41, 123, 123, 123, 164, 164, 240, 266, 283, 295, 41, 41, 41,
@@ -51,7 +56,7 @@ static const opus_int16 cache_index50[105] ICONST_ATTR = {
51305, 305, 305, 318, 318, 343, 351, 358, 364, 240, 240, 240, 240, 240, 240, 56305, 305, 305, 318, 318, 343, 351, 358, 364, 240, 240, 240, 240, 240, 240,
52240, 240, 305, 305, 305, 305, 343, 343, 343, 351, 351, 370, 376, 382, 387, 57240, 240, 305, 305, 305, 305, 343, 343, 343, 351, 351, 370, 376, 382, 387,
53}; 58};
54static const unsigned char cache_bits50[392] ICONST_ATTR = { 59static const unsigned char cache_bits50[392] = {
5540, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6040, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
567, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 617, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
577, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 40, 15, 23, 28, 627, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 40, 15, 23, 28,
@@ -79,7 +84,7 @@ static const unsigned char cache_bits50[392] ICONST_ATTR = {
79106, 151, 192, 231, 5, 59, 111, 158, 202, 243, 5, 55, 103, 147, 187, 84106, 151, 192, 231, 5, 59, 111, 158, 202, 243, 5, 55, 103, 147, 187,
80224, 5, 60, 113, 161, 206, 248, 4, 65, 122, 175, 224, 4, 67, 127, 85224, 5, 60, 113, 161, 206, 248, 4, 65, 122, 175, 224, 4, 67, 127,
81182, 234, }; 86182, 234, };
82static const unsigned char cache_caps50[168] ICONST_ATTR = { 87static const unsigned char cache_caps50[168] = {
83224, 224, 224, 224, 224, 224, 224, 224, 160, 160, 160, 160, 185, 185, 185, 88224, 224, 224, 224, 224, 224, 224, 224, 160, 160, 160, 160, 185, 185, 185,
84178, 178, 168, 134, 61, 37, 224, 224, 224, 224, 224, 224, 224, 224, 240, 89178, 178, 168, 134, 61, 37, 224, 224, 224, 224, 224, 224, 224, 224, 240,
85240, 240, 240, 207, 207, 207, 198, 198, 183, 144, 66, 40, 160, 160, 160, 90240, 240, 240, 207, 207, 207, 198, 198, 183, 144, 66, 40, 160, 160, 160,
@@ -96,7 +101,7 @@ static const unsigned char cache_caps50[168] ICONST_ATTR = {
96 101
97#ifndef FFT_TWIDDLES48000_960 102#ifndef FFT_TWIDDLES48000_960
98#define FFT_TWIDDLES48000_960 103#define FFT_TWIDDLES48000_960
99static const kiss_twiddle_cpx fft_twiddles48000_960[480] ICONST_ATTR = { 104static const kiss_twiddle_cpx fft_twiddles48000_960[480] = {
100{32767, 0}, {32766, -429}, 105{32767, 0}, {32766, -429},
101{32757, -858}, {32743, -1287}, 106{32757, -858}, {32743, -1287},
102{32724, -1715}, {32698, -2143}, 107{32724, -1715}, {32698, -2143},
@@ -424,53 +429,73 @@ static const opus_int16 fft_bitrev60[60] = {
424 429
425#ifndef FFT_STATE48000_960_0 430#ifndef FFT_STATE48000_960_0
426#define FFT_STATE48000_960_0 431#define FFT_STATE48000_960_0
427static const kiss_fft_state fft_state48000_960_0 ICONST_ATTR = { 432static const kiss_fft_state fft_state48000_960_0 = {
428480, /* nfft */ 433480, /* nfft */
42917476, /* scale */ 43417476, /* scale */
4308, /* scale_shift */ 4358, /* scale_shift */
431-1, /* shift */ 436-1, /* shift */
432{5, 96, 3, 32, 4, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, }, /* factors */ 437{5, 96, 3, 32, 4, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, }, /* factors */
433fft_bitrev480, /* bitrev */ 438fft_bitrev480, /* bitrev */
434fft_twiddles48000_960, /* bitrev */ 439fft_twiddles48000_960, /* bitrev */
440#ifdef OVERRIDE_FFT
441(arch_fft_state *)&cfg_arch_480,
442#else
443NULL,
444#endif
435}; 445};
436#endif 446#endif
437 447
438#ifndef FFT_STATE48000_960_1 448#ifndef FFT_STATE48000_960_1
439#define FFT_STATE48000_960_1 449#define FFT_STATE48000_960_1
440static const kiss_fft_state fft_state48000_960_1 ICONST_ATTR = { 450static const kiss_fft_state fft_state48000_960_1 = {
441240, /* nfft */ 451240, /* nfft */
44217476, /* scale */ 45217476, /* scale */
4437, /* scale_shift */ 4537, /* scale_shift */
4441, /* shift */ 4541, /* shift */
445{5, 48, 3, 16, 4, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ 455{5, 48, 3, 16, 4, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
446fft_bitrev240, /* bitrev */ 456fft_bitrev240, /* bitrev */
447fft_twiddles48000_960, /* bitrev */ 457fft_twiddles48000_960, /* bitrev */
458#ifdef OVERRIDE_FFT
459(arch_fft_state *)&cfg_arch_240,
460#else
461NULL,
462#endif
448}; 463};
449#endif 464#endif
450 465
451#ifndef FFT_STATE48000_960_2 466#ifndef FFT_STATE48000_960_2
452#define FFT_STATE48000_960_2 467#define FFT_STATE48000_960_2
453static const kiss_fft_state fft_state48000_960_2 ICONST_ATTR = { 468static const kiss_fft_state fft_state48000_960_2 = {
454120, /* nfft */ 469120, /* nfft */
45517476, /* scale */ 47017476, /* scale */
4566, /* scale_shift */ 4716, /* scale_shift */
4572, /* shift */ 4722, /* shift */
458{5, 24, 3, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ 473{5, 24, 3, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
459fft_bitrev120, /* bitrev */ 474fft_bitrev120, /* bitrev */
460fft_twiddles48000_960, /* bitrev */ 475fft_twiddles48000_960, /* bitrev */
476#ifdef OVERRIDE_FFT
477(arch_fft_state *)&cfg_arch_120,
478#else
479NULL,
480#endif
461}; 481};
462#endif 482#endif
463 483
464#ifndef FFT_STATE48000_960_3 484#ifndef FFT_STATE48000_960_3
465#define FFT_STATE48000_960_3 485#define FFT_STATE48000_960_3
466static const kiss_fft_state fft_state48000_960_3 ICONST_ATTR = { 486static const kiss_fft_state fft_state48000_960_3 = {
46760, /* nfft */ 48760, /* nfft */
46817476, /* scale */ 48817476, /* scale */
4695, /* scale_shift */ 4895, /* scale_shift */
4703, /* shift */ 4903, /* shift */
471{5, 12, 3, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ 491{5, 12, 3, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
472fft_bitrev60, /* bitrev */ 492fft_bitrev60, /* bitrev */
473fft_twiddles48000_960, /* bitrev */ 493fft_twiddles48000_960, /* bitrev */
494#ifdef OVERRIDE_FFT
495(arch_fft_state *)&cfg_arch_60,
496#else
497NULL,
498#endif
474}; 499};
475#endif 500#endif
476 501
@@ -478,7 +503,7 @@ fft_twiddles48000_960, /* bitrev */
478 503
479#ifndef MDCT_TWIDDLES960 504#ifndef MDCT_TWIDDLES960
480#define MDCT_TWIDDLES960 505#define MDCT_TWIDDLES960
481static const opus_val16 mdct_twiddles960[1800] ICONST_ATTR = { 506static const opus_val16 mdct_twiddles960[1800] = {
48232767, 32767, 32767, 32766, 32765, 50732767, 32767, 32767, 32766, 32765,
48332763, 32761, 32759, 32756, 32753, 50832763, 32761, 32759, 32756, 32753,
48432750, 32746, 32742, 32738, 32733, 50932750, 32746, 32742, 32738, 32733,
@@ -842,7 +867,7 @@ static const opus_val16 mdct_twiddles960[1800] ICONST_ATTR = {
842}; 867};
843#endif 868#endif
844 869
845static const CELTMode mode48000_960_120 ICONST_ATTR = { 870static const CELTMode mode48000_960_120 = {
84648000, /* Fs */ 87148000, /* Fs */
847120, /* overlap */ 872120, /* overlap */
84821, /* nbEBands */ 87321, /* nbEBands */
diff --git a/lib/rbcodec/codecs/libopus/celt/static_modes_fixed_arm_ne10.h b/lib/rbcodec/codecs/libopus/celt/static_modes_fixed_arm_ne10.h
new file mode 100644
index 0000000000..7623092192
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/static_modes_fixed_arm_ne10.h
@@ -0,0 +1,388 @@
1/* The contents of this file was automatically generated by
2 * dump_mode_arm_ne10.c with arguments: 48000 960
3 * It contains static definitions for some pre-defined modes. */
4#include <NE10_types.h>
5
6#ifndef NE10_FFT_PARAMS48000_960
7#define NE10_FFT_PARAMS48000_960
8static const ne10_int32_t ne10_factors_480[64] = {
94, 40, 4, 30, 2, 15, 5, 3, 3, 1, 1, 0, 0, 0, 0,
100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
130, 0, 0, 0, };
14static const ne10_int32_t ne10_factors_240[64] = {
153, 20, 4, 15, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0,
160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
190, 0, 0, 0, };
20static const ne10_int32_t ne10_factors_120[64] = {
213, 10, 2, 15, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0,
220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
250, 0, 0, 0, };
26static const ne10_int32_t ne10_factors_60[64] = {
272, 5, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
310, 0, 0, 0, };
32static const ne10_fft_cpx_int32_t ne10_twiddles_480[480] = {
33{0,0}, {2147483647,0}, {2147483647,0},
34{2147483647,0}, {1961823921,-873460313}, {1436946998,-1595891394},
35{2147483647,0}, {1436946998,-1595891394}, {-224473265,-2135719496},
36{2147483647,0}, {663608871,-2042378339}, {-1737350854,-1262259096},
37{2147483647,0}, {-224473265,-2135719496}, {-2100555935,446487152},
38{2147483647,0}, {2100555974,-446486968}, {1961823921,-873460313},
39{1737350743,-1262259248}, {1436946998,-1595891394}, {1073741769,-1859775424},
40{663608871,-2042378339}, {224473078,-2135719516}, {-224473265,-2135719496},
41{-663609049,-2042378281}, {-1073741932,-1859775330}, {-1436947137,-1595891268},
42{-1737350854,-1262259096}, {-1961823997,-873460141}, {-2100556013,-446486785},
43{2147483647,0}, {2144540595,-112390613}, {2135719506,-224473172},
44{2121044558,-335940465}, {2100555974,-446486968}, {2074309912,-555809682},
45{2042378310,-663608960}, {2004848691,-769589332}, {1961823921,-873460313},
46{1913421927,-974937199}, {1859775377,-1073741851}, {1801031311,-1169603450},
47{1737350743,-1262259248}, {1668908218,-1351455280}, {1595891331,-1436947067},
48{1518500216,-1518500282}, {1436946998,-1595891394}, {1351455207,-1668908277},
49{1262259172,-1737350799}, {1169603371,-1801031362}, {1073741769,-1859775424},
50{974937230,-1913421912}, {873460227,-1961823959}, {769589125,-2004848771},
51{663608871,-2042378339}, {555809715,-2074309903}, {446486876,-2100555994},
52{335940246,-2121044593}, {224473078,-2135719516}, {112390647,-2144540593},
53{2147483647,0}, {2135719506,-224473172}, {2100555974,-446486968},
54{2042378310,-663608960}, {1961823921,-873460313}, {1859775377,-1073741851},
55{1737350743,-1262259248}, {1595891331,-1436947067}, {1436946998,-1595891394},
56{1262259172,-1737350799}, {1073741769,-1859775424}, {873460227,-1961823959},
57{663608871,-2042378339}, {446486876,-2100555994}, {224473078,-2135719516},
58{-94,-2147483647}, {-224473265,-2135719496}, {-446487060,-2100555955},
59{-663609049,-2042378281}, {-873460398,-1961823883}, {-1073741932,-1859775330},
60{-1262259116,-1737350839}, {-1436947137,-1595891268}, {-1595891628,-1436946738},
61{-1737350854,-1262259096}, {-1859775343,-1073741910}, {-1961823997,-873460141},
62{-2042378447,-663608538}, {-2100556013,-446486785}, {-2135719499,-224473240},
63{2147483647,0}, {2121044558,-335940465}, {2042378310,-663608960},
64{1913421927,-974937199}, {1737350743,-1262259248}, {1518500216,-1518500282},
65{1262259172,-1737350799}, {974937230,-1913421912}, {663608871,-2042378339},
66{335940246,-2121044593}, {-94,-2147483647}, {-335940431,-2121044564},
67{-663609049,-2042378281}, {-974937397,-1913421827}, {-1262259116,-1737350839},
68{-1518500258,-1518500240}, {-1737350854,-1262259096}, {-1913422071,-974936918},
69{-2042378447,-663608538}, {-2121044568,-335940406}, {-2147483647,188},
70{-2121044509,335940777}, {-2042378331,663608895}, {-1913421900,974937252},
71{-1737350633,1262259400}, {-1518499993,1518500506}, {-1262258813,1737351059},
72{-974936606,1913422229}, {-663609179,2042378239}, {-335940566,2121044542},
73{2147483647,0}, {2147299667,-28109693}, {2146747758,-56214570},
74{2145828015,-84309815}, {2144540595,-112390613}, {2142885719,-140452154},
75{2140863671,-168489630}, {2138474797,-196498235}, {2135719506,-224473172},
76{2132598271,-252409646}, {2129111626,-280302871}, {2125260168,-308148068},
77{2121044558,-335940465}, {2116465518,-363675300}, {2111523833,-391347822},
78{2106220349,-418953288}, {2100555974,-446486968}, {2094531681,-473944146},
79{2088148500,-501320115}, {2081407525,-528610186}, {2074309912,-555809682},
80{2066856885,-582913912}, {2059049696,-609918325}, {2050889698,-636818231},
81{2042378310,-663608960}, {2033516972,-690285983}, {2024307180,-716844791},
82{2014750533,-743280770}, {2004848691,-769589332}, {1994603329,-795766029},
83{1984016179,-821806435}, {1973089077,-847706028}, {1961823921,-873460313},
84{1950222618,-899064934}, {1938287127,-924515564}, {1926019520,-949807783},
85{1913421927,-974937199}, {1900496481,-999899565}, {1887245364,-1024690661},
86{1873670877,-1049306180}, {1859775377,-1073741851}, {1845561215,-1097993541},
87{1831030826,-1122057097}, {1816186632,-1145928502}, {1801031311,-1169603450},
88{1785567394,-1193077993}, {1769797456,-1216348214}, {1753724345,-1239409914},
89{1737350743,-1262259248}, {1720679456,-1284892300}, {1703713340,-1307305194},
90{1686455222,-1329494189}, {1668908218,-1351455280}, {1651075255,-1373184807},
91{1632959307,-1394679144}, {1614563642,-1415934412}, {1595891331,-1436947067},
92{1576945572,-1457713510}, {1557729613,-1478230181}, {1538246655,-1498493658},
93{1518500216,-1518500282}, {1498493590,-1538246721}, {1478230113,-1557729677},
94{1457713441,-1576945636}, {1436946998,-1595891394}, {1415934341,-1614563704},
95{1394679073,-1632959368}, {1373184735,-1651075315}, {1351455207,-1668908277},
96{1329494115,-1686455280}, {1307305120,-1703713397}, {1284892225,-1720679512},
97{1262259172,-1737350799}, {1239409837,-1753724400}, {1216348136,-1769797510},
98{1193077915,-1785567446}, {1169603371,-1801031362}, {1145928423,-1816186682},
99{1122057017,-1831030875}, {1097993571,-1845561197}, {1073741769,-1859775424},
100{1049305987,-1873670985}, {1024690635,-1887245378}, {999899482,-1900496524},
101{974937230,-1913421912}, {949807699,-1926019561}, {924515422,-1938287195},
102{899064965,-1950222603}, {873460227,-1961823959}, {847705824,-1973089164},
103{821806407,-1984016190}, {795765941,-1994603364}, {769589125,-2004848771},
104{743280682,-2014750566}, {716844642,-2024307233}, {690286016,-2033516961},
105{663608871,-2042378339}, {636818019,-2050889764}, {609918296,-2059049705},
106{582913822,-2066856911}, {555809715,-2074309903}, {528610126,-2081407540},
107{501319962,-2088148536}, {473944148,-2094531680}, {446486876,-2100555994},
108{418953102,-2106220386}, {391347792,-2111523838}, {363675176,-2116465540},
109{335940246,-2121044593}, {308148006,-2125260177}, {280302715,-2129111646},
110{252409648,-2132598271}, {224473078,-2135719516}, {196498046,-2138474814},
111{168489600,-2140863674}, {140452029,-2142885728}, {112390647,-2144540593},
112{84309753,-2145828017}, {56214412,-2146747762}, {28109695,-2147299667},
113{2147483647,0}, {2146747758,-56214570}, {2144540595,-112390613},
114{2140863671,-168489630}, {2135719506,-224473172}, {2129111626,-280302871},
115{2121044558,-335940465}, {2111523833,-391347822}, {2100555974,-446486968},
116{2088148500,-501320115}, {2074309912,-555809682}, {2059049696,-609918325},
117{2042378310,-663608960}, {2024307180,-716844791}, {2004848691,-769589332},
118{1984016179,-821806435}, {1961823921,-873460313}, {1938287127,-924515564},
119{1913421927,-974937199}, {1887245364,-1024690661}, {1859775377,-1073741851},
120{1831030826,-1122057097}, {1801031311,-1169603450}, {1769797456,-1216348214},
121{1737350743,-1262259248}, {1703713340,-1307305194}, {1668908218,-1351455280},
122{1632959307,-1394679144}, {1595891331,-1436947067}, {1557729613,-1478230181},
123{1518500216,-1518500282}, {1478230113,-1557729677}, {1436946998,-1595891394},
124{1394679073,-1632959368}, {1351455207,-1668908277}, {1307305120,-1703713397},
125{1262259172,-1737350799}, {1216348136,-1769797510}, {1169603371,-1801031362},
126{1122057017,-1831030875}, {1073741769,-1859775424}, {1024690635,-1887245378},
127{974937230,-1913421912}, {924515422,-1938287195}, {873460227,-1961823959},
128{821806407,-1984016190}, {769589125,-2004848771}, {716844642,-2024307233},
129{663608871,-2042378339}, {609918296,-2059049705}, {555809715,-2074309903},
130{501319962,-2088148536}, {446486876,-2100555994}, {391347792,-2111523838},
131{335940246,-2121044593}, {280302715,-2129111646}, {224473078,-2135719516},
132{168489600,-2140863674}, {112390647,-2144540593}, {56214412,-2146747762},
133{-94,-2147483647}, {-56214600,-2146747757}, {-112390835,-2144540584},
134{-168489787,-2140863659}, {-224473265,-2135719496}, {-280302901,-2129111622},
135{-335940431,-2121044564}, {-391347977,-2111523804}, {-446487060,-2100555955},
136{-501320144,-2088148493}, {-555809896,-2074309855}, {-609918476,-2059049651},
137{-663609049,-2042378281}, {-716844819,-2024307170}, {-769589300,-2004848703},
138{-821806581,-1984016118}, {-873460398,-1961823883}, {-924515591,-1938287114},
139{-974937397,-1913421827}, {-1024690575,-1887245411}, {-1073741932,-1859775330},
140{-1122057395,-1831030643}, {-1169603421,-1801031330}, {-1216348291,-1769797403},
141{-1262259116,-1737350839}, {-1307305268,-1703713283}, {-1351455453,-1668908078},
142{-1394679021,-1632959413}, {-1436947137,-1595891268}, {-1478230435,-1557729372},
143{-1518500258,-1518500240}, {-1557729742,-1478230045}, {-1595891628,-1436946738},
144{-1632959429,-1394679001}, {-1668908417,-1351455035}, {-1703713298,-1307305248},
145{-1737350854,-1262259096}, {-1769797708,-1216347848}, {-1801031344,-1169603400},
146{-1831030924,-1122056937}, {-1859775343,-1073741910}, {-1887245423,-1024690552},
147{-1913422071,-974936918}, {-1938287125,-924515568}, {-1961823997,-873460141},
148{-1984016324,-821806084}, {-2004848713,-769589276}, {-2024307264,-716844553},
149{-2042378447,-663608538}, {-2059049731,-609918206}, {-2074309994,-555809377},
150{-2088148499,-501320119}, {-2100556013,-446486785}, {-2111523902,-391347448},
151{-2121044568,-335940406}, {-2129111659,-280302621}, {-2135719499,-224473240},
152{-2140863681,-168489506}, {-2144540612,-112390298}, {-2146747758,-56214574},
153{2147483647,0}, {2145828015,-84309815}, {2140863671,-168489630},
154{2132598271,-252409646}, {2121044558,-335940465}, {2106220349,-418953288},
155{2088148500,-501320115}, {2066856885,-582913912}, {2042378310,-663608960},
156{2014750533,-743280770}, {1984016179,-821806435}, {1950222618,-899064934},
157{1913421927,-974937199}, {1873670877,-1049306180}, {1831030826,-1122057097},
158{1785567394,-1193077993}, {1737350743,-1262259248}, {1686455222,-1329494189},
159{1632959307,-1394679144}, {1576945572,-1457713510}, {1518500216,-1518500282},
160{1457713441,-1576945636}, {1394679073,-1632959368}, {1329494115,-1686455280},
161{1262259172,-1737350799}, {1193077915,-1785567446}, {1122057017,-1831030875},
162{1049305987,-1873670985}, {974937230,-1913421912}, {899064965,-1950222603},
163{821806407,-1984016190}, {743280682,-2014750566}, {663608871,-2042378339},
164{582913822,-2066856911}, {501319962,-2088148536}, {418953102,-2106220386},
165{335940246,-2121044593}, {252409648,-2132598271}, {168489600,-2140863674},
166{84309753,-2145828017}, {-94,-2147483647}, {-84309940,-2145828010},
167{-168489787,-2140863659}, {-252409834,-2132598249}, {-335940431,-2121044564},
168{-418953286,-2106220349}, {-501320144,-2088148493}, {-582914003,-2066856860},
169{-663609049,-2042378281}, {-743280858,-2014750501}, {-821806581,-1984016118},
170{-899065136,-1950222525}, {-974937397,-1913421827}, {-1049306374,-1873670768},
171{-1122057395,-1831030643}, {-1193078284,-1785567199}, {-1262259116,-1737350839},
172{-1329494061,-1686455323}, {-1394679021,-1632959413}, {-1457713485,-1576945595},
173{-1518500258,-1518500240}, {-1576945613,-1457713466}, {-1632959429,-1394679001},
174{-1686455338,-1329494041}, {-1737350854,-1262259096}, {-1785567498,-1193077837},
175{-1831030924,-1122056937}, {-1873671031,-1049305905}, {-1913422071,-974936918},
176{-1950222750,-899064648}, {-1984016324,-821806084}, {-2014750687,-743280354},
177{-2042378447,-663608538}, {-2066856867,-582913978}, {-2088148499,-501320119},
178{-2106220354,-418953261}, {-2121044568,-335940406}, {-2132598282,-252409555},
179{-2140863681,-168489506}, {-2145828021,-84309659}, {-2147483647,188},
180{-2145828006,84310034}, {-2140863651,168489881}, {-2132598237,252409928},
181{-2121044509,335940777}, {-2106220281,418953629}, {-2088148411,501320484},
182{-2066856765,582914339}, {-2042378331,663608895}, {-2014750557,743280706},
183{-1984016181,821806431}, {-1950222593,899064989}, {-1913421900,974937252},
184{-1873670848,1049306232}, {-1831030728,1122057257}, {-1785567289,1193078149},
185{-1737350633,1262259400}, {-1686455106,1329494336}, {-1632959185,1394679287},
186{-1576945358,1457713742}, {-1518499993,1518500506}, {-1457713209,1576945850},
187{-1394678735,1632959656}, {-1329493766,1686455555}, {-1262258813,1737351059},
188{-1193077546,1785567692}, {-1122056638,1831031107}, {-1049305599,1873671202},
189{-974936606,1913422229}, {-899064330,1950222896}, {-821805761,1984016458},
190{-743280025,2014750808}, {-663609179,2042378239}, {-582914134,2066856823},
191{-501320277,2088148461}, {-418953420,2106220322}, {-335940566,2121044542},
192{-252409716,2132598263}, {-168489668,2140863668}, {-84309821,2145828015},
193};
194static const ne10_fft_cpx_int32_t ne10_twiddles_240[240] = {
195{0,0}, {2147483647,0}, {2147483647,0},
196{2147483647,0}, {1961823921,-873460313}, {1436946998,-1595891394},
197{2147483647,0}, {1436946998,-1595891394}, {-224473265,-2135719496},
198{2147483647,0}, {663608871,-2042378339}, {-1737350854,-1262259096},
199{2147483647,0}, {-224473265,-2135719496}, {-2100555935,446487152},
200{2147483647,0}, {2135719506,-224473172}, {2100555974,-446486968},
201{2042378310,-663608960}, {1961823921,-873460313}, {1859775377,-1073741851},
202{1737350743,-1262259248}, {1595891331,-1436947067}, {1436946998,-1595891394},
203{1262259172,-1737350799}, {1073741769,-1859775424}, {873460227,-1961823959},
204{663608871,-2042378339}, {446486876,-2100555994}, {224473078,-2135719516},
205{2147483647,0}, {2100555974,-446486968}, {1961823921,-873460313},
206{1737350743,-1262259248}, {1436946998,-1595891394}, {1073741769,-1859775424},
207{663608871,-2042378339}, {224473078,-2135719516}, {-224473265,-2135719496},
208{-663609049,-2042378281}, {-1073741932,-1859775330}, {-1436947137,-1595891268},
209{-1737350854,-1262259096}, {-1961823997,-873460141}, {-2100556013,-446486785},
210{2147483647,0}, {2042378310,-663608960}, {1737350743,-1262259248},
211{1262259172,-1737350799}, {663608871,-2042378339}, {-94,-2147483647},
212{-663609049,-2042378281}, {-1262259116,-1737350839}, {-1737350854,-1262259096},
213{-2042378447,-663608538}, {-2147483647,188}, {-2042378331,663608895},
214{-1737350633,1262259400}, {-1262258813,1737351059}, {-663609179,2042378239},
215{2147483647,0}, {2146747758,-56214570}, {2144540595,-112390613},
216{2140863671,-168489630}, {2135719506,-224473172}, {2129111626,-280302871},
217{2121044558,-335940465}, {2111523833,-391347822}, {2100555974,-446486968},
218{2088148500,-501320115}, {2074309912,-555809682}, {2059049696,-609918325},
219{2042378310,-663608960}, {2024307180,-716844791}, {2004848691,-769589332},
220{1984016179,-821806435}, {1961823921,-873460313}, {1938287127,-924515564},
221{1913421927,-974937199}, {1887245364,-1024690661}, {1859775377,-1073741851},
222{1831030826,-1122057097}, {1801031311,-1169603450}, {1769797456,-1216348214},
223{1737350743,-1262259248}, {1703713340,-1307305194}, {1668908218,-1351455280},
224{1632959307,-1394679144}, {1595891331,-1436947067}, {1557729613,-1478230181},
225{1518500216,-1518500282}, {1478230113,-1557729677}, {1436946998,-1595891394},
226{1394679073,-1632959368}, {1351455207,-1668908277}, {1307305120,-1703713397},
227{1262259172,-1737350799}, {1216348136,-1769797510}, {1169603371,-1801031362},
228{1122057017,-1831030875}, {1073741769,-1859775424}, {1024690635,-1887245378},
229{974937230,-1913421912}, {924515422,-1938287195}, {873460227,-1961823959},
230{821806407,-1984016190}, {769589125,-2004848771}, {716844642,-2024307233},
231{663608871,-2042378339}, {609918296,-2059049705}, {555809715,-2074309903},
232{501319962,-2088148536}, {446486876,-2100555994}, {391347792,-2111523838},
233{335940246,-2121044593}, {280302715,-2129111646}, {224473078,-2135719516},
234{168489600,-2140863674}, {112390647,-2144540593}, {56214412,-2146747762},
235{2147483647,0}, {2144540595,-112390613}, {2135719506,-224473172},
236{2121044558,-335940465}, {2100555974,-446486968}, {2074309912,-555809682},
237{2042378310,-663608960}, {2004848691,-769589332}, {1961823921,-873460313},
238{1913421927,-974937199}, {1859775377,-1073741851}, {1801031311,-1169603450},
239{1737350743,-1262259248}, {1668908218,-1351455280}, {1595891331,-1436947067},
240{1518500216,-1518500282}, {1436946998,-1595891394}, {1351455207,-1668908277},
241{1262259172,-1737350799}, {1169603371,-1801031362}, {1073741769,-1859775424},
242{974937230,-1913421912}, {873460227,-1961823959}, {769589125,-2004848771},
243{663608871,-2042378339}, {555809715,-2074309903}, {446486876,-2100555994},
244{335940246,-2121044593}, {224473078,-2135719516}, {112390647,-2144540593},
245{-94,-2147483647}, {-112390835,-2144540584}, {-224473265,-2135719496},
246{-335940431,-2121044564}, {-446487060,-2100555955}, {-555809896,-2074309855},
247{-663609049,-2042378281}, {-769589300,-2004848703}, {-873460398,-1961823883},
248{-974937397,-1913421827}, {-1073741932,-1859775330}, {-1169603421,-1801031330},
249{-1262259116,-1737350839}, {-1351455453,-1668908078}, {-1436947137,-1595891268},
250{-1518500258,-1518500240}, {-1595891628,-1436946738}, {-1668908417,-1351455035},
251{-1737350854,-1262259096}, {-1801031344,-1169603400}, {-1859775343,-1073741910},
252{-1913422071,-974936918}, {-1961823997,-873460141}, {-2004848713,-769589276},
253{-2042378447,-663608538}, {-2074309994,-555809377}, {-2100556013,-446486785},
254{-2121044568,-335940406}, {-2135719499,-224473240}, {-2144540612,-112390298},
255{2147483647,0}, {2140863671,-168489630}, {2121044558,-335940465},
256{2088148500,-501320115}, {2042378310,-663608960}, {1984016179,-821806435},
257{1913421927,-974937199}, {1831030826,-1122057097}, {1737350743,-1262259248},
258{1632959307,-1394679144}, {1518500216,-1518500282}, {1394679073,-1632959368},
259{1262259172,-1737350799}, {1122057017,-1831030875}, {974937230,-1913421912},
260{821806407,-1984016190}, {663608871,-2042378339}, {501319962,-2088148536},
261{335940246,-2121044593}, {168489600,-2140863674}, {-94,-2147483647},
262{-168489787,-2140863659}, {-335940431,-2121044564}, {-501320144,-2088148493},
263{-663609049,-2042378281}, {-821806581,-1984016118}, {-974937397,-1913421827},
264{-1122057395,-1831030643}, {-1262259116,-1737350839}, {-1394679021,-1632959413},
265{-1518500258,-1518500240}, {-1632959429,-1394679001}, {-1737350854,-1262259096},
266{-1831030924,-1122056937}, {-1913422071,-974936918}, {-1984016324,-821806084},
267{-2042378447,-663608538}, {-2088148499,-501320119}, {-2121044568,-335940406},
268{-2140863681,-168489506}, {-2147483647,188}, {-2140863651,168489881},
269{-2121044509,335940777}, {-2088148411,501320484}, {-2042378331,663608895},
270{-1984016181,821806431}, {-1913421900,974937252}, {-1831030728,1122057257},
271{-1737350633,1262259400}, {-1632959185,1394679287}, {-1518499993,1518500506},
272{-1394678735,1632959656}, {-1262258813,1737351059}, {-1122056638,1831031107},
273{-974936606,1913422229}, {-821805761,1984016458}, {-663609179,2042378239},
274{-501320277,2088148461}, {-335940566,2121044542}, {-168489668,2140863668},
275};
276static const ne10_fft_cpx_int32_t ne10_twiddles_120[120] = {
277{0,0}, {2147483647,0}, {2147483647,0},
278{2147483647,0}, {1961823921,-873460313}, {1436946998,-1595891394},
279{2147483647,0}, {1436946998,-1595891394}, {-224473265,-2135719496},
280{2147483647,0}, {663608871,-2042378339}, {-1737350854,-1262259096},
281{2147483647,0}, {-224473265,-2135719496}, {-2100555935,446487152},
282{2147483647,0}, {2100555974,-446486968}, {1961823921,-873460313},
283{1737350743,-1262259248}, {1436946998,-1595891394}, {1073741769,-1859775424},
284{663608871,-2042378339}, {224473078,-2135719516}, {-224473265,-2135719496},
285{-663609049,-2042378281}, {-1073741932,-1859775330}, {-1436947137,-1595891268},
286{-1737350854,-1262259096}, {-1961823997,-873460141}, {-2100556013,-446486785},
287{2147483647,0}, {2144540595,-112390613}, {2135719506,-224473172},
288{2121044558,-335940465}, {2100555974,-446486968}, {2074309912,-555809682},
289{2042378310,-663608960}, {2004848691,-769589332}, {1961823921,-873460313},
290{1913421927,-974937199}, {1859775377,-1073741851}, {1801031311,-1169603450},
291{1737350743,-1262259248}, {1668908218,-1351455280}, {1595891331,-1436947067},
292{1518500216,-1518500282}, {1436946998,-1595891394}, {1351455207,-1668908277},
293{1262259172,-1737350799}, {1169603371,-1801031362}, {1073741769,-1859775424},
294{974937230,-1913421912}, {873460227,-1961823959}, {769589125,-2004848771},
295{663608871,-2042378339}, {555809715,-2074309903}, {446486876,-2100555994},
296{335940246,-2121044593}, {224473078,-2135719516}, {112390647,-2144540593},
297{2147483647,0}, {2135719506,-224473172}, {2100555974,-446486968},
298{2042378310,-663608960}, {1961823921,-873460313}, {1859775377,-1073741851},
299{1737350743,-1262259248}, {1595891331,-1436947067}, {1436946998,-1595891394},
300{1262259172,-1737350799}, {1073741769,-1859775424}, {873460227,-1961823959},
301{663608871,-2042378339}, {446486876,-2100555994}, {224473078,-2135719516},
302{-94,-2147483647}, {-224473265,-2135719496}, {-446487060,-2100555955},
303{-663609049,-2042378281}, {-873460398,-1961823883}, {-1073741932,-1859775330},
304{-1262259116,-1737350839}, {-1436947137,-1595891268}, {-1595891628,-1436946738},
305{-1737350854,-1262259096}, {-1859775343,-1073741910}, {-1961823997,-873460141},
306{-2042378447,-663608538}, {-2100556013,-446486785}, {-2135719499,-224473240},
307{2147483647,0}, {2121044558,-335940465}, {2042378310,-663608960},
308{1913421927,-974937199}, {1737350743,-1262259248}, {1518500216,-1518500282},
309{1262259172,-1737350799}, {974937230,-1913421912}, {663608871,-2042378339},
310{335940246,-2121044593}, {-94,-2147483647}, {-335940431,-2121044564},
311{-663609049,-2042378281}, {-974937397,-1913421827}, {-1262259116,-1737350839},
312{-1518500258,-1518500240}, {-1737350854,-1262259096}, {-1913422071,-974936918},
313{-2042378447,-663608538}, {-2121044568,-335940406}, {-2147483647,188},
314{-2121044509,335940777}, {-2042378331,663608895}, {-1913421900,974937252},
315{-1737350633,1262259400}, {-1518499993,1518500506}, {-1262258813,1737351059},
316{-974936606,1913422229}, {-663609179,2042378239}, {-335940566,2121044542},
317};
318static const ne10_fft_cpx_int32_t ne10_twiddles_60[60] = {
319{0,0}, {2147483647,0}, {2147483647,0},
320{2147483647,0}, {1961823921,-873460313}, {1436946998,-1595891394},
321{2147483647,0}, {1436946998,-1595891394}, {-224473265,-2135719496},
322{2147483647,0}, {663608871,-2042378339}, {-1737350854,-1262259096},
323{2147483647,0}, {-224473265,-2135719496}, {-2100555935,446487152},
324{2147483647,0}, {2135719506,-224473172}, {2100555974,-446486968},
325{2042378310,-663608960}, {1961823921,-873460313}, {1859775377,-1073741851},
326{1737350743,-1262259248}, {1595891331,-1436947067}, {1436946998,-1595891394},
327{1262259172,-1737350799}, {1073741769,-1859775424}, {873460227,-1961823959},
328{663608871,-2042378339}, {446486876,-2100555994}, {224473078,-2135719516},
329{2147483647,0}, {2100555974,-446486968}, {1961823921,-873460313},
330{1737350743,-1262259248}, {1436946998,-1595891394}, {1073741769,-1859775424},
331{663608871,-2042378339}, {224473078,-2135719516}, {-224473265,-2135719496},
332{-663609049,-2042378281}, {-1073741932,-1859775330}, {-1436947137,-1595891268},
333{-1737350854,-1262259096}, {-1961823997,-873460141}, {-2100556013,-446486785},
334{2147483647,0}, {2042378310,-663608960}, {1737350743,-1262259248},
335{1262259172,-1737350799}, {663608871,-2042378339}, {-94,-2147483647},
336{-663609049,-2042378281}, {-1262259116,-1737350839}, {-1737350854,-1262259096},
337{-2042378447,-663608538}, {-2147483647,188}, {-2042378331,663608895},
338{-1737350633,1262259400}, {-1262258813,1737351059}, {-663609179,2042378239},
339};
340static const ne10_fft_state_int32_t ne10_fft_state_int32_t_480 = {
341120,
342(ne10_int32_t *)ne10_factors_480,
343(ne10_fft_cpx_int32_t *)ne10_twiddles_480,
344NULL,
345(ne10_fft_cpx_int32_t *)&ne10_twiddles_480[120],
346};
347static const arch_fft_state cfg_arch_480 = {
3481,
349(void *)&ne10_fft_state_int32_t_480,
350};
351
352static const ne10_fft_state_int32_t ne10_fft_state_int32_t_240 = {
35360,
354(ne10_int32_t *)ne10_factors_240,
355(ne10_fft_cpx_int32_t *)ne10_twiddles_240,
356NULL,
357(ne10_fft_cpx_int32_t *)&ne10_twiddles_240[60],
358};
359static const arch_fft_state cfg_arch_240 = {
3601,
361(void *)&ne10_fft_state_int32_t_240,
362};
363
364static const ne10_fft_state_int32_t ne10_fft_state_int32_t_120 = {
36530,
366(ne10_int32_t *)ne10_factors_120,
367(ne10_fft_cpx_int32_t *)ne10_twiddles_120,
368NULL,
369(ne10_fft_cpx_int32_t *)&ne10_twiddles_120[30],
370};
371static const arch_fft_state cfg_arch_120 = {
3721,
373(void *)&ne10_fft_state_int32_t_120,
374};
375
376static const ne10_fft_state_int32_t ne10_fft_state_int32_t_60 = {
37715,
378(ne10_int32_t *)ne10_factors_60,
379(ne10_fft_cpx_int32_t *)ne10_twiddles_60,
380NULL,
381(ne10_fft_cpx_int32_t *)&ne10_twiddles_60[15],
382};
383static const arch_fft_state cfg_arch_60 = {
3841,
385(void *)&ne10_fft_state_int32_t_60,
386};
387
388#endif /* end NE10_FFT_PARAMS48000_960 */
diff --git a/lib/rbcodec/codecs/libopus/celt/static_modes_float.h b/lib/rbcodec/codecs/libopus/celt/static_modes_float.h
new file mode 100644
index 0000000000..e102a38391
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/static_modes_float.h
@@ -0,0 +1,888 @@
1/* The contents of this file was automatically generated by dump_modes.c
2 with arguments: 48000 960
3 It contains static definitions for some pre-defined modes. */
4#include "modes.h"
5#include "rate.h"
6
7#ifdef HAVE_ARM_NE10
8#define OVERRIDE_FFT 1
9#include "static_modes_float_arm_ne10.h"
10#endif
11
12#ifndef DEF_WINDOW120
13#define DEF_WINDOW120
14static const opus_val16 window120[120] = {
156.7286966e-05f, 0.00060551348f, 0.0016815970f, 0.0032947962f, 0.0054439943f,
160.0081276923f, 0.011344001f, 0.015090633f, 0.019364886f, 0.024163635f,
170.029483315f, 0.035319905f, 0.041668911f, 0.048525347f, 0.055883718f,
180.063737999f, 0.072081616f, 0.080907428f, 0.090207705f, 0.099974111f,
190.11019769f, 0.12086883f, 0.13197729f, 0.14351214f, 0.15546177f,
200.16781389f, 0.18055550f, 0.19367290f, 0.20715171f, 0.22097682f,
210.23513243f, 0.24960208f, 0.26436860f, 0.27941419f, 0.29472040f,
220.31026818f, 0.32603788f, 0.34200931f, 0.35816177f, 0.37447407f,
230.39092462f, 0.40749142f, 0.42415215f, 0.44088423f, 0.45766484f,
240.47447104f, 0.49127978f, 0.50806798f, 0.52481261f, 0.54149077f,
250.55807973f, 0.57455701f, 0.59090049f, 0.60708841f, 0.62309951f,
260.63891306f, 0.65450896f, 0.66986776f, 0.68497077f, 0.69980010f,
270.71433873f, 0.72857055f, 0.74248043f, 0.75605424f, 0.76927895f,
280.78214257f, 0.79463430f, 0.80674445f, 0.81846456f, 0.82978733f,
290.84070669f, 0.85121779f, 0.86131698f, 0.87100183f, 0.88027111f,
300.88912479f, 0.89756398f, 0.90559094f, 0.91320904f, 0.92042270f,
310.92723738f, 0.93365955f, 0.93969656f, 0.94535671f, 0.95064907f,
320.95558353f, 0.96017067f, 0.96442171f, 0.96834849f, 0.97196334f,
330.97527906f, 0.97830883f, 0.98106616f, 0.98356480f, 0.98581869f,
340.98784191f, 0.98964856f, 0.99125274f, 0.99266849f, 0.99390969f,
350.99499004f, 0.99592297f, 0.99672162f, 0.99739874f, 0.99796667f,
360.99843728f, 0.99882195f, 0.99913147f, 0.99937606f, 0.99956527f,
370.99970802f, 0.99981248f, 0.99988613f, 0.99993565f, 0.99996697f,
380.99998518f, 0.99999457f, 0.99999859f, 0.99999982f, 1.0000000f,
39};
40#endif
41
42#ifndef DEF_LOGN400
43#define DEF_LOGN400
44static const opus_int16 logN400[21] = {
450, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 21, 21, 24, 29, 34, 36, };
46#endif
47
48#ifndef DEF_PULSE_CACHE50
49#define DEF_PULSE_CACHE50
50static const opus_int16 cache_index50[105] = {
51-1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 41, 41, 41,
5282, 82, 123, 164, 200, 222, 0, 0, 0, 0, 0, 0, 0, 0, 41,
5341, 41, 41, 123, 123, 123, 164, 164, 240, 266, 283, 295, 41, 41, 41,
5441, 41, 41, 41, 41, 123, 123, 123, 123, 240, 240, 240, 266, 266, 305,
55318, 328, 336, 123, 123, 123, 123, 123, 123, 123, 123, 240, 240, 240, 240,
56305, 305, 305, 318, 318, 343, 351, 358, 364, 240, 240, 240, 240, 240, 240,
57240, 240, 305, 305, 305, 305, 343, 343, 343, 351, 351, 370, 376, 382, 387,
58};
59static const unsigned char cache_bits50[392] = {
6040, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
617, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
627, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 40, 15, 23, 28,
6331, 34, 36, 38, 39, 41, 42, 43, 44, 45, 46, 47, 47, 49, 50,
6451, 52, 53, 54, 55, 55, 57, 58, 59, 60, 61, 62, 63, 63, 65,
6566, 67, 68, 69, 70, 71, 71, 40, 20, 33, 41, 48, 53, 57, 61,
6664, 66, 69, 71, 73, 75, 76, 78, 80, 82, 85, 87, 89, 91, 92,
6794, 96, 98, 101, 103, 105, 107, 108, 110, 112, 114, 117, 119, 121, 123,
68124, 126, 128, 40, 23, 39, 51, 60, 67, 73, 79, 83, 87, 91, 94,
6997, 100, 102, 105, 107, 111, 115, 118, 121, 124, 126, 129, 131, 135, 139,
70142, 145, 148, 150, 153, 155, 159, 163, 166, 169, 172, 174, 177, 179, 35,
7128, 49, 65, 78, 89, 99, 107, 114, 120, 126, 132, 136, 141, 145, 149,
72153, 159, 165, 171, 176, 180, 185, 189, 192, 199, 205, 211, 216, 220, 225,
73229, 232, 239, 245, 251, 21, 33, 58, 79, 97, 112, 125, 137, 148, 157,
74166, 174, 182, 189, 195, 201, 207, 217, 227, 235, 243, 251, 17, 35, 63,
7586, 106, 123, 139, 152, 165, 177, 187, 197, 206, 214, 222, 230, 237, 250,
7625, 31, 55, 75, 91, 105, 117, 128, 138, 146, 154, 161, 168, 174, 180,
77185, 190, 200, 208, 215, 222, 229, 235, 240, 245, 255, 16, 36, 65, 89,
78110, 128, 144, 159, 173, 185, 196, 207, 217, 226, 234, 242, 250, 11, 41,
7974, 103, 128, 151, 172, 191, 209, 225, 241, 255, 9, 43, 79, 110, 138,
80163, 186, 207, 227, 246, 12, 39, 71, 99, 123, 144, 164, 182, 198, 214,
81228, 241, 253, 9, 44, 81, 113, 142, 168, 192, 214, 235, 255, 7, 49,
8290, 127, 160, 191, 220, 247, 6, 51, 95, 134, 170, 203, 234, 7, 47,
8387, 123, 155, 184, 212, 237, 6, 52, 97, 137, 174, 208, 240, 5, 57,
84106, 151, 192, 231, 5, 59, 111, 158, 202, 243, 5, 55, 103, 147, 187,
85224, 5, 60, 113, 161, 206, 248, 4, 65, 122, 175, 224, 4, 67, 127,
86182, 234, };
87static const unsigned char cache_caps50[168] = {
88224, 224, 224, 224, 224, 224, 224, 224, 160, 160, 160, 160, 185, 185, 185,
89178, 178, 168, 134, 61, 37, 224, 224, 224, 224, 224, 224, 224, 224, 240,
90240, 240, 240, 207, 207, 207, 198, 198, 183, 144, 66, 40, 160, 160, 160,
91160, 160, 160, 160, 160, 185, 185, 185, 185, 193, 193, 193, 183, 183, 172,
92138, 64, 38, 240, 240, 240, 240, 240, 240, 240, 240, 207, 207, 207, 207,
93204, 204, 204, 193, 193, 180, 143, 66, 40, 185, 185, 185, 185, 185, 185,
94185, 185, 193, 193, 193, 193, 193, 193, 193, 183, 183, 172, 138, 65, 39,
95207, 207, 207, 207, 207, 207, 207, 207, 204, 204, 204, 204, 201, 201, 201,
96188, 188, 176, 141, 66, 40, 193, 193, 193, 193, 193, 193, 193, 193, 193,
97193, 193, 193, 194, 194, 194, 184, 184, 173, 139, 65, 39, 204, 204, 204,
98204, 204, 204, 204, 204, 201, 201, 201, 201, 198, 198, 198, 187, 187, 175,
99140, 66, 40, };
100#endif
101
102#ifndef FFT_TWIDDLES48000_960
103#define FFT_TWIDDLES48000_960
104static const kiss_twiddle_cpx fft_twiddles48000_960[480] = {
105{1.0000000f, -0.0000000f}, {0.99991433f, -0.013089596f},
106{0.99965732f, -0.026176948f}, {0.99922904f, -0.039259816f},
107{0.99862953f, -0.052335956f}, {0.99785892f, -0.065403129f},
108{0.99691733f, -0.078459096f}, {0.99580493f, -0.091501619f},
109{0.99452190f, -0.10452846f}, {0.99306846f, -0.11753740f},
110{0.99144486f, -0.13052619f}, {0.98965139f, -0.14349262f},
111{0.98768834f, -0.15643447f}, {0.98555606f, -0.16934950f},
112{0.98325491f, -0.18223553f}, {0.98078528f, -0.19509032f},
113{0.97814760f, -0.20791169f}, {0.97534232f, -0.22069744f},
114{0.97236992f, -0.23344536f}, {0.96923091f, -0.24615329f},
115{0.96592583f, -0.25881905f}, {0.96245524f, -0.27144045f},
116{0.95881973f, -0.28401534f}, {0.95501994f, -0.29654157f},
117{0.95105652f, -0.30901699f}, {0.94693013f, -0.32143947f},
118{0.94264149f, -0.33380686f}, {0.93819134f, -0.34611706f},
119{0.93358043f, -0.35836795f}, {0.92880955f, -0.37055744f},
120{0.92387953f, -0.38268343f}, {0.91879121f, -0.39474386f},
121{0.91354546f, -0.40673664f}, {0.90814317f, -0.41865974f},
122{0.90258528f, -0.43051110f}, {0.89687274f, -0.44228869f},
123{0.89100652f, -0.45399050f}, {0.88498764f, -0.46561452f},
124{0.87881711f, -0.47715876f}, {0.87249601f, -0.48862124f},
125{0.86602540f, -0.50000000f}, {0.85940641f, -0.51129309f},
126{0.85264016f, -0.52249856f}, {0.84572782f, -0.53361452f},
127{0.83867057f, -0.54463904f}, {0.83146961f, -0.55557023f},
128{0.82412619f, -0.56640624f}, {0.81664156f, -0.57714519f},
129{0.80901699f, -0.58778525f}, {0.80125381f, -0.59832460f},
130{0.79335334f, -0.60876143f}, {0.78531693f, -0.61909395f},
131{0.77714596f, -0.62932039f}, {0.76884183f, -0.63943900f},
132{0.76040597f, -0.64944805f}, {0.75183981f, -0.65934582f},
133{0.74314483f, -0.66913061f}, {0.73432251f, -0.67880075f},
134{0.72537437f, -0.68835458f}, {0.71630194f, -0.69779046f},
135{0.70710678f, -0.70710678f}, {0.69779046f, -0.71630194f},
136{0.68835458f, -0.72537437f}, {0.67880075f, -0.73432251f},
137{0.66913061f, -0.74314483f}, {0.65934582f, -0.75183981f},
138{0.64944805f, -0.76040597f}, {0.63943900f, -0.76884183f},
139{0.62932039f, -0.77714596f}, {0.61909395f, -0.78531693f},
140{0.60876143f, -0.79335334f}, {0.59832460f, -0.80125381f},
141{0.58778525f, -0.80901699f}, {0.57714519f, -0.81664156f},
142{0.56640624f, -0.82412619f}, {0.55557023f, -0.83146961f},
143{0.54463904f, -0.83867057f}, {0.53361452f, -0.84572782f},
144{0.52249856f, -0.85264016f}, {0.51129309f, -0.85940641f},
145{0.50000000f, -0.86602540f}, {0.48862124f, -0.87249601f},
146{0.47715876f, -0.87881711f}, {0.46561452f, -0.88498764f},
147{0.45399050f, -0.89100652f}, {0.44228869f, -0.89687274f},
148{0.43051110f, -0.90258528f}, {0.41865974f, -0.90814317f},
149{0.40673664f, -0.91354546f}, {0.39474386f, -0.91879121f},
150{0.38268343f, -0.92387953f}, {0.37055744f, -0.92880955f},
151{0.35836795f, -0.93358043f}, {0.34611706f, -0.93819134f},
152{0.33380686f, -0.94264149f}, {0.32143947f, -0.94693013f},
153{0.30901699f, -0.95105652f}, {0.29654157f, -0.95501994f},
154{0.28401534f, -0.95881973f}, {0.27144045f, -0.96245524f},
155{0.25881905f, -0.96592583f}, {0.24615329f, -0.96923091f},
156{0.23344536f, -0.97236992f}, {0.22069744f, -0.97534232f},
157{0.20791169f, -0.97814760f}, {0.19509032f, -0.98078528f},
158{0.18223553f, -0.98325491f}, {0.16934950f, -0.98555606f},
159{0.15643447f, -0.98768834f}, {0.14349262f, -0.98965139f},
160{0.13052619f, -0.99144486f}, {0.11753740f, -0.99306846f},
161{0.10452846f, -0.99452190f}, {0.091501619f, -0.99580493f},
162{0.078459096f, -0.99691733f}, {0.065403129f, -0.99785892f},
163{0.052335956f, -0.99862953f}, {0.039259816f, -0.99922904f},
164{0.026176948f, -0.99965732f}, {0.013089596f, -0.99991433f},
165{6.1230318e-17f, -1.0000000f}, {-0.013089596f, -0.99991433f},
166{-0.026176948f, -0.99965732f}, {-0.039259816f, -0.99922904f},
167{-0.052335956f, -0.99862953f}, {-0.065403129f, -0.99785892f},
168{-0.078459096f, -0.99691733f}, {-0.091501619f, -0.99580493f},
169{-0.10452846f, -0.99452190f}, {-0.11753740f, -0.99306846f},
170{-0.13052619f, -0.99144486f}, {-0.14349262f, -0.98965139f},
171{-0.15643447f, -0.98768834f}, {-0.16934950f, -0.98555606f},
172{-0.18223553f, -0.98325491f}, {-0.19509032f, -0.98078528f},
173{-0.20791169f, -0.97814760f}, {-0.22069744f, -0.97534232f},
174{-0.23344536f, -0.97236992f}, {-0.24615329f, -0.96923091f},
175{-0.25881905f, -0.96592583f}, {-0.27144045f, -0.96245524f},
176{-0.28401534f, -0.95881973f}, {-0.29654157f, -0.95501994f},
177{-0.30901699f, -0.95105652f}, {-0.32143947f, -0.94693013f},
178{-0.33380686f, -0.94264149f}, {-0.34611706f, -0.93819134f},
179{-0.35836795f, -0.93358043f}, {-0.37055744f, -0.92880955f},
180{-0.38268343f, -0.92387953f}, {-0.39474386f, -0.91879121f},
181{-0.40673664f, -0.91354546f}, {-0.41865974f, -0.90814317f},
182{-0.43051110f, -0.90258528f}, {-0.44228869f, -0.89687274f},
183{-0.45399050f, -0.89100652f}, {-0.46561452f, -0.88498764f},
184{-0.47715876f, -0.87881711f}, {-0.48862124f, -0.87249601f},
185{-0.50000000f, -0.86602540f}, {-0.51129309f, -0.85940641f},
186{-0.52249856f, -0.85264016f}, {-0.53361452f, -0.84572782f},
187{-0.54463904f, -0.83867057f}, {-0.55557023f, -0.83146961f},
188{-0.56640624f, -0.82412619f}, {-0.57714519f, -0.81664156f},
189{-0.58778525f, -0.80901699f}, {-0.59832460f, -0.80125381f},
190{-0.60876143f, -0.79335334f}, {-0.61909395f, -0.78531693f},
191{-0.62932039f, -0.77714596f}, {-0.63943900f, -0.76884183f},
192{-0.64944805f, -0.76040597f}, {-0.65934582f, -0.75183981f},
193{-0.66913061f, -0.74314483f}, {-0.67880075f, -0.73432251f},
194{-0.68835458f, -0.72537437f}, {-0.69779046f, -0.71630194f},
195{-0.70710678f, -0.70710678f}, {-0.71630194f, -0.69779046f},
196{-0.72537437f, -0.68835458f}, {-0.73432251f, -0.67880075f},
197{-0.74314483f, -0.66913061f}, {-0.75183981f, -0.65934582f},
198{-0.76040597f, -0.64944805f}, {-0.76884183f, -0.63943900f},
199{-0.77714596f, -0.62932039f}, {-0.78531693f, -0.61909395f},
200{-0.79335334f, -0.60876143f}, {-0.80125381f, -0.59832460f},
201{-0.80901699f, -0.58778525f}, {-0.81664156f, -0.57714519f},
202{-0.82412619f, -0.56640624f}, {-0.83146961f, -0.55557023f},
203{-0.83867057f, -0.54463904f}, {-0.84572782f, -0.53361452f},
204{-0.85264016f, -0.52249856f}, {-0.85940641f, -0.51129309f},
205{-0.86602540f, -0.50000000f}, {-0.87249601f, -0.48862124f},
206{-0.87881711f, -0.47715876f}, {-0.88498764f, -0.46561452f},
207{-0.89100652f, -0.45399050f}, {-0.89687274f, -0.44228869f},
208{-0.90258528f, -0.43051110f}, {-0.90814317f, -0.41865974f},
209{-0.91354546f, -0.40673664f}, {-0.91879121f, -0.39474386f},
210{-0.92387953f, -0.38268343f}, {-0.92880955f, -0.37055744f},
211{-0.93358043f, -0.35836795f}, {-0.93819134f, -0.34611706f},
212{-0.94264149f, -0.33380686f}, {-0.94693013f, -0.32143947f},
213{-0.95105652f, -0.30901699f}, {-0.95501994f, -0.29654157f},
214{-0.95881973f, -0.28401534f}, {-0.96245524f, -0.27144045f},
215{-0.96592583f, -0.25881905f}, {-0.96923091f, -0.24615329f},
216{-0.97236992f, -0.23344536f}, {-0.97534232f, -0.22069744f},
217{-0.97814760f, -0.20791169f}, {-0.98078528f, -0.19509032f},
218{-0.98325491f, -0.18223553f}, {-0.98555606f, -0.16934950f},
219{-0.98768834f, -0.15643447f}, {-0.98965139f, -0.14349262f},
220{-0.99144486f, -0.13052619f}, {-0.99306846f, -0.11753740f},
221{-0.99452190f, -0.10452846f}, {-0.99580493f, -0.091501619f},
222{-0.99691733f, -0.078459096f}, {-0.99785892f, -0.065403129f},
223{-0.99862953f, -0.052335956f}, {-0.99922904f, -0.039259816f},
224{-0.99965732f, -0.026176948f}, {-0.99991433f, -0.013089596f},
225{-1.0000000f, -1.2246064e-16f}, {-0.99991433f, 0.013089596f},
226{-0.99965732f, 0.026176948f}, {-0.99922904f, 0.039259816f},
227{-0.99862953f, 0.052335956f}, {-0.99785892f, 0.065403129f},
228{-0.99691733f, 0.078459096f}, {-0.99580493f, 0.091501619f},
229{-0.99452190f, 0.10452846f}, {-0.99306846f, 0.11753740f},
230{-0.99144486f, 0.13052619f}, {-0.98965139f, 0.14349262f},
231{-0.98768834f, 0.15643447f}, {-0.98555606f, 0.16934950f},
232{-0.98325491f, 0.18223553f}, {-0.98078528f, 0.19509032f},
233{-0.97814760f, 0.20791169f}, {-0.97534232f, 0.22069744f},
234{-0.97236992f, 0.23344536f}, {-0.96923091f, 0.24615329f},
235{-0.96592583f, 0.25881905f}, {-0.96245524f, 0.27144045f},
236{-0.95881973f, 0.28401534f}, {-0.95501994f, 0.29654157f},
237{-0.95105652f, 0.30901699f}, {-0.94693013f, 0.32143947f},
238{-0.94264149f, 0.33380686f}, {-0.93819134f, 0.34611706f},
239{-0.93358043f, 0.35836795f}, {-0.92880955f, 0.37055744f},
240{-0.92387953f, 0.38268343f}, {-0.91879121f, 0.39474386f},
241{-0.91354546f, 0.40673664f}, {-0.90814317f, 0.41865974f},
242{-0.90258528f, 0.43051110f}, {-0.89687274f, 0.44228869f},
243{-0.89100652f, 0.45399050f}, {-0.88498764f, 0.46561452f},
244{-0.87881711f, 0.47715876f}, {-0.87249601f, 0.48862124f},
245{-0.86602540f, 0.50000000f}, {-0.85940641f, 0.51129309f},
246{-0.85264016f, 0.52249856f}, {-0.84572782f, 0.53361452f},
247{-0.83867057f, 0.54463904f}, {-0.83146961f, 0.55557023f},
248{-0.82412619f, 0.56640624f}, {-0.81664156f, 0.57714519f},
249{-0.80901699f, 0.58778525f}, {-0.80125381f, 0.59832460f},
250{-0.79335334f, 0.60876143f}, {-0.78531693f, 0.61909395f},
251{-0.77714596f, 0.62932039f}, {-0.76884183f, 0.63943900f},
252{-0.76040597f, 0.64944805f}, {-0.75183981f, 0.65934582f},
253{-0.74314483f, 0.66913061f}, {-0.73432251f, 0.67880075f},
254{-0.72537437f, 0.68835458f}, {-0.71630194f, 0.69779046f},
255{-0.70710678f, 0.70710678f}, {-0.69779046f, 0.71630194f},
256{-0.68835458f, 0.72537437f}, {-0.67880075f, 0.73432251f},
257{-0.66913061f, 0.74314483f}, {-0.65934582f, 0.75183981f},
258{-0.64944805f, 0.76040597f}, {-0.63943900f, 0.76884183f},
259{-0.62932039f, 0.77714596f}, {-0.61909395f, 0.78531693f},
260{-0.60876143f, 0.79335334f}, {-0.59832460f, 0.80125381f},
261{-0.58778525f, 0.80901699f}, {-0.57714519f, 0.81664156f},
262{-0.56640624f, 0.82412619f}, {-0.55557023f, 0.83146961f},
263{-0.54463904f, 0.83867057f}, {-0.53361452f, 0.84572782f},
264{-0.52249856f, 0.85264016f}, {-0.51129309f, 0.85940641f},
265{-0.50000000f, 0.86602540f}, {-0.48862124f, 0.87249601f},
266{-0.47715876f, 0.87881711f}, {-0.46561452f, 0.88498764f},
267{-0.45399050f, 0.89100652f}, {-0.44228869f, 0.89687274f},
268{-0.43051110f, 0.90258528f}, {-0.41865974f, 0.90814317f},
269{-0.40673664f, 0.91354546f}, {-0.39474386f, 0.91879121f},
270{-0.38268343f, 0.92387953f}, {-0.37055744f, 0.92880955f},
271{-0.35836795f, 0.93358043f}, {-0.34611706f, 0.93819134f},
272{-0.33380686f, 0.94264149f}, {-0.32143947f, 0.94693013f},
273{-0.30901699f, 0.95105652f}, {-0.29654157f, 0.95501994f},
274{-0.28401534f, 0.95881973f}, {-0.27144045f, 0.96245524f},
275{-0.25881905f, 0.96592583f}, {-0.24615329f, 0.96923091f},
276{-0.23344536f, 0.97236992f}, {-0.22069744f, 0.97534232f},
277{-0.20791169f, 0.97814760f}, {-0.19509032f, 0.98078528f},
278{-0.18223553f, 0.98325491f}, {-0.16934950f, 0.98555606f},
279{-0.15643447f, 0.98768834f}, {-0.14349262f, 0.98965139f},
280{-0.13052619f, 0.99144486f}, {-0.11753740f, 0.99306846f},
281{-0.10452846f, 0.99452190f}, {-0.091501619f, 0.99580493f},
282{-0.078459096f, 0.99691733f}, {-0.065403129f, 0.99785892f},
283{-0.052335956f, 0.99862953f}, {-0.039259816f, 0.99922904f},
284{-0.026176948f, 0.99965732f}, {-0.013089596f, 0.99991433f},
285{-1.8369095e-16f, 1.0000000f}, {0.013089596f, 0.99991433f},
286{0.026176948f, 0.99965732f}, {0.039259816f, 0.99922904f},
287{0.052335956f, 0.99862953f}, {0.065403129f, 0.99785892f},
288{0.078459096f, 0.99691733f}, {0.091501619f, 0.99580493f},
289{0.10452846f, 0.99452190f}, {0.11753740f, 0.99306846f},
290{0.13052619f, 0.99144486f}, {0.14349262f, 0.98965139f},
291{0.15643447f, 0.98768834f}, {0.16934950f, 0.98555606f},
292{0.18223553f, 0.98325491f}, {0.19509032f, 0.98078528f},
293{0.20791169f, 0.97814760f}, {0.22069744f, 0.97534232f},
294{0.23344536f, 0.97236992f}, {0.24615329f, 0.96923091f},
295{0.25881905f, 0.96592583f}, {0.27144045f, 0.96245524f},
296{0.28401534f, 0.95881973f}, {0.29654157f, 0.95501994f},
297{0.30901699f, 0.95105652f}, {0.32143947f, 0.94693013f},
298{0.33380686f, 0.94264149f}, {0.34611706f, 0.93819134f},
299{0.35836795f, 0.93358043f}, {0.37055744f, 0.92880955f},
300{0.38268343f, 0.92387953f}, {0.39474386f, 0.91879121f},
301{0.40673664f, 0.91354546f}, {0.41865974f, 0.90814317f},
302{0.43051110f, 0.90258528f}, {0.44228869f, 0.89687274f},
303{0.45399050f, 0.89100652f}, {0.46561452f, 0.88498764f},
304{0.47715876f, 0.87881711f}, {0.48862124f, 0.87249601f},
305{0.50000000f, 0.86602540f}, {0.51129309f, 0.85940641f},
306{0.52249856f, 0.85264016f}, {0.53361452f, 0.84572782f},
307{0.54463904f, 0.83867057f}, {0.55557023f, 0.83146961f},
308{0.56640624f, 0.82412619f}, {0.57714519f, 0.81664156f},
309{0.58778525f, 0.80901699f}, {0.59832460f, 0.80125381f},
310{0.60876143f, 0.79335334f}, {0.61909395f, 0.78531693f},
311{0.62932039f, 0.77714596f}, {0.63943900f, 0.76884183f},
312{0.64944805f, 0.76040597f}, {0.65934582f, 0.75183981f},
313{0.66913061f, 0.74314483f}, {0.67880075f, 0.73432251f},
314{0.68835458f, 0.72537437f}, {0.69779046f, 0.71630194f},
315{0.70710678f, 0.70710678f}, {0.71630194f, 0.69779046f},
316{0.72537437f, 0.68835458f}, {0.73432251f, 0.67880075f},
317{0.74314483f, 0.66913061f}, {0.75183981f, 0.65934582f},
318{0.76040597f, 0.64944805f}, {0.76884183f, 0.63943900f},
319{0.77714596f, 0.62932039f}, {0.78531693f, 0.61909395f},
320{0.79335334f, 0.60876143f}, {0.80125381f, 0.59832460f},
321{0.80901699f, 0.58778525f}, {0.81664156f, 0.57714519f},
322{0.82412619f, 0.56640624f}, {0.83146961f, 0.55557023f},
323{0.83867057f, 0.54463904f}, {0.84572782f, 0.53361452f},
324{0.85264016f, 0.52249856f}, {0.85940641f, 0.51129309f},
325{0.86602540f, 0.50000000f}, {0.87249601f, 0.48862124f},
326{0.87881711f, 0.47715876f}, {0.88498764f, 0.46561452f},
327{0.89100652f, 0.45399050f}, {0.89687274f, 0.44228869f},
328{0.90258528f, 0.43051110f}, {0.90814317f, 0.41865974f},
329{0.91354546f, 0.40673664f}, {0.91879121f, 0.39474386f},
330{0.92387953f, 0.38268343f}, {0.92880955f, 0.37055744f},
331{0.93358043f, 0.35836795f}, {0.93819134f, 0.34611706f},
332{0.94264149f, 0.33380686f}, {0.94693013f, 0.32143947f},
333{0.95105652f, 0.30901699f}, {0.95501994f, 0.29654157f},
334{0.95881973f, 0.28401534f}, {0.96245524f, 0.27144045f},
335{0.96592583f, 0.25881905f}, {0.96923091f, 0.24615329f},
336{0.97236992f, 0.23344536f}, {0.97534232f, 0.22069744f},
337{0.97814760f, 0.20791169f}, {0.98078528f, 0.19509032f},
338{0.98325491f, 0.18223553f}, {0.98555606f, 0.16934950f},
339{0.98768834f, 0.15643447f}, {0.98965139f, 0.14349262f},
340{0.99144486f, 0.13052619f}, {0.99306846f, 0.11753740f},
341{0.99452190f, 0.10452846f}, {0.99580493f, 0.091501619f},
342{0.99691733f, 0.078459096f}, {0.99785892f, 0.065403129f},
343{0.99862953f, 0.052335956f}, {0.99922904f, 0.039259816f},
344{0.99965732f, 0.026176948f}, {0.99991433f, 0.013089596f},
345};
346#ifndef FFT_BITREV480
347#define FFT_BITREV480
348static const opus_int16 fft_bitrev480[480] = {
3490, 96, 192, 288, 384, 32, 128, 224, 320, 416, 64, 160, 256, 352, 448,
3508, 104, 200, 296, 392, 40, 136, 232, 328, 424, 72, 168, 264, 360, 456,
35116, 112, 208, 304, 400, 48, 144, 240, 336, 432, 80, 176, 272, 368, 464,
35224, 120, 216, 312, 408, 56, 152, 248, 344, 440, 88, 184, 280, 376, 472,
3534, 100, 196, 292, 388, 36, 132, 228, 324, 420, 68, 164, 260, 356, 452,
35412, 108, 204, 300, 396, 44, 140, 236, 332, 428, 76, 172, 268, 364, 460,
35520, 116, 212, 308, 404, 52, 148, 244, 340, 436, 84, 180, 276, 372, 468,
35628, 124, 220, 316, 412, 60, 156, 252, 348, 444, 92, 188, 284, 380, 476,
3571, 97, 193, 289, 385, 33, 129, 225, 321, 417, 65, 161, 257, 353, 449,
3589, 105, 201, 297, 393, 41, 137, 233, 329, 425, 73, 169, 265, 361, 457,
35917, 113, 209, 305, 401, 49, 145, 241, 337, 433, 81, 177, 273, 369, 465,
36025, 121, 217, 313, 409, 57, 153, 249, 345, 441, 89, 185, 281, 377, 473,
3615, 101, 197, 293, 389, 37, 133, 229, 325, 421, 69, 165, 261, 357, 453,
36213, 109, 205, 301, 397, 45, 141, 237, 333, 429, 77, 173, 269, 365, 461,
36321, 117, 213, 309, 405, 53, 149, 245, 341, 437, 85, 181, 277, 373, 469,
36429, 125, 221, 317, 413, 61, 157, 253, 349, 445, 93, 189, 285, 381, 477,
3652, 98, 194, 290, 386, 34, 130, 226, 322, 418, 66, 162, 258, 354, 450,
36610, 106, 202, 298, 394, 42, 138, 234, 330, 426, 74, 170, 266, 362, 458,
36718, 114, 210, 306, 402, 50, 146, 242, 338, 434, 82, 178, 274, 370, 466,
36826, 122, 218, 314, 410, 58, 154, 250, 346, 442, 90, 186, 282, 378, 474,
3696, 102, 198, 294, 390, 38, 134, 230, 326, 422, 70, 166, 262, 358, 454,
37014, 110, 206, 302, 398, 46, 142, 238, 334, 430, 78, 174, 270, 366, 462,
37122, 118, 214, 310, 406, 54, 150, 246, 342, 438, 86, 182, 278, 374, 470,
37230, 126, 222, 318, 414, 62, 158, 254, 350, 446, 94, 190, 286, 382, 478,
3733, 99, 195, 291, 387, 35, 131, 227, 323, 419, 67, 163, 259, 355, 451,
37411, 107, 203, 299, 395, 43, 139, 235, 331, 427, 75, 171, 267, 363, 459,
37519, 115, 211, 307, 403, 51, 147, 243, 339, 435, 83, 179, 275, 371, 467,
37627, 123, 219, 315, 411, 59, 155, 251, 347, 443, 91, 187, 283, 379, 475,
3777, 103, 199, 295, 391, 39, 135, 231, 327, 423, 71, 167, 263, 359, 455,
37815, 111, 207, 303, 399, 47, 143, 239, 335, 431, 79, 175, 271, 367, 463,
37923, 119, 215, 311, 407, 55, 151, 247, 343, 439, 87, 183, 279, 375, 471,
38031, 127, 223, 319, 415, 63, 159, 255, 351, 447, 95, 191, 287, 383, 479,
381};
382#endif
383
384#ifndef FFT_BITREV240
385#define FFT_BITREV240
386static const opus_int16 fft_bitrev240[240] = {
3870, 48, 96, 144, 192, 16, 64, 112, 160, 208, 32, 80, 128, 176, 224,
3884, 52, 100, 148, 196, 20, 68, 116, 164, 212, 36, 84, 132, 180, 228,
3898, 56, 104, 152, 200, 24, 72, 120, 168, 216, 40, 88, 136, 184, 232,
39012, 60, 108, 156, 204, 28, 76, 124, 172, 220, 44, 92, 140, 188, 236,
3911, 49, 97, 145, 193, 17, 65, 113, 161, 209, 33, 81, 129, 177, 225,
3925, 53, 101, 149, 197, 21, 69, 117, 165, 213, 37, 85, 133, 181, 229,
3939, 57, 105, 153, 201, 25, 73, 121, 169, 217, 41, 89, 137, 185, 233,
39413, 61, 109, 157, 205, 29, 77, 125, 173, 221, 45, 93, 141, 189, 237,
3952, 50, 98, 146, 194, 18, 66, 114, 162, 210, 34, 82, 130, 178, 226,
3966, 54, 102, 150, 198, 22, 70, 118, 166, 214, 38, 86, 134, 182, 230,
39710, 58, 106, 154, 202, 26, 74, 122, 170, 218, 42, 90, 138, 186, 234,
39814, 62, 110, 158, 206, 30, 78, 126, 174, 222, 46, 94, 142, 190, 238,
3993, 51, 99, 147, 195, 19, 67, 115, 163, 211, 35, 83, 131, 179, 227,
4007, 55, 103, 151, 199, 23, 71, 119, 167, 215, 39, 87, 135, 183, 231,
40111, 59, 107, 155, 203, 27, 75, 123, 171, 219, 43, 91, 139, 187, 235,
40215, 63, 111, 159, 207, 31, 79, 127, 175, 223, 47, 95, 143, 191, 239,
403};
404#endif
405
406#ifndef FFT_BITREV120
407#define FFT_BITREV120
408static const opus_int16 fft_bitrev120[120] = {
4090, 24, 48, 72, 96, 8, 32, 56, 80, 104, 16, 40, 64, 88, 112,
4104, 28, 52, 76, 100, 12, 36, 60, 84, 108, 20, 44, 68, 92, 116,
4111, 25, 49, 73, 97, 9, 33, 57, 81, 105, 17, 41, 65, 89, 113,
4125, 29, 53, 77, 101, 13, 37, 61, 85, 109, 21, 45, 69, 93, 117,
4132, 26, 50, 74, 98, 10, 34, 58, 82, 106, 18, 42, 66, 90, 114,
4146, 30, 54, 78, 102, 14, 38, 62, 86, 110, 22, 46, 70, 94, 118,
4153, 27, 51, 75, 99, 11, 35, 59, 83, 107, 19, 43, 67, 91, 115,
4167, 31, 55, 79, 103, 15, 39, 63, 87, 111, 23, 47, 71, 95, 119,
417};
418#endif
419
420#ifndef FFT_BITREV60
421#define FFT_BITREV60
422static const opus_int16 fft_bitrev60[60] = {
4230, 12, 24, 36, 48, 4, 16, 28, 40, 52, 8, 20, 32, 44, 56,
4241, 13, 25, 37, 49, 5, 17, 29, 41, 53, 9, 21, 33, 45, 57,
4252, 14, 26, 38, 50, 6, 18, 30, 42, 54, 10, 22, 34, 46, 58,
4263, 15, 27, 39, 51, 7, 19, 31, 43, 55, 11, 23, 35, 47, 59,
427};
428#endif
429
430#ifndef FFT_STATE48000_960_0
431#define FFT_STATE48000_960_0
432static const kiss_fft_state fft_state48000_960_0 = {
433480, /* nfft */
4340.002083333f, /* scale */
435-1, /* shift */
436{5, 96, 3, 32, 4, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, }, /* factors */
437fft_bitrev480, /* bitrev */
438fft_twiddles48000_960, /* bitrev */
439#ifdef OVERRIDE_FFT
440(arch_fft_state *)&cfg_arch_480,
441#else
442NULL,
443#endif
444};
445#endif
446
447#ifndef FFT_STATE48000_960_1
448#define FFT_STATE48000_960_1
449static const kiss_fft_state fft_state48000_960_1 = {
450240, /* nfft */
4510.004166667f, /* scale */
4521, /* shift */
453{5, 48, 3, 16, 4, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
454fft_bitrev240, /* bitrev */
455fft_twiddles48000_960, /* bitrev */
456#ifdef OVERRIDE_FFT
457(arch_fft_state *)&cfg_arch_240,
458#else
459NULL,
460#endif
461};
462#endif
463
464#ifndef FFT_STATE48000_960_2
465#define FFT_STATE48000_960_2
466static const kiss_fft_state fft_state48000_960_2 = {
467120, /* nfft */
4680.008333333f, /* scale */
4692, /* shift */
470{5, 24, 3, 8, 2, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
471fft_bitrev120, /* bitrev */
472fft_twiddles48000_960, /* bitrev */
473#ifdef OVERRIDE_FFT
474(arch_fft_state *)&cfg_arch_120,
475#else
476NULL,
477#endif
478};
479#endif
480
481#ifndef FFT_STATE48000_960_3
482#define FFT_STATE48000_960_3
483static const kiss_fft_state fft_state48000_960_3 = {
48460, /* nfft */
4850.016666667f, /* scale */
4863, /* shift */
487{5, 12, 3, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */
488fft_bitrev60, /* bitrev */
489fft_twiddles48000_960, /* bitrev */
490#ifdef OVERRIDE_FFT
491(arch_fft_state *)&cfg_arch_60,
492#else
493NULL,
494#endif
495};
496#endif
497
498#endif
499
500#ifndef MDCT_TWIDDLES960
501#define MDCT_TWIDDLES960
502static const opus_val16 mdct_twiddles960[1800] = {
5030.99999994f, 0.99999321f, 0.99997580f, 0.99994773f, 0.99990886f,
5040.99985933f, 0.99979913f, 0.99972820f, 0.99964654f, 0.99955416f,
5050.99945110f, 0.99933738f, 0.99921292f, 0.99907774f, 0.99893188f,
5060.99877530f, 0.99860805f, 0.99843007f, 0.99824142f, 0.99804211f,
5070.99783206f, 0.99761140f, 0.99737996f, 0.99713790f, 0.99688518f,
5080.99662173f, 0.99634761f, 0.99606287f, 0.99576741f, 0.99546129f,
5090.99514455f, 0.99481714f, 0.99447906f, 0.99413031f, 0.99377096f,
5100.99340093f, 0.99302030f, 0.99262899f, 0.99222708f, 0.99181455f,
5110.99139136f, 0.99095762f, 0.99051321f, 0.99005818f, 0.98959261f,
5120.98911643f, 0.98862964f, 0.98813224f, 0.98762429f, 0.98710573f,
5130.98657662f, 0.98603696f, 0.98548669f, 0.98492593f, 0.98435456f,
5140.98377270f, 0.98318028f, 0.98257732f, 0.98196387f, 0.98133987f,
5150.98070538f, 0.98006040f, 0.97940493f, 0.97873890f, 0.97806245f,
5160.97737551f, 0.97667813f, 0.97597027f, 0.97525197f, 0.97452319f,
5170.97378403f, 0.97303438f, 0.97227436f, 0.97150391f, 0.97072303f,
5180.96993178f, 0.96913016f, 0.96831810f, 0.96749574f, 0.96666300f,
5190.96581990f, 0.96496642f, 0.96410263f, 0.96322852f, 0.96234411f,
5200.96144938f, 0.96054435f, 0.95962906f, 0.95870346f, 0.95776761f,
5210.95682150f, 0.95586514f, 0.95489854f, 0.95392174f, 0.95293468f,
5220.95193744f, 0.95093000f, 0.94991243f, 0.94888461f, 0.94784665f,
5230.94679856f, 0.94574034f, 0.94467193f, 0.94359344f, 0.94250488f,
5240.94140619f, 0.94029742f, 0.93917859f, 0.93804967f, 0.93691075f,
5250.93576175f, 0.93460274f, 0.93343377f, 0.93225473f, 0.93106574f,
5260.92986679f, 0.92865789f, 0.92743903f, 0.92621022f, 0.92497152f,
5270.92372292f, 0.92246443f, 0.92119598f, 0.91991776f, 0.91862965f,
5280.91733170f, 0.91602397f, 0.91470635f, 0.91337901f, 0.91204184f,
5290.91069490f, 0.90933824f, 0.90797186f, 0.90659571f, 0.90520984f,
5300.90381432f, 0.90240908f, 0.90099424f, 0.89956969f, 0.89813554f,
5310.89669174f, 0.89523834f, 0.89377540f, 0.89230281f, 0.89082074f,
5320.88932908f, 0.88782793f, 0.88631725f, 0.88479710f, 0.88326746f,
5330.88172835f, 0.88017982f, 0.87862182f, 0.87705445f, 0.87547767f,
5340.87389153f, 0.87229604f, 0.87069118f, 0.86907703f, 0.86745358f,
5350.86582077f, 0.86417878f, 0.86252749f, 0.86086690f, 0.85919720f,
5360.85751826f, 0.85583007f, 0.85413277f, 0.85242635f, 0.85071075f,
5370.84898609f, 0.84725231f, 0.84550947f, 0.84375757f, 0.84199661f,
5380.84022665f, 0.83844769f, 0.83665979f, 0.83486289f, 0.83305705f,
5390.83124226f, 0.82941860f, 0.82758605f, 0.82574469f, 0.82389444f,
5400.82203537f, 0.82016748f, 0.81829083f, 0.81640542f, 0.81451124f,
5410.81260836f, 0.81069672f, 0.80877650f, 0.80684757f, 0.80490994f,
5420.80296379f, 0.80100900f, 0.79904562f, 0.79707366f, 0.79509324f,
5430.79310423f, 0.79110676f, 0.78910083f, 0.78708643f, 0.78506362f,
5440.78303236f, 0.78099275f, 0.77894479f, 0.77688843f, 0.77482378f,
5450.77275085f, 0.77066964f, 0.76858020f, 0.76648247f, 0.76437658f,
5460.76226246f, 0.76014024f, 0.75800985f, 0.75587130f, 0.75372469f,
5470.75157005f, 0.74940729f, 0.74723655f, 0.74505776f, 0.74287105f,
5480.74067634f, 0.73847371f, 0.73626316f, 0.73404479f, 0.73181850f,
5490.72958434f, 0.72734243f, 0.72509271f, 0.72283524f, 0.72057003f,
5500.71829706f, 0.71601641f, 0.71372813f, 0.71143216f, 0.70912862f,
5510.70681745f, 0.70449871f, 0.70217246f, 0.69983864f, 0.69749737f,
5520.69514859f, 0.69279242f, 0.69042879f, 0.68805778f, 0.68567938f,
5530.68329364f, 0.68090063f, 0.67850029f, 0.67609268f, 0.67367786f,
5540.67125577f, 0.66882652f, 0.66639012f, 0.66394657f, 0.66149592f,
5550.65903819f, 0.65657341f, 0.65410155f, 0.65162271f, 0.64913690f,
5560.64664418f, 0.64414448f, 0.64163786f, 0.63912445f, 0.63660413f,
5570.63407701f, 0.63154310f, 0.62900239f, 0.62645501f, 0.62390089f,
5580.62134010f, 0.61877263f, 0.61619854f, 0.61361790f, 0.61103064f,
5590.60843682f, 0.60583651f, 0.60322970f, 0.60061646f, 0.59799677f,
5600.59537065f, 0.59273821f, 0.59009939f, 0.58745426f, 0.58480281f,
5610.58214509f, 0.57948118f, 0.57681108f, 0.57413477f, 0.57145232f,
5620.56876373f, 0.56606907f, 0.56336832f, 0.56066155f, 0.55794877f,
5630.55523002f, 0.55250537f, 0.54977477f, 0.54703826f, 0.54429591f,
5640.54154772f, 0.53879374f, 0.53603399f, 0.53326851f, 0.53049731f,
5650.52772039f, 0.52493787f, 0.52214974f, 0.51935595f, 0.51655668f,
5660.51375180f, 0.51094145f, 0.50812566f, 0.50530440f, 0.50247771f,
5670.49964568f, 0.49680826f, 0.49396557f, 0.49111754f, 0.48826426f,
5680.48540577f, 0.48254207f, 0.47967321f, 0.47679919f, 0.47392011f,
5690.47103590f, 0.46814668f, 0.46525243f, 0.46235323f, 0.45944905f,
5700.45653993f, 0.45362595f, 0.45070711f, 0.44778344f, 0.44485497f,
5710.44192174f, 0.43898380f, 0.43604112f, 0.43309379f, 0.43014181f,
5720.42718524f, 0.42422408f, 0.42125839f, 0.41828820f, 0.41531351f,
5730.41233435f, 0.40935081f, 0.40636289f, 0.40337059f, 0.40037400f,
5740.39737311f, 0.39436796f, 0.39135858f, 0.38834500f, 0.38532731f,
5750.38230544f, 0.37927949f, 0.37624949f, 0.37321547f, 0.37017745f,
5760.36713544f, 0.36408952f, 0.36103970f, 0.35798600f, 0.35492846f,
5770.35186714f, 0.34880206f, 0.34573323f, 0.34266070f, 0.33958447f,
5780.33650464f, 0.33342120f, 0.33033419f, 0.32724363f, 0.32414958f,
5790.32105204f, 0.31795108f, 0.31484672f, 0.31173897f, 0.30862790f,
5800.30551350f, 0.30239585f, 0.29927495f, 0.29615086f, 0.29302359f,
5810.28989318f, 0.28675964f, 0.28362307f, 0.28048345f, 0.27734083f,
5820.27419522f, 0.27104670f, 0.26789525f, 0.26474094f, 0.26158381f,
5830.25842386f, 0.25526115f, 0.25209570f, 0.24892756f, 0.24575676f,
5840.24258332f, 0.23940729f, 0.23622867f, 0.23304754f, 0.22986393f,
5850.22667783f, 0.22348931f, 0.22029841f, 0.21710514f, 0.21390954f,
5860.21071166f, 0.20751151f, 0.20430915f, 0.20110460f, 0.19789790f,
5870.19468907f, 0.19147816f, 0.18826519f, 0.18505022f, 0.18183327f,
5880.17861435f, 0.17539354f, 0.17217083f, 0.16894630f, 0.16571994f,
5890.16249183f, 0.15926196f, 0.15603039f, 0.15279715f, 0.14956227f,
5900.14632578f, 0.14308774f, 0.13984816f, 0.13660708f, 0.13336454f,
5910.13012058f, 0.12687522f, 0.12362850f, 0.12038045f, 0.11713112f,
5920.11388054f, 0.11062872f, 0.10737573f, 0.10412160f, 0.10086634f,
5930.097609997f, 0.094352618f, 0.091094226f, 0.087834857f, 0.084574550f,
5940.081313334f, 0.078051247f, 0.074788325f, 0.071524605f, 0.068260118f,
5950.064994894f, 0.061728980f, 0.058462404f, 0.055195201f, 0.051927410f,
5960.048659060f, 0.045390189f, 0.042120833f, 0.038851023f, 0.035580799f,
5970.032310195f, 0.029039243f, 0.025767982f, 0.022496443f, 0.019224664f,
5980.015952680f, 0.012680525f, 0.0094082337f, 0.0061358409f, 0.0028633832f,
599-0.00040910527f, -0.0036815894f, -0.0069540343f, -0.010226404f, -0.013498665f,
600-0.016770782f, -0.020042717f, -0.023314439f, -0.026585912f, -0.029857099f,
601-0.033127967f, -0.036398482f, -0.039668605f, -0.042938303f, -0.046207540f,
602-0.049476285f, -0.052744497f, -0.056012146f, -0.059279196f, -0.062545612f,
603-0.065811358f, -0.069076397f, -0.072340697f, -0.075604223f, -0.078866936f,
604-0.082128808f, -0.085389800f, -0.088649876f, -0.091909006f, -0.095167145f,
605-0.098424271f, -0.10168034f, -0.10493532f, -0.10818918f, -0.11144188f,
606-0.11469338f, -0.11794366f, -0.12119267f, -0.12444039f, -0.12768677f,
607-0.13093179f, -0.13417540f, -0.13741758f, -0.14065829f, -0.14389749f,
608-0.14713514f, -0.15037122f, -0.15360570f, -0.15683852f, -0.16006967f,
609-0.16329910f, -0.16652679f, -0.16975269f, -0.17297678f, -0.17619900f,
610-0.17941935f, -0.18263777f, -0.18585424f, -0.18906870f, -0.19228116f,
611-0.19549155f, -0.19869985f, -0.20190603f, -0.20511003f, -0.20831184f,
612-0.21151142f, -0.21470875f, -0.21790376f, -0.22109644f, -0.22428675f,
613-0.22747467f, -0.23066014f, -0.23384315f, -0.23702365f, -0.24020162f,
614-0.24337701f, -0.24654980f, -0.24971995f, -0.25288740f, -0.25605217f,
615-0.25921419f, -0.26237345f, -0.26552987f, -0.26868346f, -0.27183419f,
616-0.27498198f, -0.27812684f, -0.28126872f, -0.28440759f, -0.28754342f,
617-0.29067615f, -0.29380578f, -0.29693225f, -0.30005556f, -0.30317566f,
618-0.30629250f, -0.30940607f, -0.31251630f, -0.31562322f, -0.31872672f,
619-0.32182685f, -0.32492352f, -0.32801670f, -0.33110636f, -0.33419248f,
620-0.33727503f, -0.34035397f, -0.34342924f, -0.34650084f, -0.34956875f,
621-0.35263291f, -0.35569328f, -0.35874987f, -0.36180258f, -0.36485144f,
622-0.36789638f, -0.37093741f, -0.37397444f, -0.37700745f, -0.38003644f,
623-0.38306138f, -0.38608220f, -0.38909888f, -0.39211139f, -0.39511973f,
624-0.39812380f, -0.40112361f, -0.40411916f, -0.40711036f, -0.41009718f,
625-0.41307965f, -0.41605768f, -0.41903123f, -0.42200032f, -0.42496487f,
626-0.42792490f, -0.43088034f, -0.43383113f, -0.43677729f, -0.43971881f,
627-0.44265559f, -0.44558764f, -0.44851488f, -0.45143735f, -0.45435500f,
628-0.45726776f, -0.46017563f, -0.46307856f, -0.46597654f, -0.46886954f,
629-0.47175750f, -0.47464043f, -0.47751826f, -0.48039100f, -0.48325855f,
630-0.48612097f, -0.48897815f, -0.49183011f, -0.49467680f, -0.49751821f,
631-0.50035429f, -0.50318497f, -0.50601029f, -0.50883019f, -0.51164466f,
632-0.51445359f, -0.51725709f, -0.52005500f, -0.52284735f, -0.52563411f,
633-0.52841520f, -0.53119069f, -0.53396046f, -0.53672451f, -0.53948283f,
634-0.54223537f, -0.54498214f, -0.54772300f, -0.55045801f, -0.55318713f,
635-0.55591035f, -0.55862761f, -0.56133890f, -0.56404412f, -0.56674337f,
636-0.56943649f, -0.57212353f, -0.57480448f, -0.57747924f, -0.58014780f,
637-0.58281022f, -0.58546633f, -0.58811617f, -0.59075975f, -0.59339696f,
638-0.59602785f, -0.59865236f, -0.60127044f, -0.60388207f, -0.60648727f,
639-0.60908598f, -0.61167812f, -0.61426371f, -0.61684275f, -0.61941516f,
640-0.62198097f, -0.62454009f, -0.62709254f, -0.62963831f, -0.63217729f,
641-0.63470948f, -0.63723493f, -0.63975352f, -0.64226526f, -0.64477009f,
642-0.64726806f, -0.64975911f, -0.65224314f, -0.65472025f, -0.65719032f,
643-0.65965337f, -0.66210932f, -0.66455823f, -0.66700000f, -0.66943461f,
644-0.67186207f, -0.67428231f, -0.67669535f, -0.67910111f, -0.68149966f,
645-0.68389088f, -0.68627477f, -0.68865126f, -0.69102043f, -0.69338220f,
646-0.69573659f, -0.69808346f, -0.70042288f, -0.70275480f, -0.70507920f,
647-0.70739603f, -0.70970529f, -0.71200693f, -0.71430099f, -0.71658736f,
648-0.71886611f, -0.72113711f, -0.72340041f, -0.72565591f, -0.72790372f,
649-0.73014367f, -0.73237586f, -0.73460019f, -0.73681659f, -0.73902518f,
650-0.74122584f, -0.74341851f, -0.74560326f, -0.74778003f, -0.74994880f,
651-0.75210953f, -0.75426215f, -0.75640678f, -0.75854325f, -0.76067162f,
652-0.76279181f, -0.76490390f, -0.76700771f, -0.76910341f, -0.77119076f,
653-0.77326995f, -0.77534080f, -0.77740335f, -0.77945763f, -0.78150350f,
654-0.78354102f, -0.78557014f, -0.78759086f, -0.78960317f, -0.79160696f,
655-0.79360235f, -0.79558921f, -0.79756755f, -0.79953730f, -0.80149853f,
656-0.80345118f, -0.80539525f, -0.80733067f, -0.80925739f, -0.81117553f,
657-0.81308490f, -0.81498563f, -0.81687760f, -0.81876087f, -0.82063532f,
658-0.82250100f, -0.82435787f, -0.82620591f, -0.82804507f, -0.82987541f,
659-0.83169687f, -0.83350939f, -0.83531296f, -0.83710766f, -0.83889335f,
660-0.84067005f, -0.84243774f, -0.84419644f, -0.84594607f, -0.84768665f,
661-0.84941816f, -0.85114056f, -0.85285389f, -0.85455805f, -0.85625303f,
662-0.85793889f, -0.85961550f, -0.86128294f, -0.86294121f, -0.86459017f,
663-0.86622989f, -0.86786032f, -0.86948150f, -0.87109333f, -0.87269586f,
664-0.87428904f, -0.87587279f, -0.87744725f, -0.87901229f, -0.88056785f,
665-0.88211405f, -0.88365078f, -0.88517809f, -0.88669586f, -0.88820416f,
666-0.88970292f, -0.89119220f, -0.89267188f, -0.89414203f, -0.89560264f,
667-0.89705360f, -0.89849502f, -0.89992678f, -0.90134889f, -0.90276134f,
668-0.90416414f, -0.90555727f, -0.90694070f, -0.90831441f, -0.90967834f,
669-0.91103262f, -0.91237706f, -0.91371179f, -0.91503674f, -0.91635185f,
670-0.91765714f, -0.91895264f, -0.92023826f, -0.92151409f, -0.92277998f,
671-0.92403603f, -0.92528218f, -0.92651838f, -0.92774469f, -0.92896110f,
672-0.93016750f, -0.93136400f, -0.93255049f, -0.93372697f, -0.93489349f,
673-0.93604994f, -0.93719643f, -0.93833286f, -0.93945926f, -0.94057560f,
674-0.94168180f, -0.94277799f, -0.94386405f, -0.94494003f, -0.94600588f,
675-0.94706154f, -0.94810712f, -0.94914252f, -0.95016778f, -0.95118284f,
676-0.95218778f, -0.95318246f, -0.95416695f, -0.95514119f, -0.95610523f,
677-0.95705903f, -0.95800257f, -0.95893586f, -0.95985889f, -0.96077162f,
678-0.96167403f, -0.96256620f, -0.96344805f, -0.96431959f, -0.96518075f,
679-0.96603161f, -0.96687216f, -0.96770233f, -0.96852213f, -0.96933156f,
680-0.97013056f, -0.97091925f, -0.97169751f, -0.97246534f, -0.97322279f,
681-0.97396982f, -0.97470641f, -0.97543252f, -0.97614825f, -0.97685349f,
682-0.97754824f, -0.97823256f, -0.97890645f, -0.97956979f, -0.98022264f,
683-0.98086500f, -0.98149687f, -0.98211825f, -0.98272908f, -0.98332942f,
684-0.98391914f, -0.98449844f, -0.98506713f, -0.98562527f, -0.98617285f,
685-0.98670989f, -0.98723638f, -0.98775226f, -0.98825759f, -0.98875231f,
686-0.98923647f, -0.98971003f, -0.99017298f, -0.99062532f, -0.99106705f,
687-0.99149817f, -0.99191868f, -0.99232858f, -0.99272782f, -0.99311644f,
688-0.99349445f, -0.99386179f, -0.99421853f, -0.99456459f, -0.99489999f,
689-0.99522477f, -0.99553883f, -0.99584228f, -0.99613506f, -0.99641716f,
690-0.99668860f, -0.99694937f, -0.99719942f, -0.99743885f, -0.99766755f,
691-0.99788558f, -0.99809295f, -0.99828959f, -0.99847561f, -0.99865085f,
692-0.99881548f, -0.99896932f, -0.99911255f, -0.99924499f, -0.99936682f,
693-0.99947786f, -0.99957830f, -0.99966794f, -0.99974692f, -0.99981517f,
694-0.99987274f, -0.99991959f, -0.99995571f, -0.99998116f, -0.99999589f,
6950.99999964f, 0.99997288f, 0.99990326f, 0.99979085f, 0.99963558f,
6960.99943751f, 0.99919659f, 0.99891287f, 0.99858636f, 0.99821711f,
6970.99780506f, 0.99735034f, 0.99685282f, 0.99631262f, 0.99572974f,
6980.99510419f, 0.99443603f, 0.99372530f, 0.99297196f, 0.99217612f,
6990.99133772f, 0.99045694f, 0.98953366f, 0.98856801f, 0.98756003f,
7000.98650974f, 0.98541719f, 0.98428243f, 0.98310548f, 0.98188645f,
7010.98062533f, 0.97932225f, 0.97797716f, 0.97659022f, 0.97516143f,
7020.97369087f, 0.97217858f, 0.97062469f, 0.96902919f, 0.96739221f,
7030.96571374f, 0.96399397f, 0.96223283f, 0.96043050f, 0.95858705f,
7040.95670253f, 0.95477700f, 0.95281059f, 0.95080340f, 0.94875544f,
7050.94666684f, 0.94453770f, 0.94236809f, 0.94015813f, 0.93790787f,
7060.93561745f, 0.93328691f, 0.93091643f, 0.92850608f, 0.92605597f,
7070.92356616f, 0.92103678f, 0.91846794f, 0.91585976f, 0.91321236f,
7080.91052586f, 0.90780038f, 0.90503591f, 0.90223277f, 0.89939094f,
7090.89651060f, 0.89359182f, 0.89063478f, 0.88763964f, 0.88460642f,
7100.88153529f, 0.87842643f, 0.87527996f, 0.87209594f, 0.86887461f,
7110.86561602f, 0.86232042f, 0.85898781f, 0.85561842f, 0.85221243f,
7120.84876984f, 0.84529096f, 0.84177583f, 0.83822471f, 0.83463764f,
7130.83101481f, 0.82735640f, 0.82366252f, 0.81993335f, 0.81616908f,
7140.81236988f, 0.80853581f, 0.80466717f, 0.80076402f, 0.79682660f,
7150.79285502f, 0.78884947f, 0.78481019f, 0.78073722f, 0.77663082f,
7160.77249116f, 0.76831841f, 0.76411277f, 0.75987434f, 0.75560343f,
7170.75130010f, 0.74696463f, 0.74259710f, 0.73819780f, 0.73376691f,
7180.72930455f, 0.72481096f, 0.72028631f, 0.71573079f, 0.71114463f,
7190.70652801f, 0.70188117f, 0.69720417f, 0.69249737f, 0.68776089f,
7200.68299496f, 0.67819971f, 0.67337549f, 0.66852236f, 0.66364062f,
7210.65873051f, 0.65379208f, 0.64882571f, 0.64383155f, 0.63880974f,
7220.63376063f, 0.62868434f, 0.62358117f, 0.61845124f, 0.61329484f,
7230.60811216f, 0.60290343f, 0.59766883f, 0.59240872f, 0.58712316f,
7240.58181250f, 0.57647687f, 0.57111657f, 0.56573176f, 0.56032276f,
7250.55488980f, 0.54943299f, 0.54395270f, 0.53844911f, 0.53292239f,
7260.52737290f, 0.52180082f, 0.51620632f, 0.51058978f, 0.50495136f,
7270.49929130f, 0.49360985f, 0.48790723f, 0.48218375f, 0.47643960f,
7280.47067502f, 0.46489030f, 0.45908567f, 0.45326138f, 0.44741765f,
7290.44155475f, 0.43567297f, 0.42977250f, 0.42385364f, 0.41791660f,
7300.41196167f, 0.40598908f, 0.39999911f, 0.39399201f, 0.38796803f,
7310.38192743f, 0.37587047f, 0.36979741f, 0.36370850f, 0.35760403f,
7320.35148421f, 0.34534934f, 0.33919969f, 0.33303553f, 0.32685706f,
7330.32066461f, 0.31445843f, 0.30823877f, 0.30200592f, 0.29576012f,
7340.28950164f, 0.28323078f, 0.27694780f, 0.27065292f, 0.26434645f,
7350.25802869f, 0.25169984f, 0.24536023f, 0.23901010f, 0.23264973f,
7360.22627939f, 0.21989937f, 0.21350993f, 0.20711134f, 0.20070387f,
7370.19428782f, 0.18786344f, 0.18143101f, 0.17499080f, 0.16854310f,
7380.16208819f, 0.15562633f, 0.14915779f, 0.14268288f, 0.13620184f,
7390.12971498f, 0.12322257f, 0.11672486f, 0.11022217f, 0.10371475f,
7400.097202882f, 0.090686858f, 0.084166944f, 0.077643424f, 0.071116582f,
7410.064586692f, 0.058054037f, 0.051518895f, 0.044981543f, 0.038442269f,
7420.031901345f, 0.025359053f, 0.018815678f, 0.012271495f, 0.0057267868f,
743-0.00081816671f, -0.0073630852f, -0.013907688f, -0.020451695f, -0.026994826f,
744-0.033536803f, -0.040077340f, -0.046616159f, -0.053152986f, -0.059687532f,
745-0.066219524f, -0.072748676f, -0.079274714f, -0.085797355f, -0.092316322f,
746-0.098831341f, -0.10534211f, -0.11184838f, -0.11834986f, -0.12484626f,
747-0.13133731f, -0.13782275f, -0.14430228f, -0.15077563f, -0.15724251f,
748-0.16370267f, -0.17015581f, -0.17660165f, -0.18303993f, -0.18947038f,
749-0.19589271f, -0.20230664f, -0.20871192f, -0.21510825f, -0.22149536f,
750-0.22787298f, -0.23424086f, -0.24059868f, -0.24694622f, -0.25328314f,
751-0.25960925f, -0.26592422f, -0.27222782f, -0.27851975f, -0.28479972f,
752-0.29106751f, -0.29732284f, -0.30356544f, -0.30979502f, -0.31601134f,
753-0.32221413f, -0.32840309f, -0.33457801f, -0.34073856f, -0.34688455f,
754-0.35301566f, -0.35913166f, -0.36523229f, -0.37131724f, -0.37738630f,
755-0.38343921f, -0.38947567f, -0.39549544f, -0.40149832f, -0.40748394f,
756-0.41345215f, -0.41940263f, -0.42533514f, -0.43124944f, -0.43714526f,
757-0.44302234f, -0.44888046f, -0.45471936f, -0.46053877f, -0.46633846f,
758-0.47211814f, -0.47787762f, -0.48361665f, -0.48933494f, -0.49503228f,
759-0.50070840f, -0.50636309f, -0.51199609f, -0.51760709f, -0.52319598f,
760-0.52876246f, -0.53430629f, -0.53982723f, -0.54532504f, -0.55079949f,
761-0.55625033f, -0.56167740f, -0.56708032f, -0.57245898f, -0.57781315f,
762-0.58314258f, -0.58844697f, -0.59372622f, -0.59897995f, -0.60420811f,
763-0.60941035f, -0.61458647f, -0.61973625f, -0.62485951f, -0.62995601f,
764-0.63502556f, -0.64006782f, -0.64508271f, -0.65007001f, -0.65502942f,
765-0.65996075f, -0.66486382f, -0.66973841f, -0.67458433f, -0.67940134f,
766-0.68418926f, -0.68894786f, -0.69367695f, -0.69837630f, -0.70304573f,
767-0.70768511f, -0.71229410f, -0.71687263f, -0.72142041f, -0.72593731f,
768-0.73042315f, -0.73487765f, -0.73930067f, -0.74369204f, -0.74805158f,
769-0.75237900f, -0.75667429f, -0.76093709f, -0.76516730f, -0.76936477f,
770-0.77352923f, -0.77766061f, -0.78175867f, -0.78582323f, -0.78985411f,
771-0.79385114f, -0.79781419f, -0.80174309f, -0.80563760f, -0.80949765f,
772-0.81332302f, -0.81711352f, -0.82086903f, -0.82458937f, -0.82827437f,
773-0.83192390f, -0.83553779f, -0.83911592f, -0.84265804f, -0.84616417f,
774-0.84963393f, -0.85306740f, -0.85646427f, -0.85982448f, -0.86314780f,
775-0.86643422f, -0.86968350f, -0.87289548f, -0.87607014f, -0.87920725f,
776-0.88230664f, -0.88536829f, -0.88839203f, -0.89137769f, -0.89432514f,
777-0.89723432f, -0.90010506f, -0.90293723f, -0.90573072f, -0.90848541f,
778-0.91120118f, -0.91387796f, -0.91651553f, -0.91911387f, -0.92167282f,
779-0.92419231f, -0.92667222f, -0.92911243f, -0.93151283f, -0.93387336f,
780-0.93619382f, -0.93847424f, -0.94071442f, -0.94291431f, -0.94507378f,
781-0.94719279f, -0.94927126f, -0.95130903f, -0.95330608f, -0.95526224f,
782-0.95717752f, -0.95905179f, -0.96088499f, -0.96267700f, -0.96442777f,
783-0.96613729f, -0.96780539f, -0.96943200f, -0.97101706f, -0.97256058f,
784-0.97406244f, -0.97552258f, -0.97694093f, -0.97831738f, -0.97965199f,
785-0.98094457f, -0.98219514f, -0.98340368f, -0.98457009f, -0.98569429f,
786-0.98677629f, -0.98781598f, -0.98881340f, -0.98976845f, -0.99068111f,
787-0.99155134f, -0.99237907f, -0.99316430f, -0.99390697f, -0.99460709f,
788-0.99526459f, -0.99587947f, -0.99645168f, -0.99698120f, -0.99746799f,
789-0.99791211f, -0.99831343f, -0.99867201f, -0.99898779f, -0.99926084f,
790-0.99949104f, -0.99967843f, -0.99982297f, -0.99992472f, -0.99998361f,
7910.99999869f, 0.99989158f, 0.99961317f, 0.99916345f, 0.99854255f,
7920.99775058f, 0.99678761f, 0.99565387f, 0.99434954f, 0.99287480f,
7930.99122995f, 0.98941529f, 0.98743105f, 0.98527765f, 0.98295540f,
7940.98046476f, 0.97780609f, 0.97497988f, 0.97198665f, 0.96882683f,
7950.96550101f, 0.96200979f, 0.95835376f, 0.95453346f, 0.95054960f,
7960.94640291f, 0.94209403f, 0.93762374f, 0.93299282f, 0.92820197f,
7970.92325211f, 0.91814411f, 0.91287869f, 0.90745693f, 0.90187967f,
7980.89614785f, 0.89026248f, 0.88422459f, 0.87803519f, 0.87169534f,
7990.86520612f, 0.85856867f, 0.85178405f, 0.84485358f, 0.83777827f,
8000.83055943f, 0.82319832f, 0.81569612f, 0.80805415f, 0.80027372f,
8010.79235619f, 0.78430289f, 0.77611518f, 0.76779449f, 0.75934225f,
8020.75075996f, 0.74204898f, 0.73321080f, 0.72424710f, 0.71515924f,
8030.70594883f, 0.69661748f, 0.68716675f, 0.67759830f, 0.66791373f,
8040.65811473f, 0.64820296f, 0.63818014f, 0.62804794f, 0.61780810f,
8050.60746247f, 0.59701276f, 0.58646071f, 0.57580817f, 0.56505698f,
8060.55420899f, 0.54326600f, 0.53222996f, 0.52110273f, 0.50988621f,
8070.49858227f, 0.48719296f, 0.47572014f, 0.46416581f, 0.45253196f,
8080.44082057f, 0.42903364f, 0.41717321f, 0.40524128f, 0.39323992f,
8090.38117120f, 0.36903715f, 0.35683987f, 0.34458145f, 0.33226398f,
8100.31988961f, 0.30746040f, 0.29497850f, 0.28244606f, 0.26986524f,
8110.25723818f, 0.24456702f, 0.23185398f, 0.21910121f, 0.20631088f,
8120.19348522f, 0.18062639f, 0.16773662f, 0.15481812f, 0.14187308f,
8130.12890373f, 0.11591230f, 0.10290100f, 0.089872077f, 0.076827750f,
8140.063770257f, 0.050701842f, 0.037624735f, 0.024541186f, 0.011453429f,
815-0.0016362892f, -0.014725727f, -0.027812643f, -0.040894791f, -0.053969935f,
816-0.067035832f, -0.080090240f, -0.093130924f, -0.10615565f, -0.11916219f,
817-0.13214831f, -0.14511178f, -0.15805040f, -0.17096193f, -0.18384418f,
818-0.19669491f, -0.20951195f, -0.22229309f, -0.23503613f, -0.24773891f,
819-0.26039925f, -0.27301496f, -0.28558388f, -0.29810387f, -0.31057280f,
820-0.32298848f, -0.33534884f, -0.34765175f, -0.35989508f, -0.37207675f,
821-0.38419467f, -0.39624676f, -0.40823093f, -0.42014518f, -0.43198743f,
822-0.44375566f, -0.45544785f, -0.46706200f, -0.47859612f, -0.49004826f,
823-0.50141639f, -0.51269865f, -0.52389306f, -0.53499764f, -0.54601061f,
824-0.55693001f, -0.56775403f, -0.57848072f, -0.58910829f, -0.59963489f,
825-0.61005878f, -0.62037814f, -0.63059121f, -0.64069623f, -0.65069145f,
826-0.66057515f, -0.67034572f, -0.68000144f, -0.68954057f, -0.69896162f,
827-0.70826286f, -0.71744281f, -0.72649974f, -0.73543227f, -0.74423873f,
828-0.75291771f, -0.76146764f, -0.76988715f, -0.77817470f, -0.78632891f,
829-0.79434842f, -0.80223179f, -0.80997771f, -0.81758487f, -0.82505190f,
830-0.83237761f, -0.83956063f, -0.84659988f, -0.85349399f, -0.86024189f,
831-0.86684239f, -0.87329435f, -0.87959671f, -0.88574833f, -0.89174819f,
832-0.89759529f, -0.90328854f, -0.90882701f, -0.91420978f, -0.91943592f,
833-0.92450452f, -0.92941469f, -0.93416560f, -0.93875647f, -0.94318646f,
834-0.94745487f, -0.95156091f, -0.95550388f, -0.95928317f, -0.96289814f,
835-0.96634805f, -0.96963239f, -0.97275060f, -0.97570217f, -0.97848648f,
836-0.98110318f, -0.98355180f, -0.98583186f, -0.98794299f, -0.98988485f,
837-0.99165714f, -0.99325943f, -0.99469161f, -0.99595332f, -0.99704438f,
838-0.99796462f, -0.99871385f, -0.99929196f, -0.99969882f, -0.99993443f,
8390.99999464f, 0.99956632f, 0.99845290f, 0.99665523f, 0.99417448f,
8400.99101239f, 0.98717111f, 0.98265326f, 0.97746199f, 0.97160077f,
8410.96507365f, 0.95788515f, 0.95004016f, 0.94154406f, 0.93240267f,
8420.92262226f, 0.91220951f, 0.90117162f, 0.88951606f, 0.87725091f,
8430.86438453f, 0.85092574f, 0.83688372f, 0.82226819f, 0.80708915f,
8440.79135692f, 0.77508235f, 0.75827658f, 0.74095112f, 0.72311783f,
8450.70478898f, 0.68597710f, 0.66669506f, 0.64695615f, 0.62677377f,
8460.60616189f, 0.58513457f, 0.56370622f, 0.54189157f, 0.51970547f,
8470.49716324f, 0.47428027f, 0.45107225f, 0.42755505f, 0.40374488f,
8480.37965798f, 0.35531086f, 0.33072025f, 0.30590299f, 0.28087607f,
8490.25565663f, 0.23026201f, 0.20470956f, 0.17901683f, 0.15320139f,
8500.12728097f, 0.10127331f, 0.075196236f, 0.049067631f, 0.022905400f,
851-0.0032725304f, -0.029448219f, -0.055603724f, -0.081721120f, -0.10778251f,
852-0.13377003f, -0.15966587f, -0.18545228f, -0.21111161f, -0.23662624f,
853-0.26197869f, -0.28715160f, -0.31212771f, -0.33688989f, -0.36142120f,
854-0.38570482f, -0.40972409f, -0.43346253f, -0.45690393f, -0.48003218f,
855-0.50283146f, -0.52528608f, -0.54738069f, -0.56910020f, -0.59042966f,
856-0.61135447f, -0.63186026f, -0.65193301f, -0.67155898f, -0.69072473f,
857-0.70941705f, -0.72762316f, -0.74533063f, -0.76252723f, -0.77920127f,
858-0.79534131f, -0.81093621f, -0.82597536f, -0.84044844f, -0.85434550f,
859-0.86765707f, -0.88037395f, -0.89248747f, -0.90398932f, -0.91487163f,
860-0.92512697f, -0.93474823f, -0.94372886f, -0.95206273f, -0.95974404f,
861-0.96676767f, -0.97312868f, -0.97882277f, -0.98384601f, -0.98819500f,
862-0.99186671f, -0.99485862f, -0.99716878f, -0.99879545f, -0.99973762f,
863};
864#endif
865
866static const CELTMode mode48000_960_120 = {
86748000, /* Fs */
868120, /* overlap */
86921, /* nbEBands */
87021, /* effEBands */
871{0.85000610f, 0.0000000f, 1.0000000f, 1.0000000f, }, /* preemph */
872eband5ms, /* eBands */
8733, /* maxLM */
8748, /* nbShortMdcts */
875120, /* shortMdctSize */
87611, /* nbAllocVectors */
877band_allocation, /* allocVectors */
878logN400, /* logN */
879window120, /* window */
880{1920, 3, {&fft_state48000_960_0, &fft_state48000_960_1, &fft_state48000_960_2, &fft_state48000_960_3, }, mdct_twiddles960}, /* mdct */
881{392, cache_index50, cache_bits50, cache_caps50}, /* cache */
882};
883
884/* List of all the available modes */
885#define TOTAL_MODES 1
886static const CELTMode * const static_mode_list[TOTAL_MODES] = {
887&mode48000_960_120,
888};
diff --git a/lib/rbcodec/codecs/libopus/celt/static_modes_float_arm_ne10.h b/lib/rbcodec/codecs/libopus/celt/static_modes_float_arm_ne10.h
new file mode 100644
index 0000000000..66e1abb101
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/static_modes_float_arm_ne10.h
@@ -0,0 +1,404 @@
1/* The contents of this file was automatically generated by
2 * dump_mode_arm_ne10.c with arguments: 48000 960
3 * It contains static definitions for some pre-defined modes. */
4#include <NE10_types.h>
5
6#ifndef NE10_FFT_PARAMS48000_960
7#define NE10_FFT_PARAMS48000_960
8static const ne10_int32_t ne10_factors_480[64] = {
94, 40, 4, 30, 2, 15, 5, 3, 3, 1, 1, 0, 0, 0, 0,
100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
130, 0, 0, 0, };
14static const ne10_int32_t ne10_factors_240[64] = {
153, 20, 4, 15, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0,
160, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
170, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
180, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
190, 0, 0, 0, };
20static const ne10_int32_t ne10_factors_120[64] = {
213, 10, 2, 15, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0,
220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
250, 0, 0, 0, };
26static const ne10_int32_t ne10_factors_60[64] = {
272, 5, 5, 3, 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
280, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
290, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
300, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
310, 0, 0, 0, };
32static const ne10_fft_cpx_float32_t ne10_twiddles_480[480] = {
33{1.0000000f,0.0000000f}, {1.0000000f,-0.0000000f}, {1.0000000f,-0.0000000f},
34{1.0000000f,-0.0000000f}, {0.91354543f,-0.40673664f}, {0.66913056f,-0.74314487f},
35{1.0000000f,-0.0000000f}, {0.66913056f,-0.74314487f}, {-0.10452851f,-0.99452192f},
36{1.0000000f,-0.0000000f}, {0.30901697f,-0.95105654f}, {-0.80901700f,-0.58778518f},
37{1.0000000f,-0.0000000f}, {-0.10452851f,-0.99452192f}, {-0.97814757f,0.20791179f},
38{1.0000000f,-0.0000000f}, {0.97814763f,-0.20791170f}, {0.91354543f,-0.40673664f},
39{0.80901700f,-0.58778524f}, {0.66913056f,-0.74314487f}, {0.49999997f,-0.86602545f},
40{0.30901697f,-0.95105654f}, {0.10452842f,-0.99452192f}, {-0.10452851f,-0.99452192f},
41{-0.30901703f,-0.95105648f}, {-0.50000006f,-0.86602533f}, {-0.66913068f,-0.74314475f},
42{-0.80901700f,-0.58778518f}, {-0.91354549f,-0.40673658f}, {-0.97814763f,-0.20791161f},
43{1.0000000f,-0.0000000f}, {0.99862951f,-0.052335959f}, {0.99452192f,-0.10452846f},
44{0.98768836f,-0.15643448f}, {0.97814763f,-0.20791170f}, {0.96592581f,-0.25881904f},
45{0.95105648f,-0.30901700f}, {0.93358040f,-0.35836795f}, {0.91354543f,-0.40673664f},
46{0.89100653f,-0.45399052f}, {0.86602545f,-0.50000000f}, {0.83867055f,-0.54463905f},
47{0.80901700f,-0.58778524f}, {0.77714598f,-0.62932038f}, {0.74314475f,-0.66913062f},
48{0.70710677f,-0.70710683f}, {0.66913056f,-0.74314487f}, {0.62932038f,-0.77714598f},
49{0.58778524f,-0.80901700f}, {0.54463899f,-0.83867055f}, {0.49999997f,-0.86602545f},
50{0.45399052f,-0.89100653f}, {0.40673661f,-0.91354549f}, {0.35836786f,-0.93358046f},
51{0.30901697f,-0.95105654f}, {0.25881907f,-0.96592581f}, {0.20791166f,-0.97814763f},
52{0.15643437f,-0.98768836f}, {0.10452842f,-0.99452192f}, {0.052335974f,-0.99862951f},
53{1.0000000f,-0.0000000f}, {0.99452192f,-0.10452846f}, {0.97814763f,-0.20791170f},
54{0.95105648f,-0.30901700f}, {0.91354543f,-0.40673664f}, {0.86602545f,-0.50000000f},
55{0.80901700f,-0.58778524f}, {0.74314475f,-0.66913062f}, {0.66913056f,-0.74314487f},
56{0.58778524f,-0.80901700f}, {0.49999997f,-0.86602545f}, {0.40673661f,-0.91354549f},
57{0.30901697f,-0.95105654f}, {0.20791166f,-0.97814763f}, {0.10452842f,-0.99452192f},
58{-4.3711388e-08f,-1.0000000f}, {-0.10452851f,-0.99452192f}, {-0.20791174f,-0.97814757f},
59{-0.30901703f,-0.95105648f}, {-0.40673670f,-0.91354543f}, {-0.50000006f,-0.86602533f},
60{-0.58778518f,-0.80901700f}, {-0.66913068f,-0.74314475f}, {-0.74314493f,-0.66913044f},
61{-0.80901700f,-0.58778518f}, {-0.86602539f,-0.50000006f}, {-0.91354549f,-0.40673658f},
62{-0.95105654f,-0.30901679f}, {-0.97814763f,-0.20791161f}, {-0.99452192f,-0.10452849f},
63{1.0000000f,-0.0000000f}, {0.98768836f,-0.15643448f}, {0.95105648f,-0.30901700f},
64{0.89100653f,-0.45399052f}, {0.80901700f,-0.58778524f}, {0.70710677f,-0.70710683f},
65{0.58778524f,-0.80901700f}, {0.45399052f,-0.89100653f}, {0.30901697f,-0.95105654f},
66{0.15643437f,-0.98768836f}, {-4.3711388e-08f,-1.0000000f}, {-0.15643445f,-0.98768836f},
67{-0.30901703f,-0.95105648f}, {-0.45399061f,-0.89100647f}, {-0.58778518f,-0.80901700f},
68{-0.70710677f,-0.70710677f}, {-0.80901700f,-0.58778518f}, {-0.89100659f,-0.45399037f},
69{-0.95105654f,-0.30901679f}, {-0.98768836f,-0.15643445f}, {-1.0000000f,8.7422777e-08f},
70{-0.98768830f,0.15643461f}, {-0.95105654f,0.30901697f}, {-0.89100653f,0.45399055f},
71{-0.80901694f,0.58778536f}, {-0.70710665f,0.70710689f}, {-0.58778507f,0.80901712f},
72{-0.45399022f,0.89100665f}, {-0.30901709f,0.95105648f}, {-0.15643452f,0.98768830f},
73{1.0000000f,-0.0000000f}, {0.99991435f,-0.013089596f}, {0.99965733f,-0.026176950f},
74{0.99922901f,-0.039259817f}, {0.99862951f,-0.052335959f}, {0.99785894f,-0.065403134f},
75{0.99691731f,-0.078459099f}, {0.99580491f,-0.091501623f}, {0.99452192f,-0.10452846f},
76{0.99306846f,-0.11753740f}, {0.99144489f,-0.13052620f}, {0.98965138f,-0.14349262f},
77{0.98768836f,-0.15643448f}, {0.98555607f,-0.16934951f}, {0.98325491f,-0.18223552f},
78{0.98078525f,-0.19509032f}, {0.97814763f,-0.20791170f}, {0.97534233f,-0.22069745f},
79{0.97236991f,-0.23344538f}, {0.96923089f,-0.24615330f}, {0.96592581f,-0.25881904f},
80{0.96245521f,-0.27144045f}, {0.95881975f,-0.28401536f}, {0.95501995f,-0.29654160f},
81{0.95105648f,-0.30901700f}, {0.94693011f,-0.32143945f}, {0.94264150f,-0.33380687f},
82{0.93819129f,-0.34611708f}, {0.93358040f,-0.35836795f}, {0.92880952f,-0.37055743f},
83{0.92387956f,-0.38268346f}, {0.91879117f,-0.39474389f}, {0.91354543f,-0.40673664f},
84{0.90814316f,-0.41865975f}, {0.90258527f,-0.43051112f}, {0.89687270f,-0.44228873f},
85{0.89100653f,-0.45399052f}, {0.88498765f,-0.46561453f}, {0.87881708f,-0.47715878f},
86{0.87249601f,-0.48862126f}, {0.86602545f,-0.50000000f}, {0.85940641f,-0.51129311f},
87{0.85264015f,-0.52249855f}, {0.84572786f,-0.53361452f}, {0.83867055f,-0.54463905f},
88{0.83146960f,-0.55557024f}, {0.82412618f,-0.56640625f}, {0.81664151f,-0.57714522f},
89{0.80901700f,-0.58778524f}, {0.80125380f,-0.59832460f}, {0.79335332f,-0.60876143f},
90{0.78531694f,-0.61909395f}, {0.77714598f,-0.62932038f}, {0.76884180f,-0.63943899f},
91{0.76040596f,-0.64944810f}, {0.75183982f,-0.65934587f}, {0.74314475f,-0.66913062f},
92{0.73432249f,-0.67880076f}, {0.72537434f,-0.68835455f}, {0.71630192f,-0.69779050f},
93{0.70710677f,-0.70710683f}, {0.69779044f,-0.71630198f}, {0.68835455f,-0.72537440f},
94{0.67880070f,-0.73432255f}, {0.66913056f,-0.74314487f}, {0.65934581f,-0.75183982f},
95{0.64944804f,-0.76040596f}, {0.63943899f,-0.76884186f}, {0.62932038f,-0.77714598f},
96{0.61909395f,-0.78531694f}, {0.60876137f,-0.79335338f}, {0.59832460f,-0.80125386f},
97{0.58778524f,-0.80901700f}, {0.57714516f,-0.81664151f}, {0.56640625f,-0.82412618f},
98{0.55557019f,-0.83146960f}, {0.54463899f,-0.83867055f}, {0.53361452f,-0.84572786f},
99{0.52249849f,-0.85264015f}, {0.51129311f,-0.85940641f}, {0.49999997f,-0.86602545f},
100{0.48862118f,-0.87249601f}, {0.47715876f,-0.87881708f}, {0.46561447f,-0.88498765f},
101{0.45399052f,-0.89100653f}, {0.44228867f,-0.89687276f}, {0.43051103f,-0.90258533f},
102{0.41865975f,-0.90814316f}, {0.40673661f,-0.91354549f}, {0.39474380f,-0.91879129f},
103{0.38268343f,-0.92387956f}, {0.37055740f,-0.92880958f}, {0.35836786f,-0.93358046f},
104{0.34611705f,-0.93819135f}, {0.33380681f,-0.94264150f}, {0.32143947f,-0.94693011f},
105{0.30901697f,-0.95105654f}, {0.29654151f,-0.95501995f}, {0.28401533f,-0.95881975f},
106{0.27144039f,-0.96245527f}, {0.25881907f,-0.96592581f}, {0.24615327f,-0.96923089f},
107{0.23344530f,-0.97236991f}, {0.22069745f,-0.97534233f}, {0.20791166f,-0.97814763f},
108{0.19509023f,-0.98078531f}, {0.18223552f,-0.98325491f}, {0.16934945f,-0.98555607f},
109{0.15643437f,-0.98768836f}, {0.14349259f,-0.98965138f}, {0.13052613f,-0.99144489f},
110{0.11753740f,-0.99306846f}, {0.10452842f,-0.99452192f}, {0.091501534f,-0.99580491f},
111{0.078459084f,-0.99691731f}, {0.065403074f,-0.99785894f}, {0.052335974f,-0.99862951f},
112{0.039259788f,-0.99922901f}, {0.026176875f,-0.99965733f}, {0.013089597f,-0.99991435f},
113{1.0000000f,-0.0000000f}, {0.99965733f,-0.026176950f}, {0.99862951f,-0.052335959f},
114{0.99691731f,-0.078459099f}, {0.99452192f,-0.10452846f}, {0.99144489f,-0.13052620f},
115{0.98768836f,-0.15643448f}, {0.98325491f,-0.18223552f}, {0.97814763f,-0.20791170f},
116{0.97236991f,-0.23344538f}, {0.96592581f,-0.25881904f}, {0.95881975f,-0.28401536f},
117{0.95105648f,-0.30901700f}, {0.94264150f,-0.33380687f}, {0.93358040f,-0.35836795f},
118{0.92387956f,-0.38268346f}, {0.91354543f,-0.40673664f}, {0.90258527f,-0.43051112f},
119{0.89100653f,-0.45399052f}, {0.87881708f,-0.47715878f}, {0.86602545f,-0.50000000f},
120{0.85264015f,-0.52249855f}, {0.83867055f,-0.54463905f}, {0.82412618f,-0.56640625f},
121{0.80901700f,-0.58778524f}, {0.79335332f,-0.60876143f}, {0.77714598f,-0.62932038f},
122{0.76040596f,-0.64944810f}, {0.74314475f,-0.66913062f}, {0.72537434f,-0.68835455f},
123{0.70710677f,-0.70710683f}, {0.68835455f,-0.72537440f}, {0.66913056f,-0.74314487f},
124{0.64944804f,-0.76040596f}, {0.62932038f,-0.77714598f}, {0.60876137f,-0.79335338f},
125{0.58778524f,-0.80901700f}, {0.56640625f,-0.82412618f}, {0.54463899f,-0.83867055f},
126{0.52249849f,-0.85264015f}, {0.49999997f,-0.86602545f}, {0.47715876f,-0.87881708f},
127{0.45399052f,-0.89100653f}, {0.43051103f,-0.90258533f}, {0.40673661f,-0.91354549f},
128{0.38268343f,-0.92387956f}, {0.35836786f,-0.93358046f}, {0.33380681f,-0.94264150f},
129{0.30901697f,-0.95105654f}, {0.28401533f,-0.95881975f}, {0.25881907f,-0.96592581f},
130{0.23344530f,-0.97236991f}, {0.20791166f,-0.97814763f}, {0.18223552f,-0.98325491f},
131{0.15643437f,-0.98768836f}, {0.13052613f,-0.99144489f}, {0.10452842f,-0.99452192f},
132{0.078459084f,-0.99691731f}, {0.052335974f,-0.99862951f}, {0.026176875f,-0.99965733f},
133{-4.3711388e-08f,-1.0000000f}, {-0.026176963f,-0.99965733f}, {-0.052336060f,-0.99862951f},
134{-0.078459173f,-0.99691731f}, {-0.10452851f,-0.99452192f}, {-0.13052621f,-0.99144489f},
135{-0.15643445f,-0.98768836f}, {-0.18223560f,-0.98325491f}, {-0.20791174f,-0.97814757f},
136{-0.23344538f,-0.97236991f}, {-0.25881916f,-0.96592581f}, {-0.28401542f,-0.95881969f},
137{-0.30901703f,-0.95105648f}, {-0.33380687f,-0.94264150f}, {-0.35836795f,-0.93358040f},
138{-0.38268352f,-0.92387950f}, {-0.40673670f,-0.91354543f}, {-0.43051112f,-0.90258527f},
139{-0.45399061f,-0.89100647f}, {-0.47715873f,-0.87881708f}, {-0.50000006f,-0.86602533f},
140{-0.52249867f,-0.85264009f}, {-0.54463905f,-0.83867055f}, {-0.56640631f,-0.82412612f},
141{-0.58778518f,-0.80901700f}, {-0.60876143f,-0.79335332f}, {-0.62932050f,-0.77714586f},
142{-0.64944804f,-0.76040596f}, {-0.66913068f,-0.74314475f}, {-0.68835467f,-0.72537428f},
143{-0.70710677f,-0.70710677f}, {-0.72537446f,-0.68835449f}, {-0.74314493f,-0.66913044f},
144{-0.76040596f,-0.64944804f}, {-0.77714604f,-0.62932026f}, {-0.79335332f,-0.60876143f},
145{-0.80901700f,-0.58778518f}, {-0.82412624f,-0.56640613f}, {-0.83867055f,-0.54463899f},
146{-0.85264021f,-0.52249849f}, {-0.86602539f,-0.50000006f}, {-0.87881714f,-0.47715873f},
147{-0.89100659f,-0.45399037f}, {-0.90258527f,-0.43051112f}, {-0.91354549f,-0.40673658f},
148{-0.92387956f,-0.38268328f}, {-0.93358040f,-0.35836792f}, {-0.94264150f,-0.33380675f},
149{-0.95105654f,-0.30901679f}, {-0.95881975f,-0.28401530f}, {-0.96592587f,-0.25881892f},
150{-0.97236991f,-0.23344538f}, {-0.97814763f,-0.20791161f}, {-0.98325491f,-0.18223536f},
151{-0.98768836f,-0.15643445f}, {-0.99144489f,-0.13052608f}, {-0.99452192f,-0.10452849f},
152{-0.99691737f,-0.078459039f}, {-0.99862957f,-0.052335810f}, {-0.99965733f,-0.026176952f},
153{1.0000000f,-0.0000000f}, {0.99922901f,-0.039259817f}, {0.99691731f,-0.078459099f},
154{0.99306846f,-0.11753740f}, {0.98768836f,-0.15643448f}, {0.98078525f,-0.19509032f},
155{0.97236991f,-0.23344538f}, {0.96245521f,-0.27144045f}, {0.95105648f,-0.30901700f},
156{0.93819129f,-0.34611708f}, {0.92387956f,-0.38268346f}, {0.90814316f,-0.41865975f},
157{0.89100653f,-0.45399052f}, {0.87249601f,-0.48862126f}, {0.85264015f,-0.52249855f},
158{0.83146960f,-0.55557024f}, {0.80901700f,-0.58778524f}, {0.78531694f,-0.61909395f},
159{0.76040596f,-0.64944810f}, {0.73432249f,-0.67880076f}, {0.70710677f,-0.70710683f},
160{0.67880070f,-0.73432255f}, {0.64944804f,-0.76040596f}, {0.61909395f,-0.78531694f},
161{0.58778524f,-0.80901700f}, {0.55557019f,-0.83146960f}, {0.52249849f,-0.85264015f},
162{0.48862118f,-0.87249601f}, {0.45399052f,-0.89100653f}, {0.41865975f,-0.90814316f},
163{0.38268343f,-0.92387956f}, {0.34611705f,-0.93819135f}, {0.30901697f,-0.95105654f},
164{0.27144039f,-0.96245527f}, {0.23344530f,-0.97236991f}, {0.19509023f,-0.98078531f},
165{0.15643437f,-0.98768836f}, {0.11753740f,-0.99306846f}, {0.078459084f,-0.99691731f},
166{0.039259788f,-0.99922901f}, {-4.3711388e-08f,-1.0000000f}, {-0.039259877f,-0.99922901f},
167{-0.078459173f,-0.99691731f}, {-0.11753749f,-0.99306846f}, {-0.15643445f,-0.98768836f},
168{-0.19509032f,-0.98078525f}, {-0.23344538f,-0.97236991f}, {-0.27144048f,-0.96245521f},
169{-0.30901703f,-0.95105648f}, {-0.34611711f,-0.93819129f}, {-0.38268352f,-0.92387950f},
170{-0.41865984f,-0.90814310f}, {-0.45399061f,-0.89100647f}, {-0.48862135f,-0.87249595f},
171{-0.52249867f,-0.85264009f}, {-0.55557036f,-0.83146954f}, {-0.58778518f,-0.80901700f},
172{-0.61909389f,-0.78531694f}, {-0.64944804f,-0.76040596f}, {-0.67880076f,-0.73432249f},
173{-0.70710677f,-0.70710677f}, {-0.73432249f,-0.67880070f}, {-0.76040596f,-0.64944804f},
174{-0.78531694f,-0.61909389f}, {-0.80901700f,-0.58778518f}, {-0.83146966f,-0.55557019f},
175{-0.85264021f,-0.52249849f}, {-0.87249607f,-0.48862115f}, {-0.89100659f,-0.45399037f},
176{-0.90814322f,-0.41865960f}, {-0.92387956f,-0.38268328f}, {-0.93819135f,-0.34611690f},
177{-0.95105654f,-0.30901679f}, {-0.96245521f,-0.27144048f}, {-0.97236991f,-0.23344538f},
178{-0.98078531f,-0.19509031f}, {-0.98768836f,-0.15643445f}, {-0.99306846f,-0.11753736f},
179{-0.99691737f,-0.078459039f}, {-0.99922901f,-0.039259743f}, {-1.0000000f,8.7422777e-08f},
180{-0.99922901f,0.039259918f}, {-0.99691731f,0.078459218f}, {-0.99306846f,0.11753753f},
181{-0.98768830f,0.15643461f}, {-0.98078525f,0.19509049f}, {-0.97236985f,0.23344554f},
182{-0.96245515f,0.27144065f}, {-0.95105654f,0.30901697f}, {-0.93819135f,0.34611705f},
183{-0.92387956f,0.38268346f}, {-0.90814316f,0.41865975f}, {-0.89100653f,0.45399055f},
184{-0.87249601f,0.48862129f}, {-0.85264015f,0.52249861f}, {-0.83146960f,0.55557030f},
185{-0.80901694f,0.58778536f}, {-0.78531688f,0.61909401f}, {-0.76040590f,0.64944816f},
186{-0.73432243f,0.67880082f}, {-0.70710665f,0.70710689f}, {-0.67880058f,0.73432261f},
187{-0.64944792f,0.76040608f}, {-0.61909378f,0.78531706f}, {-0.58778507f,0.80901712f},
188{-0.55557001f,0.83146977f}, {-0.52249837f,0.85264033f}, {-0.48862100f,0.87249613f},
189{-0.45399022f,0.89100665f}, {-0.41865945f,0.90814328f}, {-0.38268313f,0.92387968f},
190{-0.34611672f,0.93819147f}, {-0.30901709f,0.95105648f}, {-0.27144054f,0.96245521f},
191{-0.23344545f,0.97236991f}, {-0.19509038f,0.98078525f}, {-0.15643452f,0.98768830f},
192{-0.11753743f,0.99306846f}, {-0.078459114f,0.99691731f}, {-0.039259821f,0.99922901f},
193};
194static const ne10_fft_cpx_float32_t ne10_twiddles_240[240] = {
195{1.0000000f,0.0000000f}, {1.0000000f,-0.0000000f}, {1.0000000f,-0.0000000f},
196{1.0000000f,-0.0000000f}, {0.91354543f,-0.40673664f}, {0.66913056f,-0.74314487f},
197{1.0000000f,-0.0000000f}, {0.66913056f,-0.74314487f}, {-0.10452851f,-0.99452192f},
198{1.0000000f,-0.0000000f}, {0.30901697f,-0.95105654f}, {-0.80901700f,-0.58778518f},
199{1.0000000f,-0.0000000f}, {-0.10452851f,-0.99452192f}, {-0.97814757f,0.20791179f},
200{1.0000000f,-0.0000000f}, {0.99452192f,-0.10452846f}, {0.97814763f,-0.20791170f},
201{0.95105648f,-0.30901700f}, {0.91354543f,-0.40673664f}, {0.86602545f,-0.50000000f},
202{0.80901700f,-0.58778524f}, {0.74314475f,-0.66913062f}, {0.66913056f,-0.74314487f},
203{0.58778524f,-0.80901700f}, {0.49999997f,-0.86602545f}, {0.40673661f,-0.91354549f},
204{0.30901697f,-0.95105654f}, {0.20791166f,-0.97814763f}, {0.10452842f,-0.99452192f},
205{1.0000000f,-0.0000000f}, {0.97814763f,-0.20791170f}, {0.91354543f,-0.40673664f},
206{0.80901700f,-0.58778524f}, {0.66913056f,-0.74314487f}, {0.49999997f,-0.86602545f},
207{0.30901697f,-0.95105654f}, {0.10452842f,-0.99452192f}, {-0.10452851f,-0.99452192f},
208{-0.30901703f,-0.95105648f}, {-0.50000006f,-0.86602533f}, {-0.66913068f,-0.74314475f},
209{-0.80901700f,-0.58778518f}, {-0.91354549f,-0.40673658f}, {-0.97814763f,-0.20791161f},
210{1.0000000f,-0.0000000f}, {0.95105648f,-0.30901700f}, {0.80901700f,-0.58778524f},
211{0.58778524f,-0.80901700f}, {0.30901697f,-0.95105654f}, {-4.3711388e-08f,-1.0000000f},
212{-0.30901703f,-0.95105648f}, {-0.58778518f,-0.80901700f}, {-0.80901700f,-0.58778518f},
213{-0.95105654f,-0.30901679f}, {-1.0000000f,8.7422777e-08f}, {-0.95105654f,0.30901697f},
214{-0.80901694f,0.58778536f}, {-0.58778507f,0.80901712f}, {-0.30901709f,0.95105648f},
215{1.0000000f,-0.0000000f}, {0.99965733f,-0.026176950f}, {0.99862951f,-0.052335959f},
216{0.99691731f,-0.078459099f}, {0.99452192f,-0.10452846f}, {0.99144489f,-0.13052620f},
217{0.98768836f,-0.15643448f}, {0.98325491f,-0.18223552f}, {0.97814763f,-0.20791170f},
218{0.97236991f,-0.23344538f}, {0.96592581f,-0.25881904f}, {0.95881975f,-0.28401536f},
219{0.95105648f,-0.30901700f}, {0.94264150f,-0.33380687f}, {0.93358040f,-0.35836795f},
220{0.92387956f,-0.38268346f}, {0.91354543f,-0.40673664f}, {0.90258527f,-0.43051112f},
221{0.89100653f,-0.45399052f}, {0.87881708f,-0.47715878f}, {0.86602545f,-0.50000000f},
222{0.85264015f,-0.52249855f}, {0.83867055f,-0.54463905f}, {0.82412618f,-0.56640625f},
223{0.80901700f,-0.58778524f}, {0.79335332f,-0.60876143f}, {0.77714598f,-0.62932038f},
224{0.76040596f,-0.64944810f}, {0.74314475f,-0.66913062f}, {0.72537434f,-0.68835455f},
225{0.70710677f,-0.70710683f}, {0.68835455f,-0.72537440f}, {0.66913056f,-0.74314487f},
226{0.64944804f,-0.76040596f}, {0.62932038f,-0.77714598f}, {0.60876137f,-0.79335338f},
227{0.58778524f,-0.80901700f}, {0.56640625f,-0.82412618f}, {0.54463899f,-0.83867055f},
228{0.52249849f,-0.85264015f}, {0.49999997f,-0.86602545f}, {0.47715876f,-0.87881708f},
229{0.45399052f,-0.89100653f}, {0.43051103f,-0.90258533f}, {0.40673661f,-0.91354549f},
230{0.38268343f,-0.92387956f}, {0.35836786f,-0.93358046f}, {0.33380681f,-0.94264150f},
231{0.30901697f,-0.95105654f}, {0.28401533f,-0.95881975f}, {0.25881907f,-0.96592581f},
232{0.23344530f,-0.97236991f}, {0.20791166f,-0.97814763f}, {0.18223552f,-0.98325491f},
233{0.15643437f,-0.98768836f}, {0.13052613f,-0.99144489f}, {0.10452842f,-0.99452192f},
234{0.078459084f,-0.99691731f}, {0.052335974f,-0.99862951f}, {0.026176875f,-0.99965733f},
235{1.0000000f,-0.0000000f}, {0.99862951f,-0.052335959f}, {0.99452192f,-0.10452846f},
236{0.98768836f,-0.15643448f}, {0.97814763f,-0.20791170f}, {0.96592581f,-0.25881904f},
237{0.95105648f,-0.30901700f}, {0.93358040f,-0.35836795f}, {0.91354543f,-0.40673664f},
238{0.89100653f,-0.45399052f}, {0.86602545f,-0.50000000f}, {0.83867055f,-0.54463905f},
239{0.80901700f,-0.58778524f}, {0.77714598f,-0.62932038f}, {0.74314475f,-0.66913062f},
240{0.70710677f,-0.70710683f}, {0.66913056f,-0.74314487f}, {0.62932038f,-0.77714598f},
241{0.58778524f,-0.80901700f}, {0.54463899f,-0.83867055f}, {0.49999997f,-0.86602545f},
242{0.45399052f,-0.89100653f}, {0.40673661f,-0.91354549f}, {0.35836786f,-0.93358046f},
243{0.30901697f,-0.95105654f}, {0.25881907f,-0.96592581f}, {0.20791166f,-0.97814763f},
244{0.15643437f,-0.98768836f}, {0.10452842f,-0.99452192f}, {0.052335974f,-0.99862951f},
245{-4.3711388e-08f,-1.0000000f}, {-0.052336060f,-0.99862951f}, {-0.10452851f,-0.99452192f},
246{-0.15643445f,-0.98768836f}, {-0.20791174f,-0.97814757f}, {-0.25881916f,-0.96592581f},
247{-0.30901703f,-0.95105648f}, {-0.35836795f,-0.93358040f}, {-0.40673670f,-0.91354543f},
248{-0.45399061f,-0.89100647f}, {-0.50000006f,-0.86602533f}, {-0.54463905f,-0.83867055f},
249{-0.58778518f,-0.80901700f}, {-0.62932050f,-0.77714586f}, {-0.66913068f,-0.74314475f},
250{-0.70710677f,-0.70710677f}, {-0.74314493f,-0.66913044f}, {-0.77714604f,-0.62932026f},
251{-0.80901700f,-0.58778518f}, {-0.83867055f,-0.54463899f}, {-0.86602539f,-0.50000006f},
252{-0.89100659f,-0.45399037f}, {-0.91354549f,-0.40673658f}, {-0.93358040f,-0.35836792f},
253{-0.95105654f,-0.30901679f}, {-0.96592587f,-0.25881892f}, {-0.97814763f,-0.20791161f},
254{-0.98768836f,-0.15643445f}, {-0.99452192f,-0.10452849f}, {-0.99862957f,-0.052335810f},
255{1.0000000f,-0.0000000f}, {0.99691731f,-0.078459099f}, {0.98768836f,-0.15643448f},
256{0.97236991f,-0.23344538f}, {0.95105648f,-0.30901700f}, {0.92387956f,-0.38268346f},
257{0.89100653f,-0.45399052f}, {0.85264015f,-0.52249855f}, {0.80901700f,-0.58778524f},
258{0.76040596f,-0.64944810f}, {0.70710677f,-0.70710683f}, {0.64944804f,-0.76040596f},
259{0.58778524f,-0.80901700f}, {0.52249849f,-0.85264015f}, {0.45399052f,-0.89100653f},
260{0.38268343f,-0.92387956f}, {0.30901697f,-0.95105654f}, {0.23344530f,-0.97236991f},
261{0.15643437f,-0.98768836f}, {0.078459084f,-0.99691731f}, {-4.3711388e-08f,-1.0000000f},
262{-0.078459173f,-0.99691731f}, {-0.15643445f,-0.98768836f}, {-0.23344538f,-0.97236991f},
263{-0.30901703f,-0.95105648f}, {-0.38268352f,-0.92387950f}, {-0.45399061f,-0.89100647f},
264{-0.52249867f,-0.85264009f}, {-0.58778518f,-0.80901700f}, {-0.64944804f,-0.76040596f},
265{-0.70710677f,-0.70710677f}, {-0.76040596f,-0.64944804f}, {-0.80901700f,-0.58778518f},
266{-0.85264021f,-0.52249849f}, {-0.89100659f,-0.45399037f}, {-0.92387956f,-0.38268328f},
267{-0.95105654f,-0.30901679f}, {-0.97236991f,-0.23344538f}, {-0.98768836f,-0.15643445f},
268{-0.99691737f,-0.078459039f}, {-1.0000000f,8.7422777e-08f}, {-0.99691731f,0.078459218f},
269{-0.98768830f,0.15643461f}, {-0.97236985f,0.23344554f}, {-0.95105654f,0.30901697f},
270{-0.92387956f,0.38268346f}, {-0.89100653f,0.45399055f}, {-0.85264015f,0.52249861f},
271{-0.80901694f,0.58778536f}, {-0.76040590f,0.64944816f}, {-0.70710665f,0.70710689f},
272{-0.64944792f,0.76040608f}, {-0.58778507f,0.80901712f}, {-0.52249837f,0.85264033f},
273{-0.45399022f,0.89100665f}, {-0.38268313f,0.92387968f}, {-0.30901709f,0.95105648f},
274{-0.23344545f,0.97236991f}, {-0.15643452f,0.98768830f}, {-0.078459114f,0.99691731f},
275};
276static const ne10_fft_cpx_float32_t ne10_twiddles_120[120] = {
277{1.0000000f,0.0000000f}, {1.0000000f,-0.0000000f}, {1.0000000f,-0.0000000f},
278{1.0000000f,-0.0000000f}, {0.91354543f,-0.40673664f}, {0.66913056f,-0.74314487f},
279{1.0000000f,-0.0000000f}, {0.66913056f,-0.74314487f}, {-0.10452851f,-0.99452192f},
280{1.0000000f,-0.0000000f}, {0.30901697f,-0.95105654f}, {-0.80901700f,-0.58778518f},
281{1.0000000f,-0.0000000f}, {-0.10452851f,-0.99452192f}, {-0.97814757f,0.20791179f},
282{1.0000000f,-0.0000000f}, {0.97814763f,-0.20791170f}, {0.91354543f,-0.40673664f},
283{0.80901700f,-0.58778524f}, {0.66913056f,-0.74314487f}, {0.49999997f,-0.86602545f},
284{0.30901697f,-0.95105654f}, {0.10452842f,-0.99452192f}, {-0.10452851f,-0.99452192f},
285{-0.30901703f,-0.95105648f}, {-0.50000006f,-0.86602533f}, {-0.66913068f,-0.74314475f},
286{-0.80901700f,-0.58778518f}, {-0.91354549f,-0.40673658f}, {-0.97814763f,-0.20791161f},
287{1.0000000f,-0.0000000f}, {0.99862951f,-0.052335959f}, {0.99452192f,-0.10452846f},
288{0.98768836f,-0.15643448f}, {0.97814763f,-0.20791170f}, {0.96592581f,-0.25881904f},
289{0.95105648f,-0.30901700f}, {0.93358040f,-0.35836795f}, {0.91354543f,-0.40673664f},
290{0.89100653f,-0.45399052f}, {0.86602545f,-0.50000000f}, {0.83867055f,-0.54463905f},
291{0.80901700f,-0.58778524f}, {0.77714598f,-0.62932038f}, {0.74314475f,-0.66913062f},
292{0.70710677f,-0.70710683f}, {0.66913056f,-0.74314487f}, {0.62932038f,-0.77714598f},
293{0.58778524f,-0.80901700f}, {0.54463899f,-0.83867055f}, {0.49999997f,-0.86602545f},
294{0.45399052f,-0.89100653f}, {0.40673661f,-0.91354549f}, {0.35836786f,-0.93358046f},
295{0.30901697f,-0.95105654f}, {0.25881907f,-0.96592581f}, {0.20791166f,-0.97814763f},
296{0.15643437f,-0.98768836f}, {0.10452842f,-0.99452192f}, {0.052335974f,-0.99862951f},
297{1.0000000f,-0.0000000f}, {0.99452192f,-0.10452846f}, {0.97814763f,-0.20791170f},
298{0.95105648f,-0.30901700f}, {0.91354543f,-0.40673664f}, {0.86602545f,-0.50000000f},
299{0.80901700f,-0.58778524f}, {0.74314475f,-0.66913062f}, {0.66913056f,-0.74314487f},
300{0.58778524f,-0.80901700f}, {0.49999997f,-0.86602545f}, {0.40673661f,-0.91354549f},
301{0.30901697f,-0.95105654f}, {0.20791166f,-0.97814763f}, {0.10452842f,-0.99452192f},
302{-4.3711388e-08f,-1.0000000f}, {-0.10452851f,-0.99452192f}, {-0.20791174f,-0.97814757f},
303{-0.30901703f,-0.95105648f}, {-0.40673670f,-0.91354543f}, {-0.50000006f,-0.86602533f},
304{-0.58778518f,-0.80901700f}, {-0.66913068f,-0.74314475f}, {-0.74314493f,-0.66913044f},
305{-0.80901700f,-0.58778518f}, {-0.86602539f,-0.50000006f}, {-0.91354549f,-0.40673658f},
306{-0.95105654f,-0.30901679f}, {-0.97814763f,-0.20791161f}, {-0.99452192f,-0.10452849f},
307{1.0000000f,-0.0000000f}, {0.98768836f,-0.15643448f}, {0.95105648f,-0.30901700f},
308{0.89100653f,-0.45399052f}, {0.80901700f,-0.58778524f}, {0.70710677f,-0.70710683f},
309{0.58778524f,-0.80901700f}, {0.45399052f,-0.89100653f}, {0.30901697f,-0.95105654f},
310{0.15643437f,-0.98768836f}, {-4.3711388e-08f,-1.0000000f}, {-0.15643445f,-0.98768836f},
311{-0.30901703f,-0.95105648f}, {-0.45399061f,-0.89100647f}, {-0.58778518f,-0.80901700f},
312{-0.70710677f,-0.70710677f}, {-0.80901700f,-0.58778518f}, {-0.89100659f,-0.45399037f},
313{-0.95105654f,-0.30901679f}, {-0.98768836f,-0.15643445f}, {-1.0000000f,8.7422777e-08f},
314{-0.98768830f,0.15643461f}, {-0.95105654f,0.30901697f}, {-0.89100653f,0.45399055f},
315{-0.80901694f,0.58778536f}, {-0.70710665f,0.70710689f}, {-0.58778507f,0.80901712f},
316{-0.45399022f,0.89100665f}, {-0.30901709f,0.95105648f}, {-0.15643452f,0.98768830f},
317};
318static const ne10_fft_cpx_float32_t ne10_twiddles_60[60] = {
319{1.0000000f,0.0000000f}, {1.0000000f,-0.0000000f}, {1.0000000f,-0.0000000f},
320{1.0000000f,-0.0000000f}, {0.91354543f,-0.40673664f}, {0.66913056f,-0.74314487f},
321{1.0000000f,-0.0000000f}, {0.66913056f,-0.74314487f}, {-0.10452851f,-0.99452192f},
322{1.0000000f,-0.0000000f}, {0.30901697f,-0.95105654f}, {-0.80901700f,-0.58778518f},
323{1.0000000f,-0.0000000f}, {-0.10452851f,-0.99452192f}, {-0.97814757f,0.20791179f},
324{1.0000000f,-0.0000000f}, {0.99452192f,-0.10452846f}, {0.97814763f,-0.20791170f},
325{0.95105648f,-0.30901700f}, {0.91354543f,-0.40673664f}, {0.86602545f,-0.50000000f},
326{0.80901700f,-0.58778524f}, {0.74314475f,-0.66913062f}, {0.66913056f,-0.74314487f},
327{0.58778524f,-0.80901700f}, {0.49999997f,-0.86602545f}, {0.40673661f,-0.91354549f},
328{0.30901697f,-0.95105654f}, {0.20791166f,-0.97814763f}, {0.10452842f,-0.99452192f},
329{1.0000000f,-0.0000000f}, {0.97814763f,-0.20791170f}, {0.91354543f,-0.40673664f},
330{0.80901700f,-0.58778524f}, {0.66913056f,-0.74314487f}, {0.49999997f,-0.86602545f},
331{0.30901697f,-0.95105654f}, {0.10452842f,-0.99452192f}, {-0.10452851f,-0.99452192f},
332{-0.30901703f,-0.95105648f}, {-0.50000006f,-0.86602533f}, {-0.66913068f,-0.74314475f},
333{-0.80901700f,-0.58778518f}, {-0.91354549f,-0.40673658f}, {-0.97814763f,-0.20791161f},
334{1.0000000f,-0.0000000f}, {0.95105648f,-0.30901700f}, {0.80901700f,-0.58778524f},
335{0.58778524f,-0.80901700f}, {0.30901697f,-0.95105654f}, {-4.3711388e-08f,-1.0000000f},
336{-0.30901703f,-0.95105648f}, {-0.58778518f,-0.80901700f}, {-0.80901700f,-0.58778518f},
337{-0.95105654f,-0.30901679f}, {-1.0000000f,8.7422777e-08f}, {-0.95105654f,0.30901697f},
338{-0.80901694f,0.58778536f}, {-0.58778507f,0.80901712f}, {-0.30901709f,0.95105648f},
339};
340static const ne10_fft_state_float32_t ne10_fft_state_float32_t_480 = {
341120,
342(ne10_int32_t *)ne10_factors_480,
343(ne10_fft_cpx_float32_t *)ne10_twiddles_480,
344NULL,
345(ne10_fft_cpx_float32_t *)&ne10_twiddles_480[120],
346/* is_forward_scaled = true */
347(ne10_int32_t) 1,
348/* is_backward_scaled = false */
349(ne10_int32_t) 0,
350};
351static const arch_fft_state cfg_arch_480 = {
3521,
353(void *)&ne10_fft_state_float32_t_480,
354};
355
356static const ne10_fft_state_float32_t ne10_fft_state_float32_t_240 = {
35760,
358(ne10_int32_t *)ne10_factors_240,
359(ne10_fft_cpx_float32_t *)ne10_twiddles_240,
360NULL,
361(ne10_fft_cpx_float32_t *)&ne10_twiddles_240[60],
362/* is_forward_scaled = true */
363(ne10_int32_t) 1,
364/* is_backward_scaled = false */
365(ne10_int32_t) 0,
366};
367static const arch_fft_state cfg_arch_240 = {
3681,
369(void *)&ne10_fft_state_float32_t_240,
370};
371
372static const ne10_fft_state_float32_t ne10_fft_state_float32_t_120 = {
37330,
374(ne10_int32_t *)ne10_factors_120,
375(ne10_fft_cpx_float32_t *)ne10_twiddles_120,
376NULL,
377(ne10_fft_cpx_float32_t *)&ne10_twiddles_120[30],
378/* is_forward_scaled = true */
379(ne10_int32_t) 1,
380/* is_backward_scaled = false */
381(ne10_int32_t) 0,
382};
383static const arch_fft_state cfg_arch_120 = {
3841,
385(void *)&ne10_fft_state_float32_t_120,
386};
387
388static const ne10_fft_state_float32_t ne10_fft_state_float32_t_60 = {
38915,
390(ne10_int32_t *)ne10_factors_60,
391(ne10_fft_cpx_float32_t *)ne10_twiddles_60,
392NULL,
393(ne10_fft_cpx_float32_t *)&ne10_twiddles_60[15],
394/* is_forward_scaled = true */
395(ne10_int32_t) 1,
396/* is_backward_scaled = false */
397(ne10_int32_t) 0,
398};
399static const arch_fft_state cfg_arch_60 = {
4001,
401(void *)&ne10_fft_state_float32_t_60,
402};
403
404#endif /* end NE10_FFT_PARAMS48000_960 */
diff --git a/lib/rbcodec/codecs/libopus/celt/tests/test_unit_cwrs32.c b/lib/rbcodec/codecs/libopus/celt/tests/test_unit_cwrs32.c
new file mode 100644
index 0000000000..36dd8af5f5
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/tests/test_unit_cwrs32.c
@@ -0,0 +1,161 @@
1/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation,
2 Gregory Maxwell
3 Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */
4/*
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include <stdio.h>
34#include <string.h>
35
36#ifndef CUSTOM_MODES
37#define CUSTOM_MODES
38#else
39#define TEST_CUSTOM_MODES
40#endif
41
42#define CELT_C
43#include "stack_alloc.h"
44#include "entenc.c"
45#include "entdec.c"
46#include "entcode.c"
47#include "cwrs.c"
48#include "mathops.c"
49#include "rate.h"
50
51#define NMAX (240)
52#define KMAX (128)
53
54#ifdef TEST_CUSTOM_MODES
55
56#define NDIMS (44)
57static const int pn[NDIMS]={
58 2, 3, 4, 5, 6, 7, 8, 9, 10,
59 11, 12, 13, 14, 15, 16, 18, 20, 22,
60 24, 26, 28, 30, 32, 36, 40, 44, 48,
61 52, 56, 60, 64, 72, 80, 88, 96, 104,
62 112, 120, 128, 144, 160, 176, 192, 208
63};
64static const int pkmax[NDIMS]={
65 128, 128, 128, 128, 88, 52, 36, 26, 22,
66 18, 16, 15, 13, 12, 12, 11, 10, 9,
67 9, 8, 8, 7, 7, 7, 7, 6, 6,
68 6, 6, 6, 5, 5, 5, 5, 5, 5,
69 4, 4, 4, 4, 4, 4, 4, 4
70};
71
72#else /* TEST_CUSTOM_MODES */
73
74#define NDIMS (22)
75static const int pn[NDIMS]={
76 2, 3, 4, 6, 8, 9, 11, 12, 16,
77 18, 22, 24, 32, 36, 44, 48, 64, 72,
78 88, 96, 144, 176
79};
80static const int pkmax[NDIMS]={
81 128, 128, 128, 88, 36, 26, 18, 16, 12,
82 11, 9, 9, 7, 7, 6, 6, 5, 5,
83 5, 5, 4, 4
84};
85
86#endif
87
88int main(void){
89 int t;
90 int n;
91 ALLOC_STACK;
92 for(t=0;t<NDIMS;t++){
93 int pseudo;
94 n=pn[t];
95 for(pseudo=1;pseudo<41;pseudo++)
96 {
97 int k;
98#if defined(SMALL_FOOTPRINT)
99 opus_uint32 uu[KMAX+2U];
100#endif
101 opus_uint32 inc;
102 opus_uint32 nc;
103 opus_uint32 i;
104 k=get_pulses(pseudo);
105 if (k>pkmax[t])break;
106 printf("Testing CWRS with N=%i, K=%i...\n",n,k);
107#if defined(SMALL_FOOTPRINT)
108 nc=ncwrs_urow(n,k,uu);
109#else
110 nc=CELT_PVQ_V(n,k);
111#endif
112 inc=nc/20000;
113 if(inc<1)inc=1;
114 for(i=0;i<nc;i+=inc){
115#if defined(SMALL_FOOTPRINT)
116 opus_uint32 u[KMAX+2U];
117#endif
118 int y[NMAX];
119 int sy;
120 opus_uint32 v;
121 opus_uint32 ii;
122 int j;
123#if defined(SMALL_FOOTPRINT)
124 memcpy(u,uu,(k+2U)*sizeof(*u));
125 cwrsi(n,k,i,y,u);
126#else
127 cwrsi(n,k,i,y);
128#endif
129 sy=0;
130 for(j=0;j<n;j++)sy+=abs(y[j]);
131 if(sy!=k){
132 fprintf(stderr,"N=%d Pulse count mismatch in cwrsi (%d!=%d).\n",
133 n,sy,k);
134 return 99;
135 }
136 /*printf("%6u of %u:",i,nc);
137 for(j=0;j<n;j++)printf(" %+3i",y[j]);
138 printf(" ->");*/
139#if defined(SMALL_FOOTPRINT)
140 ii=icwrs(n,k,&v,y,u);
141#else
142 ii=icwrs(n,y);
143 v=CELT_PVQ_V(n,k);
144#endif
145 if(ii!=i){
146 fprintf(stderr,"Combination-index mismatch (%lu!=%lu).\n",
147 (long)ii,(long)i);
148 return 1;
149 }
150 if(v!=nc){
151 fprintf(stderr,"Combination count mismatch (%lu!=%lu).\n",
152 (long)v,(long)nc);
153 return 2;
154 }
155 /*printf(" %6u\n",i);*/
156 }
157 /*printf("\n");*/
158 }
159 }
160 return 0;
161}
diff --git a/lib/rbcodec/codecs/libopus/celt/tests/test_unit_dft.c b/lib/rbcodec/codecs/libopus/celt/tests/test_unit_dft.c
new file mode 100644
index 0000000000..70f8f4937b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/tests/test_unit_dft.c
@@ -0,0 +1,179 @@
1/* Copyright (c) 2008 Xiph.Org Foundation
2 Written by Jean-Marc Valin */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <stdio.h>
33
34#include "stack_alloc.h"
35#include "kiss_fft.h"
36#include "mathops.h"
37#include "modes.h"
38
39#ifndef M_PI
40#define M_PI 3.141592653
41#endif
42
43int ret = 0;
44
45void check(kiss_fft_cpx * in,kiss_fft_cpx * out,int nfft,int isinverse)
46{
47 int bin,k;
48 double errpow=0,sigpow=0, snr;
49
50 for (bin=0;bin<nfft;++bin) {
51 double ansr = 0;
52 double ansi = 0;
53 double difr;
54 double difi;
55
56 for (k=0;k<nfft;++k) {
57 double phase = -2*M_PI*bin*k/nfft;
58 double re = cos(phase);
59 double im = sin(phase);
60 if (isinverse)
61 im = -im;
62
63 if (!isinverse)
64 {
65 re /= nfft;
66 im /= nfft;
67 }
68
69 ansr += in[k].r * re - in[k].i * im;
70 ansi += in[k].r * im + in[k].i * re;
71 }
72 /*printf ("%d %d ", (int)ansr, (int)ansi);*/
73 difr = ansr - out[bin].r;
74 difi = ansi - out[bin].i;
75 errpow += difr*difr + difi*difi;
76 sigpow += ansr*ansr+ansi*ansi;
77 }
78 snr = 10*log10(sigpow/errpow);
79 printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
80 if (snr<60) {
81 printf( "** poor snr: %f ** \n", snr);
82 ret = 1;
83 }
84}
85
86void test1d(int nfft,int isinverse,int arch)
87{
88 size_t buflen = sizeof(kiss_fft_cpx)*nfft;
89 kiss_fft_cpx *in;
90 kiss_fft_cpx *out;
91 int k;
92#ifdef CUSTOM_MODES
93 kiss_fft_state *cfg = opus_fft_alloc(nfft,0,0,arch);
94#else
95 int id;
96 const kiss_fft_state *cfg;
97 CELTMode *mode = opus_custom_mode_create(48000, 960, NULL);
98 if (nfft == 480) id = 0;
99 else if (nfft == 240) id = 1;
100 else if (nfft == 120) id = 2;
101 else if (nfft == 60) id = 3;
102 else return;
103 cfg = mode->mdct.kfft[id];
104#endif
105
106 in = (kiss_fft_cpx*)malloc(buflen);
107 out = (kiss_fft_cpx*)malloc(buflen);
108
109 for (k=0;k<nfft;++k) {
110 in[k].r = (rand() % 32767) - 16384;
111 in[k].i = (rand() % 32767) - 16384;
112 }
113
114 for (k=0;k<nfft;++k) {
115 in[k].r *= 32768;
116 in[k].i *= 32768;
117 }
118
119 if (isinverse)
120 {
121 for (k=0;k<nfft;++k) {
122 in[k].r /= nfft;
123 in[k].i /= nfft;
124 }
125 }
126
127 /*for (k=0;k<nfft;++k) printf("%d %d ", in[k].r, in[k].i);printf("\n");*/
128
129 if (isinverse)
130 opus_ifft(cfg,in,out, arch);
131 else
132 opus_fft(cfg,in,out, arch);
133
134 /*for (k=0;k<nfft;++k) printf("%d %d ", out[k].r, out[k].i);printf("\n");*/
135
136 check(in,out,nfft,isinverse);
137
138 free(in);
139 free(out);
140#ifdef CUSTOM_MODES
141 opus_fft_free(cfg, arch);
142#endif
143}
144
145int main(int argc,char ** argv)
146{
147 ALLOC_STACK;
148 int arch = opus_select_arch();
149
150 if (argc>1) {
151 int k;
152 for (k=1;k<argc;++k) {
153 test1d(atoi(argv[k]),0,arch);
154 test1d(atoi(argv[k]),1,arch);
155 }
156 }else{
157 test1d(32,0,arch);
158 test1d(32,1,arch);
159 test1d(128,0,arch);
160 test1d(128,1,arch);
161 test1d(256,0,arch);
162 test1d(256,1,arch);
163#ifndef RADIX_TWO_ONLY
164 test1d(36,0,arch);
165 test1d(36,1,arch);
166 test1d(50,0,arch);
167 test1d(50,1,arch);
168 test1d(60,0,arch);
169 test1d(60,1,arch);
170 test1d(120,0,arch);
171 test1d(120,1,arch);
172 test1d(240,0,arch);
173 test1d(240,1,arch);
174 test1d(480,0,arch);
175 test1d(480,1,arch);
176#endif
177 }
178 return ret;
179}
diff --git a/lib/rbcodec/codecs/libopus/celt/tests/test_unit_entropy.c b/lib/rbcodec/codecs/libopus/celt/tests/test_unit_entropy.c
new file mode 100644
index 0000000000..7f674529df
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/tests/test_unit_entropy.c
@@ -0,0 +1,383 @@
1/* Copyright (c) 2007-2011 Xiph.Org Foundation, Mozilla Corporation,
2 Gregory Maxwell
3 Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */
4/*
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include <stdlib.h>
34#include <stdio.h>
35#include <math.h>
36#include <time.h>
37#define CELT_C
38#include "entcode.h"
39#include "entenc.h"
40#include "entdec.h"
41#include <string.h>
42
43#include "entenc.c"
44#include "entdec.c"
45#include "entcode.c"
46
47#ifndef M_LOG2E
48# define M_LOG2E 1.4426950408889634074
49#endif
50#define DATA_SIZE 10000000
51#define DATA_SIZE2 10000
52
53int main(int _argc,char **_argv){
54 ec_enc enc;
55 ec_dec dec;
56 long nbits;
57 long nbits2;
58 double entropy;
59 int ft;
60 int ftb;
61 int sz;
62 int i;
63 int ret;
64 unsigned int sym;
65 unsigned int seed;
66 unsigned char *ptr;
67 const char *env_seed;
68 ret=0;
69 entropy=0;
70 if (_argc > 2) {
71 fprintf(stderr, "Usage: %s [<seed>]\n", _argv[0]);
72 return 1;
73 }
74 env_seed = getenv("SEED");
75 if (_argc > 1)
76 seed = atoi(_argv[1]);
77 else if (env_seed)
78 seed = atoi(env_seed);
79 else
80 seed = time(NULL);
81 /*Testing encoding of raw bit values.*/
82 ptr = (unsigned char *)malloc(DATA_SIZE);
83 ec_enc_init(&enc,ptr, DATA_SIZE);
84 for(ft=2;ft<1024;ft++){
85 for(i=0;i<ft;i++){
86 entropy+=log(ft)*M_LOG2E;
87 ec_enc_uint(&enc,i,ft);
88 }
89 }
90 /*Testing encoding of raw bit values.*/
91 for(ftb=1;ftb<16;ftb++){
92 for(i=0;i<(1<<ftb);i++){
93 entropy+=ftb;
94 nbits=ec_tell(&enc);
95 ec_enc_bits(&enc,i,ftb);
96 nbits2=ec_tell(&enc);
97 if(nbits2-nbits!=ftb){
98 fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
99 nbits2-nbits,ftb);
100 ret=-1;
101 }
102 }
103 }
104 nbits=ec_tell_frac(&enc);
105 ec_enc_done(&enc);
106 fprintf(stderr,
107 "Encoded %0.2lf bits of entropy to %0.2lf bits (%0.3lf%% wasted).\n",
108 entropy,ldexp(nbits,-3),100*(nbits-ldexp(entropy,3))/nbits);
109 fprintf(stderr,"Packed to %li bytes.\n",(long)ec_range_bytes(&enc));
110 ec_dec_init(&dec,ptr,DATA_SIZE);
111 for(ft=2;ft<1024;ft++){
112 for(i=0;i<ft;i++){
113 sym=ec_dec_uint(&dec,ft);
114 if(sym!=(unsigned)i){
115 fprintf(stderr,"Decoded %i instead of %i with ft of %i.\n",sym,i,ft);
116 ret=-1;
117 }
118 }
119 }
120 for(ftb=1;ftb<16;ftb++){
121 for(i=0;i<(1<<ftb);i++){
122 sym=ec_dec_bits(&dec,ftb);
123 if(sym!=(unsigned)i){
124 fprintf(stderr,"Decoded %i instead of %i with ftb of %i.\n",sym,i,ftb);
125 ret=-1;
126 }
127 }
128 }
129 nbits2=ec_tell_frac(&dec);
130 if(nbits!=nbits2){
131 fprintf(stderr,
132 "Reported number of bits used was %0.2lf, should be %0.2lf.\n",
133 ldexp(nbits2,-3),ldexp(nbits,-3));
134 ret=-1;
135 }
136 /*Testing an encoder bust prefers range coder data over raw bits.
137 This isn't a general guarantee, will only work for data that is buffered in
138 the encoder state and not yet stored in the user buffer, and should never
139 get used in practice.
140 It's mostly here for code coverage completeness.*/
141 /*Start with a 16-bit buffer.*/
142 ec_enc_init(&enc,ptr,2);
143 /*Write 7 raw bits.*/
144 ec_enc_bits(&enc,0x55,7);
145 /*Write 12.3 bits of range coder data.*/
146 ec_enc_uint(&enc,1,2);
147 ec_enc_uint(&enc,1,3);
148 ec_enc_uint(&enc,1,4);
149 ec_enc_uint(&enc,1,5);
150 ec_enc_uint(&enc,2,6);
151 ec_enc_uint(&enc,6,7);
152 ec_enc_done(&enc);
153 ec_dec_init(&dec,ptr,2);
154 if(!enc.error
155 /*The raw bits should have been overwritten by the range coder data.*/
156 ||ec_dec_bits(&dec,7)!=0x05
157 /*And all the range coder data should have been encoded correctly.*/
158 ||ec_dec_uint(&dec,2)!=1
159 ||ec_dec_uint(&dec,3)!=1
160 ||ec_dec_uint(&dec,4)!=1
161 ||ec_dec_uint(&dec,5)!=1
162 ||ec_dec_uint(&dec,6)!=2
163 ||ec_dec_uint(&dec,7)!=6){
164 fprintf(stderr,"Encoder bust overwrote range coder data with raw bits.\n");
165 ret=-1;
166 }
167 srand(seed);
168 fprintf(stderr,"Testing random streams... Random seed: %u (%.4X)\n", seed, rand() % 65536);
169 for(i=0;i<409600;i++){
170 unsigned *data;
171 unsigned *tell;
172 unsigned tell_bits;
173 int j;
174 int zeros;
175 ft=rand()/((RAND_MAX>>(rand()%11U))+1U)+10;
176 sz=rand()/((RAND_MAX>>(rand()%9U))+1U);
177 data=(unsigned *)malloc(sz*sizeof(*data));
178 tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
179 ec_enc_init(&enc,ptr,DATA_SIZE2);
180 zeros = rand()%13==0;
181 tell[0]=ec_tell_frac(&enc);
182 for(j=0;j<sz;j++){
183 if (zeros)
184 data[j]=0;
185 else
186 data[j]=rand()%ft;
187 ec_enc_uint(&enc,data[j],ft);
188 tell[j+1]=ec_tell_frac(&enc);
189 }
190 if (rand()%2==0)
191 while(ec_tell(&enc)%8 != 0)
192 ec_enc_uint(&enc, rand()%2, 2);
193 tell_bits = ec_tell(&enc);
194 ec_enc_done(&enc);
195 if(tell_bits!=(unsigned)ec_tell(&enc)){
196 fprintf(stderr,"ec_tell() changed after ec_enc_done(): %i instead of %i (Random seed: %u)\n",
197 ec_tell(&enc),tell_bits,seed);
198 ret=-1;
199 }
200 if ((tell_bits+7)/8 < ec_range_bytes(&enc))
201 {
202 fprintf (stderr, "ec_tell() lied, there's %i bytes instead of %d (Random seed: %u)\n",
203 ec_range_bytes(&enc), (tell_bits+7)/8,seed);
204 ret=-1;
205 }
206 ec_dec_init(&dec,ptr,DATA_SIZE2);
207 if(ec_tell_frac(&dec)!=tell[0]){
208 fprintf(stderr,
209 "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
210 0,ec_tell_frac(&dec),tell[0],seed);
211 }
212 for(j=0;j<sz;j++){
213 sym=ec_dec_uint(&dec,ft);
214 if(sym!=data[j]){
215 fprintf(stderr,
216 "Decoded %i instead of %i with ft of %i at position %i of %i (Random seed: %u).\n",
217 sym,data[j],ft,j,sz,seed);
218 ret=-1;
219 }
220 if(ec_tell_frac(&dec)!=tell[j+1]){
221 fprintf(stderr,
222 "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
223 j+1,ec_tell_frac(&dec),tell[j+1],seed);
224 }
225 }
226 free(tell);
227 free(data);
228 }
229 /*Test compatibility between multiple different encode/decode routines.*/
230 for(i=0;i<409600;i++){
231 unsigned *logp1;
232 unsigned *data;
233 unsigned *tell;
234 unsigned *enc_method;
235 int j;
236 sz=rand()/((RAND_MAX>>(rand()%9U))+1U);
237 logp1=(unsigned *)malloc(sz*sizeof(*logp1));
238 data=(unsigned *)malloc(sz*sizeof(*data));
239 tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
240 enc_method=(unsigned *)malloc(sz*sizeof(*enc_method));
241 ec_enc_init(&enc,ptr,DATA_SIZE2);
242 tell[0]=ec_tell_frac(&enc);
243 for(j=0;j<sz;j++){
244 data[j]=rand()/((RAND_MAX>>1)+1);
245 logp1[j]=(rand()%15)+1;
246 enc_method[j]=rand()/((RAND_MAX>>2)+1);
247 switch(enc_method[j]){
248 case 0:{
249 ec_encode(&enc,data[j]?(1<<logp1[j])-1:0,
250 (1<<logp1[j])-(data[j]?0:1),1<<logp1[j]);
251 }break;
252 case 1:{
253 ec_encode_bin(&enc,data[j]?(1<<logp1[j])-1:0,
254 (1<<logp1[j])-(data[j]?0:1),logp1[j]);
255 }break;
256 case 2:{
257 ec_enc_bit_logp(&enc,data[j],logp1[j]);
258 }break;
259 case 3:{
260 unsigned char icdf[2];
261 icdf[0]=1;
262 icdf[1]=0;
263 ec_enc_icdf(&enc,data[j],icdf,logp1[j]);
264 }break;
265 }
266 tell[j+1]=ec_tell_frac(&enc);
267 }
268 ec_enc_done(&enc);
269 if((ec_tell(&enc)+7U)/8U<ec_range_bytes(&enc)){
270 fprintf(stderr,"tell() lied, there's %i bytes instead of %d (Random seed: %u)\n",
271 ec_range_bytes(&enc),(ec_tell(&enc)+7)/8,seed);
272 ret=-1;
273 }
274 ec_dec_init(&dec,ptr,DATA_SIZE2);
275 if(ec_tell_frac(&dec)!=tell[0]){
276 fprintf(stderr,
277 "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
278 0,ec_tell_frac(&dec),tell[0],seed);
279 }
280 for(j=0;j<sz;j++){
281 int fs;
282 int dec_method;
283 dec_method=rand()/((RAND_MAX>>2)+1);
284 switch(dec_method){
285 case 0:{
286 fs=ec_decode(&dec,1<<logp1[j]);
287 sym=fs>=(1<<logp1[j])-1;
288 ec_dec_update(&dec,sym?(1<<logp1[j])-1:0,
289 (1<<logp1[j])-(sym?0:1),1<<logp1[j]);
290 }break;
291 case 1:{
292 fs=ec_decode_bin(&dec,logp1[j]);
293 sym=fs>=(1<<logp1[j])-1;
294 ec_dec_update(&dec,sym?(1<<logp1[j])-1:0,
295 (1<<logp1[j])-(sym?0:1),1<<logp1[j]);
296 }break;
297 case 2:{
298 sym=ec_dec_bit_logp(&dec,logp1[j]);
299 }break;
300 case 3:{
301 unsigned char icdf[2];
302 icdf[0]=1;
303 icdf[1]=0;
304 sym=ec_dec_icdf(&dec,icdf,logp1[j]);
305 }break;
306 }
307 if(sym!=data[j]){
308 fprintf(stderr,
309 "Decoded %i instead of %i with logp1 of %i at position %i of %i (Random seed: %u).\n",
310 sym,data[j],logp1[j],j,sz,seed);
311 fprintf(stderr,"Encoding method: %i, decoding method: %i\n",
312 enc_method[j],dec_method);
313 ret=-1;
314 }
315 if(ec_tell_frac(&dec)!=tell[j+1]){
316 fprintf(stderr,
317 "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
318 j+1,ec_tell_frac(&dec),tell[j+1],seed);
319 }
320 }
321 free(enc_method);
322 free(tell);
323 free(data);
324 free(logp1);
325 }
326 ec_enc_init(&enc,ptr,DATA_SIZE2);
327 ec_enc_bit_logp(&enc,0,1);
328 ec_enc_bit_logp(&enc,0,1);
329 ec_enc_bit_logp(&enc,0,1);
330 ec_enc_bit_logp(&enc,0,1);
331 ec_enc_bit_logp(&enc,0,2);
332 ec_enc_patch_initial_bits(&enc,3,2);
333 if(enc.error){
334 fprintf(stderr,"patch_initial_bits failed");
335 ret=-1;
336 }
337 ec_enc_patch_initial_bits(&enc,0,5);
338 if(!enc.error){
339 fprintf(stderr,"patch_initial_bits didn't fail when it should have");
340 ret=-1;
341 }
342 ec_enc_done(&enc);
343 if(ec_range_bytes(&enc)!=1||ptr[0]!=192){
344 fprintf(stderr,"Got %d when expecting 192 for patch_initial_bits",ptr[0]);
345 ret=-1;
346 }
347 ec_enc_init(&enc,ptr,DATA_SIZE2);
348 ec_enc_bit_logp(&enc,0,1);
349 ec_enc_bit_logp(&enc,0,1);
350 ec_enc_bit_logp(&enc,1,6);
351 ec_enc_bit_logp(&enc,0,2);
352 ec_enc_patch_initial_bits(&enc,0,2);
353 if(enc.error){
354 fprintf(stderr,"patch_initial_bits failed");
355 ret=-1;
356 }
357 ec_enc_done(&enc);
358 if(ec_range_bytes(&enc)!=2||ptr[0]!=63){
359 fprintf(stderr,"Got %d when expecting 63 for patch_initial_bits",ptr[0]);
360 ret=-1;
361 }
362 ec_enc_init(&enc,ptr,2);
363 ec_enc_bit_logp(&enc,0,2);
364 for(i=0;i<48;i++){
365 ec_enc_bits(&enc,0,1);
366 }
367 ec_enc_done(&enc);
368 if(!enc.error){
369 fprintf(stderr,"Raw bits overfill didn't fail when it should have");
370 ret=-1;
371 }
372 ec_enc_init(&enc,ptr,2);
373 for(i=0;i<17;i++){
374 ec_enc_bits(&enc,0,1);
375 }
376 ec_enc_done(&enc);
377 if(!enc.error){
378 fprintf(stderr,"17 raw bits encoded in two bytes");
379 ret=-1;
380 }
381 free(ptr);
382 return ret;
383}
diff --git a/lib/rbcodec/codecs/libopus/celt/tests/test_unit_laplace.c b/lib/rbcodec/codecs/libopus/celt/tests/test_unit_laplace.c
new file mode 100644
index 0000000000..727bf012ef
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/tests/test_unit_laplace.c
@@ -0,0 +1,93 @@
1/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation
2 Written by Jean-Marc Valin and Timothy B. Terriberry */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <stdio.h>
33#include <stdlib.h>
34#define CELT_C
35#include "laplace.h"
36#include "stack_alloc.h"
37
38#include "entenc.c"
39#include "entdec.c"
40#include "entcode.c"
41#include "laplace.c"
42
43#define DATA_SIZE 40000
44
45int ec_laplace_get_start_freq(int decay)
46{
47 opus_uint32 ft = 32768 - LAPLACE_MINP*(2*LAPLACE_NMIN+1);
48 int fs = (ft*(16384-decay))/(16384+decay);
49 return fs+LAPLACE_MINP;
50}
51
52int main(void)
53{
54 int i;
55 int ret = 0;
56 ec_enc enc;
57 ec_dec dec;
58 unsigned char *ptr;
59 int val[10000], decay[10000];
60 ALLOC_STACK;
61 ptr = (unsigned char *)malloc(DATA_SIZE);
62 ec_enc_init(&enc,ptr,DATA_SIZE);
63
64 val[0] = 3; decay[0] = 6000;
65 val[1] = 0; decay[1] = 5800;
66 val[2] = -1; decay[2] = 5600;
67 for (i=3;i<10000;i++)
68 {
69 val[i] = rand()%15-7;
70 decay[i] = rand()%11000+5000;
71 }
72 for (i=0;i<10000;i++)
73 ec_laplace_encode(&enc, &val[i],
74 ec_laplace_get_start_freq(decay[i]), decay[i]);
75
76 ec_enc_done(&enc);
77
78 ec_dec_init(&dec,ec_get_buffer(&enc),ec_range_bytes(&enc));
79
80 for (i=0;i<10000;i++)
81 {
82 int d = ec_laplace_decode(&dec,
83 ec_laplace_get_start_freq(decay[i]), decay[i]);
84 if (d != val[i])
85 {
86 fprintf (stderr, "Got %d instead of %d\n", d, val[i]);
87 ret = 1;
88 }
89 }
90
91 free(ptr);
92 return ret;
93}
diff --git a/lib/rbcodec/codecs/libopus/celt/tests/test_unit_mathops.c b/lib/rbcodec/codecs/libopus/celt/tests/test_unit_mathops.c
new file mode 100644
index 0000000000..874e9adf0f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/tests/test_unit_mathops.c
@@ -0,0 +1,266 @@
1/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation,
2 Gregory Maxwell
3 Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */
4/*
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#ifndef CUSTOM_MODES
34#define CUSTOM_MODES
35#endif
36
37#include <stdio.h>
38#include <math.h>
39#include "mathops.h"
40#include "bands.h"
41
42#ifdef FIXED_POINT
43#define WORD "%d"
44#else
45#define WORD "%f"
46#endif
47
48int ret = 0;
49
50void testdiv(void)
51{
52 opus_int32 i;
53 for (i=1;i<=327670;i++)
54 {
55 double prod;
56 opus_val32 val;
57 val = celt_rcp(i);
58#ifdef FIXED_POINT
59 prod = (1./32768./65526.)*val*i;
60#else
61 prod = val*i;
62#endif
63 if (fabs(prod-1) > .00025)
64 {
65 fprintf (stderr, "div failed: 1/%d="WORD" (product = %f)\n", i, val, prod);
66 ret = 1;
67 }
68 }
69}
70
71void testsqrt(void)
72{
73 opus_int32 i;
74 for (i=1;i<=1000000000;i++)
75 {
76 double ratio;
77 opus_val16 val;
78 val = celt_sqrt(i);
79 ratio = val/sqrt(i);
80 if (fabs(ratio - 1) > .0005 && fabs(val-sqrt(i)) > 2)
81 {
82 fprintf (stderr, "sqrt failed: sqrt(%d)="WORD" (ratio = %f)\n", i, val, ratio);
83 ret = 1;
84 }
85 i+= i>>10;
86 }
87}
88
89void testbitexactcos(void)
90{
91 int i;
92 opus_int32 min_d,max_d,last,chk;
93 chk=max_d=0;
94 last=min_d=32767;
95 for(i=64;i<=16320;i++)
96 {
97 opus_int32 d;
98 opus_int32 q=bitexact_cos(i);
99 chk ^= q*i;
100 d = last - q;
101 if (d>max_d)max_d=d;
102 if (d<min_d)min_d=d;
103 last = q;
104 }
105 if ((chk!=89408644)||(max_d!=5)||(min_d!=0)||(bitexact_cos(64)!=32767)||
106 (bitexact_cos(16320)!=200)||(bitexact_cos(8192)!=23171))
107 {
108 fprintf (stderr, "bitexact_cos failed\n");
109 ret = 1;
110 }
111}
112
113void testbitexactlog2tan(void)
114{
115 int i,fail;
116 opus_int32 min_d,max_d,last,chk;
117 fail=chk=max_d=0;
118 last=min_d=15059;
119 for(i=64;i<8193;i++)
120 {
121 opus_int32 d;
122 opus_int32 mid=bitexact_cos(i);
123 opus_int32 side=bitexact_cos(16384-i);
124 opus_int32 q=bitexact_log2tan(mid,side);
125 chk ^= q*i;
126 d = last - q;
127 if (q!=-1*bitexact_log2tan(side,mid))
128 fail = 1;
129 if (d>max_d)max_d=d;
130 if (d<min_d)min_d=d;
131 last = q;
132 }
133 if ((chk!=15821257)||(max_d!=61)||(min_d!=-2)||fail||
134 (bitexact_log2tan(32767,200)!=15059)||(bitexact_log2tan(30274,12540)!=2611)||
135 (bitexact_log2tan(23171,23171)!=0))
136 {
137 fprintf (stderr, "bitexact_log2tan failed\n");
138 ret = 1;
139 }
140}
141
142#ifndef FIXED_POINT
143void testlog2(void)
144{
145 float x;
146 for (x=0.001;x<1677700.0;x+=(x/8.0))
147 {
148 float error = fabs((1.442695040888963387*log(x))-celt_log2(x));
149 if (error>0.0009)
150 {
151 fprintf (stderr, "celt_log2 failed: fabs((1.442695040888963387*log(x))-celt_log2(x))>0.001 (x = %f, error = %f)\n", x,error);
152 ret = 1;
153 }
154 }
155}
156
157void testexp2(void)
158{
159 float x;
160 for (x=-11.0;x<24.0;x+=0.0007)
161 {
162 float error = fabs(x-(1.442695040888963387*log(celt_exp2(x))));
163 if (error>0.0002)
164 {
165 fprintf (stderr, "celt_exp2 failed: fabs(x-(1.442695040888963387*log(celt_exp2(x))))>0.0005 (x = %f, error = %f)\n", x,error);
166 ret = 1;
167 }
168 }
169}
170
171void testexp2log2(void)
172{
173 float x;
174 for (x=-11.0;x<24.0;x+=0.0007)
175 {
176 float error = fabs(x-(celt_log2(celt_exp2(x))));
177 if (error>0.001)
178 {
179 fprintf (stderr, "celt_log2/celt_exp2 failed: fabs(x-(celt_log2(celt_exp2(x))))>0.001 (x = %f, error = %f)\n", x,error);
180 ret = 1;
181 }
182 }
183}
184#else
185void testlog2(void)
186{
187 opus_val32 x;
188 for (x=8;x<1073741824;x+=(x>>3))
189 {
190 float error = fabs((1.442695040888963387*log(x/16384.0))-celt_log2(x)/1024.0);
191 if (error>0.003)
192 {
193 fprintf (stderr, "celt_log2 failed: x = %ld, error = %f\n", (long)x,error);
194 ret = 1;
195 }
196 }
197}
198
199void testexp2(void)
200{
201 opus_val16 x;
202 for (x=-32768;x<15360;x++)
203 {
204 float error1 = fabs(x/1024.0-(1.442695040888963387*log(celt_exp2(x)/65536.0)));
205 float error2 = fabs(exp(0.6931471805599453094*x/1024.0)-celt_exp2(x)/65536.0);
206 if (error1>0.0002&&error2>0.00004)
207 {
208 fprintf (stderr, "celt_exp2 failed: x = "WORD", error1 = %f, error2 = %f\n", x,error1,error2);
209 ret = 1;
210 }
211 }
212}
213
214void testexp2log2(void)
215{
216 opus_val32 x;
217 for (x=8;x<65536;x+=(x>>3))
218 {
219 float error = fabs(x-0.25*celt_exp2(celt_log2(x)))/16384;
220 if (error>0.004)
221 {
222 fprintf (stderr, "celt_log2/celt_exp2 failed: fabs(x-(celt_exp2(celt_log2(x))))>0.001 (x = %ld, error = %f)\n", (long)x,error);
223 ret = 1;
224 }
225 }
226}
227
228void testilog2(void)
229{
230 opus_val32 x;
231 for (x=1;x<=268435455;x+=127)
232 {
233 opus_val32 lg;
234 opus_val32 y;
235
236 lg = celt_ilog2(x);
237 if (lg<0 || lg>=31)
238 {
239 printf("celt_ilog2 failed: 0<=celt_ilog2(x)<31 (x = %d, celt_ilog2(x) = %d)\n",x,lg);
240 ret = 1;
241 }
242 y = 1<<lg;
243
244 if (x<y || (x>>1)>=y)
245 {
246 printf("celt_ilog2 failed: 2**celt_ilog2(x)<=x<2**(celt_ilog2(x)+1) (x = %d, 2**celt_ilog2(x) = %d)\n",x,y);
247 ret = 1;
248 }
249 }
250}
251#endif
252
253int main(void)
254{
255 testbitexactcos();
256 testbitexactlog2tan();
257 testdiv();
258 testsqrt();
259 testlog2();
260 testexp2();
261 testexp2log2();
262#ifdef FIXED_POINT
263 testilog2();
264#endif
265 return ret;
266}
diff --git a/lib/rbcodec/codecs/libopus/celt/tests/test_unit_mdct.c b/lib/rbcodec/codecs/libopus/celt/tests/test_unit_mdct.c
new file mode 100644
index 0000000000..4a563ccfe3
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/tests/test_unit_mdct.c
@@ -0,0 +1,227 @@
1/* Copyright (c) 2008-2011 Xiph.Org Foundation
2 Written by Jean-Marc Valin */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <stdio.h>
33
34#include "mdct.h"
35#include "stack_alloc.h"
36#include "kiss_fft.h"
37#include "mdct.h"
38#include "modes.h"
39
40#ifndef M_PI
41#define M_PI 3.141592653
42#endif
43
44int ret = 0;
45void check(kiss_fft_scalar * in,kiss_fft_scalar * out,int nfft,int isinverse)
46{
47 int bin,k;
48 double errpow=0,sigpow=0;
49 double snr;
50 for (bin=0;bin<nfft/2;++bin) {
51 double ansr = 0;
52 double difr;
53
54 for (k=0;k<nfft;++k) {
55 double phase = 2*M_PI*(k+.5+.25*nfft)*(bin+.5)/nfft;
56 double re = cos(phase);
57
58 re /= nfft/4;
59
60 ansr += in[k] * re;
61 }
62 /*printf ("%f %f\n", ansr, out[bin]);*/
63 difr = ansr - out[bin];
64 errpow += difr*difr;
65 sigpow += ansr*ansr;
66 }
67 snr = 10*log10(sigpow/errpow);
68 printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
69 if (snr<60) {
70 printf( "** poor snr: %f **\n", snr);
71 ret = 1;
72 }
73}
74
75void check_inv(kiss_fft_scalar * in,kiss_fft_scalar * out,int nfft,int isinverse)
76{
77 int bin,k;
78 double errpow=0,sigpow=0;
79 double snr;
80 for (bin=0;bin<nfft;++bin) {
81 double ansr = 0;
82 double difr;
83
84 for (k=0;k<nfft/2;++k) {
85 double phase = 2*M_PI*(bin+.5+.25*nfft)*(k+.5)/nfft;
86 double re = cos(phase);
87
88 /*re *= 2;*/
89
90 ansr += in[k] * re;
91 }
92 /*printf ("%f %f\n", ansr, out[bin]);*/
93 difr = ansr - out[bin];
94 errpow += difr*difr;
95 sigpow += ansr*ansr;
96 }
97 snr = 10*log10(sigpow/errpow);
98 printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
99 if (snr<60) {
100 printf( "** poor snr: %f **\n", snr);
101 ret = 1;
102 }
103}
104
105
106void test1d(int nfft,int isinverse,int arch)
107{
108 size_t buflen = sizeof(kiss_fft_scalar)*nfft;
109 kiss_fft_scalar *in;
110 kiss_fft_scalar *in_copy;
111 kiss_fft_scalar *out;
112 opus_val16 *window;
113 int k;
114
115#ifdef CUSTOM_MODES
116 int shift = 0;
117 const mdct_lookup *cfg;
118 mdct_lookup _cfg;
119 clt_mdct_init(&_cfg, nfft, 0, arch);
120 cfg = &_cfg;
121#else
122 int shift;
123 const mdct_lookup *cfg;
124 CELTMode *mode = opus_custom_mode_create(48000, 960, NULL);
125 if (nfft == 1920) shift = 0;
126 else if (nfft == 960) shift = 1;
127 else if (nfft == 480) shift = 2;
128 else if (nfft == 240) shift = 3;
129 else return;
130 cfg = &mode->mdct;
131#endif
132
133 in = (kiss_fft_scalar*)malloc(buflen);
134 in_copy = (kiss_fft_scalar*)malloc(buflen);
135 out = (kiss_fft_scalar*)malloc(buflen);
136 window = (opus_val16*)malloc(sizeof(opus_val16)*nfft/2);
137
138 for (k=0;k<nfft;++k) {
139 in[k] = (rand() % 32768) - 16384;
140 }
141
142 for (k=0;k<nfft/2;++k) {
143 window[k] = Q15ONE;
144 }
145 for (k=0;k<nfft;++k) {
146 in[k] *= 32768;
147 }
148
149 if (isinverse)
150 {
151 for (k=0;k<nfft;++k) {
152 in[k] /= nfft;
153 }
154 }
155
156 for (k=0;k<nfft;++k)
157 in_copy[k] = in[k];
158 /*for (k=0;k<nfft;++k) printf("%d %d ", in[k].r, in[k].i);printf("\n");*/
159
160 if (isinverse)
161 {
162 for (k=0;k<nfft;++k)
163 out[k] = 0;
164 clt_mdct_backward(cfg,in,out, window, nfft/2, shift, 1, arch);
165 /* apply TDAC because clt_mdct_backward() no longer does that */
166 for (k=0;k<nfft/4;++k)
167 out[nfft-k-1] = out[nfft/2+k];
168 check_inv(in,out,nfft,isinverse);
169 } else {
170 clt_mdct_forward(cfg,in,out,window, nfft/2, shift, 1, arch);
171 check(in_copy,out,nfft,isinverse);
172 }
173 /*for (k=0;k<nfft;++k) printf("%d %d ", out[k].r, out[k].i);printf("\n");*/
174
175
176 free(in);
177 free(in_copy);
178 free(out);
179 free(window);
180#ifdef CUSTOM_MODES
181 clt_mdct_clear(&_cfg, arch);
182#endif
183}
184
185int main(int argc,char ** argv)
186{
187 ALLOC_STACK;
188 int arch = opus_select_arch();
189
190 if (argc>1) {
191 int k;
192 for (k=1;k<argc;++k) {
193 test1d(atoi(argv[k]),0,arch);
194 test1d(atoi(argv[k]),1,arch);
195 }
196 }else{
197 test1d(32,0,arch);
198 test1d(32,1,arch);
199 test1d(256,0,arch);
200 test1d(256,1,arch);
201 test1d(512,0,arch);
202 test1d(512,1,arch);
203 test1d(1024,0,arch);
204 test1d(1024,1,arch);
205 test1d(2048,0,arch);
206 test1d(2048,1,arch);
207#ifndef RADIX_TWO_ONLY
208 test1d(36,0,arch);
209 test1d(36,1,arch);
210 test1d(40,0,arch);
211 test1d(40,1,arch);
212 test1d(60,0,arch);
213 test1d(60,1,arch);
214 test1d(120,0,arch);
215 test1d(120,1,arch);
216 test1d(240,0,arch);
217 test1d(240,1,arch);
218 test1d(480,0,arch);
219 test1d(480,1,arch);
220 test1d(960,0,arch);
221 test1d(960,1,arch);
222 test1d(1920,0,arch);
223 test1d(1920,1,arch);
224#endif
225 }
226 return ret;
227}
diff --git a/lib/rbcodec/codecs/libopus/celt/tests/test_unit_rotation.c b/lib/rbcodec/codecs/libopus/celt/tests/test_unit_rotation.c
new file mode 100644
index 0000000000..8a31b3f2b1
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/tests/test_unit_rotation.c
@@ -0,0 +1,86 @@
1/* Copyright (c) 2008-2011 Xiph.Org Foundation
2 Written by Jean-Marc Valin */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#ifndef CUSTOM_MODES
33#define CUSTOM_MODES
34#endif
35
36#include <stdio.h>
37#include <stdlib.h>
38#include "vq.h"
39#include "bands.h"
40#include "stack_alloc.h"
41#include <math.h>
42
43
44#define MAX_SIZE 100
45
46int ret=0;
47void test_rotation(int N, int K)
48{
49 int i;
50 double err = 0, ener = 0, snr, snr0;
51 opus_val16 x0[MAX_SIZE];
52 opus_val16 x1[MAX_SIZE];
53 for (i=0;i<N;i++)
54 x1[i] = x0[i] = rand()%32767-16384;
55 exp_rotation(x1, N, 1, 1, K, SPREAD_NORMAL);
56 for (i=0;i<N;i++)
57 {
58 err += (x0[i]-(double)x1[i])*(x0[i]-(double)x1[i]);
59 ener += x0[i]*(double)x0[i];
60 }
61 snr0 = 20*log10(ener/err);
62 err = ener = 0;
63 exp_rotation(x1, N, -1, 1, K, SPREAD_NORMAL);
64 for (i=0;i<N;i++)
65 {
66 err += (x0[i]-(double)x1[i])*(x0[i]-(double)x1[i]);
67 ener += x0[i]*(double)x0[i];
68 }
69 snr = 20*log10(ener/err);
70 printf ("SNR for size %d (%d pulses) is %f (was %f without inverse)\n", N, K, snr, snr0);
71 if (snr < 60 || snr0 > 20)
72 {
73 fprintf(stderr, "FAIL!\n");
74 ret = 1;
75 }
76}
77
78int main(void)
79{
80 ALLOC_STACK;
81 test_rotation(15, 3);
82 test_rotation(23, 5);
83 test_rotation(50, 3);
84 test_rotation(80, 1);
85 return ret;
86}
diff --git a/lib/rbcodec/codecs/libopus/celt/tests/test_unit_types.c b/lib/rbcodec/codecs/libopus/celt/tests/test_unit_types.c
new file mode 100644
index 0000000000..67a0fb8ed3
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/tests/test_unit_types.c
@@ -0,0 +1,50 @@
1/* Copyright (c) 2008-2011 Xiph.Org Foundation
2 Written by Jean-Marc Valin */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "opus_types.h"
33#include <stdio.h>
34
35int main(void)
36{
37 opus_int16 i = 1;
38 i <<= 14;
39 if (i>>14 != 1)
40 {
41 fprintf(stderr, "opus_int16 isn't 16 bits\n");
42 return 1;
43 }
44 if (sizeof(opus_int16)*2 != sizeof(opus_int32))
45 {
46 fprintf(stderr, "16*2 != 32\n");
47 return 1;
48 }
49 return 0;
50}
diff --git a/lib/rbcodec/codecs/libopus/celt/vq.c b/lib/rbcodec/codecs/libopus/celt/vq.c
index b047b22774..a6b5552d69 100644
--- a/lib/rbcodec/codecs/libopus/celt/vq.c
+++ b/lib/rbcodec/codecs/libopus/celt/vq.c
@@ -39,10 +39,6 @@
39#include "rate.h" 39#include "rate.h"
40#include "pitch.h" 40#include "pitch.h"
41 41
42#if defined(MIPSr1_ASM)
43#include "mips/vq_mipsr1.h"
44#endif
45
46#ifndef OVERRIDE_vq_exp_rotation1 42#ifndef OVERRIDE_vq_exp_rotation1
47static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_val16 s) 43static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_val16 s)
48{ 44{
@@ -71,7 +67,7 @@ static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_
71} 67}
72#endif /* OVERRIDE_vq_exp_rotation1 */ 68#endif /* OVERRIDE_vq_exp_rotation1 */
73 69
74static void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread) 70void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread)
75{ 71{
76 static const int SPREAD_FACTOR[3]={15,10,5}; 72 static const int SPREAD_FACTOR[3]={15,10,5};
77 int i; 73 int i;
@@ -162,42 +158,27 @@ static unsigned extract_collapse_mask(int *iy, int N, int B)
162 return collapse_mask; 158 return collapse_mask;
163} 159}
164 160
165unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc 161opus_val16 op_pvq_search_c(celt_norm *X, int *iy, int K, int N, int arch)
166#ifdef RESYNTH
167 , opus_val16 gain
168#endif
169 )
170{ 162{
171 VARDECL(celt_norm, y); 163 VARDECL(celt_norm, y);
172 VARDECL(int, iy); 164 VARDECL(int, signx);
173 VARDECL(opus_val16, signx);
174 int i, j; 165 int i, j;
175 opus_val16 s;
176 int pulsesLeft; 166 int pulsesLeft;
177 opus_val32 sum; 167 opus_val32 sum;
178 opus_val32 xy; 168 opus_val32 xy;
179 opus_val16 yy; 169 opus_val16 yy;
180 unsigned collapse_mask;
181 SAVE_STACK; 170 SAVE_STACK;
182 171
183 celt_assert2(K>0, "alg_quant() needs at least one pulse"); 172 (void)arch;
184 celt_assert2(N>1, "alg_quant() needs at least two dimensions");
185
186 ALLOC(y, N, celt_norm); 173 ALLOC(y, N, celt_norm);
187 ALLOC(iy, N, int); 174 ALLOC(signx, N, int);
188 ALLOC(signx, N, opus_val16);
189
190 exp_rotation(X, N, 1, B, K, spread);
191 175
192 /* Get rid of the sign */ 176 /* Get rid of the sign */
193 sum = 0; 177 sum = 0;
194 j=0; do { 178 j=0; do {
195 if (X[j]>0) 179 signx[j] = X[j]<0;
196 signx[j]=1; 180 /* OPT: Make sure the compiler doesn't use a branch on ABS16(). */
197 else { 181 X[j] = ABS16(X[j]);
198 signx[j]=-1;
199 X[j]=-X[j];
200 }
201 iy[j] = 0; 182 iy[j] = 0;
202 y[j] = 0; 183 y[j] = 0;
203 } while (++j<N); 184 } while (++j<N);
@@ -229,7 +210,12 @@ unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc
229 while (++j<N); 210 while (++j<N);
230 sum = QCONST16(1.f,14); 211 sum = QCONST16(1.f,14);
231 } 212 }
232 rcp = EXTRACT16(MULT16_32_Q16(K-1, celt_rcp(sum))); 213#ifdef FIXED_POINT
214 rcp = EXTRACT16(MULT16_32_Q16(K, celt_rcp(sum)));
215#else
216 /* Using K+e with e < 1 guarantees we cannot get more than K pulses. */
217 rcp = EXTRACT16(MULT16_32_Q16(K+0.8f, celt_rcp(sum)));
218#endif
233 j=0; do { 219 j=0; do {
234#ifdef FIXED_POINT 220#ifdef FIXED_POINT
235 /* It's really important to round *towards zero* here */ 221 /* It's really important to round *towards zero* here */
@@ -244,12 +230,12 @@ unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc
244 pulsesLeft -= iy[j]; 230 pulsesLeft -= iy[j];
245 } while (++j<N); 231 } while (++j<N);
246 } 232 }
247 celt_assert2(pulsesLeft>=1, "Allocated too many pulses in the quick pass"); 233 celt_sig_assert(pulsesLeft>=0);
248 234
249 /* This should never happen, but just in case it does (e.g. on silence) 235 /* This should never happen, but just in case it does (e.g. on silence)
250 we fill the first bin with pulses. */ 236 we fill the first bin with pulses. */
251#ifdef FIXED_POINT_DEBUG 237#ifdef FIXED_POINT_DEBUG
252 celt_assert2(pulsesLeft<=N+3, "Not enough pulses in the quick pass"); 238 celt_sig_assert(pulsesLeft<=N+3);
253#endif 239#endif
254 if (pulsesLeft > N+3) 240 if (pulsesLeft > N+3)
255 { 241 {
@@ -260,12 +246,12 @@ unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc
260 pulsesLeft=0; 246 pulsesLeft=0;
261 } 247 }
262 248
263 s = 1;
264 for (i=0;i<pulsesLeft;i++) 249 for (i=0;i<pulsesLeft;i++)
265 { 250 {
251 opus_val16 Rxy, Ryy;
266 int best_id; 252 int best_id;
267 opus_val32 best_num = -VERY_LARGE16; 253 opus_val32 best_num;
268 opus_val16 best_den = 0; 254 opus_val16 best_den;
269#ifdef FIXED_POINT 255#ifdef FIXED_POINT
270 int rshift; 256 int rshift;
271#endif 257#endif
@@ -275,10 +261,23 @@ unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc
275 best_id = 0; 261 best_id = 0;
276 /* The squared magnitude term gets added anyway, so we might as well 262 /* The squared magnitude term gets added anyway, so we might as well
277 add it outside the loop */ 263 add it outside the loop */
278 yy = ADD32(yy, 1); 264 yy = ADD16(yy, 1);
279 j=0; 265
266 /* Calculations for position 0 are out of the loop, in part to reduce
267 mispredicted branches (since the if condition is usually false)
268 in the loop. */
269 /* Temporary sums of the new pulse(s) */
270 Rxy = EXTRACT16(SHR32(ADD32(xy, EXTEND32(X[0])),rshift));
271 /* We're multiplying y[j] by two so we don't have to do it here */
272 Ryy = ADD16(yy, y[0]);
273
274 /* Approximate score: we maximise Rxy/sqrt(Ryy) (we're guaranteed that
275 Rxy is positive because the sign is pre-computed) */
276 Rxy = MULT16_16_Q15(Rxy,Rxy);
277 best_den = Ryy;
278 best_num = Rxy;
279 j=1;
280 do { 280 do {
281 opus_val16 Rxy, Ryy;
282 /* Temporary sums of the new pulse(s) */ 281 /* Temporary sums of the new pulse(s) */
283 Rxy = EXTRACT16(SHR32(ADD32(xy, EXTEND32(X[j])),rshift)); 282 Rxy = EXTRACT16(SHR32(ADD32(xy, EXTEND32(X[j])),rshift));
284 /* We're multiplying y[j] by two so we don't have to do it here */ 283 /* We're multiplying y[j] by two so we don't have to do it here */
@@ -289,8 +288,11 @@ unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc
289 Rxy = MULT16_16_Q15(Rxy,Rxy); 288 Rxy = MULT16_16_Q15(Rxy,Rxy);
290 /* The idea is to check for num/den >= best_num/best_den, but that way 289 /* The idea is to check for num/den >= best_num/best_den, but that way
291 we can do it without any division */ 290 we can do it without any division */
292 /* OPT: Make sure to use conditional moves here */ 291 /* OPT: It's not clear whether a cmov is faster than a branch here
293 if (MULT16_16(best_den, Rxy) > MULT16_16(Ryy, best_num)) 292 since the condition is more often false than true and using
293 a cmov introduces data dependencies across iterations. The optimal
294 choice may be architecture-dependent. */
295 if (opus_unlikely(MULT16_16(best_den, Rxy) > MULT16_16(Ryy, best_num)))
294 { 296 {
295 best_den = Ryy; 297 best_den = Ryy;
296 best_num = Rxy; 298 best_num = Rxy;
@@ -305,23 +307,47 @@ unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc
305 307
306 /* Only now that we've made the final choice, update y/iy */ 308 /* Only now that we've made the final choice, update y/iy */
307 /* Multiplying y[j] by 2 so we don't have to do it everywhere else */ 309 /* Multiplying y[j] by 2 so we don't have to do it everywhere else */
308 y[best_id] += 2*s; 310 y[best_id] += 2;
309 iy[best_id]++; 311 iy[best_id]++;
310 } 312 }
311 313
312 /* Put the original sign back */ 314 /* Put the original sign back */
313 j=0; 315 j=0;
314 do { 316 do {
315 X[j] = MULT16_16(signx[j],X[j]); 317 /*iy[j] = signx[j] ? -iy[j] : iy[j];*/
316 if (signx[j] < 0) 318 /* OPT: The is more likely to be compiled without a branch than the code above
317 iy[j] = -iy[j]; 319 but has the same performance otherwise. */
320 iy[j] = (iy[j]^-signx[j]) + signx[j];
318 } while (++j<N); 321 } while (++j<N);
322 RESTORE_STACK;
323 return yy;
324}
325
326unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc,
327 opus_val16 gain, int resynth, int arch)
328{
329 VARDECL(int, iy);
330 opus_val16 yy;
331 unsigned collapse_mask;
332 SAVE_STACK;
333
334 celt_assert2(K>0, "alg_quant() needs at least one pulse");
335 celt_assert2(N>1, "alg_quant() needs at least two dimensions");
336
337 /* Covers vectorization by up to 4. */
338 ALLOC(iy, N+3, int);
339
340 exp_rotation(X, N, 1, B, K, spread);
341
342 yy = op_pvq_search(X, iy, K, N, arch);
343
319 encode_pulses(iy, N, K, enc); 344 encode_pulses(iy, N, K, enc);
320 345
321#ifdef RESYNTH 346 if (resynth)
322 normalise_residual(iy, X, N, yy, gain); 347 {
323 exp_rotation(X, N, -1, B, K, spread); 348 normalise_residual(iy, X, N, yy, gain);
324#endif 349 exp_rotation(X, N, -1, B, K, spread);
350 }
325 351
326 collapse_mask = extract_collapse_mask(iy, N, B); 352 collapse_mask = extract_collapse_mask(iy, N, B);
327 RESTORE_STACK; 353 RESTORE_STACK;
@@ -350,7 +376,7 @@ unsigned alg_unquant(celt_norm *X, int N, int K, int spread, int B,
350} 376}
351 377
352#ifndef OVERRIDE_renormalise_vector 378#ifndef OVERRIDE_renormalise_vector
353void renormalise_vector(celt_norm *X, int N, opus_val16 gain) 379void renormalise_vector(celt_norm *X, int N, opus_val16 gain, int arch)
354{ 380{
355 int i; 381 int i;
356#ifdef FIXED_POINT 382#ifdef FIXED_POINT
@@ -360,7 +386,7 @@ void renormalise_vector(celt_norm *X, int N, opus_val16 gain)
360 opus_val16 g; 386 opus_val16 g;
361 opus_val32 t; 387 opus_val32 t;
362 celt_norm *xptr; 388 celt_norm *xptr;
363 E = EPSILON + celt_inner_prod(X, X, N); 389 E = EPSILON + celt_inner_prod(X, X, N, arch);
364#ifdef FIXED_POINT 390#ifdef FIXED_POINT
365 k = celt_ilog2(E)>>1; 391 k = celt_ilog2(E)>>1;
366#endif 392#endif
@@ -377,7 +403,7 @@ void renormalise_vector(celt_norm *X, int N, opus_val16 gain)
377} 403}
378#endif /* OVERRIDE_renormalise_vector */ 404#endif /* OVERRIDE_renormalise_vector */
379 405
380int stereo_itheta(const celt_norm *X, const celt_norm *Y, int stereo, int N) 406int stereo_itheta(const celt_norm *X, const celt_norm *Y, int stereo, int N, int arch)
381{ 407{
382 int i; 408 int i;
383 int itheta; 409 int itheta;
@@ -396,8 +422,8 @@ int stereo_itheta(const celt_norm *X, const celt_norm *Y, int stereo, int N)
396 Eside = MAC16_16(Eside, s, s); 422 Eside = MAC16_16(Eside, s, s);
397 } 423 }
398 } else { 424 } else {
399 Emid += celt_inner_prod(X, X, N); 425 Emid += celt_inner_prod(X, X, N, arch);
400 Eside += celt_inner_prod(Y, Y, N); 426 Eside += celt_inner_prod(Y, Y, N, arch);
401 } 427 }
402 mid = celt_sqrt(Emid); 428 mid = celt_sqrt(Emid);
403 side = celt_sqrt(Eside); 429 side = celt_sqrt(Eside);
@@ -405,7 +431,7 @@ int stereo_itheta(const celt_norm *X, const celt_norm *Y, int stereo, int N)
405 /* 0.63662 = 2/pi */ 431 /* 0.63662 = 2/pi */
406 itheta = MULT16_16_Q15(QCONST16(0.63662f,15),celt_atan2p(side, mid)); 432 itheta = MULT16_16_Q15(QCONST16(0.63662f,15),celt_atan2p(side, mid));
407#else 433#else
408 itheta = (int)floor(.5f+16384*0.63662f*atan2(side,mid)); 434 itheta = (int)floor(.5f+16384*0.63662f*fast_atan2f(side,mid));
409#endif 435#endif
410 436
411 return itheta; 437 return itheta;
diff --git a/lib/rbcodec/codecs/libopus/celt/vq.h b/lib/rbcodec/codecs/libopus/celt/vq.h
index 84115cbcbb..0dfe6af058 100644
--- a/lib/rbcodec/codecs/libopus/celt/vq.h
+++ b/lib/rbcodec/codecs/libopus/celt/vq.h
@@ -37,6 +37,23 @@
37#include "entdec.h" 37#include "entdec.h"
38#include "modes.h" 38#include "modes.h"
39 39
40#if (defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(FIXED_POINT))
41#include "x86/vq_sse.h"
42#endif
43
44#if defined(MIPSr1_ASM)
45#include "mips/vq_mipsr1.h"
46#endif
47
48void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread);
49
50opus_val16 op_pvq_search_c(celt_norm *X, int *iy, int K, int N, int arch);
51
52#if !defined(OVERRIDE_OP_PVQ_SEARCH)
53#define op_pvq_search(x, iy, K, N, arch) \
54 (op_pvq_search_c(x, iy, K, N, arch))
55#endif
56
40/** Algebraic pulse-vector quantiser. The signal x is replaced by the sum of 57/** Algebraic pulse-vector quantiser. The signal x is replaced by the sum of
41 * the pitch and a combination of pulses such that its norm is still equal 58 * the pitch and a combination of pulses such that its norm is still equal
42 * to 1. This is the function that will typically require the most CPU. 59 * to 1. This is the function that will typically require the most CPU.
@@ -46,12 +63,8 @@
46 * @param enc Entropy encoder state 63 * @param enc Entropy encoder state
47 * @ret A mask indicating which blocks in the band received pulses 64 * @ret A mask indicating which blocks in the band received pulses
48*/ 65*/
49unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, 66unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc,
50 ec_enc *enc 67 opus_val16 gain, int resynth, int arch);
51#ifdef RESYNTH
52 , opus_val16 gain
53#endif
54 );
55 68
56/** Algebraic pulse decoder 69/** Algebraic pulse decoder
57 * @param X Decoded normalised spectrum (returned) 70 * @param X Decoded normalised spectrum (returned)
@@ -63,8 +76,8 @@ unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B,
63unsigned alg_unquant(celt_norm *X, int N, int K, int spread, int B, 76unsigned alg_unquant(celt_norm *X, int N, int K, int spread, int B,
64 ec_dec *dec, opus_val16 gain); 77 ec_dec *dec, opus_val16 gain);
65 78
66void renormalise_vector(celt_norm *X, int N, opus_val16 gain); 79void renormalise_vector(celt_norm *X, int N, opus_val16 gain, int arch);
67 80
68int stereo_itheta(const celt_norm *X, const celt_norm *Y, int stereo, int N); 81int stereo_itheta(const celt_norm *X, const celt_norm *Y, int stereo, int N, int arch);
69 82
70#endif /* VQ_H */ 83#endif /* VQ_H */
diff --git a/lib/rbcodec/codecs/libopus/celt/x86/celt_lpc_sse.h b/lib/rbcodec/codecs/libopus/celt/x86/celt_lpc_sse.h
new file mode 100644
index 0000000000..7d1ecf7533
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/x86/celt_lpc_sse.h
@@ -0,0 +1,66 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifndef CELT_LPC_SSE_H
29#define CELT_LPC_SSE_H
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35#if defined(OPUS_X86_MAY_HAVE_SSE4_1) && defined(FIXED_POINT)
36#define OVERRIDE_CELT_FIR
37
38void celt_fir_sse4_1(
39 const opus_val16 *x,
40 const opus_val16 *num,
41 opus_val16 *y,
42 int N,
43 int ord,
44 int arch);
45
46#if defined(OPUS_X86_PRESUME_SSE4_1)
47#define celt_fir(x, num, y, N, ord, arch) \
48 ((void)arch, celt_fir_sse4_1(x, num, y, N, ord, arch))
49
50#else
51
52extern void (*const CELT_FIR_IMPL[OPUS_ARCHMASK + 1])(
53 const opus_val16 *x,
54 const opus_val16 *num,
55 opus_val16 *y,
56 int N,
57 int ord,
58 int arch);
59
60# define celt_fir(x, num, y, N, ord, arch) \
61 ((*CELT_FIR_IMPL[(arch) & OPUS_ARCHMASK])(x, num, y, N, ord, arch))
62
63#endif
64#endif
65
66#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/x86/celt_lpc_sse4_1.c b/lib/rbcodec/codecs/libopus/celt/x86/celt_lpc_sse4_1.c
new file mode 100644
index 0000000000..5478568849
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/x86/celt_lpc_sse4_1.c
@@ -0,0 +1,89 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <xmmintrin.h>
33#include <emmintrin.h>
34#include <smmintrin.h>
35#include "celt_lpc.h"
36#include "stack_alloc.h"
37#include "mathops.h"
38#include "pitch.h"
39#include "x86cpu.h"
40
41#if defined(FIXED_POINT)
42
43void celt_fir_sse4_1(const opus_val16 *x,
44 const opus_val16 *num,
45 opus_val16 *y,
46 int N,
47 int ord,
48 int arch)
49{
50 int i,j;
51 VARDECL(opus_val16, rnum);
52
53 __m128i vecNoA;
54 opus_int32 noA ;
55 SAVE_STACK;
56
57 ALLOC(rnum, ord, opus_val16);
58 for(i=0;i<ord;i++)
59 rnum[i] = num[ord-i-1];
60 noA = EXTEND32(1) << SIG_SHIFT >> 1;
61 vecNoA = _mm_set_epi32(noA, noA, noA, noA);
62
63 for (i=0;i<N-3;i+=4)
64 {
65 opus_val32 sums[4] = {0};
66 __m128i vecSum, vecX;
67
68 xcorr_kernel(rnum, x+i-ord, sums, ord, arch);
69
70 vecSum = _mm_loadu_si128((__m128i *)sums);
71 vecSum = _mm_add_epi32(vecSum, vecNoA);
72 vecSum = _mm_srai_epi32(vecSum, SIG_SHIFT);
73 vecX = OP_CVTEPI16_EPI32_M64(x + i);
74 vecSum = _mm_add_epi32(vecSum, vecX);
75 vecSum = _mm_packs_epi32(vecSum, vecSum);
76 _mm_storel_epi64((__m128i *)(y + i), vecSum);
77 }
78 for (;i<N;i++)
79 {
80 opus_val32 sum = 0;
81 for (j=0;j<ord;j++)
82 sum = MAC16_16(sum, rnum[j], x[i+j-ord]);
83 y[i] = SATURATE16(ADD32(EXTEND32(x[i]), PSHR32(sum, SIG_SHIFT)));
84 }
85
86 RESTORE_STACK;
87}
88
89#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/x86/pitch_sse.c b/lib/rbcodec/codecs/libopus/celt/x86/pitch_sse.c
new file mode 100644
index 0000000000..20e73126b6
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/x86/pitch_sse.c
@@ -0,0 +1,185 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "macros.h"
33#include "celt_lpc.h"
34#include "stack_alloc.h"
35#include "mathops.h"
36#include "pitch.h"
37
38#if defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT)
39
40#include <xmmintrin.h>
41#include "arch.h"
42
43void xcorr_kernel_sse(const opus_val16 *x, const opus_val16 *y, opus_val32 sum[4], int len)
44{
45 int j;
46 __m128 xsum1, xsum2;
47 xsum1 = _mm_loadu_ps(sum);
48 xsum2 = _mm_setzero_ps();
49
50 for (j = 0; j < len-3; j += 4)
51 {
52 __m128 x0 = _mm_loadu_ps(x+j);
53 __m128 yj = _mm_loadu_ps(y+j);
54 __m128 y3 = _mm_loadu_ps(y+j+3);
55
56 xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0x00),yj));
57 xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0x55),
58 _mm_shuffle_ps(yj,y3,0x49)));
59 xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0xaa),
60 _mm_shuffle_ps(yj,y3,0x9e)));
61 xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0xff),y3));
62 }
63 if (j < len)
64 {
65 xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_load1_ps(x+j),_mm_loadu_ps(y+j)));
66 if (++j < len)
67 {
68 xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(_mm_load1_ps(x+j),_mm_loadu_ps(y+j)));
69 if (++j < len)
70 {
71 xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_load1_ps(x+j),_mm_loadu_ps(y+j)));
72 }
73 }
74 }
75 _mm_storeu_ps(sum,_mm_add_ps(xsum1,xsum2));
76}
77
78
79void dual_inner_prod_sse(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
80 int N, opus_val32 *xy1, opus_val32 *xy2)
81{
82 int i;
83 __m128 xsum1, xsum2;
84 xsum1 = _mm_setzero_ps();
85 xsum2 = _mm_setzero_ps();
86 for (i=0;i<N-3;i+=4)
87 {
88 __m128 xi = _mm_loadu_ps(x+i);
89 __m128 y1i = _mm_loadu_ps(y01+i);
90 __m128 y2i = _mm_loadu_ps(y02+i);
91 xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(xi, y1i));
92 xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(xi, y2i));
93 }
94 /* Horizontal sum */
95 xsum1 = _mm_add_ps(xsum1, _mm_movehl_ps(xsum1, xsum1));
96 xsum1 = _mm_add_ss(xsum1, _mm_shuffle_ps(xsum1, xsum1, 0x55));
97 _mm_store_ss(xy1, xsum1);
98 xsum2 = _mm_add_ps(xsum2, _mm_movehl_ps(xsum2, xsum2));
99 xsum2 = _mm_add_ss(xsum2, _mm_shuffle_ps(xsum2, xsum2, 0x55));
100 _mm_store_ss(xy2, xsum2);
101 for (;i<N;i++)
102 {
103 *xy1 = MAC16_16(*xy1, x[i], y01[i]);
104 *xy2 = MAC16_16(*xy2, x[i], y02[i]);
105 }
106}
107
108opus_val32 celt_inner_prod_sse(const opus_val16 *x, const opus_val16 *y,
109 int N)
110{
111 int i;
112 float xy;
113 __m128 sum;
114 sum = _mm_setzero_ps();
115 /* FIXME: We should probably go 8-way and use 2 sums. */
116 for (i=0;i<N-3;i+=4)
117 {
118 __m128 xi = _mm_loadu_ps(x+i);
119 __m128 yi = _mm_loadu_ps(y+i);
120 sum = _mm_add_ps(sum,_mm_mul_ps(xi, yi));
121 }
122 /* Horizontal sum */
123 sum = _mm_add_ps(sum, _mm_movehl_ps(sum, sum));
124 sum = _mm_add_ss(sum, _mm_shuffle_ps(sum, sum, 0x55));
125 _mm_store_ss(&xy, sum);
126 for (;i<N;i++)
127 {
128 xy = MAC16_16(xy, x[i], y[i]);
129 }
130 return xy;
131}
132
133void comb_filter_const_sse(opus_val32 *y, opus_val32 *x, int T, int N,
134 opus_val16 g10, opus_val16 g11, opus_val16 g12)
135{
136 int i;
137 __m128 x0v;
138 __m128 g10v, g11v, g12v;
139 g10v = _mm_load1_ps(&g10);
140 g11v = _mm_load1_ps(&g11);
141 g12v = _mm_load1_ps(&g12);
142 x0v = _mm_loadu_ps(&x[-T-2]);
143 for (i=0;i<N-3;i+=4)
144 {
145 __m128 yi, yi2, x1v, x2v, x3v, x4v;
146 const opus_val32 *xp = &x[i-T-2];
147 yi = _mm_loadu_ps(x+i);
148 x4v = _mm_loadu_ps(xp+4);
149#if 0
150 /* Slower version with all loads */
151 x1v = _mm_loadu_ps(xp+1);
152 x2v = _mm_loadu_ps(xp+2);
153 x3v = _mm_loadu_ps(xp+3);
154#else
155 x2v = _mm_shuffle_ps(x0v, x4v, 0x4e);
156 x1v = _mm_shuffle_ps(x0v, x2v, 0x99);
157 x3v = _mm_shuffle_ps(x2v, x4v, 0x99);
158#endif
159
160 yi = _mm_add_ps(yi, _mm_mul_ps(g10v,x2v));
161#if 0 /* Set to 1 to make it bit-exact with the non-SSE version */
162 yi = _mm_add_ps(yi, _mm_mul_ps(g11v,_mm_add_ps(x3v,x1v)));
163 yi = _mm_add_ps(yi, _mm_mul_ps(g12v,_mm_add_ps(x4v,x0v)));
164#else
165 /* Use partial sums */
166 yi2 = _mm_add_ps(_mm_mul_ps(g11v,_mm_add_ps(x3v,x1v)),
167 _mm_mul_ps(g12v,_mm_add_ps(x4v,x0v)));
168 yi = _mm_add_ps(yi, yi2);
169#endif
170 x0v=x4v;
171 _mm_storeu_ps(y+i, yi);
172 }
173#ifdef CUSTOM_MODES
174 for (;i<N;i++)
175 {
176 y[i] = x[i]
177 + MULT16_32_Q15(g10,x[i-T])
178 + MULT16_32_Q15(g11,ADD32(x[i-T+1],x[i-T-1]))
179 + MULT16_32_Q15(g12,ADD32(x[i-T+2],x[i-T-2]));
180 }
181#endif
182}
183
184
185#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/x86/pitch_sse.h b/lib/rbcodec/codecs/libopus/celt/x86/pitch_sse.h
new file mode 100644
index 0000000000..e5f87ab51a
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/x86/pitch_sse.h
@@ -0,0 +1,192 @@
1/* Copyright (c) 2013 Jean-Marc Valin and John Ridges
2 Copyright (c) 2014, Cisco Systems, INC MingXiang WeiZhou MinPeng YanWang*/
3/**
4 @file pitch_sse.h
5 @brief Pitch analysis
6 */
7
8/*
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions
11 are met:
12
13 - Redistributions of source code must retain the above copyright
14 notice, this list of conditions and the following disclaimer.
15
16 - Redistributions in binary form must reproduce the above copyright
17 notice, this list of conditions and the following disclaimer in the
18 documentation and/or other materials provided with the distribution.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
24 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#ifndef PITCH_SSE_H
34#define PITCH_SSE_H
35
36#if defined(HAVE_CONFIG_H)
37#include "config.h"
38#endif
39
40#if defined(OPUS_X86_MAY_HAVE_SSE4_1) && defined(FIXED_POINT)
41void xcorr_kernel_sse4_1(
42 const opus_int16 *x,
43 const opus_int16 *y,
44 opus_val32 sum[4],
45 int len);
46#endif
47
48#if defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT)
49void xcorr_kernel_sse(
50 const opus_val16 *x,
51 const opus_val16 *y,
52 opus_val32 sum[4],
53 int len);
54#endif
55
56#if defined(OPUS_X86_PRESUME_SSE4_1) && defined(FIXED_POINT)
57#define OVERRIDE_XCORR_KERNEL
58#define xcorr_kernel(x, y, sum, len, arch) \
59 ((void)arch, xcorr_kernel_sse4_1(x, y, sum, len))
60
61#elif defined(OPUS_X86_PRESUME_SSE) && !defined(FIXED_POINT)
62#define OVERRIDE_XCORR_KERNEL
63#define xcorr_kernel(x, y, sum, len, arch) \
64 ((void)arch, xcorr_kernel_sse(x, y, sum, len))
65
66#elif (defined(OPUS_X86_MAY_HAVE_SSE4_1) && defined(FIXED_POINT)) || (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT))
67
68extern void (*const XCORR_KERNEL_IMPL[OPUS_ARCHMASK + 1])(
69 const opus_val16 *x,
70 const opus_val16 *y,
71 opus_val32 sum[4],
72 int len);
73
74#define OVERRIDE_XCORR_KERNEL
75#define xcorr_kernel(x, y, sum, len, arch) \
76 ((*XCORR_KERNEL_IMPL[(arch) & OPUS_ARCHMASK])(x, y, sum, len))
77
78#endif
79
80#if defined(OPUS_X86_MAY_HAVE_SSE4_1) && defined(FIXED_POINT)
81opus_val32 celt_inner_prod_sse4_1(
82 const opus_int16 *x,
83 const opus_int16 *y,
84 int N);
85#endif
86
87#if defined(OPUS_X86_MAY_HAVE_SSE2) && defined(FIXED_POINT)
88opus_val32 celt_inner_prod_sse2(
89 const opus_int16 *x,
90 const opus_int16 *y,
91 int N);
92#endif
93
94#if defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(FIXED_POINT)
95opus_val32 celt_inner_prod_sse(
96 const opus_val16 *x,
97 const opus_val16 *y,
98 int N);
99#endif
100
101
102#if defined(OPUS_X86_PRESUME_SSE4_1) && defined(FIXED_POINT)
103#define OVERRIDE_CELT_INNER_PROD
104#define celt_inner_prod(x, y, N, arch) \
105 ((void)arch, celt_inner_prod_sse4_1(x, y, N))
106
107#elif defined(OPUS_X86_PRESUME_SSE2) && defined(FIXED_POINT) && !defined(OPUS_X86_MAY_HAVE_SSE4_1)
108#define OVERRIDE_CELT_INNER_PROD
109#define celt_inner_prod(x, y, N, arch) \
110 ((void)arch, celt_inner_prod_sse2(x, y, N))
111
112#elif defined(OPUS_X86_PRESUME_SSE) && !defined(FIXED_POINT)
113#define OVERRIDE_CELT_INNER_PROD
114#define celt_inner_prod(x, y, N, arch) \
115 ((void)arch, celt_inner_prod_sse(x, y, N))
116
117
118#elif ((defined(OPUS_X86_MAY_HAVE_SSE4_1) || defined(OPUS_X86_MAY_HAVE_SSE2)) && defined(FIXED_POINT)) || \
119 (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT))
120
121extern opus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK + 1])(
122 const opus_val16 *x,
123 const opus_val16 *y,
124 int N);
125
126#define OVERRIDE_CELT_INNER_PROD
127#define celt_inner_prod(x, y, N, arch) \
128 ((*CELT_INNER_PROD_IMPL[(arch) & OPUS_ARCHMASK])(x, y, N))
129
130#endif
131
132#if defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT)
133
134#define OVERRIDE_DUAL_INNER_PROD
135#define OVERRIDE_COMB_FILTER_CONST
136
137#undef dual_inner_prod
138#undef comb_filter_const
139
140void dual_inner_prod_sse(const opus_val16 *x,
141 const opus_val16 *y01,
142 const opus_val16 *y02,
143 int N,
144 opus_val32 *xy1,
145 opus_val32 *xy2);
146
147void comb_filter_const_sse(opus_val32 *y,
148 opus_val32 *x,
149 int T,
150 int N,
151 opus_val16 g10,
152 opus_val16 g11,
153 opus_val16 g12);
154
155
156#if defined(OPUS_X86_PRESUME_SSE)
157# define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) \
158 ((void)(arch),dual_inner_prod_sse(x, y01, y02, N, xy1, xy2))
159
160# define comb_filter_const(y, x, T, N, g10, g11, g12, arch) \
161 ((void)(arch),comb_filter_const_sse(y, x, T, N, g10, g11, g12))
162#else
163
164extern void (*const DUAL_INNER_PROD_IMPL[OPUS_ARCHMASK + 1])(
165 const opus_val16 *x,
166 const opus_val16 *y01,
167 const opus_val16 *y02,
168 int N,
169 opus_val32 *xy1,
170 opus_val32 *xy2);
171
172#define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) \
173 ((*DUAL_INNER_PROD_IMPL[(arch) & OPUS_ARCHMASK])(x, y01, y02, N, xy1, xy2))
174
175extern void (*const COMB_FILTER_CONST_IMPL[OPUS_ARCHMASK + 1])(
176 opus_val32 *y,
177 opus_val32 *x,
178 int T,
179 int N,
180 opus_val16 g10,
181 opus_val16 g11,
182 opus_val16 g12);
183
184#define comb_filter_const(y, x, T, N, g10, g11, g12, arch) \
185 ((*COMB_FILTER_CONST_IMPL[(arch) & OPUS_ARCHMASK])(y, x, T, N, g10, g11, g12))
186
187#define NON_STATIC_COMB_FILTER_CONST_C
188
189#endif
190#endif
191
192#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/x86/pitch_sse2.c b/lib/rbcodec/codecs/libopus/celt/x86/pitch_sse2.c
new file mode 100644
index 0000000000..a0e7d1beaf
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/x86/pitch_sse2.c
@@ -0,0 +1,95 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <xmmintrin.h>
33#include <emmintrin.h>
34
35#include "macros.h"
36#include "celt_lpc.h"
37#include "stack_alloc.h"
38#include "mathops.h"
39#include "pitch.h"
40
41#if defined(OPUS_X86_MAY_HAVE_SSE2) && defined(FIXED_POINT)
42opus_val32 celt_inner_prod_sse2(const opus_val16 *x, const opus_val16 *y,
43 int N)
44{
45 opus_int i, dataSize16;
46 opus_int32 sum;
47
48 __m128i inVec1_76543210, inVec1_FEDCBA98, acc1;
49 __m128i inVec2_76543210, inVec2_FEDCBA98, acc2;
50
51 sum = 0;
52 dataSize16 = N & ~15;
53
54 acc1 = _mm_setzero_si128();
55 acc2 = _mm_setzero_si128();
56
57 for (i=0;i<dataSize16;i+=16)
58 {
59 inVec1_76543210 = _mm_loadu_si128((__m128i *)(&x[i + 0]));
60 inVec2_76543210 = _mm_loadu_si128((__m128i *)(&y[i + 0]));
61
62 inVec1_FEDCBA98 = _mm_loadu_si128((__m128i *)(&x[i + 8]));
63 inVec2_FEDCBA98 = _mm_loadu_si128((__m128i *)(&y[i + 8]));
64
65 inVec1_76543210 = _mm_madd_epi16(inVec1_76543210, inVec2_76543210);
66 inVec1_FEDCBA98 = _mm_madd_epi16(inVec1_FEDCBA98, inVec2_FEDCBA98);
67
68 acc1 = _mm_add_epi32(acc1, inVec1_76543210);
69 acc2 = _mm_add_epi32(acc2, inVec1_FEDCBA98);
70 }
71
72 acc1 = _mm_add_epi32( acc1, acc2 );
73
74 if (N - i >= 8)
75 {
76 inVec1_76543210 = _mm_loadu_si128((__m128i *)(&x[i + 0]));
77 inVec2_76543210 = _mm_loadu_si128((__m128i *)(&y[i + 0]));
78
79 inVec1_76543210 = _mm_madd_epi16(inVec1_76543210, inVec2_76543210);
80
81 acc1 = _mm_add_epi32(acc1, inVec1_76543210);
82 i += 8;
83 }
84
85 acc1 = _mm_add_epi32(acc1, _mm_unpackhi_epi64( acc1, acc1));
86 acc1 = _mm_add_epi32(acc1, _mm_shufflelo_epi16( acc1, 0x0E));
87 sum += _mm_cvtsi128_si32(acc1);
88
89 for (;i<N;i++) {
90 sum = silk_SMLABB(sum, x[i], y[i]);
91 }
92
93 return sum;
94}
95#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/x86/pitch_sse4_1.c b/lib/rbcodec/codecs/libopus/celt/x86/pitch_sse4_1.c
new file mode 100644
index 0000000000..a092c68b24
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/x86/pitch_sse4_1.c
@@ -0,0 +1,195 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <xmmintrin.h>
33#include <emmintrin.h>
34
35#include "macros.h"
36#include "celt_lpc.h"
37#include "stack_alloc.h"
38#include "mathops.h"
39#include "pitch.h"
40
41#if defined(OPUS_X86_MAY_HAVE_SSE4_1) && defined(FIXED_POINT)
42#include <smmintrin.h>
43#include "x86cpu.h"
44
45opus_val32 celt_inner_prod_sse4_1(const opus_val16 *x, const opus_val16 *y,
46 int N)
47{
48 opus_int i, dataSize16;
49 opus_int32 sum;
50 __m128i inVec1_76543210, inVec1_FEDCBA98, acc1;
51 __m128i inVec2_76543210, inVec2_FEDCBA98, acc2;
52 __m128i inVec1_3210, inVec2_3210;
53
54 sum = 0;
55 dataSize16 = N & ~15;
56
57 acc1 = _mm_setzero_si128();
58 acc2 = _mm_setzero_si128();
59
60 for (i=0;i<dataSize16;i+=16) {
61 inVec1_76543210 = _mm_loadu_si128((__m128i *)(&x[i + 0]));
62 inVec2_76543210 = _mm_loadu_si128((__m128i *)(&y[i + 0]));
63
64 inVec1_FEDCBA98 = _mm_loadu_si128((__m128i *)(&x[i + 8]));
65 inVec2_FEDCBA98 = _mm_loadu_si128((__m128i *)(&y[i + 8]));
66
67 inVec1_76543210 = _mm_madd_epi16(inVec1_76543210, inVec2_76543210);
68 inVec1_FEDCBA98 = _mm_madd_epi16(inVec1_FEDCBA98, inVec2_FEDCBA98);
69
70 acc1 = _mm_add_epi32(acc1, inVec1_76543210);
71 acc2 = _mm_add_epi32(acc2, inVec1_FEDCBA98);
72 }
73
74 acc1 = _mm_add_epi32(acc1, acc2);
75
76 if (N - i >= 8)
77 {
78 inVec1_76543210 = _mm_loadu_si128((__m128i *)(&x[i + 0]));
79 inVec2_76543210 = _mm_loadu_si128((__m128i *)(&y[i + 0]));
80
81 inVec1_76543210 = _mm_madd_epi16(inVec1_76543210, inVec2_76543210);
82
83 acc1 = _mm_add_epi32(acc1, inVec1_76543210);
84 i += 8;
85 }
86
87 if (N - i >= 4)
88 {
89 inVec1_3210 = OP_CVTEPI16_EPI32_M64(&x[i + 0]);
90 inVec2_3210 = OP_CVTEPI16_EPI32_M64(&y[i + 0]);
91
92 inVec1_3210 = _mm_mullo_epi32(inVec1_3210, inVec2_3210);
93
94 acc1 = _mm_add_epi32(acc1, inVec1_3210);
95 i += 4;
96 }
97
98 acc1 = _mm_add_epi32(acc1, _mm_unpackhi_epi64(acc1, acc1));
99 acc1 = _mm_add_epi32(acc1, _mm_shufflelo_epi16(acc1, 0x0E));
100
101 sum += _mm_cvtsi128_si32(acc1);
102
103 for (;i<N;i++)
104 {
105 sum = silk_SMLABB(sum, x[i], y[i]);
106 }
107
108 return sum;
109}
110
111void xcorr_kernel_sse4_1(const opus_val16 * x, const opus_val16 * y, opus_val32 sum[ 4 ], int len)
112{
113 int j;
114
115 __m128i vecX, vecX0, vecX1, vecX2, vecX3;
116 __m128i vecY0, vecY1, vecY2, vecY3;
117 __m128i sum0, sum1, sum2, sum3, vecSum;
118 __m128i initSum;
119
120 celt_assert(len >= 3);
121
122 sum0 = _mm_setzero_si128();
123 sum1 = _mm_setzero_si128();
124 sum2 = _mm_setzero_si128();
125 sum3 = _mm_setzero_si128();
126
127 for (j=0;j<(len-7);j+=8)
128 {
129 vecX = _mm_loadu_si128((__m128i *)(&x[j + 0]));
130 vecY0 = _mm_loadu_si128((__m128i *)(&y[j + 0]));
131 vecY1 = _mm_loadu_si128((__m128i *)(&y[j + 1]));
132 vecY2 = _mm_loadu_si128((__m128i *)(&y[j + 2]));
133 vecY3 = _mm_loadu_si128((__m128i *)(&y[j + 3]));
134
135 sum0 = _mm_add_epi32(sum0, _mm_madd_epi16(vecX, vecY0));
136 sum1 = _mm_add_epi32(sum1, _mm_madd_epi16(vecX, vecY1));
137 sum2 = _mm_add_epi32(sum2, _mm_madd_epi16(vecX, vecY2));
138 sum3 = _mm_add_epi32(sum3, _mm_madd_epi16(vecX, vecY3));
139 }
140
141 sum0 = _mm_add_epi32(sum0, _mm_unpackhi_epi64( sum0, sum0));
142 sum0 = _mm_add_epi32(sum0, _mm_shufflelo_epi16( sum0, 0x0E));
143
144 sum1 = _mm_add_epi32(sum1, _mm_unpackhi_epi64( sum1, sum1));
145 sum1 = _mm_add_epi32(sum1, _mm_shufflelo_epi16( sum1, 0x0E));
146
147 sum2 = _mm_add_epi32(sum2, _mm_unpackhi_epi64( sum2, sum2));
148 sum2 = _mm_add_epi32(sum2, _mm_shufflelo_epi16( sum2, 0x0E));
149
150 sum3 = _mm_add_epi32(sum3, _mm_unpackhi_epi64( sum3, sum3));
151 sum3 = _mm_add_epi32(sum3, _mm_shufflelo_epi16( sum3, 0x0E));
152
153 vecSum = _mm_unpacklo_epi64(_mm_unpacklo_epi32(sum0, sum1),
154 _mm_unpacklo_epi32(sum2, sum3));
155
156 for (;j<(len-3);j+=4)
157 {
158 vecX = OP_CVTEPI16_EPI32_M64(&x[j + 0]);
159 vecX0 = _mm_shuffle_epi32(vecX, 0x00);
160 vecX1 = _mm_shuffle_epi32(vecX, 0x55);
161 vecX2 = _mm_shuffle_epi32(vecX, 0xaa);
162 vecX3 = _mm_shuffle_epi32(vecX, 0xff);
163
164 vecY0 = OP_CVTEPI16_EPI32_M64(&y[j + 0]);
165 vecY1 = OP_CVTEPI16_EPI32_M64(&y[j + 1]);
166 vecY2 = OP_CVTEPI16_EPI32_M64(&y[j + 2]);
167 vecY3 = OP_CVTEPI16_EPI32_M64(&y[j + 3]);
168
169 sum0 = _mm_mullo_epi32(vecX0, vecY0);
170 sum1 = _mm_mullo_epi32(vecX1, vecY1);
171 sum2 = _mm_mullo_epi32(vecX2, vecY2);
172 sum3 = _mm_mullo_epi32(vecX3, vecY3);
173
174 sum0 = _mm_add_epi32(sum0, sum1);
175 sum2 = _mm_add_epi32(sum2, sum3);
176 vecSum = _mm_add_epi32(vecSum, sum0);
177 vecSum = _mm_add_epi32(vecSum, sum2);
178 }
179
180 for (;j<len;j++)
181 {
182 vecX = OP_CVTEPI16_EPI32_M64(&x[j + 0]);
183 vecX0 = _mm_shuffle_epi32(vecX, 0x00);
184
185 vecY0 = OP_CVTEPI16_EPI32_M64(&y[j + 0]);
186
187 sum0 = _mm_mullo_epi32(vecX0, vecY0);
188 vecSum = _mm_add_epi32(vecSum, sum0);
189 }
190
191 initSum = _mm_loadu_si128((__m128i *)(&sum[0]));
192 initSum = _mm_add_epi32(initSum, vecSum);
193 _mm_storeu_si128((__m128i *)sum, initSum);
194}
195#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/x86/vq_sse.h b/lib/rbcodec/codecs/libopus/celt/x86/vq_sse.h
new file mode 100644
index 0000000000..b4efe8f249
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/x86/vq_sse.h
@@ -0,0 +1,50 @@
1/* Copyright (c) 2016 Jean-Marc Valin */
2/*
3 Redistribution and use in source and binary forms, with or without
4 modification, are permitted provided that the following conditions
5 are met:
6
7 - Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9
10 - Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
18 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*/
26
27#ifndef VQ_SSE_H
28#define VQ_SSE_H
29
30#if defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(FIXED_POINT)
31#define OVERRIDE_OP_PVQ_SEARCH
32
33opus_val16 op_pvq_search_sse2(celt_norm *_X, int *iy, int K, int N, int arch);
34
35#if defined(OPUS_X86_PRESUME_SSE2)
36#define op_pvq_search(x, iy, K, N, arch) \
37 (op_pvq_search_sse2(x, iy, K, N, arch))
38
39#else
40
41extern opus_val16 (*const OP_PVQ_SEARCH_IMPL[OPUS_ARCHMASK + 1])(
42 celt_norm *_X, int *iy, int K, int N, int arch);
43
44# define op_pvq_search(X, iy, K, N, arch) \
45 ((*OP_PVQ_SEARCH_IMPL[(arch) & OPUS_ARCHMASK])(X, iy, K, N, arch))
46
47#endif
48#endif
49
50#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/x86/vq_sse2.c b/lib/rbcodec/codecs/libopus/celt/x86/vq_sse2.c
new file mode 100644
index 0000000000..775042860d
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/x86/vq_sse2.c
@@ -0,0 +1,217 @@
1/* Copyright (c) 2007-2008 CSIRO
2 Copyright (c) 2007-2009 Xiph.Org Foundation
3 Copyright (c) 2007-2016 Jean-Marc Valin */
4/*
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include <xmmintrin.h>
34#include <emmintrin.h>
35#include "celt_lpc.h"
36#include "stack_alloc.h"
37#include "mathops.h"
38#include "vq.h"
39#include "x86cpu.h"
40
41
42#ifndef FIXED_POINT
43
44opus_val16 op_pvq_search_sse2(celt_norm *_X, int *iy, int K, int N, int arch)
45{
46 int i, j;
47 int pulsesLeft;
48 float xy, yy;
49 VARDECL(celt_norm, y);
50 VARDECL(celt_norm, X);
51 VARDECL(float, signy);
52 __m128 signmask;
53 __m128 sums;
54 __m128i fours;
55 SAVE_STACK;
56
57 (void)arch;
58 /* All bits set to zero, except for the sign bit. */
59 signmask = _mm_set_ps1(-0.f);
60 fours = _mm_set_epi32(4, 4, 4, 4);
61 ALLOC(y, N+3, celt_norm);
62 ALLOC(X, N+3, celt_norm);
63 ALLOC(signy, N+3, float);
64
65 OPUS_COPY(X, _X, N);
66 X[N] = X[N+1] = X[N+2] = 0;
67 sums = _mm_setzero_ps();
68 for (j=0;j<N;j+=4)
69 {
70 __m128 x4, s4;
71 x4 = _mm_loadu_ps(&X[j]);
72 s4 = _mm_cmplt_ps(x4, _mm_setzero_ps());
73 /* Get rid of the sign */
74 x4 = _mm_andnot_ps(signmask, x4);
75 sums = _mm_add_ps(sums, x4);
76 /* Clear y and iy in case we don't do the projection. */
77 _mm_storeu_ps(&y[j], _mm_setzero_ps());
78 _mm_storeu_si128((__m128i*)&iy[j], _mm_setzero_si128());
79 _mm_storeu_ps(&X[j], x4);
80 _mm_storeu_ps(&signy[j], s4);
81 }
82 sums = _mm_add_ps(sums, _mm_shuffle_ps(sums, sums, _MM_SHUFFLE(1, 0, 3, 2)));
83 sums = _mm_add_ps(sums, _mm_shuffle_ps(sums, sums, _MM_SHUFFLE(2, 3, 0, 1)));
84
85 xy = yy = 0;
86
87 pulsesLeft = K;
88
89 /* Do a pre-search by projecting on the pyramid */
90 if (K > (N>>1))
91 {
92 __m128i pulses_sum;
93 __m128 yy4, xy4;
94 __m128 rcp4;
95 opus_val32 sum = _mm_cvtss_f32(sums);
96 /* If X is too small, just replace it with a pulse at 0 */
97 /* Prevents infinities and NaNs from causing too many pulses
98 to be allocated. 64 is an approximation of infinity here. */
99 if (!(sum > EPSILON && sum < 64))
100 {
101 X[0] = QCONST16(1.f,14);
102 j=1; do
103 X[j]=0;
104 while (++j<N);
105 sums = _mm_set_ps1(1.f);
106 }
107 /* Using K+e with e < 1 guarantees we cannot get more than K pulses. */
108 rcp4 = _mm_mul_ps(_mm_set_ps1((float)(K+.8)), _mm_rcp_ps(sums));
109 xy4 = yy4 = _mm_setzero_ps();
110 pulses_sum = _mm_setzero_si128();
111 for (j=0;j<N;j+=4)
112 {
113 __m128 rx4, x4, y4;
114 __m128i iy4;
115 x4 = _mm_loadu_ps(&X[j]);
116 rx4 = _mm_mul_ps(x4, rcp4);
117 iy4 = _mm_cvttps_epi32(rx4);
118 pulses_sum = _mm_add_epi32(pulses_sum, iy4);
119 _mm_storeu_si128((__m128i*)&iy[j], iy4);
120 y4 = _mm_cvtepi32_ps(iy4);
121 xy4 = _mm_add_ps(xy4, _mm_mul_ps(x4, y4));
122 yy4 = _mm_add_ps(yy4, _mm_mul_ps(y4, y4));
123 /* double the y[] vector so we don't have to do it in the search loop. */
124 _mm_storeu_ps(&y[j], _mm_add_ps(y4, y4));
125 }
126 pulses_sum = _mm_add_epi32(pulses_sum, _mm_shuffle_epi32(pulses_sum, _MM_SHUFFLE(1, 0, 3, 2)));
127 pulses_sum = _mm_add_epi32(pulses_sum, _mm_shuffle_epi32(pulses_sum, _MM_SHUFFLE(2, 3, 0, 1)));
128 pulsesLeft -= _mm_cvtsi128_si32(pulses_sum);
129 xy4 = _mm_add_ps(xy4, _mm_shuffle_ps(xy4, xy4, _MM_SHUFFLE(1, 0, 3, 2)));
130 xy4 = _mm_add_ps(xy4, _mm_shuffle_ps(xy4, xy4, _MM_SHUFFLE(2, 3, 0, 1)));
131 xy = _mm_cvtss_f32(xy4);
132 yy4 = _mm_add_ps(yy4, _mm_shuffle_ps(yy4, yy4, _MM_SHUFFLE(1, 0, 3, 2)));
133 yy4 = _mm_add_ps(yy4, _mm_shuffle_ps(yy4, yy4, _MM_SHUFFLE(2, 3, 0, 1)));
134 yy = _mm_cvtss_f32(yy4);
135 }
136 X[N] = X[N+1] = X[N+2] = -100;
137 y[N] = y[N+1] = y[N+2] = 100;
138 celt_sig_assert(pulsesLeft>=0);
139
140 /* This should never happen, but just in case it does (e.g. on silence)
141 we fill the first bin with pulses. */
142 if (pulsesLeft > N+3)
143 {
144 opus_val16 tmp = (opus_val16)pulsesLeft;
145 yy = MAC16_16(yy, tmp, tmp);
146 yy = MAC16_16(yy, tmp, y[0]);
147 iy[0] += pulsesLeft;
148 pulsesLeft=0;
149 }
150
151 for (i=0;i<pulsesLeft;i++)
152 {
153 int best_id;
154 __m128 xy4, yy4;
155 __m128 max, max2;
156 __m128i count;
157 __m128i pos;
158 /* The squared magnitude term gets added anyway, so we might as well
159 add it outside the loop */
160 yy = ADD16(yy, 1);
161 xy4 = _mm_load1_ps(&xy);
162 yy4 = _mm_load1_ps(&yy);
163 max = _mm_setzero_ps();
164 pos = _mm_setzero_si128();
165 count = _mm_set_epi32(3, 2, 1, 0);
166 for (j=0;j<N;j+=4)
167 {
168 __m128 x4, y4, r4;
169 x4 = _mm_loadu_ps(&X[j]);
170 y4 = _mm_loadu_ps(&y[j]);
171 x4 = _mm_add_ps(x4, xy4);
172 y4 = _mm_add_ps(y4, yy4);
173 y4 = _mm_rsqrt_ps(y4);
174 r4 = _mm_mul_ps(x4, y4);
175 /* Update the index of the max. */
176 pos = _mm_max_epi16(pos, _mm_and_si128(count, _mm_castps_si128(_mm_cmpgt_ps(r4, max))));
177 /* Update the max. */
178 max = _mm_max_ps(max, r4);
179 /* Update the indices (+4) */
180 count = _mm_add_epi32(count, fours);
181 }
182 /* Horizontal max */
183 max2 = _mm_max_ps(max, _mm_shuffle_ps(max, max, _MM_SHUFFLE(1, 0, 3, 2)));
184 max2 = _mm_max_ps(max2, _mm_shuffle_ps(max2, max2, _MM_SHUFFLE(2, 3, 0, 1)));
185 /* Now that max2 contains the max at all positions, look at which value(s) of the
186 partial max is equal to the global max. */
187 pos = _mm_and_si128(pos, _mm_castps_si128(_mm_cmpeq_ps(max, max2)));
188 pos = _mm_max_epi16(pos, _mm_unpackhi_epi64(pos, pos));
189 pos = _mm_max_epi16(pos, _mm_shufflelo_epi16(pos, _MM_SHUFFLE(1, 0, 3, 2)));
190 best_id = _mm_cvtsi128_si32(pos);
191
192 /* Updating the sums of the new pulse(s) */
193 xy = ADD32(xy, EXTEND32(X[best_id]));
194 /* We're multiplying y[j] by two so we don't have to do it here */
195 yy = ADD16(yy, y[best_id]);
196
197 /* Only now that we've made the final choice, update y/iy */
198 /* Multiplying y[j] by 2 so we don't have to do it everywhere else */
199 y[best_id] += 2;
200 iy[best_id]++;
201 }
202
203 /* Put the original sign back */
204 for (j=0;j<N;j+=4)
205 {
206 __m128i y4;
207 __m128i s4;
208 y4 = _mm_loadu_si128((__m128i*)&iy[j]);
209 s4 = _mm_castps_si128(_mm_loadu_ps(&signy[j]));
210 y4 = _mm_xor_si128(_mm_add_epi32(y4, s4), s4);
211 _mm_storeu_si128((__m128i*)&iy[j], y4);
212 }
213 RESTORE_STACK;
214 return yy;
215}
216
217#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/x86/x86_celt_map.c b/lib/rbcodec/codecs/libopus/celt/x86/x86_celt_map.c
new file mode 100644
index 0000000000..d39d88edec
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/x86/x86_celt_map.c
@@ -0,0 +1,167 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#if defined(HAVE_CONFIG_H)
29#include "config.h"
30#endif
31
32#include "x86/x86cpu.h"
33#include "celt_lpc.h"
34#include "pitch.h"
35#include "pitch_sse.h"
36#include "vq.h"
37
38#if defined(OPUS_HAVE_RTCD)
39
40# if defined(FIXED_POINT)
41
42#if defined(OPUS_X86_MAY_HAVE_SSE4_1) && !defined(OPUS_X86_PRESUME_SSE4_1)
43
44void (*const CELT_FIR_IMPL[OPUS_ARCHMASK + 1])(
45 const opus_val16 *x,
46 const opus_val16 *num,
47 opus_val16 *y,
48 int N,
49 int ord,
50 int arch
51) = {
52 celt_fir_c, /* non-sse */
53 celt_fir_c,
54 celt_fir_c,
55 MAY_HAVE_SSE4_1(celt_fir), /* sse4.1 */
56 MAY_HAVE_SSE4_1(celt_fir) /* avx */
57};
58
59void (*const XCORR_KERNEL_IMPL[OPUS_ARCHMASK + 1])(
60 const opus_val16 *x,
61 const opus_val16 *y,
62 opus_val32 sum[4],
63 int len
64) = {
65 xcorr_kernel_c, /* non-sse */
66 xcorr_kernel_c,
67 xcorr_kernel_c,
68 MAY_HAVE_SSE4_1(xcorr_kernel), /* sse4.1 */
69 MAY_HAVE_SSE4_1(xcorr_kernel) /* avx */
70};
71
72#endif
73
74#if (defined(OPUS_X86_MAY_HAVE_SSE4_1) && !defined(OPUS_X86_PRESUME_SSE4_1)) || \
75 (!defined(OPUS_X86_MAY_HAVE_SSE_4_1) && defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(OPUS_X86_PRESUME_SSE2))
76
77opus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK + 1])(
78 const opus_val16 *x,
79 const opus_val16 *y,
80 int N
81) = {
82 celt_inner_prod_c, /* non-sse */
83 celt_inner_prod_c,
84 MAY_HAVE_SSE2(celt_inner_prod),
85 MAY_HAVE_SSE4_1(celt_inner_prod), /* sse4.1 */
86 MAY_HAVE_SSE4_1(celt_inner_prod) /* avx */
87};
88
89#endif
90
91# else
92
93#if defined(OPUS_X86_MAY_HAVE_SSE) && !defined(OPUS_X86_PRESUME_SSE)
94
95void (*const XCORR_KERNEL_IMPL[OPUS_ARCHMASK + 1])(
96 const opus_val16 *x,
97 const opus_val16 *y,
98 opus_val32 sum[4],
99 int len
100) = {
101 xcorr_kernel_c, /* non-sse */
102 MAY_HAVE_SSE(xcorr_kernel),
103 MAY_HAVE_SSE(xcorr_kernel),
104 MAY_HAVE_SSE(xcorr_kernel),
105 MAY_HAVE_SSE(xcorr_kernel)
106};
107
108opus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK + 1])(
109 const opus_val16 *x,
110 const opus_val16 *y,
111 int N
112) = {
113 celt_inner_prod_c, /* non-sse */
114 MAY_HAVE_SSE(celt_inner_prod),
115 MAY_HAVE_SSE(celt_inner_prod),
116 MAY_HAVE_SSE(celt_inner_prod),
117 MAY_HAVE_SSE(celt_inner_prod)
118};
119
120void (*const DUAL_INNER_PROD_IMPL[OPUS_ARCHMASK + 1])(
121 const opus_val16 *x,
122 const opus_val16 *y01,
123 const opus_val16 *y02,
124 int N,
125 opus_val32 *xy1,
126 opus_val32 *xy2
127) = {
128 dual_inner_prod_c, /* non-sse */
129 MAY_HAVE_SSE(dual_inner_prod),
130 MAY_HAVE_SSE(dual_inner_prod),
131 MAY_HAVE_SSE(dual_inner_prod),
132 MAY_HAVE_SSE(dual_inner_prod)
133};
134
135void (*const COMB_FILTER_CONST_IMPL[OPUS_ARCHMASK + 1])(
136 opus_val32 *y,
137 opus_val32 *x,
138 int T,
139 int N,
140 opus_val16 g10,
141 opus_val16 g11,
142 opus_val16 g12
143) = {
144 comb_filter_const_c, /* non-sse */
145 MAY_HAVE_SSE(comb_filter_const),
146 MAY_HAVE_SSE(comb_filter_const),
147 MAY_HAVE_SSE(comb_filter_const),
148 MAY_HAVE_SSE(comb_filter_const)
149};
150
151
152#endif
153
154#if defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(OPUS_X86_PRESUME_SSE2)
155opus_val16 (*const OP_PVQ_SEARCH_IMPL[OPUS_ARCHMASK + 1])(
156 celt_norm *_X, int *iy, int K, int N, int arch
157) = {
158 op_pvq_search_c, /* non-sse */
159 op_pvq_search_c,
160 MAY_HAVE_SSE2(op_pvq_search),
161 MAY_HAVE_SSE2(op_pvq_search),
162 MAY_HAVE_SSE2(op_pvq_search)
163};
164#endif
165
166#endif
167#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/x86/x86cpu.c b/lib/rbcodec/codecs/libopus/celt/x86/x86cpu.c
new file mode 100644
index 0000000000..080eb25e41
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/x86/x86cpu.c
@@ -0,0 +1,157 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "cpu_support.h"
33#include "macros.h"
34#include "main.h"
35#include "pitch.h"
36#include "x86cpu.h"
37
38#if (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(OPUS_X86_PRESUME_SSE)) || \
39 (defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(OPUS_X86_PRESUME_SSE2)) || \
40 (defined(OPUS_X86_MAY_HAVE_SSE4_1) && !defined(OPUS_X86_PRESUME_SSE4_1)) || \
41 (defined(OPUS_X86_MAY_HAVE_AVX) && !defined(OPUS_X86_PRESUME_AVX))
42
43
44#if defined(_MSC_VER)
45
46#include <intrin.h>
47static _inline void cpuid(unsigned int CPUInfo[4], unsigned int InfoType)
48{
49 __cpuid((int*)CPUInfo, InfoType);
50}
51
52#else
53
54#if defined(CPU_INFO_BY_C)
55#include <cpuid.h>
56#endif
57
58static void cpuid(unsigned int CPUInfo[4], unsigned int InfoType)
59{
60#if defined(CPU_INFO_BY_ASM)
61#if defined(__i386__) && defined(__PIC__)
62/* %ebx is PIC register in 32-bit, so mustn't clobber it. */
63 __asm__ __volatile__ (
64 "xchg %%ebx, %1\n"
65 "cpuid\n"
66 "xchg %%ebx, %1\n":
67 "=a" (CPUInfo[0]),
68 "=r" (CPUInfo[1]),
69 "=c" (CPUInfo[2]),
70 "=d" (CPUInfo[3]) :
71 "0" (InfoType)
72 );
73#else
74 __asm__ __volatile__ (
75 "cpuid":
76 "=a" (CPUInfo[0]),
77 "=b" (CPUInfo[1]),
78 "=c" (CPUInfo[2]),
79 "=d" (CPUInfo[3]) :
80 "0" (InfoType)
81 );
82#endif
83#elif defined(CPU_INFO_BY_C)
84 __get_cpuid(InfoType, &(CPUInfo[0]), &(CPUInfo[1]), &(CPUInfo[2]), &(CPUInfo[3]));
85#endif
86}
87
88#endif
89
90typedef struct CPU_Feature{
91 /* SIMD: 128-bit */
92 int HW_SSE;
93 int HW_SSE2;
94 int HW_SSE41;
95 /* SIMD: 256-bit */
96 int HW_AVX;
97} CPU_Feature;
98
99static void opus_cpu_feature_check(CPU_Feature *cpu_feature)
100{
101 unsigned int info[4] = {0};
102 unsigned int nIds = 0;
103
104 cpuid(info, 0);
105 nIds = info[0];
106
107 if (nIds >= 1){
108 cpuid(info, 1);
109 cpu_feature->HW_SSE = (info[3] & (1 << 25)) != 0;
110 cpu_feature->HW_SSE2 = (info[3] & (1 << 26)) != 0;
111 cpu_feature->HW_SSE41 = (info[2] & (1 << 19)) != 0;
112 cpu_feature->HW_AVX = (info[2] & (1 << 28)) != 0;
113 }
114 else {
115 cpu_feature->HW_SSE = 0;
116 cpu_feature->HW_SSE2 = 0;
117 cpu_feature->HW_SSE41 = 0;
118 cpu_feature->HW_AVX = 0;
119 }
120}
121
122int opus_select_arch(void)
123{
124 CPU_Feature cpu_feature;
125 int arch;
126
127 opus_cpu_feature_check(&cpu_feature);
128
129 arch = 0;
130 if (!cpu_feature.HW_SSE)
131 {
132 return arch;
133 }
134 arch++;
135
136 if (!cpu_feature.HW_SSE2)
137 {
138 return arch;
139 }
140 arch++;
141
142 if (!cpu_feature.HW_SSE41)
143 {
144 return arch;
145 }
146 arch++;
147
148 if (!cpu_feature.HW_AVX)
149 {
150 return arch;
151 }
152 arch++;
153
154 return arch;
155}
156
157#endif
diff --git a/lib/rbcodec/codecs/libopus/celt/x86/x86cpu.h b/lib/rbcodec/codecs/libopus/celt/x86/x86cpu.h
new file mode 100644
index 0000000000..1e2bf17b9b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/celt/x86/x86cpu.h
@@ -0,0 +1,95 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#if !defined(X86CPU_H)
29# define X86CPU_H
30
31# if defined(OPUS_X86_MAY_HAVE_SSE)
32# define MAY_HAVE_SSE(name) name ## _sse
33# else
34# define MAY_HAVE_SSE(name) name ## _c
35# endif
36
37# if defined(OPUS_X86_MAY_HAVE_SSE2)
38# define MAY_HAVE_SSE2(name) name ## _sse2
39# else
40# define MAY_HAVE_SSE2(name) name ## _c
41# endif
42
43# if defined(OPUS_X86_MAY_HAVE_SSE4_1)
44# define MAY_HAVE_SSE4_1(name) name ## _sse4_1
45# else
46# define MAY_HAVE_SSE4_1(name) name ## _c
47# endif
48
49# if defined(OPUS_X86_MAY_HAVE_AVX)
50# define MAY_HAVE_AVX(name) name ## _avx
51# else
52# define MAY_HAVE_AVX(name) name ## _c
53# endif
54
55# if defined(OPUS_HAVE_RTCD)
56int opus_select_arch(void);
57# endif
58
59/*gcc appears to emit MOVDQA's to load the argument of an _mm_cvtepi8_epi32()
60 or _mm_cvtepi16_epi32() when optimizations are disabled, even though the
61 actual PMOVSXWD instruction takes an m32 or m64. Unlike a normal memory
62 reference, these require 16-byte alignment and load a full 16 bytes (instead
63 of 4 or 8), possibly reading out of bounds.
64
65 We can insert an explicit MOVD or MOVQ using _mm_cvtsi32_si128() or
66 _mm_loadl_epi64(), which should have the same semantics as an m32 or m64
67 reference in the PMOVSXWD instruction itself, but gcc is not smart enough to
68 optimize this out when optimizations ARE enabled.
69
70 Clang, in contrast, requires us to do this always for _mm_cvtepi8_epi32
71 (which is fair, since technically the compiler is always allowed to do the
72 dereference before invoking the function implementing the intrinsic).
73 However, it is smart enough to eliminate the extra MOVD instruction.
74 For _mm_cvtepi16_epi32, it does the right thing, though does *not* optimize out
75 the extra MOVQ if it's specified explicitly */
76
77# if defined(__clang__) || !defined(__OPTIMIZE__)
78# define OP_CVTEPI8_EPI32_M32(x) \
79 (_mm_cvtepi8_epi32(_mm_cvtsi32_si128(*(int *)(x))))
80# else
81# define OP_CVTEPI8_EPI32_M32(x) \
82 (_mm_cvtepi8_epi32(*(__m128i *)(x)))
83#endif
84
85/* similar reasoning about the instruction sequence as in the 32-bit macro above,
86 */
87# if defined(__clang__) || !defined(__OPTIMIZE__)
88# define OP_CVTEPI16_EPI32_M64(x) \
89 (_mm_cvtepi16_epi32(_mm_loadl_epi64((__m128i *)(x))))
90# else
91# define OP_CVTEPI16_EPI32_M64(x) \
92 (_mm_cvtepi16_epi32(*(__m128i *)(x)))
93# endif
94
95#endif
diff --git a/lib/rbcodec/codecs/libopus/mapping_matrix.c b/lib/rbcodec/codecs/libopus/mapping_matrix.c
new file mode 100644
index 0000000000..31298af057
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/mapping_matrix.c
@@ -0,0 +1,378 @@
1/* Copyright (c) 2017 Google Inc.
2 Written by Andrew Allen */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "arch.h"
33#include "float_cast.h"
34#include "opus_private.h"
35#include "opus_defines.h"
36#include "mapping_matrix.h"
37
38#define MATRIX_INDEX(nb_rows, row, col) (nb_rows * col + row)
39
40opus_int32 mapping_matrix_get_size(int rows, int cols)
41{
42 opus_int32 size;
43
44 /* Mapping Matrix must only support up to 255 channels in or out.
45 * Additionally, the total cell count must be <= 65004 octets in order
46 * for the matrix to be stored in an OGG header.
47 */
48 if (rows > 255 || cols > 255)
49 return 0;
50 size = rows * (opus_int32)cols * sizeof(opus_int16);
51 if (size > 65004)
52 return 0;
53
54 return align(sizeof(MappingMatrix)) + align(size);
55}
56
57opus_int16 *mapping_matrix_get_data(const MappingMatrix *matrix)
58{
59 /* void* cast avoids clang -Wcast-align warning */
60 return (opus_int16*)(void*)((char*)matrix + align(sizeof(MappingMatrix)));
61}
62
63void mapping_matrix_init(MappingMatrix * const matrix,
64 int rows, int cols, int gain, const opus_int16 *data, opus_int32 data_size)
65{
66 int i;
67 opus_int16 *ptr;
68
69#if !defined(ENABLE_ASSERTIONS)
70 (void)data_size;
71#endif
72 celt_assert(align(data_size) == align(rows * cols * sizeof(opus_int16)));
73
74 matrix->rows = rows;
75 matrix->cols = cols;
76 matrix->gain = gain;
77 ptr = mapping_matrix_get_data(matrix);
78 for (i = 0; i < rows * cols; i++)
79 {
80 ptr[i] = data[i];
81 }
82}
83
84#ifndef DISABLE_FLOAT_API
85void mapping_matrix_multiply_channel_in_float(
86 const MappingMatrix *matrix,
87 const float *input,
88 int input_rows,
89 opus_val16 *output,
90 int output_row,
91 int output_rows,
92 int frame_size)
93{
94 /* Matrix data is ordered col-wise. */
95 opus_int16* matrix_data;
96 int i, col;
97
98 celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows);
99
100 matrix_data = mapping_matrix_get_data(matrix);
101
102 for (i = 0; i < frame_size; i++)
103 {
104 float tmp = 0;
105 for (col = 0; col < input_rows; col++)
106 {
107 tmp +=
108 matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] *
109 input[MATRIX_INDEX(input_rows, col, i)];
110 }
111#if defined(FIXED_POINT)
112 output[output_rows * i] = FLOAT2INT16((1/32768.f)*tmp);
113#else
114 output[output_rows * i] = (1/32768.f)*tmp;
115#endif
116 }
117}
118
119void mapping_matrix_multiply_channel_out_float(
120 const MappingMatrix *matrix,
121 const opus_val16 *input,
122 int input_row,
123 int input_rows,
124 float *output,
125 int output_rows,
126 int frame_size
127)
128{
129 /* Matrix data is ordered col-wise. */
130 opus_int16* matrix_data;
131 int i, row;
132 float input_sample;
133
134 celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows);
135
136 matrix_data = mapping_matrix_get_data(matrix);
137
138 for (i = 0; i < frame_size; i++)
139 {
140#if defined(FIXED_POINT)
141 input_sample = (1/32768.f)*input[input_rows * i];
142#else
143 input_sample = input[input_rows * i];
144#endif
145 for (row = 0; row < output_rows; row++)
146 {
147 float tmp =
148 (1/32768.f)*matrix_data[MATRIX_INDEX(matrix->rows, row, input_row)] *
149 input_sample;
150 output[MATRIX_INDEX(output_rows, row, i)] += tmp;
151 }
152 }
153}
154#endif /* DISABLE_FLOAT_API */
155
156void mapping_matrix_multiply_channel_in_short(
157 const MappingMatrix *matrix,
158 const opus_int16 *input,
159 int input_rows,
160 opus_val16 *output,
161 int output_row,
162 int output_rows,
163 int frame_size)
164{
165 /* Matrix data is ordered col-wise. */
166 opus_int16* matrix_data;
167 int i, col;
168
169 celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows);
170
171 matrix_data = mapping_matrix_get_data(matrix);
172
173 for (i = 0; i < frame_size; i++)
174 {
175 opus_val32 tmp = 0;
176 for (col = 0; col < input_rows; col++)
177 {
178#if defined(FIXED_POINT)
179 tmp +=
180 ((opus_int32)matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] *
181 (opus_int32)input[MATRIX_INDEX(input_rows, col, i)]) >> 8;
182#else
183 tmp +=
184 matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] *
185 input[MATRIX_INDEX(input_rows, col, i)];
186#endif
187 }
188#if defined(FIXED_POINT)
189 output[output_rows * i] = (opus_int16)((tmp + 64) >> 7);
190#else
191 output[output_rows * i] = (1/(32768.f*32768.f))*tmp;
192#endif
193 }
194}
195
196void mapping_matrix_multiply_channel_out_short(
197 const MappingMatrix *matrix,
198 const opus_val16 *input,
199 int input_row,
200 int input_rows,
201 opus_int16 *output,
202 int output_rows,
203 int frame_size)
204{
205 /* Matrix data is ordered col-wise. */
206 opus_int16* matrix_data;
207 int i, row;
208 opus_int32 input_sample;
209
210 celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows);
211
212 matrix_data = mapping_matrix_get_data(matrix);
213
214 for (i = 0; i < frame_size; i++)
215 {
216#if defined(FIXED_POINT)
217 input_sample = (opus_int32)input[input_rows * i];
218#else
219 input_sample = (opus_int32)FLOAT2INT16(input[input_rows * i]);
220#endif
221 for (row = 0; row < output_rows; row++)
222 {
223 opus_int32 tmp =
224 (opus_int32)matrix_data[MATRIX_INDEX(matrix->rows, row, input_row)] *
225 input_sample;
226 output[MATRIX_INDEX(output_rows, row, i)] += (tmp + 16384) >> 15;
227 }
228 }
229}
230
231const MappingMatrix mapping_matrix_foa_mixing = { 6, 6, 0 };
232const opus_int16 mapping_matrix_foa_mixing_data[36] = {
233 16384, 0, -16384, 23170, 0, 0, 16384, 23170,
234 16384, 0, 0, 0, 16384, 0, -16384, -23170,
235 0, 0, 16384, -23170, 16384, 0, 0, 0,
236 0, 0, 0, 0, 32767, 0, 0, 0,
237 0, 0, 0, 32767
238};
239
240const MappingMatrix mapping_matrix_soa_mixing = { 11, 11, 0 };
241const opus_int16 mapping_matrix_soa_mixing_data[121] = {
242 10923, 7723, 13377, -13377, 11585, 9459, 7723, -16384,
243 -6689, 0, 0, 10923, 7723, 13377, 13377, -11585,
244 9459, 7723, 16384, -6689, 0, 0, 10923, -15447,
245 13377, 0, 0, -18919, 7723, 0, 13377, 0,
246 0, 10923, 7723, -13377, -13377, 11585, -9459, 7723,
247 16384, -6689, 0, 0, 10923, -7723, 0, 13377,
248 -16384, 0, -15447, 0, 9459, 0, 0, 10923,
249 -7723, 0, -13377, 16384, 0, -15447, 0, 9459,
250 0, 0, 10923, 15447, 0, 0, 0, 0,
251 -15447, 0, -18919, 0, 0, 10923, 7723, -13377,
252 13377, -11585, -9459, 7723, -16384, -6689, 0, 0,
253 10923, -15447, -13377, 0, 0, 18919, 7723, 0,
254 13377, 0, 0, 0, 0, 0, 0, 0,
255 0, 0, 0, 0, 32767, 0, 0, 0,
256 0, 0, 0, 0, 0, 0, 0, 0,
257 32767
258};
259
260const MappingMatrix mapping_matrix_toa_mixing = { 18, 18, 0 };
261const opus_int16 mapping_matrix_toa_mixing_data[324] = {
262 8208, 0, -881, 14369, 0, 0, -8192, -4163,
263 13218, 0, 0, 0, 11095, -8836, -6218, 14833,
264 0, 0, 8208, -10161, 881, 10161, -13218, -2944,
265 -8192, 2944, 0, -10488, -6218, 6248, -11095, -6248,
266 0, -10488, 0, 0, 8208, 10161, 881, -10161,
267 -13218, 2944, -8192, -2944, 0, 10488, -6218, -6248,
268 -11095, 6248, 0, 10488, 0, 0, 8176, 5566,
269 -11552, 5566, 9681, -11205, 8192, -11205, 0, 4920,
270 -15158, 9756, -3334, 9756, 0, -4920, 0, 0,
271 8176, 7871, 11552, 0, 0, 15846, 8192, 0,
272 -9681, -6958, 0, 13797, 3334, 0, -15158, 0,
273 0, 0, 8176, 0, 11552, 7871, 0, 0,
274 8192, 15846, 9681, 0, 0, 0, 3334, 13797,
275 15158, 6958, 0, 0, 8176, 5566, -11552, -5566,
276 -9681, -11205, 8192, 11205, 0, 4920, 15158, 9756,
277 -3334, -9756, 0, 4920, 0, 0, 8208, 14369,
278 -881, 0, 0, -4163, -8192, 0, -13218, -14833,
279 0, -8836, 11095, 0, 6218, 0, 0, 0,
280 8208, 10161, 881, 10161, 13218, 2944, -8192, 2944,
281 0, 10488, 6218, -6248, -11095, -6248, 0, -10488,
282 0, 0, 8208, -14369, -881, 0, 0, 4163,
283 -8192, 0, -13218, 14833, 0, 8836, 11095, 0,
284 6218, 0, 0, 0, 8208, 0, -881, -14369,
285 0, 0, -8192, 4163, 13218, 0, 0, 0,
286 11095, 8836, -6218, -14833, 0, 0, 8176, -5566,
287 -11552, 5566, -9681, 11205, 8192, -11205, 0, -4920,
288 15158, -9756, -3334, 9756, 0, -4920, 0, 0,
289 8176, 0, 11552, -7871, 0, 0, 8192, -15846,
290 9681, 0, 0, 0, 3334, -13797, 15158, -6958,
291 0, 0, 8176, -7871, 11552, 0, 0, -15846,
292 8192, 0, -9681, 6958, 0, -13797, 3334, 0,
293 -15158, 0, 0, 0, 8176, -5566, -11552, -5566,
294 9681, 11205, 8192, 11205, 0, -4920, -15158, -9756,
295 -3334, -9756, 0, 4920, 0, 0, 8208, -10161,
296 881, -10161, 13218, -2944, -8192, -2944, 0, -10488,
297 6218, 6248, -11095, 6248, 0, 10488, 0, 0,
298 0, 0, 0, 0, 0, 0, 0, 0,
299 0, 0, 0, 0, 0, 0, 0, 0,
300 32767, 0, 0, 0, 0, 0, 0, 0,
301 0, 0, 0, 0, 0, 0, 0, 0,
302 0, 0, 0, 32767
303};
304
305const MappingMatrix mapping_matrix_foa_demixing = { 6, 6, 0 };
306const opus_int16 mapping_matrix_foa_demixing_data[36] = {
307 16384, 16384, 16384, 16384, 0, 0, 0, 23170,
308 0, -23170, 0, 0, -16384, 16384, -16384, 16384,
309 0, 0, 23170, 0, -23170, 0, 0, 0,
310 0, 0, 0, 0, 32767, 0, 0, 0,
311 0, 0, 0, 32767
312};
313
314const MappingMatrix mapping_matrix_soa_demixing = { 11, 11, 3050 };
315const opus_int16 mapping_matrix_soa_demixing_data[121] = {
316 2771, 2771, 2771, 2771, 2771, 2771, 2771, 2771,
317 2771, 0, 0, 10033, 10033, -20066, 10033, 14189,
318 14189, -28378, 10033, -20066, 0, 0, 3393, 3393,
319 3393, -3393, 0, 0, 0, -3393, -3393, 0,
320 0, -17378, 17378, 0, -17378, -24576, 24576, 0,
321 17378, 0, 0, 0, -14189, 14189, 0, -14189,
322 -28378, 28378, 0, 14189, 0, 0, 0, 2399,
323 2399, -4799, -2399, 0, 0, 0, -2399, 4799,
324 0, 0, 1959, 1959, 1959, 1959, -3918, -3918,
325 -3918, 1959, 1959, 0, 0, -4156, 4156, 0,
326 4156, 0, 0, 0, -4156, 0, 0, 0,
327 8192, 8192, -16384, 8192, 16384, 16384, -32768, 8192,
328 -16384, 0, 0, 0, 0, 0, 0, 0,
329 0, 0, 0, 0, 8312, 0, 0, 0,
330 0, 0, 0, 0, 0, 0, 0, 0,
331 8312
332};
333
334const MappingMatrix mapping_matrix_toa_demixing = { 18, 18, 0 };
335const opus_int16 mapping_matrix_toa_demixing_data[324] = {
336 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
337 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
338 0, 0, 0, -9779, 9779, 6263, 8857, 0,
339 6263, 13829, 9779, -13829, 0, -6263, 0, -8857,
340 -6263, -9779, 0, 0, -3413, 3413, 3413, -11359,
341 11359, 11359, -11359, -3413, 3413, -3413, -3413, -11359,
342 11359, 11359, -11359, 3413, 0, 0, 13829, 9779,
343 -9779, 6263, 0, 8857, -6263, 0, 9779, 0,
344 -13829, 6263, -8857, 0, -6263, -9779, 0, 0,
345 0, -15617, -15617, 6406, 0, 0, -6406, 0,
346 15617, 0, 0, -6406, 0, 0, 6406, 15617,
347 0, 0, 0, -5003, 5003, -10664, 15081, 0,
348 -10664, -7075, 5003, 7075, 0, 10664, 0, -15081,
349 10664, -5003, 0, 0, -8176, -8176, -8176, 8208,
350 8208, 8208, 8208, -8176, -8176, -8176, -8176, 8208,
351 8208, 8208, 8208, -8176, 0, 0, -7075, 5003,
352 -5003, -10664, 0, 15081, 10664, 0, 5003, 0,
353 7075, -10664, -15081, 0, 10664, -5003, 0, 0,
354 15617, 0, 0, 0, -6406, 6406, 0, -15617,
355 0, -15617, 15617, 0, 6406, -6406, 0, 0,
356 0, 0, 0, -11393, 11393, 2993, -4233, 0,
357 2993, -16112, 11393, 16112, 0, -2993, 0, 4233,
358 -2993, -11393, 0, 0, 0, -9974, -9974, -13617,
359 0, 0, 13617, 0, 9974, 0, 0, 13617,
360 0, 0, -13617, 9974, 0, 0, 0, 5579,
361 -5579, 10185, 14403, 0, 10185, -7890, -5579, 7890,
362 0, -10185, 0, -14403, -10185, 5579, 0, 0,
363 11826, -11826, -11826, -901, 901, 901, -901, 11826,
364 -11826, 11826, 11826, -901, 901, 901, -901, -11826,
365 0, 0, -7890, -5579, 5579, 10185, 0, 14403,
366 -10185, 0, -5579, 0, 7890, 10185, -14403, 0,
367 -10185, 5579, 0, 0, -9974, 0, 0, 0,
368 -13617, 13617, 0, 9974, 0, 9974, -9974, 0,
369 13617, -13617, 0, 0, 0, 0, 16112, -11393,
370 11393, -2993, 0, 4233, 2993, 0, -11393, 0,
371 -16112, -2993, -4233, 0, 2993, 11393, 0, 0,
372 0, 0, 0, 0, 0, 0, 0, 0,
373 0, 0, 0, 0, 0, 0, 0, 0,
374 32767, 0, 0, 0, 0, 0, 0, 0,
375 0, 0, 0, 0, 0, 0, 0, 0,
376 0, 0, 0, 32767
377};
378
diff --git a/lib/rbcodec/codecs/libopus/mapping_matrix.h b/lib/rbcodec/codecs/libopus/mapping_matrix.h
new file mode 100644
index 0000000000..9c20483e7a
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/mapping_matrix.h
@@ -0,0 +1,133 @@
1/* Copyright (c) 2017 Google Inc.
2 Written by Andrew Allen */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28/**
29 * @file mapping_matrix.h
30 * @brief Opus reference implementation mapping matrix API
31 */
32
33#ifndef MAPPING_MATRIX_H
34#define MAPPING_MATRIX_H
35
36#include "opus_types.h"
37#include "opus_projection.h"
38
39#ifdef __cplusplus
40extern "C" {
41#endif
42
43typedef struct MappingMatrix
44{
45 int rows; /* number of channels outputted from matrix. */
46 int cols; /* number of channels inputted to matrix. */
47 int gain; /* in dB. S7.8-format. */
48 /* Matrix cell data goes here using col-wise ordering. */
49} MappingMatrix;
50
51opus_int32 mapping_matrix_get_size(int rows, int cols);
52
53opus_int16 *mapping_matrix_get_data(const MappingMatrix *matrix);
54
55void mapping_matrix_init(
56 MappingMatrix * const st,
57 int rows,
58 int cols,
59 int gain,
60 const opus_int16 *data,
61 opus_int32 data_size
62);
63
64#ifndef DISABLE_FLOAT_API
65void mapping_matrix_multiply_channel_in_float(
66 const MappingMatrix *matrix,
67 const float *input,
68 int input_rows,
69 opus_val16 *output,
70 int output_row,
71 int output_rows,
72 int frame_size
73);
74
75void mapping_matrix_multiply_channel_out_float(
76 const MappingMatrix *matrix,
77 const opus_val16 *input,
78 int input_row,
79 int input_rows,
80 float *output,
81 int output_rows,
82 int frame_size
83);
84#endif /* DISABLE_FLOAT_API */
85
86void mapping_matrix_multiply_channel_in_short(
87 const MappingMatrix *matrix,
88 const opus_int16 *input,
89 int input_rows,
90 opus_val16 *output,
91 int output_row,
92 int output_rows,
93 int frame_size
94);
95
96void mapping_matrix_multiply_channel_out_short(
97 const MappingMatrix *matrix,
98 const opus_val16 *input,
99 int input_row,
100 int input_rows,
101 opus_int16 *output,
102 int output_rows,
103 int frame_size
104);
105
106/* Pre-computed mixing and demixing matrices for 1st to 3rd-order ambisonics.
107 * foa: first-order ambisonics
108 * soa: second-order ambisonics
109 * toa: third-order ambisonics
110 */
111extern const MappingMatrix mapping_matrix_foa_mixing;
112extern const opus_int16 mapping_matrix_foa_mixing_data[36];
113
114extern const MappingMatrix mapping_matrix_soa_mixing;
115extern const opus_int16 mapping_matrix_soa_mixing_data[121];
116
117extern const MappingMatrix mapping_matrix_toa_mixing;
118extern const opus_int16 mapping_matrix_toa_mixing_data[324];
119
120extern const MappingMatrix mapping_matrix_foa_demixing;
121extern const opus_int16 mapping_matrix_foa_demixing_data[36];
122
123extern const MappingMatrix mapping_matrix_soa_demixing;
124extern const opus_int16 mapping_matrix_soa_demixing_data[121];
125
126extern const MappingMatrix mapping_matrix_toa_demixing;
127extern const opus_int16 mapping_matrix_toa_demixing_data[324];
128
129#ifdef __cplusplus
130}
131#endif
132
133#endif /* MAPPING_MATRIX_H */
diff --git a/lib/rbcodec/codecs/libopus/mlp.c b/lib/rbcodec/codecs/libopus/mlp.c
new file mode 100644
index 0000000000..964c6a98f6
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/mlp.c
@@ -0,0 +1,144 @@
1/* Copyright (c) 2008-2011 Octasic Inc.
2 2012-2017 Jean-Marc Valin */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
19 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <math.h>
33#include "opus_types.h"
34#include "opus_defines.h"
35#include "arch.h"
36#include "tansig_table.h"
37#include "mlp.h"
38
39static OPUS_INLINE float tansig_approx(float x)
40{
41 int i;
42 float y, dy;
43 float sign=1;
44 /* Tests are reversed to catch NaNs */
45 if (!(x<8))
46 return 1;
47 if (!(x>-8))
48 return -1;
49#ifndef FIXED_POINT
50 /* Another check in case of -ffast-math */
51 if (celt_isnan(x))
52 return 0;
53#endif
54 if (x<0)
55 {
56 x=-x;
57 sign=-1;
58 }
59 i = (int)floor(.5f+25*x);
60 x -= .04f*i;
61 y = tansig_table[i];
62 dy = 1-y*y;
63 y = y + x*dy*(1 - y*x);
64 return sign*y;
65}
66
67static OPUS_INLINE float sigmoid_approx(float x)
68{
69 return .5f + .5f*tansig_approx(.5f*x);
70}
71
72static void gemm_accum(float *out, const opus_int8 *weights, int rows, int cols, int col_stride, const float *x)
73{
74 int i, j;
75 for (i=0;i<rows;i++)
76 {
77 for (j=0;j<cols;j++)
78 out[i] += weights[j*col_stride + i]*x[j];
79 }
80}
81
82void compute_dense(const DenseLayer *layer, float *output, const float *input)
83{
84 int i;
85 int N, M;
86 int stride;
87 M = layer->nb_inputs;
88 N = layer->nb_neurons;
89 stride = N;
90 for (i=0;i<N;i++)
91 output[i] = layer->bias[i];
92 gemm_accum(output, layer->input_weights, N, M, stride, input);
93 for (i=0;i<N;i++)
94 output[i] *= WEIGHTS_SCALE;
95 if (layer->sigmoid) {
96 for (i=0;i<N;i++)
97 output[i] = sigmoid_approx(output[i]);
98 } else {
99 for (i=0;i<N;i++)
100 output[i] = tansig_approx(output[i]);
101 }
102}
103
104void compute_gru(const GRULayer *gru, float *state, const float *input)
105{
106 int i;
107 int N, M;
108 int stride;
109 float tmp[MAX_NEURONS];
110 float z[MAX_NEURONS];
111 float r[MAX_NEURONS];
112 float h[MAX_NEURONS];
113 M = gru->nb_inputs;
114 N = gru->nb_neurons;
115 stride = 3*N;
116 /* Compute update gate. */
117 for (i=0;i<N;i++)
118 z[i] = gru->bias[i];
119 gemm_accum(z, gru->input_weights, N, M, stride, input);
120 gemm_accum(z, gru->recurrent_weights, N, N, stride, state);
121 for (i=0;i<N;i++)
122 z[i] = sigmoid_approx(WEIGHTS_SCALE*z[i]);
123
124 /* Compute reset gate. */
125 for (i=0;i<N;i++)
126 r[i] = gru->bias[N + i];
127 gemm_accum(r, &gru->input_weights[N], N, M, stride, input);
128 gemm_accum(r, &gru->recurrent_weights[N], N, N, stride, state);
129 for (i=0;i<N;i++)
130 r[i] = sigmoid_approx(WEIGHTS_SCALE*r[i]);
131
132 /* Compute output. */
133 for (i=0;i<N;i++)
134 h[i] = gru->bias[2*N + i];
135 for (i=0;i<N;i++)
136 tmp[i] = state[i] * r[i];
137 gemm_accum(h, &gru->input_weights[2*N], N, M, stride, input);
138 gemm_accum(h, &gru->recurrent_weights[2*N], N, N, stride, tmp);
139 for (i=0;i<N;i++)
140 h[i] = z[i]*state[i] + (1-z[i])*tansig_approx(WEIGHTS_SCALE*h[i]);
141 for (i=0;i<N;i++)
142 state[i] = h[i];
143}
144
diff --git a/lib/rbcodec/codecs/libopus/mlp.h b/lib/rbcodec/codecs/libopus/mlp.h
new file mode 100644
index 0000000000..d7670550fd
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/mlp.h
@@ -0,0 +1,60 @@
1/* Copyright (c) 2017 Jean-Marc Valin */
2/*
3 Redistribution and use in source and binary forms, with or without
4 modification, are permitted provided that the following conditions
5 are met:
6
7 - Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9
10 - Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
18 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*/
26
27#ifndef _MLP_H_
28#define _MLP_H_
29
30#include "opus_types.h"
31
32#define WEIGHTS_SCALE (1.f/128)
33
34#define MAX_NEURONS 32
35
36typedef struct {
37 const opus_int8 *bias;
38 const opus_int8 *input_weights;
39 int nb_inputs;
40 int nb_neurons;
41 int sigmoid;
42} DenseLayer;
43
44typedef struct {
45 const opus_int8 *bias;
46 const opus_int8 *input_weights;
47 const opus_int8 *recurrent_weights;
48 int nb_inputs;
49 int nb_neurons;
50} GRULayer;
51
52extern const DenseLayer layer0;
53extern const GRULayer layer1;
54extern const DenseLayer layer2;
55
56void compute_dense(const DenseLayer *layer, float *output, const float *input);
57
58void compute_gru(const GRULayer *gru, float *state, const float *input);
59
60#endif /* _MLP_H_ */
diff --git a/lib/rbcodec/codecs/libopus/mlp_data.c b/lib/rbcodec/codecs/libopus/mlp_data.c
new file mode 100644
index 0000000000..ae4178df76
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/mlp_data.c
@@ -0,0 +1,672 @@
1/*This file is automatically generated from a Keras model*/
2
3#ifdef HAVE_CONFIG_H
4#include "config.h"
5#endif
6
7#include "mlp.h"
8
9static const opus_int8 layer0_weights[800] = {
10 -30, -9, 2, -12, 5, -1, 8, 9,
11 9, 8, -13, 18, -17, -34, -5, 17,
12 -11, 0, -4, 10, 2, 10, 15, -8,
13 2, -1, 0, 5, 13, -3, -16, 1,
14 -5, 3, 7, -28, -13, 6, 36, -3,
15 19, -60, -17, -28, 7, -11, -30, -7,
16 2, -42, -21, -3, 6, -22, 33, -9,
17 7, -30, 21, -14, 24, -11, -20, -18,
18 -5, -12, 12, -49, -50, -49, 16, 9,
19 -37, -1, 9, 34, -13, -31, -31, 12,
20 16, 44, -42, 2, -9, 8, -18, -6,
21 9, 36, 19, 11, 13, 12, -21, 3,
22 -28, -12, 3, 33, 25, -14, 11, 1,
23 -94, -39, 18, -12, -11, -15, -7, 49,
24 52, 10, -43, 9, 57, 8, 21, -6,
25 14, -15, 44, -8, 7, -30, -13, -2,
26 -9, 25, -2, -127, 18, -11, -52, 26,
27 -27, 27, 10, -10, 7, 43, 6, -24,
28 41, 10, -18, -27, 10, 17, 9, 10,
29 -17, -10, 20, -6, 22, 55, 35, -80,
30 36, 25, -24, -36, 15, 9, -19, 88,
31 19, 64, -51, -35, 17, 0, -7, 41,
32 -16, 27, 4, 15, -1, 18, -16, 47,
33 -39, -54, -8, 13, -25, -20, 102, -18,
34 -5, 44, 11, -28, 71, 2, -51, -5,
35 5, 2, -83, -9, -29, 8, 21, -53,
36 58, -37, -7, 13, 38, 9, 34, -1,
37 -41, 21, 4, -24, -36, -33, -21, 32,
38 75, -2, 1, -68, -1, 47, -29, 32,
39 20, 12, -65, -87, 5, 16, -12, 24,
40 40, 15, 7, 19, -26, -17, 17, 6,
41 -2, -37, -30, -9, 32, -127, -39, 0,
42 -31, -27, 4, -22, 23, -6, -77, 35,
43 -61, 32, -37, -24, 13, -11, -1, -40,
44 -3, 17, -7, 13, 11, 59, -19, 10,
45 6, -18, 0, 13, 3, -6, -23, 19,
46 11, -17, 13, -1, -80, 40, -53, 69,
47 -29, -54, 0, -4, 33, -25, -2, 38,
48 35, 36, -15, 46, 2, -13, -16, -8,
49 -8, 12, -24, -9, -55, -5, -9, 32,
50 11, 7, 12, -18, -10, -86, -38, 54,
51 37, -25, 18, -43, 7, -27, -27, -54,
52 13, 9, 22, 70, 6, 35, -7, 23,
53 -15, -44, -6, 7, -66, -85, 32, 40,
54 -19, -9, -7, 12, -15, 7, 2, 6,
55 -35, 11, 28, 0, 26, 14, 1, 1,
56 4, 12, 18, 35, 22, -18, -3, 14,
57 -1, 7, 14, -8, -14, -3, 4, -3,
58 -19, -7, -1, -25, -27, 25, -26, -2,
59 33, -22, -27, -25, 4, -9, 7, 21,
60 26, -30, 10, -9, -20, 11, 27, 10,
61 5, -18, 14, -4, 2, -17, -5, -7,
62 -9, -13, 15, 29, 1, -10, -16, -10,
63 35, 36, -7, -22, -44, 17, 30, 22,
64 21, -1, 22, -11, 32, -8, -7, 5,
65 -10, 5, 30, -20, 29, -20, -34, 12,
66 -4, -6, 6, -13, 10, -5, -68, -1,
67 24, 9, 19, -24, -64, 31, 19, 27,
68 -26, 75, -45, 41, 39, -42, 8, 6,
69 23, -30, 16, -25, 30, 34, 8, -38,
70 -3, 18, 16, -31, 22, -4, -9, 1,
71 20, 9, 38, -32, 0, -45, 0, -6,
72 -13, 11, -25, -32, -22, 31, -24, -11,
73 -11, -4, -4, 20, -34, 22, 20, 9,
74 -25, 27, -5, 28, -29, 29, 6, 21,
75 -6, -18, 54, 4, -46, 23, 21, -14,
76 -31, 36, -41, -24, 4, 22, 10, 11,
77 7, 36, -32, -13, -52, -17, 24, 28,
78 -37, -36, -1, 24, 9, -38, 35, 48,
79 18, 2, -1, 45, 10, 39, 24, -38,
80 13, 8, -16, 8, 25, 11, 7, -29,
81 -11, 7, 20, -30, -38, -45, 14, -18,
82 -28, -9, 65, 61, 22, -53, -38, -16,
83 36, 46, 20, -39, 32, -61, -6, -6,
84 -36, -33, -18, -28, 56, 101, 45, 11,
85 -28, -23, -29, -61, 20, -47, 2, 48,
86 27, -17, 1, 40, 1, 3, -51, 15,
87 35, 28, 22, 35, 53, -61, -29, 12,
88 -6, -21, 10, 3, -20, 2, -25, 1,
89 -6, 31, 11, -3, 1, -10, -52, 6,
90 126, -105, 122, 127, -128, 127, 127, -128,
91 127, 108, 12, 127, 48, -128, -36, -128,
92 127, 127, -128, -128, 127, 89, -128, 127,
93 -128, -128, -128, 127, 127, -128, -128, -93,
94 -82, 20, 125, 65, -82, 127, 38, -74,
95 81, 88, -88, 79, 51, -47, -111, -26,
96 14, 83, -88, -112, 24, 35, -101, 98,
97 -99, -48, -45, 46, 83, -60, -79, 45,
98 -20, -41, 9, 4, 52, 54, 93, -10,
99 4, 13, 3, 123, 6, 94, -111, -69,
100 -14, -31, 10, 12, 53, -79, -11, -21,
101 -2, -44, -72, 92, 65, -57, 56, -38,
102 127, -56, -128, 127, 127, -128, 86, 117,
103 -75, -128, 127, -19, -99, -112, 127, -128,
104 127, -48, 114, 118, -128, -128, 117, -17,
105 -6, 121, -128, 127, -128, 82, 54, -106,
106 127, 127, -33, 100, -39, -23, 18, -78,
107 -34, -29, -1, -30, 127, -26, 127, -128,
108 126, -128, 27, -23, -79, -120, -127, 127,
109 72, 66, 29, 7, -66, -56, -117, -128
110};
111
112static const opus_int8 layer0_bias[32] = {
113 51, -16, 1, 13, -5, -6, -16, -7,
114 11, -6, 106, 26, 28, -14, 21, -29,
115 7, 18, -18, -17, 21, -17, -9, 20,
116 -25, -3, -34, 48, 11, -13, -31, -20
117};
118
119static const opus_int8 layer1_weights[2304] = {
120 22, -1, -7, 7, 29, -27, -31, -17,
121 -13, 33, 44, -8, 11, 33, 24, 78,
122 15, 19, 30, -2, -24, 5, 49, 5,
123 36, 29, -14, -11, -48, -33, 21, -42,
124 -38, -12, 55, -37, 54, -8, 1, 36,
125 17, 0, 51, 31, 59, 7, -12, 53,
126 4, 32, -14, 48, 5, -10, -16, -8,
127 1, -16, -56, -24, -6, 18, -2, 23,
128 6, 46, -6, -10, 20, 35, -44, -15,
129 -49, 36, 16, 5, -7, -79, -67, 12,
130 70, -3, -79, -54, -85, -24, 47, -22,
131 33, 21, 69, -1, 11, 22, 14, -16,
132 -16, -22, -28, -11, 11, -41, 31, -26,
133 -33, -19, -4, 27, 32, -50, 5, -10,
134 -38, -22, -8, 35, -31, 1, -41, -15,
135 -11, 44, 28, -17, -41, -23, 17, 2,
136 -23, -26, -13, -13, -17, 6, 14, -31,
137 -25, 9, -19, 39, -8, 4, 31, -1,
138 -45, -11, -28, -92, -46, -15, 21, 118,
139 -22, 45, -51, 11, -20, -20, -15, 13,
140 -21, -97, -29, -32, -23, -42, 94, 1,
141 23, -8, 63, -3, -46, 19, -26, 32,
142 -40, -74, -26, 26, -4, -13, 30, -20,
143 -30, -25, -14, -31, -45, -43, 4, -60,
144 -48, -12, -34, 2, 2, 3, 13, 15,
145 11, 16, 5, 46, -9, -55, -16, -57,
146 29, 14, 38, -50, -2, -44, -11, -8,
147 52, -27, -38, -7, 20, 47, 17, -59,
148 0, 47, 46, -63, 35, -17, 19, 33,
149 68, -19, 2, 15, -16, 28, -16, -103,
150 26, -35, 47, -39, -60, 30, 31, -23,
151 -52, -13, 116, 47, -25, 30, 40, 30,
152 -22, 2, 12, -27, -18, 31, -10, 27,
153 -8, -66, 12, 14, 4, -26, -28, -13,
154 3, 13, -26, -51, 37, 5, 2, -21,
155 47, 3, 13, 25, -41, -27, -8, -4,
156 5, -76, -33, 28, 10, 9, -46, -74,
157 19, 28, 25, 31, 54, -55, 68, 38,
158 -24, -32, 2, 4, 68, 11, -1, 99,
159 5, 16, -2, -74, 40, 26, -26, 33,
160 31, -1, -68, 14, -6, 25, 9, 29,
161 60, 61, 7, -7, 0, -24, 7, 77,
162 4, -1, 16, -7, 13, -15, -19, 28,
163 -31, -24, -16, 37, 24, 13, 30, 10,
164 -30, 11, 11, -10, 22, 60, 28, 45,
165 -3, -40, -62, -5, -102, 9, -32, -27,
166 -54, 21, 15, -5, 37, -43, -11, 37,
167 -19, 47, -64, -128, -27, -114, 21, -66,
168 59, 46, -3, -12, -87, -9, 4, 19,
169 -113, -36, 78, 57, -26, -38, -77, -10,
170 6, 6, -75, 25, -97, -11, 33, -46,
171 1, 13, -21, -33, -20, 16, -6, -3,
172 -11, -4, -27, 38, 8, -41, -2, -33,
173 18, 19, -26, 1, -29, -22, -4, -14,
174 -55, -11, -80, -3, 11, 34, 90, 51,
175 11, 17, 43, 36, 127, -32, 29, 103,
176 9, 27, 13, 64, 56, 70, -14, 3,
177 -12, 10, 37, 3, 12, -22, -10, 46,
178 28, 10, 20, 26, -24, 18, 9, 7,
179 14, 34, -5, -7, 31, -14, -56, 11,
180 -18, -8, -17, -7, -10, -40, 10, -33,
181 -32, -43, 5, 9, 11, -4, 10, 50,
182 -12, -5, 46, 9, 7, 1, 11, 15,
183 91, -17, 7, -50, 23, 6, -30, -99,
184 0, -17, 14, 8, -10, -25, -30, -69,
185 -62, 31, 127, 114, -23, 101, -5, -54,
186 -6, -22, 7, -56, 39, 18, -29, 0,
187 46, 8, -79, 4, -21, 18, -32, 62,
188 -12, -8, -12, -58, 31, -32, 17, 6,
189 -24, 25, 24, 9, -4, -19, 45, 6,
190 17, -14, 5, -27, 16, -4, -41, 25,
191 -36, 5, 15, 12, 50, 27, 25, 23,
192 -44, -69, -9, -19, -48, -8, 4, 12,
193 -6, 13, -19, -30, -36, 26, 37, -1,
194 -3, -30, -42, -14, -10, -20, 26, -54,
195 -27, -44, 4, 73, -26, 90, 32, -69,
196 -29, -16, 3, 103, 15, -17, 37, 24,
197 -23, -31, 33, -37, -64, 25, 13, -81,
198 -28, -32, 27, 5, -35, -23, 15, -22,
199 19, -7, 9, 30, 19, -23, 27, -13,
200 43, 29, -29, -6, 9, -40, -33, -33,
201 -32, 9, 11, -48, -8, -23, -52, 46,
202 17, -22, -42, 35, -15, -41, 16, 34,
203 31, -42, -19, -11, 55, 7, -39, 89,
204 -11, -33, 20, -14, 22, 32, 3, -17,
205 -6, 14, 34, 1, 55, -21, -90, -8,
206 18, 27, 13, -29, 21, 15, -33, -51,
207 -9, -11, 4, -16, -18, 23, -4, -4,
208 48, 1, 7, 29, -14, -12, -16, 17,
209 35, 8, 0, -7, -2, 9, 8, 17,
210 -6, 53, -32, -21, -50, 5, 99, -60,
211 -5, -53, 10, -31, 12, -5, 7, 80,
212 36, 18, -31, 9, 98, 36, -63, -35,
213 4, -13, -28, -24, 28, -13, 18, 16,
214 -1, -18, -34, 10, 20, 7, 4, 29,
215 11, 25, -7, 36, 14, 45, 24, 1,
216 -16, 30, 6, 35, -6, -11, -24, 13,
217 -1, 27, 39, 20, 48, -11, -4, -13,
218 28, 11, -31, -18, 31, -29, 22, -2,
219 -20, -16, 5, 30, -12, -28, -3, 93,
220 -16, 23, 18, -29, 6, -54, -37, 28,
221 -3, -3, -47, -3, -36, -55, -3, 41,
222 -10, 47, -2, 23, 42, -7, -71, -27,
223 83, -64, 7, -24, 8, 26, -17, 15,
224 12, 31, -30, -38, -13, -33, -56, 4,
225 -17, 20, 18, 1, -30, -5, -6, -31,
226 -14, -37, 0, 22, 10, -30, 37, -17,
227 18, 6, 5, 23, -36, -32, 14, 18,
228 -13, -61, -52, -69, 44, -30, 16, 18,
229 -4, -25, 14, 81, 26, -8, -23, -59,
230 52, -104, 17, 119, -32, 26, 17, 1,
231 23, 45, 29, -64, -57, -14, 73, 21,
232 -13, -13, 9, -68, -7, -52, 3, 24,
233 -39, 44, -15, 27, 14, 19, -9, -28,
234 -11, 5, 3, -34, -2, 2, 22, -6,
235 -23, 4, 3, 13, -22, -13, -10, -18,
236 29, 6, 44, -13, -24, -8, 2, 30,
237 14, 43, 6, 17, -73, -6, -7, 20,
238 -80, -7, -7, -28, 15, -69, -38, -5,
239 -100, -35, 15, -79, 23, 29, -18, -27,
240 21, -66, -37, 8, -22, -39, 48, 4,
241 -13, 1, -9, 11, -29, 22, 6, -49,
242 32, -14, 47, -18, -4, 44, -52, -74,
243 43, 30, 23, -14, 5, 0, -27, 4,
244 -7, 10, -4, 10, 1, -16, 11, -18,
245 -2, -5, 2, -11, 0, -20, -4, 38,
246 74, 59, 39, 64, -10, 26, -3, -40,
247 -68, 3, -30, -51, 8, -19, -27, -46,
248 51, 52, 54, 36, 90, 92, 14, 13,
249 -5, 0, 16, -62, 16, 11, -47, -37,
250 -6, -5, 21, 54, -57, 32, 42, -6,
251 62, -9, 16, 21, 24, 9, -10, -4,
252 33, 50, 13, -15, 1, -35, -48, 18,
253 -11, -17, -67, -13, 21, 38, -44, 36,
254 -16, 29, 17, 5, -10, 18, 17, -32,
255 2, 8, 22, -56, -15, -32, 40, 43,
256 19, 46, -7, -100, -96, 19, 53, 24,
257 21, -26, -48, -101, -82, 61, 38, -85,
258 -28, -34, -1, 63, -5, -5, 39, 39,
259 -38, 32, -12, -28, 20, 40, -8, 2,
260 31, 12, -35, -13, 20, -25, 30, 8,
261 3, -13, -9, -20, 2, -13, 24, 37,
262 -10, 33, 6, 20, -16, -24, -6, -6,
263 -19, -5, 22, 21, 10, 11, -4, -39,
264 -1, 6, 49, 41, -15, -57, 21, -62,
265 77, -69, -13, 0, -74, 1, -7, -38,
266 -8, 6, 63, 28, 4, 26, -52, 82,
267 63, 13, 45, -33, 44, -52, -65, -21,
268 -46, -49, 64, -17, 32, 24, 68, -39,
269 -16, -5, -26, 28, 5, -61, -28, 2,
270 24, 11, -12, -33, 9, -37, -3, -28,
271 22, -37, -12, 19, 0, -18, -2, 14,
272 1, 4, 8, -9, -2, 43, -17, -2,
273 -66, -31, 56, -40, -87, -36, -2, -4,
274 -42, -45, -1, 31, -43, -15, 27, 63,
275 -11, 32, -10, -33, 27, -19, 4, 15,
276 -26, -34, 29, -4, -39, -65, 14, -20,
277 -21, -17, -36, 13, 59, 47, -38, -33,
278 13, -37, -8, -37, -7, -6, -76, -31,
279 -12, -46, 7, 24, -21, -30, -14, 9,
280 15, -12, -13, 47, -27, -25, -1, -39,
281 0, 20, -9, 6, 7, 4, 3, 7,
282 39, 50, 22, -7, 14, -20, 1, 70,
283 -28, 29, -41, 10, -16, -5, -28, -2,
284 -37, 32, -18, 17, 62, -11, -20, -50,
285 36, 21, -62, -12, -56, 52, 50, 17,
286 3, 48, 44, -41, -25, 3, 16, -3,
287 0, 33, -6, 15, 27, 34, -25, 22,
288 9, 17, -11, 36, 16, -2, 12, 21,
289 -52, 45, -2, -10, 46, 21, -18, 67,
290 -28, -13, 30, 37, 42, 16, -9, 11,
291 75, 7, -64, -40, -10, 29, 57, -23,
292 5, 53, -77, 3, -17, -5, 47, -55,
293 -35, -36, -13, 52, -53, -71, 52, -111,
294 -23, -26, -28, 29, -43, 55, -19, 43,
295 -19, 54, -12, -33, -44, -39, -19, -10,
296 -31, -10, 21, 38, -57, -20, 2, -25,
297 8, -6, 50, 12, 15, 25, -25, 15,
298 -30, -6, 9, 25, 37, 19, -4, 31,
299 -22, 2, 4, 2, 36, 7, 3, -34,
300 -80, 36, -10, -2, -5, 31, -36, 49,
301 -70, 20, -36, 21, 24, 25, -46, -51,
302 36, -58, -48, -40, -10, 55, 71, 47,
303 10, -1, 1, 2, -46, -68, 16, 13,
304 0, -74, -29, 73, -52, -18, -11, 7,
305 -44, -82, -32, -70, -28, -1, -39, -68,
306 -6, -41, 12, -22, -16, 40, -11, -25,
307 51, -9, 21, 4, 4, -34, 7, -78,
308 16, 6, -38, -30, -2, -44, 32, 0,
309 22, 64, 5, -72, -2, -14, -10, -16,
310 -8, -25, 12, 102, -58, 37, -10, -23,
311 15, 49, 7, -7, 2, -20, -32, 45,
312 -6, 48, 28, 30, 33, -1, 22, -6,
313 30, 65, -17, 29, 74, 37, -26, -10,
314 15, -24, 19, -66, 22, -10, -31, -1,
315 -18, -9, 11, 37, -4, 45, 5, 41,
316 17, 1, 1, 24, -58, 41, 5, -51,
317 14, 8, 43, 16, -10, -1, 45, 32,
318 -64, 3, -33, -25, -3, -27, -68, 12,
319 23, -11, -13, -37, -40, 4, -21, -12,
320 32, -23, -19, 76, 41, -23, -24, -44,
321 -65, -1, -15, 1, 71, 63, 5, 20,
322 -3, 21, -23, 31, -32, 18, -2, 27,
323 31, 46, -5, -39, -5, -35, 18, -18,
324 -40, -10, 3, 12, 2, -2, -22, 40,
325 5, -6, 60, 36, 3, 29, -27, 10,
326 25, -54, 5, 26, 39, 35, -24, -37,
327 30, -91, 28, -4, -21, -27, -39, -6,
328 5, 12, -128, 38, -16, 29, -95, -29,
329 82, -2, 35, 2, 12, 8, -22, 10,
330 80, -47, 2, -25, -73, -79, 16, -30,
331 -32, -66, 48, 21, -45, -11, -47, 14,
332 -27, -17, -7, 15, -44, -14, -44, -26,
333 -32, 26, -23, 17, -7, -28, 26, -6,
334 28, 6, -26, 2, 13, -14, -23, -14,
335 19, 46, 16, 2, -33, -21, 28, -17,
336 -42, 44, -37, 1, -39, 28, 84, -46,
337 15, 10, 13, -44, 72, -26, 26, 32,
338 -28, -12, -83, 2, 10, -30, -44, -10,
339 -28, 53, 45, 65, 0, -25, 57, 36,
340 -33, 6, 29, 44, -53, 11, 19, -2,
341 -27, 35, 32, 49, 4, 23, 38, 36,
342 24, 10, 51, -39, 4, -7, 26, 37,
343 -35, 11, -47, -18, 28, 16, -35, 42,
344 17, -21, -41, 28, 14, -12, 11, -45,
345 7, -43, -15, 18, -5, 38, -40, -50,
346 -30, -21, 9, -98, 13, 12, 23, 75,
347 -56, -7, -3, -4, -1, -34, 12, -49,
348 11, 26, -18, -28, -17, 33, 13, -14,
349 40, 24, -72, -37, 10, 17, -6, 22,
350 16, 16, -6, -12, -30, -14, 10, 40,
351 -23, 12, 15, -3, -15, 13, -56, -4,
352 -30, 1, -3, -17, 27, 50, -5, 64,
353 -36, -19, 7, 29, 22, 25, 9, -16,
354 -58, -69, -40, -61, -71, -14, 42, 93,
355 26, 11, -6, -58, -11, 70, -52, 19,
356 9, -30, -33, 11, -37, -47, -21, -22,
357 -40, 10, 47, 4, -23, 17, 48, 41,
358 -48, 14, 10, 15, 34, -23, -2, -47,
359 23, -32, -13, -10, -26, -26, -4, 16,
360 38, -14, 0, -12, -7, -7, 20, 44,
361 -1, -32, -27, -16, 4, -6, -18, 14,
362 5, 4, -29, 28, 7, -7, 15, -11,
363 -20, -45, -36, 16, 84, 34, -59, -30,
364 22, 126, 8, 68, 79, -17, 21, -68,
365 37, 5, 15, 63, 49, 127, -90, 85,
366 43, 7, 16, 9, 6, -45, -57, -43,
367 57, 11, -23, -11, -29, 60, -26, 0,
368 7, 42, -24, 10, 23, -25, 8, -7,
369 -40, 19, -17, 35, 4, 27, -39, -91,
370 27, -36, 34, 2, 16, -24, 25, 7,
371 -21, 5, 17, 10, -22, -30, 9, -17,
372 -61, -26, 33, 21, 58, -51, -14, 69,
373 -38, 20, 7, 80, -4, -65, -6, -27,
374 53, -12, 47, -1, -15, 1, 60, 102,
375 -79, -4, 12, 9, 22, 37, -8, -4,
376 37, 2, -3, -15, -16, -11, -5, 19,
377 -6, -43, 20, -25, -18, 10, -27, 0,
378 -28, -27, -11, 10, -18, -2, -4, -16,
379 26, 14, -6, 7, -6, 1, 53, -2,
380 -29, 23, 9, -30, -6, -4, -6, 56,
381 70, 0, -33, -20, -17, -9, -24, 46,
382 -5, -105, 47, -46, -51, 20, 20, -53,
383 -81, -1, -7, 75, -5, -21, -65, 12,
384 -52, 22, -50, -12, 49, 54, 76, -81,
385 10, 45, -41, -59, 18, -19, 25, 14,
386 -31, -53, -5, 12, 31, 84, -23, 2,
387 7, 2, 10, -32, 39, -2, -12, 1,
388 -9, 0, -10, -11, 9, 15, -8, -2,
389 2, -1, 10, 14, -5, -40, 19, -7,
390 -7, 26, -4, 2, 1, -27, 35, 32,
391 21, -31, 26, 43, -9, 4, -32, 40,
392 -62, -52, 36, 22, 38, 22, 36, -96,
393 6, -10, -23, -49, 15, -33, -18, -3,
394 0, 41, 21, -19, 21, 23, -39, -23,
395 -6, 6, 47, 56, 4, 74, 0, -98,
396 29, -47, -14, -36, 21, -22, 22, 16,
397 13, 12, 16, -5, 13, 17, -13, -15,
398 1, -34, -26, 26, 12, 32, 27, 13,
399 -67, 27, 2, 8, 10, 18, 16, 20,
400 -17, -17, 57, -64, 5, 14, 19, 31,
401 -18, -44, -46, -16, 4, -25, 17, -126,
402 -24, 39, 4, 8, 55, -25, -34, 39,
403 -16, 3, 9, 71, 72, -31, -55, 6,
404 10, -25, 32, -85, -21, 18, -8, 15,
405 12, -27, -7, 1, -21, -2, -5, 48,
406 -16, 18, 1, -22, -26, 16, 14, -31,
407 27, -6, -15, -21, 4, -14, 18, -36
408};
409
410static const opus_int8 layer1_recur_weights[1728] = {
411 20, 67, -99, 12, 41, -25, 49, -44,
412 35, 81, 110, 47, 34, -66, -14, 14,
413 -60, 34, 29, -73, 10, 41, 35, 89,
414 7, -35, 22, 7, 27, -20, -6, 56,
415 26, 66, 6, 33, -55, 53, 1, -21,
416 14, 17, 68, 55, 59, 0, 18, -9,
417 5, -41, 6, -5, -114, -12, 29, 42,
418 -23, 10, 81, -27, 20, -53, -30, -62,
419 40, 95, 25, -4, 3, 18, -8, -15,
420 -29, -82, 2, -57, -3, -61, -29, -29,
421 49, 2, -55, 5, -69, -99, -49, -51,
422 6, -25, 12, 89, 44, -33, 5, 41,
423 1, 23, -37, -37, -28, -48, 3, 4,
424 -41, -30, -57, -35, -39, -1, -13, -56,
425 -5, 50, 49, 41, -4, -4, 33, -22,
426 -1, 33, 34, 18, 40, -42, 12, 1,
427 -6, -2, 18, 17, 39, 44, 11, 65,
428 -60, -45, 10, 91, 21, 9, -62, -11,
429 8, 69, 37, 24, -30, 21, 26, -27,
430 1, -28, 24, 66, -8, 6, -71, 34,
431 24, 44, 58, -78, -19, 57, 17, -60,
432 1, 12, -3, -1, -40, 22, 11, -5,
433 25, 12, 1, 72, 79, 7, -50, 23,
434 18, 13, 21, -11, -20, 5, 77, -94,
435 24, 15, 57, -51, 3, 36, 53, -1,
436 4, 14, 30, -31, 22, 40, 32, -11,
437 -34, -36, -59, 58, 25, 21, -54, -23,
438 40, 46, 18, 0, 12, 54, -96, -99,
439 -59, 5, 119, -38, 50, 55, 12, -16,
440 67, 0, 34, 35, 39, 35, -1, 69,
441 24, 27, -30, -35, -4, -70, 2, -44,
442 -7, -6, 19, -9, 60, 44, -21, -10,
443 37, 43, -16, -3, 30, -15, -65, 31,
444 -55, 18, -98, 76, 64, 25, 24, -18,
445 -7, -68, -10, 38, 27, -60, 36, 33,
446 16, 30, 34, -39, -37, 31, 12, 53,
447 -54, 14, -26, -49, -128, -13, -5, -22,
448 -11, -85, 55, -8, -51, -11, -33, -10,
449 -31, -76, -41, 23, 44, -40, -54, -127,
450 -101, 19, -23, -15, 15, 27, 58, -60,
451 8, 14, -33, 1, 48, -9, -11, -123,
452 3, 53, 23, 4, -28, 22, 2, -29,
453 -67, 36, 12, 7, 55, -21, 88, 20,
454 -1, -21, -17, 3, 41, 32, -10, -14,
455 -5, -57, 67, 57, 21, 23, -2, -27,
456 -73, -24, 120, 21, 18, -35, 42, -7,
457 3, -45, -25, 76, -34, 50, 11, -54,
458 -91, 3, -113, -20, -5, 47, 15, -47,
459 17, 27, -3, -26, -7, 10, 7, 74,
460 -40, 64, -7, -5, -24, -49, -24, -3,
461 -10, 27, -17, -8, -3, 14, -27, 33,
462 13, 39, 28, -7, -38, 29, 16, 44,
463 19, 55, -3, 9, -13, -57, 43, 43,
464 31, 0, -93, -17, 19, -56, 4, -12,
465 -25, 37, -85, -13, -118, 33, -17, 56,
466 71, -80, -4, 6, -11, -18, 47, -52,
467 25, 9, 48, -107, 1, 21, 20, -3,
468 10, -16, -4, 24, 17, 31, -61, -18,
469 -50, 24, -10, 12, 71, 26, 11, -3,
470 4, 1, 0, -7, -40, 18, 38, -34,
471 38, 17, 8, -34, 2, 21, 123, -32,
472 -26, 43, 14, -34, -1, -9, 37, -16,
473 6, -17, -62, 68, 22, 17, 11, -75,
474 33, -80, 62, -9, -75, 76, 36, -41,
475 -8, -40, -11, -71, 40, -39, 62, -49,
476 -81, 16, -9, -52, 52, 61, 17, -103,
477 -27, -10, -8, -54, -57, 21, 23, -16,
478 -52, 36, 18, 10, -5, 8, 15, -29,
479 5, -19, -37, 8, -53, 6, 19, -37,
480 38, -17, 48, 10, 0, 81, 46, 70,
481 -29, 101, 11, 44, -44, -3, 24, 11,
482 3, 14, -9, 11, 14, -45, 13, 46,
483 -3, -57, 68, 44, 63, 98, 25, -28,
484 -23, 15, 32, -10, 53, -6, -2, -9,
485 -6, 16, -107, -11, -11, -28, 59, 57,
486 -22, 38, 42, 83, 27, 5, 29, -30,
487 12, -21, -13, 31, 38, -21, 58, -10,
488 -10, -15, -2, -5, 11, 12, -73, -28,
489 -38, 22, 2, -25, 73, -52, -12, -55,
490 32, -63, 21, 51, 33, 52, -26, 55,
491 -26, -26, 57, -32, -4, -52, -61, 21,
492 -33, -91, -51, 69, -90, -53, -38, -44,
493 12, -76, -20, 77, -45, -7, 86, 43,
494 -109, -33, -105, -40, -121, -10, 0, -72,
495 45, -51, -75, -49, -38, -1, -62, 18,
496 -1, 30, -44, -14, -10, -67, 40, -10,
497 -34, 46, -64, -32, 29, -13, 33, 3,
498 -32, -5, 28, -27, -25, 93, 24, 68,
499 -40, 57, 23, -3, -21, -58, 17, -39,
500 -17, -22, -89, 11, 18, -46, 27, 24,
501 46, 127, 61, 87, 31, 127, -36, 47,
502 -23, 47, 127, -24, 110, 122, 30, 100,
503 0, 96, -12, 6, 50, 44, -13, 73,
504 4, 55, -11, -15, 49, 42, -6, 20,
505 -35, 58, 18, 38, 42, 72, 19, -21,
506 11, 9, -37, 7, 29, 31, 16, -17,
507 13, -50, 19, 5, -23, 51, -16, -5,
508 4, -24, 76, 10, -53, -28, -7, -65,
509 74, 40, -16, -29, 32, -16, -49, -35,
510 -3, 59, -96, -50, -43, -43, -61, -15,
511 -8, -36, -34, -33, -14, 11, -3, -39,
512 4, -114, -123, -11, -49, -21, 14, -56,
513 1, 43, -63, 26, 40, 18, -10, -26,
514 -14, -15, -35, -35, -11, 32, -44, -67,
515 2, 22, 7, 3, -9, -30, -51, -28,
516 28, 6, -22, 16, 34, -25, -52, -54,
517 -8, -6, 5, 8, 20, -16, -17, -44,
518 27, 3, 31, -5, -48, -1, -3, 116,
519 11, 71, -31, -47, 109, 50, -22, -12,
520 -57, 32, 66, 8, -25, -93, -54, -10,
521 19, -76, -34, 97, 48, -36, -18, -30,
522 -39, -26, -12, 28, 14, 12, -12, -31,
523 38, 2, 10, 4, -40, 20, 16, -61,
524 2, 64, 39, 5, 15, 33, 40, -61,
525 -49, 93, -10, 33, 28, -11, -27, -18,
526 39, -62, -6, -6, 62, 11, -8, 38,
527 -67, 12, 27, 39, -27, 123, -18, -6,
528 -65, 83, -64, 20, 19, -11, 33, 24,
529 17, 56, 78, 7, -15, 54, -101, -9,
530 115, -96, 50, 51, 35, 34, 27, 37,
531 -40, -11, 8, -36, 42, -45, 2, -23,
532 0, 67, -8, -9, -13, 50, -14, -27,
533 4, 0, -8, -14, 30, -9, 29, 15,
534 9, -38, 37, -8, 50, -46, 54, 41,
535 -11, -8, -11, -26, 39, 45, 14, -26,
536 -17, -27, 69, 38, 39, 98, 66, 0,
537 42, 123, -101, -19, -83, 117, -32, 56,
538 10, 12, -88, 79, -53, 56, 63, 95,
539 -62, 9, 36, -13, -79, -16, 37, -46,
540 35, -34, 14, 17, -54, 5, 21, -7,
541 7, 63, 56, 15, 27, -76, -25, 4,
542 -26, -63, 28, -67, -52, 43, -47, -70,
543 40, -12, 40, -66, -37, 0, 35, 37,
544 -53, 4, -17, -51, 11, 21, 14, -34,
545 -4, 24, -42, 29, 22, 7, 28, 12,
546 37, 39, -39, -19, 65, -60, -50, -2,
547 1, 82, 39, 19, -23, -43, -22, -67,
548 -35, -34, 32, 102, 81, 127, 36, 67,
549 -45, 1, -67, -52, -4, 35, 20, 28,
550 71, 86, -35, -9, -83, -34, 12, 9,
551 -23, 2, 14, 28, -23, 7, -25, 45,
552 7, 17, -37, 0, -19, 31, 26, 40,
553 -27, -16, 17, 5, -21, 23, 24, 96,
554 -55, 52, -19, -14, -6, 1, 50, -34,
555 86, -53, 38, 2, -52, -36, -13, 60,
556 -85, -120, 32, 7, -12, 22, 70, -7,
557 -94, 38, -76, -31, -20, 15, -28, 7,
558 6, 40, 53, 88, 3, 38, 18, -8,
559 -22, -23, 51, 37, -9, 13, -32, 25,
560 -21, 27, 31, 20, 18, -9, -13, 1,
561 21, -24, -13, 39, 15, -11, -29, -36,
562 18, 15, 8, 27, 21, -94, -1, -22,
563 49, 66, -1, 6, -3, -40, -18, 6,
564 28, 12, 33, -59, 62, 60, -48, 90,
565 -1, 108, 9, 18, -2, 27, 77, -65,
566 82, -48, -38, -19, -11, 127, 50, 66,
567 18, -13, -22, 60, -38, 40, -14, -26,
568 -13, 38, 67, 57, 30, 33, 26, 36,
569 38, -17, 27, -28, 20, 12, -64, 18,
570 5, -33, -27, 13, -26, 32, 35, -5,
571 -48, -14, 92, 43, -47, -14, 40, 11,
572 51, 66, 22, -63, -16, -61, 4, -28,
573 27, 20, -33, -30, -21, -29, -53, 31,
574 -40, 24, 43, -4, -19, 21, 67, 20,
575 100, -16, -93, 78, -6, -18, -52, -37,
576 -9, 66, -31, -8, 26, 18, 4, 24,
577 -22, 17, -2, -13, 27, 0, 8, -18,
578 -25, 5, -21, -24, -7, 18, -93, 21,
579 7, 2, -75, 69, 50, -5, -15, -17,
580 60, -42, 55, 1, -4, 3, 10, 46,
581 16, -13, 45, -7, -10, -44, -108, 49,
582 2, -15, -64, -12, -72, 32, -38, -45,
583 10, -54, 13, -13, -27, -36, -64, 58,
584 -62, -101, 88, -86, -71, -39, -9, -128,
585 32, 15, -4, 54, -16, -39, -26, -36,
586 46, 48, -64, -10, 19, 30, -13, 34,
587 -8, 50, 60, -22, -6, -11, -30, 5,
588 50, 32, 56, 0, 25, 6, 68, 11,
589 -29, 45, -9, -12, 4, 1, 18, -49,
590 0, -38, -19, 90, 29, 35, 51, 8,
591 -48, 96, -1, -12, -9, -32, -63, -65,
592 -7, 38, 89, 28, -85, -28, -23, -25,
593 -128, 56, 79, -36, 99, -6, -37, 7,
594 -13, -69, -46, -29, 25, 64, -21, 17,
595 1, 42, -66, 1, 80, 26, -32, 21,
596 15, 15, 6, 6, -10, 15, 127, 5,
597 38, 27, 87, -57, -25, 11, 72, -21,
598 -5, 11, -13, -66, 78, 36, -3, 41,
599 -21, 8, -33, 23, 73, 28, 57, -25,
600 -5, 4, -22, -47, 15, 4, -57, -72,
601 33, 1, 18, 2, 53, -71, -99, -21,
602 -3, -111, 108, 71, -14, 82, 25, 61,
603 -48, 5, 9, -51, -20, -25, -3, 14,
604 -33, 14, -3, -34, 22, 12, -19, -38,
605 -16, 2, 21, 16, 26, -31, 75, 44,
606 -31, 16, 26, 66, 17, -9, -22, -22,
607 22, -44, 22, 27, 2, 58, -14, 10,
608 -73, -42, 55, -25, -61, 72, -1, 30,
609 -58, -25, 63, 26, -48, -40, 26, -30,
610 60, 8, -17, -1, -18, -20, 43, -20,
611 -4, -28, 127, -106, 29, 70, 64, -27,
612 39, -33, -5, -88, -40, -52, 26, 44,
613 -17, 23, 2, -49, 22, -9, -8, 86,
614 49, -43, -60, 1, 10, 45, 36, -53,
615 -4, 33, 38, 48, -72, 1, 19, 21,
616 -65, 4, -5, -62, 27, -25, 17, -6,
617 6, -45, -39, -46, 4, 26, 127, -9,
618 18, -33, -18, -3, 33, 2, -5, 15,
619 -26, -22, -117, -63, -17, -59, 61, -74,
620 7, -47, -58, -128, -67, 15, -16, -128,
621 12, 2, 20, 9, -48, -40, 43, 3,
622 -40, -16, -38, -6, -22, -28, -16, -59,
623 -22, 6, -5, 11, -12, -66, -40, 27,
624 -62, -44, -19, 38, -3, 39, -8, 40,
625 -24, 13, 21, 50, -60, -22, 53, -29,
626 -6, 1, 22, -59, 0, 17, -39, 115
627};
628
629static const opus_int8 layer1_bias[72] = {
630 -42, 20, 16, 0, 105, 60, 1, -97,
631 24, 60, 18, 13, 62, 25, 127, 34,
632 79, 55, 118, 127, 95, 31, -4, 87,
633 21, 12, 2, -14, 18, 23, 8, 17,
634 -1, -8, 5, 4, 24, 37, 21, 13,
635 36, 13, 17, 18, 37, 30, 33, 1,
636 8, -16, -11, -5, -31, -3, -5, 0,
637 6, 3, 58, -7, -1, -16, 5, -13,
638 16, 10, -2, -14, 11, -4, 3, -11
639};
640
641static const opus_int8 layer2_weights[48] = {
642 -113, -88, 31, -128, -126, -61, 85, -35,
643 118, -128, -61, 127, -128, -17, -128, 127,
644 104, -9, -128, 33, 45, 127, 5, 83,
645 84, -128, -85, -128, -45, 48, -53, -128,
646 46, 127, -17, 125, 117, -41, -117, -91,
647 -127, -68, -1, -89, -80, 32, 106, 7
648};
649
650static const opus_int8 layer2_bias[2] = {
651 14, 117
652};
653
654const DenseLayer layer0 = {
655 layer0_bias,
656 layer0_weights,
657 25, 32, 0
658};
659
660const GRULayer layer1 = {
661 layer1_bias,
662 layer1_weights,
663 layer1_recur_weights,
664 32, 24
665};
666
667const DenseLayer layer2 = {
668 layer2_bias,
669 layer2_weights,
670 24, 2, 1
671};
672
diff --git a/lib/rbcodec/codecs/libopus/ogg/crctable.h b/lib/rbcodec/codecs/libopus/ogg/crctable.h
new file mode 100644
index 0000000000..d1fdbc7e63
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/ogg/crctable.h
@@ -0,0 +1,278 @@
1/********************************************************************
2 * *
3 * THIS FILE IS PART OF THE Ogg CONTAINER SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7 * *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2018 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
10 * *
11 ********************************************************************/
12
13#include "os_types.h"
14
15static const ogg_uint32_t crc_lookup[8][256]={
16{0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
17 0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
18 0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
19 0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
20 0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
21 0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
22 0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
23 0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
24 0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
25 0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
26 0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
27 0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
28 0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
29 0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
30 0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
31 0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
32 0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
33 0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
34 0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
35 0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
36 0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
37 0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
38 0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
39 0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
40 0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
41 0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
42 0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
43 0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
44 0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
45 0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
46 0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
47 0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4},
48
49{0x00000000,0xd219c1dc,0xa0f29e0f,0x72eb5fd3,0x452421a9,0x973de075,0xe5d6bfa6,0x37cf7e7a,
50 0x8a484352,0x5851828e,0x2abadd5d,0xf8a31c81,0xcf6c62fb,0x1d75a327,0x6f9efcf4,0xbd873d28,
51 0x10519b13,0xc2485acf,0xb0a3051c,0x62bac4c0,0x5575baba,0x876c7b66,0xf58724b5,0x279ee569,
52 0x9a19d841,0x4800199d,0x3aeb464e,0xe8f28792,0xdf3df9e8,0x0d243834,0x7fcf67e7,0xadd6a63b,
53 0x20a33626,0xf2baf7fa,0x8051a829,0x524869f5,0x6587178f,0xb79ed653,0xc5758980,0x176c485c,
54 0xaaeb7574,0x78f2b4a8,0x0a19eb7b,0xd8002aa7,0xefcf54dd,0x3dd69501,0x4f3dcad2,0x9d240b0e,
55 0x30f2ad35,0xe2eb6ce9,0x9000333a,0x4219f2e6,0x75d68c9c,0xa7cf4d40,0xd5241293,0x073dd34f,
56 0xbabaee67,0x68a32fbb,0x1a487068,0xc851b1b4,0xff9ecfce,0x2d870e12,0x5f6c51c1,0x8d75901d,
57 0x41466c4c,0x935fad90,0xe1b4f243,0x33ad339f,0x04624de5,0xd67b8c39,0xa490d3ea,0x76891236,
58 0xcb0e2f1e,0x1917eec2,0x6bfcb111,0xb9e570cd,0x8e2a0eb7,0x5c33cf6b,0x2ed890b8,0xfcc15164,
59 0x5117f75f,0x830e3683,0xf1e56950,0x23fca88c,0x1433d6f6,0xc62a172a,0xb4c148f9,0x66d88925,
60 0xdb5fb40d,0x094675d1,0x7bad2a02,0xa9b4ebde,0x9e7b95a4,0x4c625478,0x3e890bab,0xec90ca77,
61 0x61e55a6a,0xb3fc9bb6,0xc117c465,0x130e05b9,0x24c17bc3,0xf6d8ba1f,0x8433e5cc,0x562a2410,
62 0xebad1938,0x39b4d8e4,0x4b5f8737,0x994646eb,0xae893891,0x7c90f94d,0x0e7ba69e,0xdc626742,
63 0x71b4c179,0xa3ad00a5,0xd1465f76,0x035f9eaa,0x3490e0d0,0xe689210c,0x94627edf,0x467bbf03,
64 0xfbfc822b,0x29e543f7,0x5b0e1c24,0x8917ddf8,0xbed8a382,0x6cc1625e,0x1e2a3d8d,0xcc33fc51,
65 0x828cd898,0x50951944,0x227e4697,0xf067874b,0xc7a8f931,0x15b138ed,0x675a673e,0xb543a6e2,
66 0x08c49bca,0xdadd5a16,0xa83605c5,0x7a2fc419,0x4de0ba63,0x9ff97bbf,0xed12246c,0x3f0be5b0,
67 0x92dd438b,0x40c48257,0x322fdd84,0xe0361c58,0xd7f96222,0x05e0a3fe,0x770bfc2d,0xa5123df1,
68 0x189500d9,0xca8cc105,0xb8679ed6,0x6a7e5f0a,0x5db12170,0x8fa8e0ac,0xfd43bf7f,0x2f5a7ea3,
69 0xa22feebe,0x70362f62,0x02dd70b1,0xd0c4b16d,0xe70bcf17,0x35120ecb,0x47f95118,0x95e090c4,
70 0x2867adec,0xfa7e6c30,0x889533e3,0x5a8cf23f,0x6d438c45,0xbf5a4d99,0xcdb1124a,0x1fa8d396,
71 0xb27e75ad,0x6067b471,0x128ceba2,0xc0952a7e,0xf75a5404,0x254395d8,0x57a8ca0b,0x85b10bd7,
72 0x383636ff,0xea2ff723,0x98c4a8f0,0x4add692c,0x7d121756,0xaf0bd68a,0xdde08959,0x0ff94885,
73 0xc3cab4d4,0x11d37508,0x63382adb,0xb121eb07,0x86ee957d,0x54f754a1,0x261c0b72,0xf405caae,
74 0x4982f786,0x9b9b365a,0xe9706989,0x3b69a855,0x0ca6d62f,0xdebf17f3,0xac544820,0x7e4d89fc,
75 0xd39b2fc7,0x0182ee1b,0x7369b1c8,0xa1707014,0x96bf0e6e,0x44a6cfb2,0x364d9061,0xe45451bd,
76 0x59d36c95,0x8bcaad49,0xf921f29a,0x2b383346,0x1cf74d3c,0xceee8ce0,0xbc05d333,0x6e1c12ef,
77 0xe36982f2,0x3170432e,0x439b1cfd,0x9182dd21,0xa64da35b,0x74546287,0x06bf3d54,0xd4a6fc88,
78 0x6921c1a0,0xbb38007c,0xc9d35faf,0x1bca9e73,0x2c05e009,0xfe1c21d5,0x8cf77e06,0x5eeebfda,
79 0xf33819e1,0x2121d83d,0x53ca87ee,0x81d34632,0xb61c3848,0x6405f994,0x16eea647,0xc4f7679b,
80 0x79705ab3,0xab699b6f,0xd982c4bc,0x0b9b0560,0x3c547b1a,0xee4dbac6,0x9ca6e515,0x4ebf24c9},
81
82{0x00000000,0x01d8ac87,0x03b1590e,0x0269f589,0x0762b21c,0x06ba1e9b,0x04d3eb12,0x050b4795,
83 0x0ec56438,0x0f1dc8bf,0x0d743d36,0x0cac91b1,0x09a7d624,0x087f7aa3,0x0a168f2a,0x0bce23ad,
84 0x1d8ac870,0x1c5264f7,0x1e3b917e,0x1fe33df9,0x1ae87a6c,0x1b30d6eb,0x19592362,0x18818fe5,
85 0x134fac48,0x129700cf,0x10fef546,0x112659c1,0x142d1e54,0x15f5b2d3,0x179c475a,0x1644ebdd,
86 0x3b1590e0,0x3acd3c67,0x38a4c9ee,0x397c6569,0x3c7722fc,0x3daf8e7b,0x3fc67bf2,0x3e1ed775,
87 0x35d0f4d8,0x3408585f,0x3661add6,0x37b90151,0x32b246c4,0x336aea43,0x31031fca,0x30dbb34d,
88 0x269f5890,0x2747f417,0x252e019e,0x24f6ad19,0x21fdea8c,0x2025460b,0x224cb382,0x23941f05,
89 0x285a3ca8,0x2982902f,0x2beb65a6,0x2a33c921,0x2f388eb4,0x2ee02233,0x2c89d7ba,0x2d517b3d,
90 0x762b21c0,0x77f38d47,0x759a78ce,0x7442d449,0x714993dc,0x70913f5b,0x72f8cad2,0x73206655,
91 0x78ee45f8,0x7936e97f,0x7b5f1cf6,0x7a87b071,0x7f8cf7e4,0x7e545b63,0x7c3daeea,0x7de5026d,
92 0x6ba1e9b0,0x6a794537,0x6810b0be,0x69c81c39,0x6cc35bac,0x6d1bf72b,0x6f7202a2,0x6eaaae25,
93 0x65648d88,0x64bc210f,0x66d5d486,0x670d7801,0x62063f94,0x63de9313,0x61b7669a,0x606fca1d,
94 0x4d3eb120,0x4ce61da7,0x4e8fe82e,0x4f5744a9,0x4a5c033c,0x4b84afbb,0x49ed5a32,0x4835f6b5,
95 0x43fbd518,0x4223799f,0x404a8c16,0x41922091,0x44996704,0x4541cb83,0x47283e0a,0x46f0928d,
96 0x50b47950,0x516cd5d7,0x5305205e,0x52dd8cd9,0x57d6cb4c,0x560e67cb,0x54679242,0x55bf3ec5,
97 0x5e711d68,0x5fa9b1ef,0x5dc04466,0x5c18e8e1,0x5913af74,0x58cb03f3,0x5aa2f67a,0x5b7a5afd,
98 0xec564380,0xed8eef07,0xefe71a8e,0xee3fb609,0xeb34f19c,0xeaec5d1b,0xe885a892,0xe95d0415,
99 0xe29327b8,0xe34b8b3f,0xe1227eb6,0xe0fad231,0xe5f195a4,0xe4293923,0xe640ccaa,0xe798602d,
100 0xf1dc8bf0,0xf0042777,0xf26dd2fe,0xf3b57e79,0xf6be39ec,0xf766956b,0xf50f60e2,0xf4d7cc65,
101 0xff19efc8,0xfec1434f,0xfca8b6c6,0xfd701a41,0xf87b5dd4,0xf9a3f153,0xfbca04da,0xfa12a85d,
102 0xd743d360,0xd69b7fe7,0xd4f28a6e,0xd52a26e9,0xd021617c,0xd1f9cdfb,0xd3903872,0xd24894f5,
103 0xd986b758,0xd85e1bdf,0xda37ee56,0xdbef42d1,0xdee40544,0xdf3ca9c3,0xdd555c4a,0xdc8df0cd,
104 0xcac91b10,0xcb11b797,0xc978421e,0xc8a0ee99,0xcdaba90c,0xcc73058b,0xce1af002,0xcfc25c85,
105 0xc40c7f28,0xc5d4d3af,0xc7bd2626,0xc6658aa1,0xc36ecd34,0xc2b661b3,0xc0df943a,0xc10738bd,
106 0x9a7d6240,0x9ba5cec7,0x99cc3b4e,0x981497c9,0x9d1fd05c,0x9cc77cdb,0x9eae8952,0x9f7625d5,
107 0x94b80678,0x9560aaff,0x97095f76,0x96d1f3f1,0x93dab464,0x920218e3,0x906bed6a,0x91b341ed,
108 0x87f7aa30,0x862f06b7,0x8446f33e,0x859e5fb9,0x8095182c,0x814db4ab,0x83244122,0x82fceda5,
109 0x8932ce08,0x88ea628f,0x8a839706,0x8b5b3b81,0x8e507c14,0x8f88d093,0x8de1251a,0x8c39899d,
110 0xa168f2a0,0xa0b05e27,0xa2d9abae,0xa3010729,0xa60a40bc,0xa7d2ec3b,0xa5bb19b2,0xa463b535,
111 0xafad9698,0xae753a1f,0xac1ccf96,0xadc46311,0xa8cf2484,0xa9178803,0xab7e7d8a,0xaaa6d10d,
112 0xbce23ad0,0xbd3a9657,0xbf5363de,0xbe8bcf59,0xbb8088cc,0xba58244b,0xb831d1c2,0xb9e97d45,
113 0xb2275ee8,0xb3fff26f,0xb19607e6,0xb04eab61,0xb545ecf4,0xb49d4073,0xb6f4b5fa,0xb72c197d},
114
115{0x00000000,0xdc6d9ab7,0xbc1a28d9,0x6077b26e,0x7cf54c05,0xa098d6b2,0xc0ef64dc,0x1c82fe6b,
116 0xf9ea980a,0x258702bd,0x45f0b0d3,0x999d2a64,0x851fd40f,0x59724eb8,0x3905fcd6,0xe5686661,
117 0xf7142da3,0x2b79b714,0x4b0e057a,0x97639fcd,0x8be161a6,0x578cfb11,0x37fb497f,0xeb96d3c8,
118 0x0efeb5a9,0xd2932f1e,0xb2e49d70,0x6e8907c7,0x720bf9ac,0xae66631b,0xce11d175,0x127c4bc2,
119 0xeae946f1,0x3684dc46,0x56f36e28,0x8a9ef49f,0x961c0af4,0x4a719043,0x2a06222d,0xf66bb89a,
120 0x1303defb,0xcf6e444c,0xaf19f622,0x73746c95,0x6ff692fe,0xb39b0849,0xd3ecba27,0x0f812090,
121 0x1dfd6b52,0xc190f1e5,0xa1e7438b,0x7d8ad93c,0x61082757,0xbd65bde0,0xdd120f8e,0x017f9539,
122 0xe417f358,0x387a69ef,0x580ddb81,0x84604136,0x98e2bf5d,0x448f25ea,0x24f89784,0xf8950d33,
123 0xd1139055,0x0d7e0ae2,0x6d09b88c,0xb164223b,0xade6dc50,0x718b46e7,0x11fcf489,0xcd916e3e,
124 0x28f9085f,0xf49492e8,0x94e32086,0x488eba31,0x540c445a,0x8861deed,0xe8166c83,0x347bf634,
125 0x2607bdf6,0xfa6a2741,0x9a1d952f,0x46700f98,0x5af2f1f3,0x869f6b44,0xe6e8d92a,0x3a85439d,
126 0xdfed25fc,0x0380bf4b,0x63f70d25,0xbf9a9792,0xa31869f9,0x7f75f34e,0x1f024120,0xc36fdb97,
127 0x3bfad6a4,0xe7974c13,0x87e0fe7d,0x5b8d64ca,0x470f9aa1,0x9b620016,0xfb15b278,0x277828cf,
128 0xc2104eae,0x1e7dd419,0x7e0a6677,0xa267fcc0,0xbee502ab,0x6288981c,0x02ff2a72,0xde92b0c5,
129 0xcceefb07,0x108361b0,0x70f4d3de,0xac994969,0xb01bb702,0x6c762db5,0x0c019fdb,0xd06c056c,
130 0x3504630d,0xe969f9ba,0x891e4bd4,0x5573d163,0x49f12f08,0x959cb5bf,0xf5eb07d1,0x29869d66,
131 0xa6e63d1d,0x7a8ba7aa,0x1afc15c4,0xc6918f73,0xda137118,0x067eebaf,0x660959c1,0xba64c376,
132 0x5f0ca517,0x83613fa0,0xe3168dce,0x3f7b1779,0x23f9e912,0xff9473a5,0x9fe3c1cb,0x438e5b7c,
133 0x51f210be,0x8d9f8a09,0xede83867,0x3185a2d0,0x2d075cbb,0xf16ac60c,0x911d7462,0x4d70eed5,
134 0xa81888b4,0x74751203,0x1402a06d,0xc86f3ada,0xd4edc4b1,0x08805e06,0x68f7ec68,0xb49a76df,
135 0x4c0f7bec,0x9062e15b,0xf0155335,0x2c78c982,0x30fa37e9,0xec97ad5e,0x8ce01f30,0x508d8587,
136 0xb5e5e3e6,0x69887951,0x09ffcb3f,0xd5925188,0xc910afe3,0x157d3554,0x750a873a,0xa9671d8d,
137 0xbb1b564f,0x6776ccf8,0x07017e96,0xdb6ce421,0xc7ee1a4a,0x1b8380fd,0x7bf43293,0xa799a824,
138 0x42f1ce45,0x9e9c54f2,0xfeebe69c,0x22867c2b,0x3e048240,0xe26918f7,0x821eaa99,0x5e73302e,
139 0x77f5ad48,0xab9837ff,0xcbef8591,0x17821f26,0x0b00e14d,0xd76d7bfa,0xb71ac994,0x6b775323,
140 0x8e1f3542,0x5272aff5,0x32051d9b,0xee68872c,0xf2ea7947,0x2e87e3f0,0x4ef0519e,0x929dcb29,
141 0x80e180eb,0x5c8c1a5c,0x3cfba832,0xe0963285,0xfc14ccee,0x20795659,0x400ee437,0x9c637e80,
142 0x790b18e1,0xa5668256,0xc5113038,0x197caa8f,0x05fe54e4,0xd993ce53,0xb9e47c3d,0x6589e68a,
143 0x9d1cebb9,0x4171710e,0x2106c360,0xfd6b59d7,0xe1e9a7bc,0x3d843d0b,0x5df38f65,0x819e15d2,
144 0x64f673b3,0xb89be904,0xd8ec5b6a,0x0481c1dd,0x18033fb6,0xc46ea501,0xa419176f,0x78748dd8,
145 0x6a08c61a,0xb6655cad,0xd612eec3,0x0a7f7474,0x16fd8a1f,0xca9010a8,0xaae7a2c6,0x768a3871,
146 0x93e25e10,0x4f8fc4a7,0x2ff876c9,0xf395ec7e,0xef171215,0x337a88a2,0x530d3acc,0x8f60a07b},
147
148{0x00000000,0x490d678d,0x921acf1a,0xdb17a897,0x20f48383,0x69f9e40e,0xb2ee4c99,0xfbe32b14,
149 0x41e90706,0x08e4608b,0xd3f3c81c,0x9afeaf91,0x611d8485,0x2810e308,0xf3074b9f,0xba0a2c12,
150 0x83d20e0c,0xcadf6981,0x11c8c116,0x58c5a69b,0xa3268d8f,0xea2bea02,0x313c4295,0x78312518,
151 0xc23b090a,0x8b366e87,0x5021c610,0x192ca19d,0xe2cf8a89,0xabc2ed04,0x70d54593,0x39d8221e,
152 0x036501af,0x4a686622,0x917fceb5,0xd872a938,0x2391822c,0x6a9ce5a1,0xb18b4d36,0xf8862abb,
153 0x428c06a9,0x0b816124,0xd096c9b3,0x999bae3e,0x6278852a,0x2b75e2a7,0xf0624a30,0xb96f2dbd,
154 0x80b70fa3,0xc9ba682e,0x12adc0b9,0x5ba0a734,0xa0438c20,0xe94eebad,0x3259433a,0x7b5424b7,
155 0xc15e08a5,0x88536f28,0x5344c7bf,0x1a49a032,0xe1aa8b26,0xa8a7ecab,0x73b0443c,0x3abd23b1,
156 0x06ca035e,0x4fc764d3,0x94d0cc44,0xddddabc9,0x263e80dd,0x6f33e750,0xb4244fc7,0xfd29284a,
157 0x47230458,0x0e2e63d5,0xd539cb42,0x9c34accf,0x67d787db,0x2edae056,0xf5cd48c1,0xbcc02f4c,
158 0x85180d52,0xcc156adf,0x1702c248,0x5e0fa5c5,0xa5ec8ed1,0xece1e95c,0x37f641cb,0x7efb2646,
159 0xc4f10a54,0x8dfc6dd9,0x56ebc54e,0x1fe6a2c3,0xe40589d7,0xad08ee5a,0x761f46cd,0x3f122140,
160 0x05af02f1,0x4ca2657c,0x97b5cdeb,0xdeb8aa66,0x255b8172,0x6c56e6ff,0xb7414e68,0xfe4c29e5,
161 0x444605f7,0x0d4b627a,0xd65ccaed,0x9f51ad60,0x64b28674,0x2dbfe1f9,0xf6a8496e,0xbfa52ee3,
162 0x867d0cfd,0xcf706b70,0x1467c3e7,0x5d6aa46a,0xa6898f7e,0xef84e8f3,0x34934064,0x7d9e27e9,
163 0xc7940bfb,0x8e996c76,0x558ec4e1,0x1c83a36c,0xe7608878,0xae6deff5,0x757a4762,0x3c7720ef,
164 0x0d9406bc,0x44996131,0x9f8ec9a6,0xd683ae2b,0x2d60853f,0x646de2b2,0xbf7a4a25,0xf6772da8,
165 0x4c7d01ba,0x05706637,0xde67cea0,0x976aa92d,0x6c898239,0x2584e5b4,0xfe934d23,0xb79e2aae,
166 0x8e4608b0,0xc74b6f3d,0x1c5cc7aa,0x5551a027,0xaeb28b33,0xe7bfecbe,0x3ca84429,0x75a523a4,
167 0xcfaf0fb6,0x86a2683b,0x5db5c0ac,0x14b8a721,0xef5b8c35,0xa656ebb8,0x7d41432f,0x344c24a2,
168 0x0ef10713,0x47fc609e,0x9cebc809,0xd5e6af84,0x2e058490,0x6708e31d,0xbc1f4b8a,0xf5122c07,
169 0x4f180015,0x06156798,0xdd02cf0f,0x940fa882,0x6fec8396,0x26e1e41b,0xfdf64c8c,0xb4fb2b01,
170 0x8d23091f,0xc42e6e92,0x1f39c605,0x5634a188,0xadd78a9c,0xe4daed11,0x3fcd4586,0x76c0220b,
171 0xccca0e19,0x85c76994,0x5ed0c103,0x17dda68e,0xec3e8d9a,0xa533ea17,0x7e244280,0x3729250d,
172 0x0b5e05e2,0x4253626f,0x9944caf8,0xd049ad75,0x2baa8661,0x62a7e1ec,0xb9b0497b,0xf0bd2ef6,
173 0x4ab702e4,0x03ba6569,0xd8adcdfe,0x91a0aa73,0x6a438167,0x234ee6ea,0xf8594e7d,0xb15429f0,
174 0x888c0bee,0xc1816c63,0x1a96c4f4,0x539ba379,0xa878886d,0xe175efe0,0x3a624777,0x736f20fa,
175 0xc9650ce8,0x80686b65,0x5b7fc3f2,0x1272a47f,0xe9918f6b,0xa09ce8e6,0x7b8b4071,0x328627fc,
176 0x083b044d,0x413663c0,0x9a21cb57,0xd32cacda,0x28cf87ce,0x61c2e043,0xbad548d4,0xf3d82f59,
177 0x49d2034b,0x00df64c6,0xdbc8cc51,0x92c5abdc,0x692680c8,0x202be745,0xfb3c4fd2,0xb231285f,
178 0x8be90a41,0xc2e46dcc,0x19f3c55b,0x50fea2d6,0xab1d89c2,0xe210ee4f,0x390746d8,0x700a2155,
179 0xca000d47,0x830d6aca,0x581ac25d,0x1117a5d0,0xeaf48ec4,0xa3f9e949,0x78ee41de,0x31e32653},
180
181{0x00000000,0x1b280d78,0x36501af0,0x2d781788,0x6ca035e0,0x77883898,0x5af02f10,0x41d82268,
182 0xd9406bc0,0xc26866b8,0xef107130,0xf4387c48,0xb5e05e20,0xaec85358,0x83b044d0,0x989849a8,
183 0xb641ca37,0xad69c74f,0x8011d0c7,0x9b39ddbf,0xdae1ffd7,0xc1c9f2af,0xecb1e527,0xf799e85f,
184 0x6f01a1f7,0x7429ac8f,0x5951bb07,0x4279b67f,0x03a19417,0x1889996f,0x35f18ee7,0x2ed9839f,
185 0x684289d9,0x736a84a1,0x5e129329,0x453a9e51,0x04e2bc39,0x1fcab141,0x32b2a6c9,0x299aabb1,
186 0xb102e219,0xaa2aef61,0x8752f8e9,0x9c7af591,0xdda2d7f9,0xc68ada81,0xebf2cd09,0xf0dac071,
187 0xde0343ee,0xc52b4e96,0xe853591e,0xf37b5466,0xb2a3760e,0xa98b7b76,0x84f36cfe,0x9fdb6186,
188 0x0743282e,0x1c6b2556,0x311332de,0x2a3b3fa6,0x6be31dce,0x70cb10b6,0x5db3073e,0x469b0a46,
189 0xd08513b2,0xcbad1eca,0xe6d50942,0xfdfd043a,0xbc252652,0xa70d2b2a,0x8a753ca2,0x915d31da,
190 0x09c57872,0x12ed750a,0x3f956282,0x24bd6ffa,0x65654d92,0x7e4d40ea,0x53355762,0x481d5a1a,
191 0x66c4d985,0x7decd4fd,0x5094c375,0x4bbcce0d,0x0a64ec65,0x114ce11d,0x3c34f695,0x271cfbed,
192 0xbf84b245,0xa4acbf3d,0x89d4a8b5,0x92fca5cd,0xd32487a5,0xc80c8add,0xe5749d55,0xfe5c902d,
193 0xb8c79a6b,0xa3ef9713,0x8e97809b,0x95bf8de3,0xd467af8b,0xcf4fa2f3,0xe237b57b,0xf91fb803,
194 0x6187f1ab,0x7aaffcd3,0x57d7eb5b,0x4cffe623,0x0d27c44b,0x160fc933,0x3b77debb,0x205fd3c3,
195 0x0e86505c,0x15ae5d24,0x38d64aac,0x23fe47d4,0x622665bc,0x790e68c4,0x54767f4c,0x4f5e7234,
196 0xd7c63b9c,0xccee36e4,0xe196216c,0xfabe2c14,0xbb660e7c,0xa04e0304,0x8d36148c,0x961e19f4,
197 0xa5cb3ad3,0xbee337ab,0x939b2023,0x88b32d5b,0xc96b0f33,0xd243024b,0xff3b15c3,0xe41318bb,
198 0x7c8b5113,0x67a35c6b,0x4adb4be3,0x51f3469b,0x102b64f3,0x0b03698b,0x267b7e03,0x3d53737b,
199 0x138af0e4,0x08a2fd9c,0x25daea14,0x3ef2e76c,0x7f2ac504,0x6402c87c,0x497adff4,0x5252d28c,
200 0xcaca9b24,0xd1e2965c,0xfc9a81d4,0xe7b28cac,0xa66aaec4,0xbd42a3bc,0x903ab434,0x8b12b94c,
201 0xcd89b30a,0xd6a1be72,0xfbd9a9fa,0xe0f1a482,0xa12986ea,0xba018b92,0x97799c1a,0x8c519162,
202 0x14c9d8ca,0x0fe1d5b2,0x2299c23a,0x39b1cf42,0x7869ed2a,0x6341e052,0x4e39f7da,0x5511faa2,
203 0x7bc8793d,0x60e07445,0x4d9863cd,0x56b06eb5,0x17684cdd,0x0c4041a5,0x2138562d,0x3a105b55,
204 0xa28812fd,0xb9a01f85,0x94d8080d,0x8ff00575,0xce28271d,0xd5002a65,0xf8783ded,0xe3503095,
205 0x754e2961,0x6e662419,0x431e3391,0x58363ee9,0x19ee1c81,0x02c611f9,0x2fbe0671,0x34960b09,
206 0xac0e42a1,0xb7264fd9,0x9a5e5851,0x81765529,0xc0ae7741,0xdb867a39,0xf6fe6db1,0xedd660c9,
207 0xc30fe356,0xd827ee2e,0xf55ff9a6,0xee77f4de,0xafafd6b6,0xb487dbce,0x99ffcc46,0x82d7c13e,
208 0x1a4f8896,0x016785ee,0x2c1f9266,0x37379f1e,0x76efbd76,0x6dc7b00e,0x40bfa786,0x5b97aafe,
209 0x1d0ca0b8,0x0624adc0,0x2b5cba48,0x3074b730,0x71ac9558,0x6a849820,0x47fc8fa8,0x5cd482d0,
210 0xc44ccb78,0xdf64c600,0xf21cd188,0xe934dcf0,0xa8ecfe98,0xb3c4f3e0,0x9ebce468,0x8594e910,
211 0xab4d6a8f,0xb06567f7,0x9d1d707f,0x86357d07,0xc7ed5f6f,0xdcc55217,0xf1bd459f,0xea9548e7,
212 0x720d014f,0x69250c37,0x445d1bbf,0x5f7516c7,0x1ead34af,0x058539d7,0x28fd2e5f,0x33d52327},
213
214{0x00000000,0x4f576811,0x9eaed022,0xd1f9b833,0x399cbdf3,0x76cbd5e2,0xa7326dd1,0xe86505c0,
215 0x73397be6,0x3c6e13f7,0xed97abc4,0xa2c0c3d5,0x4aa5c615,0x05f2ae04,0xd40b1637,0x9b5c7e26,
216 0xe672f7cc,0xa9259fdd,0x78dc27ee,0x378b4fff,0xdfee4a3f,0x90b9222e,0x41409a1d,0x0e17f20c,
217 0x954b8c2a,0xda1ce43b,0x0be55c08,0x44b23419,0xacd731d9,0xe38059c8,0x3279e1fb,0x7d2e89ea,
218 0xc824f22f,0x87739a3e,0x568a220d,0x19dd4a1c,0xf1b84fdc,0xbeef27cd,0x6f169ffe,0x2041f7ef,
219 0xbb1d89c9,0xf44ae1d8,0x25b359eb,0x6ae431fa,0x8281343a,0xcdd65c2b,0x1c2fe418,0x53788c09,
220 0x2e5605e3,0x61016df2,0xb0f8d5c1,0xffafbdd0,0x17cab810,0x589dd001,0x89646832,0xc6330023,
221 0x5d6f7e05,0x12381614,0xc3c1ae27,0x8c96c636,0x64f3c3f6,0x2ba4abe7,0xfa5d13d4,0xb50a7bc5,
222 0x9488f9e9,0xdbdf91f8,0x0a2629cb,0x457141da,0xad14441a,0xe2432c0b,0x33ba9438,0x7cedfc29,
223 0xe7b1820f,0xa8e6ea1e,0x791f522d,0x36483a3c,0xde2d3ffc,0x917a57ed,0x4083efde,0x0fd487cf,
224 0x72fa0e25,0x3dad6634,0xec54de07,0xa303b616,0x4b66b3d6,0x0431dbc7,0xd5c863f4,0x9a9f0be5,
225 0x01c375c3,0x4e941dd2,0x9f6da5e1,0xd03acdf0,0x385fc830,0x7708a021,0xa6f11812,0xe9a67003,
226 0x5cac0bc6,0x13fb63d7,0xc202dbe4,0x8d55b3f5,0x6530b635,0x2a67de24,0xfb9e6617,0xb4c90e06,
227 0x2f957020,0x60c21831,0xb13ba002,0xfe6cc813,0x1609cdd3,0x595ea5c2,0x88a71df1,0xc7f075e0,
228 0xbadefc0a,0xf589941b,0x24702c28,0x6b274439,0x834241f9,0xcc1529e8,0x1dec91db,0x52bbf9ca,
229 0xc9e787ec,0x86b0effd,0x574957ce,0x181e3fdf,0xf07b3a1f,0xbf2c520e,0x6ed5ea3d,0x2182822c,
230 0x2dd0ee65,0x62878674,0xb37e3e47,0xfc295656,0x144c5396,0x5b1b3b87,0x8ae283b4,0xc5b5eba5,
231 0x5ee99583,0x11befd92,0xc04745a1,0x8f102db0,0x67752870,0x28224061,0xf9dbf852,0xb68c9043,
232 0xcba219a9,0x84f571b8,0x550cc98b,0x1a5ba19a,0xf23ea45a,0xbd69cc4b,0x6c907478,0x23c71c69,
233 0xb89b624f,0xf7cc0a5e,0x2635b26d,0x6962da7c,0x8107dfbc,0xce50b7ad,0x1fa90f9e,0x50fe678f,
234 0xe5f41c4a,0xaaa3745b,0x7b5acc68,0x340da479,0xdc68a1b9,0x933fc9a8,0x42c6719b,0x0d91198a,
235 0x96cd67ac,0xd99a0fbd,0x0863b78e,0x4734df9f,0xaf51da5f,0xe006b24e,0x31ff0a7d,0x7ea8626c,
236 0x0386eb86,0x4cd18397,0x9d283ba4,0xd27f53b5,0x3a1a5675,0x754d3e64,0xa4b48657,0xebe3ee46,
237 0x70bf9060,0x3fe8f871,0xee114042,0xa1462853,0x49232d93,0x06744582,0xd78dfdb1,0x98da95a0,
238 0xb958178c,0xf60f7f9d,0x27f6c7ae,0x68a1afbf,0x80c4aa7f,0xcf93c26e,0x1e6a7a5d,0x513d124c,
239 0xca616c6a,0x8536047b,0x54cfbc48,0x1b98d459,0xf3fdd199,0xbcaab988,0x6d5301bb,0x220469aa,
240 0x5f2ae040,0x107d8851,0xc1843062,0x8ed35873,0x66b65db3,0x29e135a2,0xf8188d91,0xb74fe580,
241 0x2c139ba6,0x6344f3b7,0xb2bd4b84,0xfdea2395,0x158f2655,0x5ad84e44,0x8b21f677,0xc4769e66,
242 0x717ce5a3,0x3e2b8db2,0xefd23581,0xa0855d90,0x48e05850,0x07b73041,0xd64e8872,0x9919e063,
243 0x02459e45,0x4d12f654,0x9ceb4e67,0xd3bc2676,0x3bd923b6,0x748e4ba7,0xa577f394,0xea209b85,
244 0x970e126f,0xd8597a7e,0x09a0c24d,0x46f7aa5c,0xae92af9c,0xe1c5c78d,0x303c7fbe,0x7f6b17af,
245 0xe4376989,0xab600198,0x7a99b9ab,0x35ced1ba,0xddabd47a,0x92fcbc6b,0x43050458,0x0c526c49},
246
247{0x00000000,0x5ba1dcca,0xb743b994,0xece2655e,0x6a466e9f,0x31e7b255,0xdd05d70b,0x86a40bc1,
248 0xd48cdd3e,0x8f2d01f4,0x63cf64aa,0x386eb860,0xbecab3a1,0xe56b6f6b,0x09890a35,0x5228d6ff,
249 0xadd8a7cb,0xf6797b01,0x1a9b1e5f,0x413ac295,0xc79ec954,0x9c3f159e,0x70dd70c0,0x2b7cac0a,
250 0x79547af5,0x22f5a63f,0xce17c361,0x95b61fab,0x1312146a,0x48b3c8a0,0xa451adfe,0xfff07134,
251 0x5f705221,0x04d18eeb,0xe833ebb5,0xb392377f,0x35363cbe,0x6e97e074,0x8275852a,0xd9d459e0,
252 0x8bfc8f1f,0xd05d53d5,0x3cbf368b,0x671eea41,0xe1bae180,0xba1b3d4a,0x56f95814,0x0d5884de,
253 0xf2a8f5ea,0xa9092920,0x45eb4c7e,0x1e4a90b4,0x98ee9b75,0xc34f47bf,0x2fad22e1,0x740cfe2b,
254 0x262428d4,0x7d85f41e,0x91679140,0xcac64d8a,0x4c62464b,0x17c39a81,0xfb21ffdf,0xa0802315,
255 0xbee0a442,0xe5417888,0x09a31dd6,0x5202c11c,0xd4a6cadd,0x8f071617,0x63e57349,0x3844af83,
256 0x6a6c797c,0x31cda5b6,0xdd2fc0e8,0x868e1c22,0x002a17e3,0x5b8bcb29,0xb769ae77,0xecc872bd,
257 0x13380389,0x4899df43,0xa47bba1d,0xffda66d7,0x797e6d16,0x22dfb1dc,0xce3dd482,0x959c0848,
258 0xc7b4deb7,0x9c15027d,0x70f76723,0x2b56bbe9,0xadf2b028,0xf6536ce2,0x1ab109bc,0x4110d576,
259 0xe190f663,0xba312aa9,0x56d34ff7,0x0d72933d,0x8bd698fc,0xd0774436,0x3c952168,0x6734fda2,
260 0x351c2b5d,0x6ebdf797,0x825f92c9,0xd9fe4e03,0x5f5a45c2,0x04fb9908,0xe819fc56,0xb3b8209c,
261 0x4c4851a8,0x17e98d62,0xfb0be83c,0xa0aa34f6,0x260e3f37,0x7dafe3fd,0x914d86a3,0xcaec5a69,
262 0x98c48c96,0xc365505c,0x2f873502,0x7426e9c8,0xf282e209,0xa9233ec3,0x45c15b9d,0x1e608757,
263 0x79005533,0x22a189f9,0xce43eca7,0x95e2306d,0x13463bac,0x48e7e766,0xa4058238,0xffa45ef2,
264 0xad8c880d,0xf62d54c7,0x1acf3199,0x416eed53,0xc7cae692,0x9c6b3a58,0x70895f06,0x2b2883cc,
265 0xd4d8f2f8,0x8f792e32,0x639b4b6c,0x383a97a6,0xbe9e9c67,0xe53f40ad,0x09dd25f3,0x527cf939,
266 0x00542fc6,0x5bf5f30c,0xb7179652,0xecb64a98,0x6a124159,0x31b39d93,0xdd51f8cd,0x86f02407,
267 0x26700712,0x7dd1dbd8,0x9133be86,0xca92624c,0x4c36698d,0x1797b547,0xfb75d019,0xa0d40cd3,
268 0xf2fcda2c,0xa95d06e6,0x45bf63b8,0x1e1ebf72,0x98bab4b3,0xc31b6879,0x2ff90d27,0x7458d1ed,
269 0x8ba8a0d9,0xd0097c13,0x3ceb194d,0x674ac587,0xe1eece46,0xba4f128c,0x56ad77d2,0x0d0cab18,
270 0x5f247de7,0x0485a12d,0xe867c473,0xb3c618b9,0x35621378,0x6ec3cfb2,0x8221aaec,0xd9807626,
271 0xc7e0f171,0x9c412dbb,0x70a348e5,0x2b02942f,0xada69fee,0xf6074324,0x1ae5267a,0x4144fab0,
272 0x136c2c4f,0x48cdf085,0xa42f95db,0xff8e4911,0x792a42d0,0x228b9e1a,0xce69fb44,0x95c8278e,
273 0x6a3856ba,0x31998a70,0xdd7bef2e,0x86da33e4,0x007e3825,0x5bdfe4ef,0xb73d81b1,0xec9c5d7b,
274 0xbeb48b84,0xe515574e,0x09f73210,0x5256eeda,0xd4f2e51b,0x8f5339d1,0x63b15c8f,0x38108045,
275 0x9890a350,0xc3317f9a,0x2fd31ac4,0x7472c60e,0xf2d6cdcf,0xa9771105,0x4595745b,0x1e34a891,
276 0x4c1c7e6e,0x17bda2a4,0xfb5fc7fa,0xa0fe1b30,0x265a10f1,0x7dfbcc3b,0x9119a965,0xcab875af,
277 0x3548049b,0x6ee9d851,0x820bbd0f,0xd9aa61c5,0x5f0e6a04,0x04afb6ce,0xe84dd390,0xb3ec0f5a,
278 0xe1c4d9a5,0xba65056f,0x56876031,0x0d26bcfb,0x8b82b73a,0xd0236bf0,0x3cc10eae,0x6760d264}};
diff --git a/lib/rbcodec/codecs/libopus/ogg/framing.c b/lib/rbcodec/codecs/libopus/ogg/framing.c
index f007de176a..a7032a6a35 100644
--- a/lib/rbcodec/codecs/libopus/ogg/framing.c
+++ b/lib/rbcodec/codecs/libopus/ogg/framing.c
@@ -5,14 +5,13 @@
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * 5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * 6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
7 * * 7 * *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 * 8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2018 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ * 9 * by the Xiph.Org Foundation http://www.xiph.org/ *
10 * * 10 * *
11 ******************************************************************** 11 ********************************************************************
12 12
13 function: code raw packets into framed OggSquish stream and 13 function: code raw packets into framed OggSquish stream and
14 decode Ogg streams back into raw packets 14 decode Ogg streams back into raw packets
15 last mod: $Id: framing.c 18052 2011-08-04 17:57:02Z giles $
16 15
17 note: The CRC code is directly derived from public domain code by 16 note: The CRC code is directly derived from public domain code by
18 Ross Williams (ross@guest.adelaide.edu.au). See docs/framing.html 17 Ross Williams (ross@guest.adelaide.edu.au). See docs/framing.html
@@ -20,9 +19,14 @@
20 19
21 ********************************************************************/ 20 ********************************************************************/
22 21
22#ifdef HAVE_CONFIG_H
23#include "config.h"
24#endif
25
23#include <stdlib.h> 26#include <stdlib.h>
27#include <limits.h>
24#include <string.h> 28#include <string.h>
25#include <ogg/ogg.h> 29#include "ogg.h"
26 30
27/* A complete description of Ogg framing exists in docs/framing.html */ 31/* A complete description of Ogg framing exists in docs/framing.html */
28 32
@@ -98,90 +102,31 @@ int ogg_page_packets(const ogg_page *og){
98 102
99#if 0 103#if 0
100/* helper to initialize lookup for direct-table CRC (illustrative; we 104/* helper to initialize lookup for direct-table CRC (illustrative; we
101 use the static init below) */ 105 use the static init in crctable.h) */
102 106
103static ogg_uint32_t _ogg_crc_entry(unsigned long index){ 107static void _ogg_crc_init(){
104 int i; 108 int i, j;
105 unsigned long r; 109 ogg_uint32_t polynomial, crc;
106 110 polynomial = 0x04c11db7; /* The same as the ethernet generator
107 r = index << 24; 111 polynomial, although we use an
108 for (i=0; i<8; i++) 112 unreflected alg and an init/final
109 if (r & 0x80000000UL) 113 of 0, not 0xffffffff */
110 r = (r << 1) ^ 0x04c11db7; /* The same as the ethernet generator 114 for (i = 0; i <= 0xFF; i++){
111 polynomial, although we use an 115 crc = i << 24;
112 unreflected alg and an init/final 116
113 of 0, not 0xffffffff */ 117 for (j = 0; j < 8; j++)
114 else 118 crc = (crc << 1) ^ (crc & (1 << 31) ? polynomial : 0);
115 r<<=1; 119
116 return (r & 0xffffffffUL); 120 crc_lookup[0][i] = crc;
121 }
122
123 for (i = 0; i <= 0xFF; i++)
124 for (j = 1; j < 8; j++)
125 crc_lookup[j][i] = crc_lookup[0][(crc_lookup[j - 1][i] >> 24) & 0xFF] ^ (crc_lookup[j - 1][i] << 8);
117} 126}
118#endif 127#endif
119 128
120static const ogg_uint32_t crc_lookup[256]={ 129#include "crctable.h"
121 0x00000000,0x04c11db7,0x09823b6e,0x0d4326d9,
122 0x130476dc,0x17c56b6b,0x1a864db2,0x1e475005,
123 0x2608edb8,0x22c9f00f,0x2f8ad6d6,0x2b4bcb61,
124 0x350c9b64,0x31cd86d3,0x3c8ea00a,0x384fbdbd,
125 0x4c11db70,0x48d0c6c7,0x4593e01e,0x4152fda9,
126 0x5f15adac,0x5bd4b01b,0x569796c2,0x52568b75,
127 0x6a1936c8,0x6ed82b7f,0x639b0da6,0x675a1011,
128 0x791d4014,0x7ddc5da3,0x709f7b7a,0x745e66cd,
129 0x9823b6e0,0x9ce2ab57,0x91a18d8e,0x95609039,
130 0x8b27c03c,0x8fe6dd8b,0x82a5fb52,0x8664e6e5,
131 0xbe2b5b58,0xbaea46ef,0xb7a96036,0xb3687d81,
132 0xad2f2d84,0xa9ee3033,0xa4ad16ea,0xa06c0b5d,
133 0xd4326d90,0xd0f37027,0xddb056fe,0xd9714b49,
134 0xc7361b4c,0xc3f706fb,0xceb42022,0xca753d95,
135 0xf23a8028,0xf6fb9d9f,0xfbb8bb46,0xff79a6f1,
136 0xe13ef6f4,0xe5ffeb43,0xe8bccd9a,0xec7dd02d,
137 0x34867077,0x30476dc0,0x3d044b19,0x39c556ae,
138 0x278206ab,0x23431b1c,0x2e003dc5,0x2ac12072,
139 0x128e9dcf,0x164f8078,0x1b0ca6a1,0x1fcdbb16,
140 0x018aeb13,0x054bf6a4,0x0808d07d,0x0cc9cdca,
141 0x7897ab07,0x7c56b6b0,0x71159069,0x75d48dde,
142 0x6b93dddb,0x6f52c06c,0x6211e6b5,0x66d0fb02,
143 0x5e9f46bf,0x5a5e5b08,0x571d7dd1,0x53dc6066,
144 0x4d9b3063,0x495a2dd4,0x44190b0d,0x40d816ba,
145 0xaca5c697,0xa864db20,0xa527fdf9,0xa1e6e04e,
146 0xbfa1b04b,0xbb60adfc,0xb6238b25,0xb2e29692,
147 0x8aad2b2f,0x8e6c3698,0x832f1041,0x87ee0df6,
148 0x99a95df3,0x9d684044,0x902b669d,0x94ea7b2a,
149 0xe0b41de7,0xe4750050,0xe9362689,0xedf73b3e,
150 0xf3b06b3b,0xf771768c,0xfa325055,0xfef34de2,
151 0xc6bcf05f,0xc27dede8,0xcf3ecb31,0xcbffd686,
152 0xd5b88683,0xd1799b34,0xdc3abded,0xd8fba05a,
153 0x690ce0ee,0x6dcdfd59,0x608edb80,0x644fc637,
154 0x7a089632,0x7ec98b85,0x738aad5c,0x774bb0eb,
155 0x4f040d56,0x4bc510e1,0x46863638,0x42472b8f,
156 0x5c007b8a,0x58c1663d,0x558240e4,0x51435d53,
157 0x251d3b9e,0x21dc2629,0x2c9f00f0,0x285e1d47,
158 0x36194d42,0x32d850f5,0x3f9b762c,0x3b5a6b9b,
159 0x0315d626,0x07d4cb91,0x0a97ed48,0x0e56f0ff,
160 0x1011a0fa,0x14d0bd4d,0x19939b94,0x1d528623,
161 0xf12f560e,0xf5ee4bb9,0xf8ad6d60,0xfc6c70d7,
162 0xe22b20d2,0xe6ea3d65,0xeba91bbc,0xef68060b,
163 0xd727bbb6,0xd3e6a601,0xdea580d8,0xda649d6f,
164 0xc423cd6a,0xc0e2d0dd,0xcda1f604,0xc960ebb3,
165 0xbd3e8d7e,0xb9ff90c9,0xb4bcb610,0xb07daba7,
166 0xae3afba2,0xaafbe615,0xa7b8c0cc,0xa379dd7b,
167 0x9b3660c6,0x9ff77d71,0x92b45ba8,0x9675461f,
168 0x8832161a,0x8cf30bad,0x81b02d74,0x857130c3,
169 0x5d8a9099,0x594b8d2e,0x5408abf7,0x50c9b640,
170 0x4e8ee645,0x4a4ffbf2,0x470cdd2b,0x43cdc09c,
171 0x7b827d21,0x7f436096,0x7200464f,0x76c15bf8,
172 0x68860bfd,0x6c47164a,0x61043093,0x65c52d24,
173 0x119b4be9,0x155a565e,0x18197087,0x1cd86d30,
174 0x029f3d35,0x065e2082,0x0b1d065b,0x0fdc1bec,
175 0x3793a651,0x3352bbe6,0x3e119d3f,0x3ad08088,
176 0x2497d08d,0x2056cd3a,0x2d15ebe3,0x29d4f654,
177 0xc5a92679,0xc1683bce,0xcc2b1d17,0xc8ea00a0,
178 0xd6ad50a5,0xd26c4d12,0xdf2f6bcb,0xdbee767c,
179 0xe3a1cbc1,0xe760d676,0xea23f0af,0xeee2ed18,
180 0xf0a5bd1d,0xf464a0aa,0xf9278673,0xfde69bc4,
181 0x89b8fd09,0x8d79e0be,0x803ac667,0x84fbdbd0,
182 0x9abc8bd5,0x9e7d9662,0x933eb0bb,0x97ffad0c,
183 0xafb010b1,0xab710d06,0xa6322bdf,0xa2f33668,
184 0xbcb4666d,0xb8757bda,0xb5365d03,0xb1f740b4};
185 130
186/* init the encode/decode logical stream state */ 131/* init the encode/decode logical stream state */
187 132
@@ -236,39 +181,51 @@ int ogg_stream_destroy(ogg_stream_state *os){
236/* Helpers for ogg_stream_encode; this keeps the structure and 181/* Helpers for ogg_stream_encode; this keeps the structure and
237 what's happening fairly clear */ 182 what's happening fairly clear */
238 183
239static int _os_body_expand(ogg_stream_state *os,int needed){ 184static int _os_body_expand(ogg_stream_state *os,long needed){
240 if(os->body_storage<=os->body_fill+needed){ 185 if(os->body_storage-needed<=os->body_fill){
186 long body_storage;
241 void *ret; 187 void *ret;
242 ret=_ogg_realloc(os->body_data,(os->body_storage+needed+1024)* 188 if(os->body_storage>LONG_MAX-needed){
243 sizeof(*os->body_data)); 189 ogg_stream_clear(os);
190 return -1;
191 }
192 body_storage=os->body_storage+needed;
193 if(body_storage<LONG_MAX-1024)body_storage+=1024;
194 ret=_ogg_realloc(os->body_data,body_storage*sizeof(*os->body_data));
244 if(!ret){ 195 if(!ret){
245 ogg_stream_clear(os); 196 ogg_stream_clear(os);
246 return -1; 197 return -1;
247 } 198 }
248 os->body_storage+=(needed+1024); 199 os->body_storage=body_storage;
249 os->body_data=ret; 200 os->body_data=ret;
250 } 201 }
251 return 0; 202 return 0;
252} 203}
253 204
254static int _os_lacing_expand(ogg_stream_state *os,int needed){ 205static int _os_lacing_expand(ogg_stream_state *os,long needed){
255 if(os->lacing_storage<=os->lacing_fill+needed){ 206 if(os->lacing_storage-needed<=os->lacing_fill){
207 long lacing_storage;
256 void *ret; 208 void *ret;
257 ret=_ogg_realloc(os->lacing_vals,(os->lacing_storage+needed+32)* 209 if(os->lacing_storage>LONG_MAX-needed){
258 sizeof(*os->lacing_vals)); 210 ogg_stream_clear(os);
211 return -1;
212 }
213 lacing_storage=os->lacing_storage+needed;
214 if(lacing_storage<LONG_MAX-32)lacing_storage+=32;
215 ret=_ogg_realloc(os->lacing_vals,lacing_storage*sizeof(*os->lacing_vals));
259 if(!ret){ 216 if(!ret){
260 ogg_stream_clear(os); 217 ogg_stream_clear(os);
261 return -1; 218 return -1;
262 } 219 }
263 os->lacing_vals=ret; 220 os->lacing_vals=ret;
264 ret=_ogg_realloc(os->granule_vals,(os->lacing_storage+needed+32)* 221 ret=_ogg_realloc(os->granule_vals,lacing_storage*
265 sizeof(*os->granule_vals)); 222 sizeof(*os->granule_vals));
266 if(!ret){ 223 if(!ret){
267 ogg_stream_clear(os); 224 ogg_stream_clear(os);
268 return -1; 225 return -1;
269 } 226 }
270 os->granule_vals=ret; 227 os->granule_vals=ret;
271 os->lacing_storage+=(needed+32); 228 os->lacing_storage=lacing_storage;
272 } 229 }
273 return 0; 230 return 0;
274} 231}
@@ -277,10 +234,27 @@ static int _os_lacing_expand(ogg_stream_state *os,int needed){
277/* Direct table CRC; note that this will be faster in the future if we 234/* Direct table CRC; note that this will be faster in the future if we
278 perform the checksum simultaneously with other copies */ 235 perform the checksum simultaneously with other copies */
279 236
237static ogg_uint32_t _os_update_crc(ogg_uint32_t crc, unsigned char *buffer, int size){
238 while (size>=8){
239 crc^=buffer[0]<<24|buffer[1]<<16|buffer[2]<<8|buffer[3];
240
241 crc=crc_lookup[7][ crc>>24 ]^crc_lookup[6][(crc>>16)&0xFF]^
242 crc_lookup[5][(crc>> 8)&0xFF]^crc_lookup[4][ crc &0xFF]^
243 crc_lookup[3][buffer[4] ]^crc_lookup[2][buffer[5] ]^
244 crc_lookup[1][buffer[6] ]^crc_lookup[0][buffer[7] ];
245
246 buffer+=8;
247 size-=8;
248 }
249
250 while (size--)
251 crc=(crc<<8)^crc_lookup[0][((crc >> 24)&0xff)^*buffer++];
252 return crc;
253}
254
280void ogg_page_checksum_set(ogg_page *og){ 255void ogg_page_checksum_set(ogg_page *og){
281 if(og){ 256 if(og){
282 ogg_uint32_t crc_reg=0; 257 ogg_uint32_t crc_reg=0;
283 int i;
284 258
285 /* safety; needed for API behavior, but not framing code */ 259 /* safety; needed for API behavior, but not framing code */
286 og->header[22]=0; 260 og->header[22]=0;
@@ -288,10 +262,8 @@ void ogg_page_checksum_set(ogg_page *og){
288 og->header[24]=0; 262 og->header[24]=0;
289 og->header[25]=0; 263 og->header[25]=0;
290 264
291 for(i=0;i<og->header_len;i++) 265 crc_reg=_os_update_crc(crc_reg,og->header,og->header_len);
292 crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->header[i]]; 266 crc_reg=_os_update_crc(crc_reg,og->body,og->body_len);
293 for(i=0;i<og->body_len;i++)
294 crc_reg=(crc_reg<<8)^crc_lookup[((crc_reg >> 24)&0xff)^og->body[i]];
295 267
296 og->header[22]=(unsigned char)(crc_reg&0xff); 268 og->header[22]=(unsigned char)(crc_reg&0xff);
297 og->header[23]=(unsigned char)((crc_reg>>8)&0xff); 269 og->header[23]=(unsigned char)((crc_reg>>8)&0xff);
@@ -304,12 +276,17 @@ void ogg_page_checksum_set(ogg_page *og){
304int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, int count, 276int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, int count,
305 long e_o_s, ogg_int64_t granulepos){ 277 long e_o_s, ogg_int64_t granulepos){
306 278
307 int bytes = 0, lacing_vals, i; 279 long bytes = 0, lacing_vals;
280 int i;
308 281
309 if(ogg_stream_check(os)) return -1; 282 if(ogg_stream_check(os)) return -1;
310 if(!iov) return 0; 283 if(!iov) return 0;
311 284
312 for (i = 0; i < count; ++i) bytes += (int)iov[i].iov_len; 285 for (i = 0; i < count; ++i){
286 if(iov[i].iov_len>LONG_MAX) return -1;
287 if(bytes>LONG_MAX-(long)iov[i].iov_len) return -1;
288 bytes += (long)iov[i].iov_len;
289 }
313 lacing_vals=bytes/255+1; 290 lacing_vals=bytes/255+1;
314 291
315 if(os->body_returned){ 292 if(os->body_returned){
@@ -396,9 +373,9 @@ static int ogg_stream_flush_i(ogg_stream_state *os,ogg_page *og, int force, int
396 }else{ 373 }else{
397 374
398 /* The extra packets_done, packet_just_done logic here attempts to do two things: 375 /* The extra packets_done, packet_just_done logic here attempts to do two things:
399 1) Don't unneccessarily span pages. 376 1) Don't unnecessarily span pages.
400 2) Unless necessary, don't flush pages if there are less than four packets on 377 2) Unless necessary, don't flush pages if there are less than four packets on
401 them; this expands page size to reduce unneccessary overhead if incoming packets 378 them; this expands page size to reduce unnecessary overhead if incoming packets
402 are large. 379 are large.
403 These are not necessary behaviors, just 'always better than naive flushing' 380 These are not necessary behaviors, just 'always better than naive flushing'
404 without requiring an application to explicitly request a specific optimized 381 without requiring an application to explicitly request a specific optimized
@@ -683,7 +660,7 @@ long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
683 if(oy->bodybytes+oy->headerbytes>bytes)return(0); 660 if(oy->bodybytes+oy->headerbytes>bytes)return(0);
684 661
685 /* The whole test page is buffered. Verify the checksum */ 662 /* The whole test page is buffered. Verify the checksum */
686 if (0) { 663 {
687 /* Grab the checksum bytes, set the header field to zero */ 664 /* Grab the checksum bytes, set the header field to zero */
688 char chksum[4]; 665 char chksum[4];
689 ogg_page log; 666 ogg_page log;
@@ -705,8 +682,10 @@ long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og){
705 /* replace the computed checksum with the one actually read in */ 682 /* replace the computed checksum with the one actually read in */
706 memcpy(page+22,chksum,4); 683 memcpy(page+22,chksum,4);
707 684
685#ifndef DISABLE_CRC
708 /* Bad checksum. Lose sync */ 686 /* Bad checksum. Lose sync */
709 goto sync_fail; 687 goto sync_fail;
688#endif
710 } 689 }
711 } 690 }
712 691
@@ -780,6 +759,7 @@ int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og){
780 } 759 }
781 760
782 /* loop. keep looking */ 761 /* loop. keep looking */
762
783 } 763 }
784} 764}
785 765
@@ -856,6 +836,7 @@ int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og){
856 some segments */ 836 some segments */
857 if(continued){ 837 if(continued){
858 if(os->lacing_fill<1 || 838 if(os->lacing_fill<1 ||
839 (os->lacing_vals[os->lacing_fill-1]&0xff)<255 ||
859 os->lacing_vals[os->lacing_fill-1]==0x400){ 840 os->lacing_vals[os->lacing_fill-1]==0x400){
860 bos=0; 841 bos=0;
861 for(;segptr<segments;segptr++){ 842 for(;segptr<segments;segptr++){
@@ -1023,3 +1004,1106 @@ void ogg_packet_clear(ogg_packet *op) {
1023 memset(op, 0, sizeof(*op)); 1004 memset(op, 0, sizeof(*op));
1024} 1005}
1025 1006
1007#ifdef _V_SELFTEST
1008#include <stdio.h>
1009
1010ogg_stream_state os_en, os_de;
1011ogg_sync_state oy;
1012
1013void checkpacket(ogg_packet *op,long len, int no, long pos){
1014 long j;
1015 static int sequence=0;
1016 static int lastno=0;
1017
1018 if(op->bytes!=len){
1019 fprintf(stderr,"incorrect packet length (%ld != %ld)!\n",op->bytes,len);
1020 exit(1);
1021 }
1022 if(op->granulepos!=pos){
1023 fprintf(stderr,"incorrect packet granpos (%ld != %ld)!\n",(long)op->granulepos,pos);
1024 exit(1);
1025 }
1026
1027 /* packet number just follows sequence/gap; adjust the input number
1028 for that */
1029 if(no==0){
1030 sequence=0;
1031 }else{
1032 sequence++;
1033 if(no>lastno+1)
1034 sequence++;
1035 }
1036 lastno=no;
1037 if(op->packetno!=sequence){
1038 fprintf(stderr,"incorrect packet sequence %ld != %d\n",
1039 (long)(op->packetno),sequence);
1040 exit(1);
1041 }
1042
1043 /* Test data */
1044 for(j=0;j<op->bytes;j++)
1045 if(op->packet[j]!=((j+no)&0xff)){
1046 fprintf(stderr,"body data mismatch (1) at pos %ld: %x!=%lx!\n\n",
1047 j,op->packet[j],(j+no)&0xff);
1048 exit(1);
1049 }
1050}
1051
1052void check_page(unsigned char *data,const int *header,ogg_page *og){
1053 long j;
1054 /* Test data */
1055 for(j=0;j<og->body_len;j++)
1056 if(og->body[j]!=data[j]){
1057 fprintf(stderr,"body data mismatch (2) at pos %ld: %x!=%x!\n\n",
1058 j,data[j],og->body[j]);
1059 exit(1);
1060 }
1061
1062 /* Test header */
1063 for(j=0;j<og->header_len;j++){
1064 if(og->header[j]!=header[j]){
1065 fprintf(stderr,"header content mismatch at pos %ld:\n",j);
1066 for(j=0;j<header[26]+27;j++)
1067 fprintf(stderr," (%ld)%02x:%02x",j,header[j],og->header[j]);
1068 fprintf(stderr,"\n");
1069 exit(1);
1070 }
1071 }
1072 if(og->header_len!=header[26]+27){
1073 fprintf(stderr,"header length incorrect! (%ld!=%d)\n",
1074 og->header_len,header[26]+27);
1075 exit(1);
1076 }
1077}
1078
1079void print_header(ogg_page *og){
1080 int j;
1081 fprintf(stderr,"\nHEADER:\n");
1082 fprintf(stderr," capture: %c %c %c %c version: %d flags: %x\n",
1083 og->header[0],og->header[1],og->header[2],og->header[3],
1084 (int)og->header[4],(int)og->header[5]);
1085
1086 fprintf(stderr," granulepos: %d serialno: %d pageno: %ld\n",
1087 (og->header[9]<<24)|(og->header[8]<<16)|
1088 (og->header[7]<<8)|og->header[6],
1089 (og->header[17]<<24)|(og->header[16]<<16)|
1090 (og->header[15]<<8)|og->header[14],
1091 ((long)(og->header[21])<<24)|(og->header[20]<<16)|
1092 (og->header[19]<<8)|og->header[18]);
1093
1094 fprintf(stderr," checksum: %02x:%02x:%02x:%02x\n segments: %d (",
1095 (int)og->header[22],(int)og->header[23],
1096 (int)og->header[24],(int)og->header[25],
1097 (int)og->header[26]);
1098
1099 for(j=27;j<og->header_len;j++)
1100 fprintf(stderr,"%d ",(int)og->header[j]);
1101 fprintf(stderr,")\n\n");
1102}
1103
1104void copy_page(ogg_page *og){
1105 unsigned char *temp=_ogg_malloc(og->header_len);
1106 memcpy(temp,og->header,og->header_len);
1107 og->header=temp;
1108
1109 temp=_ogg_malloc(og->body_len);
1110 memcpy(temp,og->body,og->body_len);
1111 og->body=temp;
1112}
1113
1114void free_page(ogg_page *og){
1115 _ogg_free (og->header);
1116 _ogg_free (og->body);
1117}
1118
1119void error(void){
1120 fprintf(stderr,"error!\n");
1121 exit(1);
1122}
1123
1124/* 17 only */
1125const int head1_0[] = {0x4f,0x67,0x67,0x53,0,0x06,
1126 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1127 0x01,0x02,0x03,0x04,0,0,0,0,
1128 0x15,0xed,0xec,0x91,
1129 1,
1130 17};
1131
1132/* 17, 254, 255, 256, 500, 510, 600 byte, pad */
1133const int head1_1[] = {0x4f,0x67,0x67,0x53,0,0x02,
1134 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1135 0x01,0x02,0x03,0x04,0,0,0,0,
1136 0x59,0x10,0x6c,0x2c,
1137 1,
1138 17};
1139const int head2_1[] = {0x4f,0x67,0x67,0x53,0,0x04,
1140 0x07,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
1141 0x01,0x02,0x03,0x04,1,0,0,0,
1142 0x89,0x33,0x85,0xce,
1143 13,
1144 254,255,0,255,1,255,245,255,255,0,
1145 255,255,90};
1146
1147/* nil packets; beginning,middle,end */
1148const int head1_2[] = {0x4f,0x67,0x67,0x53,0,0x02,
1149 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1150 0x01,0x02,0x03,0x04,0,0,0,0,
1151 0xff,0x7b,0x23,0x17,
1152 1,
1153 0};
1154const int head2_2[] = {0x4f,0x67,0x67,0x53,0,0x04,
1155 0x07,0x28,0x00,0x00,0x00,0x00,0x00,0x00,
1156 0x01,0x02,0x03,0x04,1,0,0,0,
1157 0x5c,0x3f,0x66,0xcb,
1158 17,
1159 17,254,255,0,0,255,1,0,255,245,255,255,0,
1160 255,255,90,0};
1161
1162/* large initial packet */
1163const int head1_3[] = {0x4f,0x67,0x67,0x53,0,0x02,
1164 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1165 0x01,0x02,0x03,0x04,0,0,0,0,
1166 0x01,0x27,0x31,0xaa,
1167 18,
1168 255,255,255,255,255,255,255,255,
1169 255,255,255,255,255,255,255,255,255,10};
1170
1171const int head2_3[] = {0x4f,0x67,0x67,0x53,0,0x04,
1172 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
1173 0x01,0x02,0x03,0x04,1,0,0,0,
1174 0x7f,0x4e,0x8a,0xd2,
1175 4,
1176 255,4,255,0};
1177
1178
1179/* continuing packet test */
1180const int head1_4[] = {0x4f,0x67,0x67,0x53,0,0x02,
1181 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1182 0x01,0x02,0x03,0x04,0,0,0,0,
1183 0xff,0x7b,0x23,0x17,
1184 1,
1185 0};
1186
1187const int head2_4[] = {0x4f,0x67,0x67,0x53,0,0x00,
1188 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1189 0x01,0x02,0x03,0x04,1,0,0,0,
1190 0xf8,0x3c,0x19,0x79,
1191 255,
1192 255,255,255,255,255,255,255,255,
1193 255,255,255,255,255,255,255,255,
1194 255,255,255,255,255,255,255,255,
1195 255,255,255,255,255,255,255,255,
1196 255,255,255,255,255,255,255,255,
1197 255,255,255,255,255,255,255,255,
1198 255,255,255,255,255,255,255,255,
1199 255,255,255,255,255,255,255,255,
1200 255,255,255,255,255,255,255,255,
1201 255,255,255,255,255,255,255,255,
1202 255,255,255,255,255,255,255,255,
1203 255,255,255,255,255,255,255,255,
1204 255,255,255,255,255,255,255,255,
1205 255,255,255,255,255,255,255,255,
1206 255,255,255,255,255,255,255,255,
1207 255,255,255,255,255,255,255,255,
1208 255,255,255,255,255,255,255,255,
1209 255,255,255,255,255,255,255,255,
1210 255,255,255,255,255,255,255,255,
1211 255,255,255,255,255,255,255,255,
1212 255,255,255,255,255,255,255,255,
1213 255,255,255,255,255,255,255,255,
1214 255,255,255,255,255,255,255,255,
1215 255,255,255,255,255,255,255,255,
1216 255,255,255,255,255,255,255,255,
1217 255,255,255,255,255,255,255,255,
1218 255,255,255,255,255,255,255,255,
1219 255,255,255,255,255,255,255,255,
1220 255,255,255,255,255,255,255,255,
1221 255,255,255,255,255,255,255,255,
1222 255,255,255,255,255,255,255,255,
1223 255,255,255,255,255,255,255};
1224
1225const int head3_4[] = {0x4f,0x67,0x67,0x53,0,0x05,
1226 0x07,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,
1227 0x01,0x02,0x03,0x04,2,0,0,0,
1228 0x38,0xe6,0xb6,0x28,
1229 6,
1230 255,220,255,4,255,0};
1231
1232
1233/* spill expansion test */
1234const int head1_4b[] = {0x4f,0x67,0x67,0x53,0,0x02,
1235 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1236 0x01,0x02,0x03,0x04,0,0,0,0,
1237 0xff,0x7b,0x23,0x17,
1238 1,
1239 0};
1240
1241const int head2_4b[] = {0x4f,0x67,0x67,0x53,0,0x00,
1242 0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
1243 0x01,0x02,0x03,0x04,1,0,0,0,
1244 0xce,0x8f,0x17,0x1a,
1245 23,
1246 255,255,255,255,255,255,255,255,
1247 255,255,255,255,255,255,255,255,255,10,255,4,255,0,0};
1248
1249
1250const int head3_4b[] = {0x4f,0x67,0x67,0x53,0,0x04,
1251 0x07,0x14,0x00,0x00,0x00,0x00,0x00,0x00,
1252 0x01,0x02,0x03,0x04,2,0,0,0,
1253 0x9b,0xb2,0x50,0xa1,
1254 1,
1255 0};
1256
1257/* page with the 255 segment limit */
1258const int head1_5[] = {0x4f,0x67,0x67,0x53,0,0x02,
1259 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1260 0x01,0x02,0x03,0x04,0,0,0,0,
1261 0xff,0x7b,0x23,0x17,
1262 1,
1263 0};
1264
1265const int head2_5[] = {0x4f,0x67,0x67,0x53,0,0x00,
1266 0x07,0xfc,0x03,0x00,0x00,0x00,0x00,0x00,
1267 0x01,0x02,0x03,0x04,1,0,0,0,
1268 0xed,0x2a,0x2e,0xa7,
1269 255,
1270 10,10,10,10,10,10,10,10,
1271 10,10,10,10,10,10,10,10,
1272 10,10,10,10,10,10,10,10,
1273 10,10,10,10,10,10,10,10,
1274 10,10,10,10,10,10,10,10,
1275 10,10,10,10,10,10,10,10,
1276 10,10,10,10,10,10,10,10,
1277 10,10,10,10,10,10,10,10,
1278 10,10,10,10,10,10,10,10,
1279 10,10,10,10,10,10,10,10,
1280 10,10,10,10,10,10,10,10,
1281 10,10,10,10,10,10,10,10,
1282 10,10,10,10,10,10,10,10,
1283 10,10,10,10,10,10,10,10,
1284 10,10,10,10,10,10,10,10,
1285 10,10,10,10,10,10,10,10,
1286 10,10,10,10,10,10,10,10,
1287 10,10,10,10,10,10,10,10,
1288 10,10,10,10,10,10,10,10,
1289 10,10,10,10,10,10,10,10,
1290 10,10,10,10,10,10,10,10,
1291 10,10,10,10,10,10,10,10,
1292 10,10,10,10,10,10,10,10,
1293 10,10,10,10,10,10,10,10,
1294 10,10,10,10,10,10,10,10,
1295 10,10,10,10,10,10,10,10,
1296 10,10,10,10,10,10,10,10,
1297 10,10,10,10,10,10,10,10,
1298 10,10,10,10,10,10,10,10,
1299 10,10,10,10,10,10,10,10,
1300 10,10,10,10,10,10,10,10,
1301 10,10,10,10,10,10,10};
1302
1303const int head3_5[] = {0x4f,0x67,0x67,0x53,0,0x04,
1304 0x07,0x00,0x04,0x00,0x00,0x00,0x00,0x00,
1305 0x01,0x02,0x03,0x04,2,0,0,0,
1306 0x6c,0x3b,0x82,0x3d,
1307 1,
1308 50};
1309
1310
1311/* packet that overspans over an entire page */
1312const int head1_6[] = {0x4f,0x67,0x67,0x53,0,0x02,
1313 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1314 0x01,0x02,0x03,0x04,0,0,0,0,
1315 0xff,0x7b,0x23,0x17,
1316 1,
1317 0};
1318
1319const int head2_6[] = {0x4f,0x67,0x67,0x53,0,0x00,
1320 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
1321 0x01,0x02,0x03,0x04,1,0,0,0,
1322 0x68,0x22,0x7c,0x3d,
1323 255,
1324 100,
1325 255,255,255,255,255,255,255,255,
1326 255,255,255,255,255,255,255,255,
1327 255,255,255,255,255,255,255,255,
1328 255,255,255,255,255,255,255,255,
1329 255,255,255,255,255,255,255,255,
1330 255,255,255,255,255,255,255,255,
1331 255,255,255,255,255,255,255,255,
1332 255,255,255,255,255,255,255,255,
1333 255,255,255,255,255,255,255,255,
1334 255,255,255,255,255,255,255,255,
1335 255,255,255,255,255,255,255,255,
1336 255,255,255,255,255,255,255,255,
1337 255,255,255,255,255,255,255,255,
1338 255,255,255,255,255,255,255,255,
1339 255,255,255,255,255,255,255,255,
1340 255,255,255,255,255,255,255,255,
1341 255,255,255,255,255,255,255,255,
1342 255,255,255,255,255,255,255,255,
1343 255,255,255,255,255,255,255,255,
1344 255,255,255,255,255,255,255,255,
1345 255,255,255,255,255,255,255,255,
1346 255,255,255,255,255,255,255,255,
1347 255,255,255,255,255,255,255,255,
1348 255,255,255,255,255,255,255,255,
1349 255,255,255,255,255,255,255,255,
1350 255,255,255,255,255,255,255,255,
1351 255,255,255,255,255,255,255,255,
1352 255,255,255,255,255,255,255,255,
1353 255,255,255,255,255,255,255,255,
1354 255,255,255,255,255,255,255,255,
1355 255,255,255,255,255,255,255,255,
1356 255,255,255,255,255,255};
1357
1358const int head3_6[] = {0x4f,0x67,0x67,0x53,0,0x01,
1359 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1360 0x01,0x02,0x03,0x04,2,0,0,0,
1361 0xf4,0x87,0xba,0xf3,
1362 255,
1363 255,255,255,255,255,255,255,255,
1364 255,255,255,255,255,255,255,255,
1365 255,255,255,255,255,255,255,255,
1366 255,255,255,255,255,255,255,255,
1367 255,255,255,255,255,255,255,255,
1368 255,255,255,255,255,255,255,255,
1369 255,255,255,255,255,255,255,255,
1370 255,255,255,255,255,255,255,255,
1371 255,255,255,255,255,255,255,255,
1372 255,255,255,255,255,255,255,255,
1373 255,255,255,255,255,255,255,255,
1374 255,255,255,255,255,255,255,255,
1375 255,255,255,255,255,255,255,255,
1376 255,255,255,255,255,255,255,255,
1377 255,255,255,255,255,255,255,255,
1378 255,255,255,255,255,255,255,255,
1379 255,255,255,255,255,255,255,255,
1380 255,255,255,255,255,255,255,255,
1381 255,255,255,255,255,255,255,255,
1382 255,255,255,255,255,255,255,255,
1383 255,255,255,255,255,255,255,255,
1384 255,255,255,255,255,255,255,255,
1385 255,255,255,255,255,255,255,255,
1386 255,255,255,255,255,255,255,255,
1387 255,255,255,255,255,255,255,255,
1388 255,255,255,255,255,255,255,255,
1389 255,255,255,255,255,255,255,255,
1390 255,255,255,255,255,255,255,255,
1391 255,255,255,255,255,255,255,255,
1392 255,255,255,255,255,255,255,255,
1393 255,255,255,255,255,255,255,255,
1394 255,255,255,255,255,255,255};
1395
1396const int head4_6[] = {0x4f,0x67,0x67,0x53,0,0x05,
1397 0x07,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
1398 0x01,0x02,0x03,0x04,3,0,0,0,
1399 0xf7,0x2f,0x6c,0x60,
1400 5,
1401 254,255,4,255,0};
1402
1403/* packet that overspans over an entire page */
1404const int head1_7[] = {0x4f,0x67,0x67,0x53,0,0x02,
1405 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
1406 0x01,0x02,0x03,0x04,0,0,0,0,
1407 0xff,0x7b,0x23,0x17,
1408 1,
1409 0};
1410
1411const int head2_7[] = {0x4f,0x67,0x67,0x53,0,0x00,
1412 0x07,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
1413 0x01,0x02,0x03,0x04,1,0,0,0,
1414 0x68,0x22,0x7c,0x3d,
1415 255,
1416 100,
1417 255,255,255,255,255,255,255,255,
1418 255,255,255,255,255,255,255,255,
1419 255,255,255,255,255,255,255,255,
1420 255,255,255,255,255,255,255,255,
1421 255,255,255,255,255,255,255,255,
1422 255,255,255,255,255,255,255,255,
1423 255,255,255,255,255,255,255,255,
1424 255,255,255,255,255,255,255,255,
1425 255,255,255,255,255,255,255,255,
1426 255,255,255,255,255,255,255,255,
1427 255,255,255,255,255,255,255,255,
1428 255,255,255,255,255,255,255,255,
1429 255,255,255,255,255,255,255,255,
1430 255,255,255,255,255,255,255,255,
1431 255,255,255,255,255,255,255,255,
1432 255,255,255,255,255,255,255,255,
1433 255,255,255,255,255,255,255,255,
1434 255,255,255,255,255,255,255,255,
1435 255,255,255,255,255,255,255,255,
1436 255,255,255,255,255,255,255,255,
1437 255,255,255,255,255,255,255,255,
1438 255,255,255,255,255,255,255,255,
1439 255,255,255,255,255,255,255,255,
1440 255,255,255,255,255,255,255,255,
1441 255,255,255,255,255,255,255,255,
1442 255,255,255,255,255,255,255,255,
1443 255,255,255,255,255,255,255,255,
1444 255,255,255,255,255,255,255,255,
1445 255,255,255,255,255,255,255,255,
1446 255,255,255,255,255,255,255,255,
1447 255,255,255,255,255,255,255,255,
1448 255,255,255,255,255,255};
1449
1450const int head3_7[] = {0x4f,0x67,0x67,0x53,0,0x05,
1451 0x07,0x08,0x00,0x00,0x00,0x00,0x00,0x00,
1452 0x01,0x02,0x03,0x04,2,0,0,0,
1453 0xd4,0xe0,0x60,0xe5,
1454 1,
1455 0};
1456
1457int compare_packet(const ogg_packet *op1, const ogg_packet *op2){
1458 if(op1->packet!=op2->packet){
1459 fprintf(stderr,"op1->packet != op2->packet\n");
1460 return(1);
1461 }
1462 if(op1->bytes!=op2->bytes){
1463 fprintf(stderr,"op1->bytes != op2->bytes\n");
1464 return(1);
1465 }
1466 if(op1->b_o_s!=op2->b_o_s){
1467 fprintf(stderr,"op1->b_o_s != op2->b_o_s\n");
1468 return(1);
1469 }
1470 if(op1->e_o_s!=op2->e_o_s){
1471 fprintf(stderr,"op1->e_o_s != op2->e_o_s\n");
1472 return(1);
1473 }
1474 if(op1->granulepos!=op2->granulepos){
1475 fprintf(stderr,"op1->granulepos != op2->granulepos\n");
1476 return(1);
1477 }
1478 if(op1->packetno!=op2->packetno){
1479 fprintf(stderr,"op1->packetno != op2->packetno\n");
1480 return(1);
1481 }
1482 return(0);
1483}
1484
1485void test_pack(const int *pl, const int **headers, int byteskip,
1486 int pageskip, int packetskip){
1487 unsigned char *data=_ogg_malloc(1024*1024); /* for scripted test cases only */
1488 long inptr=0;
1489 long outptr=0;
1490 long deptr=0;
1491 long depacket=0;
1492 long granule_pos=7,pageno=0;
1493 int i,j,packets,pageout=pageskip;
1494 int eosflag=0;
1495 int bosflag=0;
1496
1497 int byteskipcount=0;
1498
1499 ogg_stream_reset(&os_en);
1500 ogg_stream_reset(&os_de);
1501 ogg_sync_reset(&oy);
1502
1503 for(packets=0;packets<packetskip;packets++)
1504 depacket+=pl[packets];
1505
1506 for(packets=0;;packets++)if(pl[packets]==-1)break;
1507
1508 for(i=0;i<packets;i++){
1509 /* construct a test packet */
1510 ogg_packet op;
1511 int len=pl[i];
1512
1513 op.packet=data+inptr;
1514 op.bytes=len;
1515 op.e_o_s=(pl[i+1]<0?1:0);
1516 op.granulepos=granule_pos;
1517
1518 granule_pos+=1024;
1519
1520 for(j=0;j<len;j++)data[inptr++]=i+j;
1521
1522 /* submit the test packet */
1523 ogg_stream_packetin(&os_en,&op);
1524
1525 /* retrieve any finished pages */
1526 {
1527 ogg_page og;
1528
1529 while(ogg_stream_pageout(&os_en,&og)){
1530 /* We have a page. Check it carefully */
1531
1532 fprintf(stderr,"%ld, ",pageno);
1533
1534 if(headers[pageno]==NULL){
1535 fprintf(stderr,"coded too many pages!\n");
1536 exit(1);
1537 }
1538
1539 check_page(data+outptr,headers[pageno],&og);
1540
1541 outptr+=og.body_len;
1542 pageno++;
1543 if(pageskip){
1544 bosflag=1;
1545 pageskip--;
1546 deptr+=og.body_len;
1547 }
1548
1549 /* have a complete page; submit it to sync/decode */
1550
1551 {
1552 ogg_page og_de;
1553 ogg_packet op_de,op_de2;
1554 char *buf=ogg_sync_buffer(&oy,og.header_len+og.body_len);
1555 char *next=buf;
1556 byteskipcount+=og.header_len;
1557 if(byteskipcount>byteskip){
1558 memcpy(next,og.header,byteskipcount-byteskip);
1559 next+=byteskipcount-byteskip;
1560 byteskipcount=byteskip;
1561 }
1562
1563 byteskipcount+=og.body_len;
1564 if(byteskipcount>byteskip){
1565 memcpy(next,og.body,byteskipcount-byteskip);
1566 next+=byteskipcount-byteskip;
1567 byteskipcount=byteskip;
1568 }
1569
1570 ogg_sync_wrote(&oy,next-buf);
1571
1572 while(1){
1573 int ret=ogg_sync_pageout(&oy,&og_de);
1574 if(ret==0)break;
1575 if(ret<0)continue;
1576 /* got a page. Happy happy. Verify that it's good. */
1577
1578 fprintf(stderr,"(%d), ",pageout);
1579
1580 check_page(data+deptr,headers[pageout],&og_de);
1581 deptr+=og_de.body_len;
1582 pageout++;
1583
1584 /* submit it to deconstitution */
1585 ogg_stream_pagein(&os_de,&og_de);
1586
1587 /* packets out? */
1588 while(ogg_stream_packetpeek(&os_de,&op_de2)>0){
1589 ogg_stream_packetpeek(&os_de,NULL);
1590 ogg_stream_packetout(&os_de,&op_de); /* just catching them all */
1591
1592 /* verify peek and out match */
1593 if(compare_packet(&op_de,&op_de2)){
1594 fprintf(stderr,"packetout != packetpeek! pos=%ld\n",
1595 depacket);
1596 exit(1);
1597 }
1598
1599 /* verify the packet! */
1600 /* check data */
1601 if(memcmp(data+depacket,op_de.packet,op_de.bytes)){
1602 fprintf(stderr,"packet data mismatch in decode! pos=%ld\n",
1603 depacket);
1604 exit(1);
1605 }
1606 /* check bos flag */
1607 if(bosflag==0 && op_de.b_o_s==0){
1608 fprintf(stderr,"b_o_s flag not set on packet!\n");
1609 exit(1);
1610 }
1611 if(bosflag && op_de.b_o_s){
1612 fprintf(stderr,"b_o_s flag incorrectly set on packet!\n");
1613 exit(1);
1614 }
1615 bosflag=1;
1616 depacket+=op_de.bytes;
1617
1618 /* check eos flag */
1619 if(eosflag){
1620 fprintf(stderr,"Multiple decoded packets with eos flag!\n");
1621 exit(1);
1622 }
1623
1624 if(op_de.e_o_s)eosflag=1;
1625
1626 /* check granulepos flag */
1627 if(op_de.granulepos!=-1){
1628 fprintf(stderr," granule:%ld ",(long)op_de.granulepos);
1629 }
1630 }
1631 }
1632 }
1633 }
1634 }
1635 }
1636 _ogg_free(data);
1637 if(headers[pageno]!=NULL){
1638 fprintf(stderr,"did not write last page!\n");
1639 exit(1);
1640 }
1641 if(headers[pageout]!=NULL){
1642 fprintf(stderr,"did not decode last page!\n");
1643 exit(1);
1644 }
1645 if(inptr!=outptr){
1646 fprintf(stderr,"encoded page data incomplete!\n");
1647 exit(1);
1648 }
1649 if(inptr!=deptr){
1650 fprintf(stderr,"decoded page data incomplete!\n");
1651 exit(1);
1652 }
1653 if(inptr!=depacket){
1654 fprintf(stderr,"decoded packet data incomplete!\n");
1655 exit(1);
1656 }
1657 if(!eosflag){
1658 fprintf(stderr,"Never got a packet with EOS set!\n");
1659 exit(1);
1660 }
1661 fprintf(stderr,"ok.\n");
1662}
1663
1664int main(void){
1665
1666 ogg_stream_init(&os_en,0x04030201);
1667 ogg_stream_init(&os_de,0x04030201);
1668 ogg_sync_init(&oy);
1669
1670 /* Exercise each code path in the framing code. Also verify that
1671 the checksums are working. */
1672
1673 {
1674 /* 17 only */
1675 const int packets[]={17, -1};
1676 const int *headret[]={head1_0,NULL};
1677
1678 fprintf(stderr,"testing single page encoding... ");
1679 test_pack(packets,headret,0,0,0);
1680 }
1681
1682 {
1683 /* 17, 254, 255, 256, 500, 510, 600 byte, pad */
1684 const int packets[]={17, 254, 255, 256, 500, 510, 600, -1};
1685 const int *headret[]={head1_1,head2_1,NULL};
1686
1687 fprintf(stderr,"testing basic page encoding... ");
1688 test_pack(packets,headret,0,0,0);
1689 }
1690
1691 {
1692 /* nil packets; beginning,middle,end */
1693 const int packets[]={0,17, 254, 255, 0, 256, 0, 500, 510, 600, 0, -1};
1694 const int *headret[]={head1_2,head2_2,NULL};
1695
1696 fprintf(stderr,"testing basic nil packets... ");
1697 test_pack(packets,headret,0,0,0);
1698 }
1699
1700 {
1701 /* large initial packet */
1702 const int packets[]={4345,259,255,-1};
1703 const int *headret[]={head1_3,head2_3,NULL};
1704
1705 fprintf(stderr,"testing initial-packet lacing > 4k... ");
1706 test_pack(packets,headret,0,0,0);
1707 }
1708
1709 {
1710 /* continuing packet test; with page spill expansion, we have to
1711 overflow the lacing table. */
1712 const int packets[]={0,65500,259,255,-1};
1713 const int *headret[]={head1_4,head2_4,head3_4,NULL};
1714
1715 fprintf(stderr,"testing single packet page span... ");
1716 test_pack(packets,headret,0,0,0);
1717 }
1718
1719 {
1720 /* spill expand packet test */
1721 const int packets[]={0,4345,259,255,0,0,-1};
1722 const int *headret[]={head1_4b,head2_4b,head3_4b,NULL};
1723
1724 fprintf(stderr,"testing page spill expansion... ");
1725 test_pack(packets,headret,0,0,0);
1726 }
1727
1728 /* page with the 255 segment limit */
1729 {
1730
1731 const int packets[]={0,10,10,10,10,10,10,10,10,
1732 10,10,10,10,10,10,10,10,
1733 10,10,10,10,10,10,10,10,
1734 10,10,10,10,10,10,10,10,
1735 10,10,10,10,10,10,10,10,
1736 10,10,10,10,10,10,10,10,
1737 10,10,10,10,10,10,10,10,
1738 10,10,10,10,10,10,10,10,
1739 10,10,10,10,10,10,10,10,
1740 10,10,10,10,10,10,10,10,
1741 10,10,10,10,10,10,10,10,
1742 10,10,10,10,10,10,10,10,
1743 10,10,10,10,10,10,10,10,
1744 10,10,10,10,10,10,10,10,
1745 10,10,10,10,10,10,10,10,
1746 10,10,10,10,10,10,10,10,
1747 10,10,10,10,10,10,10,10,
1748 10,10,10,10,10,10,10,10,
1749 10,10,10,10,10,10,10,10,
1750 10,10,10,10,10,10,10,10,
1751 10,10,10,10,10,10,10,10,
1752 10,10,10,10,10,10,10,10,
1753 10,10,10,10,10,10,10,10,
1754 10,10,10,10,10,10,10,10,
1755 10,10,10,10,10,10,10,10,
1756 10,10,10,10,10,10,10,10,
1757 10,10,10,10,10,10,10,10,
1758 10,10,10,10,10,10,10,10,
1759 10,10,10,10,10,10,10,10,
1760 10,10,10,10,10,10,10,10,
1761 10,10,10,10,10,10,10,10,
1762 10,10,10,10,10,10,10,50,-1};
1763 const int *headret[]={head1_5,head2_5,head3_5,NULL};
1764
1765 fprintf(stderr,"testing max packet segments... ");
1766 test_pack(packets,headret,0,0,0);
1767 }
1768
1769 {
1770 /* packet that overspans over an entire page */
1771 const int packets[]={0,100,130049,259,255,-1};
1772 const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL};
1773
1774 fprintf(stderr,"testing very large packets... ");
1775 test_pack(packets,headret,0,0,0);
1776 }
1777
1778#ifndef DISABLE_CRC
1779 {
1780 /* test for the libogg 1.1.1 resync in large continuation bug
1781 found by Josh Coalson) */
1782 const int packets[]={0,100,130049,259,255,-1};
1783 const int *headret[]={head1_6,head2_6,head3_6,head4_6,NULL};
1784
1785 fprintf(stderr,"testing continuation resync in very large packets... ");
1786 test_pack(packets,headret,100,2,3);
1787 }
1788#else
1789 fprintf(stderr,"Skipping continuation resync test due to --disable-crc\n");
1790#endif
1791
1792 {
1793 /* term only page. why not? */
1794 const int packets[]={0,100,64770,-1};
1795 const int *headret[]={head1_7,head2_7,head3_7,NULL};
1796
1797 fprintf(stderr,"testing zero data page (1 nil packet)... ");
1798 test_pack(packets,headret,0,0,0);
1799 }
1800
1801
1802
1803 {
1804 /* build a bunch of pages for testing */
1805 unsigned char *data=_ogg_malloc(1024*1024);
1806 int pl[]={0, 1,1,98,4079, 1,1,2954,2057, 76,34,912,0,234,1000,1000, 1000,300,-1};
1807 int inptr=0,i,j;
1808 ogg_page og[5];
1809
1810 ogg_stream_reset(&os_en);
1811
1812 for(i=0;pl[i]!=-1;i++){
1813 ogg_packet op;
1814 int len=pl[i];
1815
1816 op.packet=data+inptr;
1817 op.bytes=len;
1818 op.e_o_s=(pl[i+1]<0?1:0);
1819 op.granulepos=(i+1)*1000;
1820
1821 for(j=0;j<len;j++)data[inptr++]=i+j;
1822 ogg_stream_packetin(&os_en,&op);
1823 }
1824
1825 _ogg_free(data);
1826
1827 /* retrieve finished pages */
1828 for(i=0;i<5;i++){
1829 if(ogg_stream_pageout(&os_en,&og[i])==0){
1830 fprintf(stderr,"Too few pages output building sync tests!\n");
1831 exit(1);
1832 }
1833 copy_page(&og[i]);
1834 }
1835
1836 /* Test lost pages on pagein/packetout: no rollback */
1837 {
1838 ogg_page temp;
1839 ogg_packet test;
1840
1841 fprintf(stderr,"Testing loss of pages... ");
1842
1843 ogg_sync_reset(&oy);
1844 ogg_stream_reset(&os_de);
1845 for(i=0;i<5;i++){
1846 memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
1847 og[i].header_len);
1848 ogg_sync_wrote(&oy,og[i].header_len);
1849 memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len);
1850 ogg_sync_wrote(&oy,og[i].body_len);
1851 }
1852
1853 ogg_sync_pageout(&oy,&temp);
1854 ogg_stream_pagein(&os_de,&temp);
1855 ogg_sync_pageout(&oy,&temp);
1856 ogg_stream_pagein(&os_de,&temp);
1857 ogg_sync_pageout(&oy,&temp);
1858 /* skip */
1859 ogg_sync_pageout(&oy,&temp);
1860 ogg_stream_pagein(&os_de,&temp);
1861
1862 /* do we get the expected results/packets? */
1863
1864 if(ogg_stream_packetout(&os_de,&test)!=1)error();
1865 checkpacket(&test,0,0,0);
1866 if(ogg_stream_packetout(&os_de,&test)!=1)error();
1867 checkpacket(&test,1,1,-1);
1868 if(ogg_stream_packetout(&os_de,&test)!=1)error();
1869 checkpacket(&test,1,2,-1);
1870 if(ogg_stream_packetout(&os_de,&test)!=1)error();
1871 checkpacket(&test,98,3,-1);
1872 if(ogg_stream_packetout(&os_de,&test)!=1)error();
1873 checkpacket(&test,4079,4,5000);
1874 if(ogg_stream_packetout(&os_de,&test)!=-1){
1875 fprintf(stderr,"Error: loss of page did not return error\n");
1876 exit(1);
1877 }
1878 if(ogg_stream_packetout(&os_de,&test)!=1)error();
1879 checkpacket(&test,76,9,-1);
1880 if(ogg_stream_packetout(&os_de,&test)!=1)error();
1881 checkpacket(&test,34,10,-1);
1882 fprintf(stderr,"ok.\n");
1883 }
1884
1885 /* Test lost pages on pagein/packetout: rollback with continuation */
1886 {
1887 ogg_page temp;
1888 ogg_packet test;
1889
1890 fprintf(stderr,"Testing loss of pages (rollback required)... ");
1891
1892 ogg_sync_reset(&oy);
1893 ogg_stream_reset(&os_de);
1894 for(i=0;i<5;i++){
1895 memcpy(ogg_sync_buffer(&oy,og[i].header_len),og[i].header,
1896 og[i].header_len);
1897 ogg_sync_wrote(&oy,og[i].header_len);
1898 memcpy(ogg_sync_buffer(&oy,og[i].body_len),og[i].body,og[i].body_len);
1899 ogg_sync_wrote(&oy,og[i].body_len);
1900 }
1901
1902 ogg_sync_pageout(&oy,&temp);
1903 ogg_stream_pagein(&os_de,&temp);
1904 ogg_sync_pageout(&oy,&temp);
1905 ogg_stream_pagein(&os_de,&temp);
1906 ogg_sync_pageout(&oy,&temp);
1907 ogg_stream_pagein(&os_de,&temp);
1908 ogg_sync_pageout(&oy,&temp);
1909 /* skip */
1910 ogg_sync_pageout(&oy,&temp);
1911 ogg_stream_pagein(&os_de,&temp);
1912
1913 /* do we get the expected results/packets? */
1914
1915 if(ogg_stream_packetout(&os_de,&test)!=1)error();
1916 checkpacket(&test,0,0,0);
1917 if(ogg_stream_packetout(&os_de,&test)!=1)error();
1918 checkpacket(&test,1,1,-1);
1919 if(ogg_stream_packetout(&os_de,&test)!=1)error();
1920 checkpacket(&test,1,2,-1);
1921 if(ogg_stream_packetout(&os_de,&test)!=1)error();
1922 checkpacket(&test,98,3,-1);
1923 if(ogg_stream_packetout(&os_de,&test)!=1)error();
1924 checkpacket(&test,4079,4,5000);
1925 if(ogg_stream_packetout(&os_de,&test)!=1)error();
1926 checkpacket(&test,1,5,-1);
1927 if(ogg_stream_packetout(&os_de,&test)!=1)error();
1928 checkpacket(&test,1,6,-1);
1929 if(ogg_stream_packetout(&os_de,&test)!=1)error();
1930 checkpacket(&test,2954,7,-1);
1931 if(ogg_stream_packetout(&os_de,&test)!=1)error();
1932 checkpacket(&test,2057,8,9000);
1933 if(ogg_stream_packetout(&os_de,&test)!=-1){
1934 fprintf(stderr,"Error: loss of page did not return error\n");
1935 exit(1);
1936 }
1937 if(ogg_stream_packetout(&os_de,&test)!=1)error();
1938 checkpacket(&test,300,17,18000);
1939 fprintf(stderr,"ok.\n");
1940 }
1941
1942 /* the rest only test sync */
1943 {
1944 ogg_page og_de;
1945 /* Test fractional page inputs: incomplete capture */
1946 fprintf(stderr,"Testing sync on partial inputs... ");
1947 ogg_sync_reset(&oy);
1948 memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
1949 3);
1950 ogg_sync_wrote(&oy,3);
1951 if(ogg_sync_pageout(&oy,&og_de)>0)error();
1952
1953 /* Test fractional page inputs: incomplete fixed header */
1954 memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+3,
1955 20);
1956 ogg_sync_wrote(&oy,20);
1957 if(ogg_sync_pageout(&oy,&og_de)>0)error();
1958
1959 /* Test fractional page inputs: incomplete header */
1960 memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+23,
1961 5);
1962 ogg_sync_wrote(&oy,5);
1963 if(ogg_sync_pageout(&oy,&og_de)>0)error();
1964
1965 /* Test fractional page inputs: incomplete body */
1966
1967 memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+28,
1968 og[1].header_len-28);
1969 ogg_sync_wrote(&oy,og[1].header_len-28);
1970 if(ogg_sync_pageout(&oy,&og_de)>0)error();
1971
1972 memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,1000);
1973 ogg_sync_wrote(&oy,1000);
1974 if(ogg_sync_pageout(&oy,&og_de)>0)error();
1975
1976 memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body+1000,
1977 og[1].body_len-1000);
1978 ogg_sync_wrote(&oy,og[1].body_len-1000);
1979 if(ogg_sync_pageout(&oy,&og_de)<=0)error();
1980
1981 fprintf(stderr,"ok.\n");
1982 }
1983
1984 /* Test fractional page inputs: page + incomplete capture */
1985 {
1986 ogg_page og_de;
1987 fprintf(stderr,"Testing sync on 1+partial inputs... ");
1988 ogg_sync_reset(&oy);
1989
1990 memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
1991 og[1].header_len);
1992 ogg_sync_wrote(&oy,og[1].header_len);
1993
1994 memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
1995 og[1].body_len);
1996 ogg_sync_wrote(&oy,og[1].body_len);
1997
1998 memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
1999 20);
2000 ogg_sync_wrote(&oy,20);
2001 if(ogg_sync_pageout(&oy,&og_de)<=0)error();
2002 if(ogg_sync_pageout(&oy,&og_de)>0)error();
2003
2004 memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header+20,
2005 og[1].header_len-20);
2006 ogg_sync_wrote(&oy,og[1].header_len-20);
2007 memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
2008 og[1].body_len);
2009 ogg_sync_wrote(&oy,og[1].body_len);
2010 if(ogg_sync_pageout(&oy,&og_de)<=0)error();
2011
2012 fprintf(stderr,"ok.\n");
2013 }
2014
2015 /* Test recapture: garbage + page */
2016 {
2017 ogg_page og_de;
2018 fprintf(stderr,"Testing search for capture... ");
2019 ogg_sync_reset(&oy);
2020
2021 /* 'garbage' */
2022 memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
2023 og[1].body_len);
2024 ogg_sync_wrote(&oy,og[1].body_len);
2025
2026 memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
2027 og[1].header_len);
2028 ogg_sync_wrote(&oy,og[1].header_len);
2029
2030 memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
2031 og[1].body_len);
2032 ogg_sync_wrote(&oy,og[1].body_len);
2033
2034 memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
2035 20);
2036 ogg_sync_wrote(&oy,20);
2037 if(ogg_sync_pageout(&oy,&og_de)>0)error();
2038 if(ogg_sync_pageout(&oy,&og_de)<=0)error();
2039 if(ogg_sync_pageout(&oy,&og_de)>0)error();
2040
2041 memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header+20,
2042 og[2].header_len-20);
2043 ogg_sync_wrote(&oy,og[2].header_len-20);
2044 memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body,
2045 og[2].body_len);
2046 ogg_sync_wrote(&oy,og[2].body_len);
2047 if(ogg_sync_pageout(&oy,&og_de)<=0)error();
2048
2049 fprintf(stderr,"ok.\n");
2050 }
2051
2052#ifndef DISABLE_CRC
2053 /* Test recapture: page + garbage + page */
2054 {
2055 ogg_page og_de;
2056 fprintf(stderr,"Testing recapture... ");
2057 ogg_sync_reset(&oy);
2058
2059 memcpy(ogg_sync_buffer(&oy,og[1].header_len),og[1].header,
2060 og[1].header_len);
2061 ogg_sync_wrote(&oy,og[1].header_len);
2062
2063 memcpy(ogg_sync_buffer(&oy,og[1].body_len),og[1].body,
2064 og[1].body_len);
2065 ogg_sync_wrote(&oy,og[1].body_len);
2066
2067 memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
2068 og[2].header_len);
2069 ogg_sync_wrote(&oy,og[2].header_len);
2070
2071 memcpy(ogg_sync_buffer(&oy,og[2].header_len),og[2].header,
2072 og[2].header_len);
2073 ogg_sync_wrote(&oy,og[2].header_len);
2074
2075 if(ogg_sync_pageout(&oy,&og_de)<=0)error();
2076
2077 memcpy(ogg_sync_buffer(&oy,og[2].body_len),og[2].body,
2078 og[2].body_len-5);
2079 ogg_sync_wrote(&oy,og[2].body_len-5);
2080
2081 memcpy(ogg_sync_buffer(&oy,og[3].header_len),og[3].header,
2082 og[3].header_len);
2083 ogg_sync_wrote(&oy,og[3].header_len);
2084
2085 memcpy(ogg_sync_buffer(&oy,og[3].body_len),og[3].body,
2086 og[3].body_len);
2087 ogg_sync_wrote(&oy,og[3].body_len);
2088
2089 if(ogg_sync_pageout(&oy,&og_de)>0)error();
2090 if(ogg_sync_pageout(&oy,&og_de)<=0)error();
2091
2092 fprintf(stderr,"ok.\n");
2093 }
2094#else
2095 fprintf(stderr,"Skipping recapture test due to --disable-crc\n");
2096#endif
2097
2098 /* Free page data that was previously copied */
2099 {
2100 for(i=0;i<5;i++){
2101 free_page(&og[i]);
2102 }
2103 }
2104 }
2105
2106 return(0);
2107}
2108
2109#endif
diff --git a/lib/rbcodec/codecs/libopus/ogg/ogg.h b/lib/rbcodec/codecs/libopus/ogg/ogg.h
index 00975ca354..330ea3c63a 100644
--- a/lib/rbcodec/codecs/libopus/ogg/ogg.h
+++ b/lib/rbcodec/codecs/libopus/ogg/ogg.h
@@ -11,7 +11,6 @@
11 ******************************************************************** 11 ********************************************************************
12 12
13 function: toplevel libogg include 13 function: toplevel libogg include
14 last mod: $Id: ogg.h 18044 2011-08-01 17:55:20Z gmaxwell $
15 14
16 ********************************************************************/ 15 ********************************************************************/
17#ifndef _OGG_H 16#ifndef _OGG_H
diff --git a/lib/rbcodec/codecs/libopus/opus.c b/lib/rbcodec/codecs/libopus/opus.c
index 0526f8b414..538b5ea74e 100644
--- a/lib/rbcodec/codecs/libopus/opus.c
+++ b/lib/rbcodec/codecs/libopus/opus.c
@@ -104,6 +104,10 @@ OPUS_EXPORT void opus_pcm_soft_clip(float *_x, int N, int C, float *declip_mem)
104 104
105 /* Compute a such that maxval + a*maxval^2 = 1 */ 105 /* Compute a such that maxval + a*maxval^2 = 1 */
106 a=(maxval-1)/(maxval*maxval); 106 a=(maxval-1)/(maxval*maxval);
107 /* Slightly boost "a" by 2^-22. This is just enough to ensure -ffast-math
108 does not cause output values larger than +/-1, but small enough not
109 to matter even for 24-bit output. */
110 a += a*2.4e-7f;
107 if (x[i*C]>0) 111 if (x[i*C]>0)
108 a = -a; 112 a = -a;
109 /* Apply soft clipping */ 113 /* Apply soft clipping */
@@ -133,7 +137,6 @@ OPUS_EXPORT void opus_pcm_soft_clip(float *_x, int N, int C, float *declip_mem)
133} 137}
134#endif 138#endif
135 139
136#if 0
137int encode_size(int size, unsigned char *data) 140int encode_size(int size, unsigned char *data)
138{ 141{
139 if (size < 252) 142 if (size < 252)
@@ -146,7 +149,6 @@ int encode_size(int size, unsigned char *data)
146 return 2; 149 return 2;
147 } 150 }
148} 151}
149#endif
150 152
151static int parse_size(const unsigned char *data, opus_int32 len, opus_int16 *size) 153static int parse_size(const unsigned char *data, opus_int32 len, opus_int16 *size)
152{ 154{
@@ -203,8 +205,10 @@ int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
203 opus_int32 pad = 0; 205 opus_int32 pad = 0;
204 const unsigned char *data0 = data; 206 const unsigned char *data0 = data;
205 207
206 if (size==NULL) 208 if (size==NULL || len<0)
207 return OPUS_BAD_ARG; 209 return OPUS_BAD_ARG;
210 if (len==0)
211 return OPUS_INVALID_PACKET;
208 212
209 framesize = opus_packet_get_samples_per_frame(data, 48000); 213 framesize = opus_packet_get_samples_per_frame(data, 48000);
210 214
@@ -248,7 +252,7 @@ int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
248 /* Number of frames encoded in bits 0 to 5 */ 252 /* Number of frames encoded in bits 0 to 5 */
249 ch = *data++; 253 ch = *data++;
250 count = ch&0x3F; 254 count = ch&0x3F;
251 if (count <= 0 || framesize*count > 5760) 255 if (count <= 0 || framesize*(opus_int32)count > 5760)
252 return OPUS_INVALID_PACKET; 256 return OPUS_INVALID_PACKET;
253 len--; 257 len--;
254 /* Padding flag is bit 6 */ 258 /* Padding flag is bit 6 */
@@ -342,7 +346,6 @@ int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
342 return count; 346 return count;
343} 347}
344 348
345#if 0
346int opus_packet_parse(const unsigned char *data, opus_int32 len, 349int opus_packet_parse(const unsigned char *data, opus_int32 len,
347 unsigned char *out_toc, const unsigned char *frames[48], 350 unsigned char *out_toc, const unsigned char *frames[48],
348 opus_int16 size[48], int *payload_offset) 351 opus_int16 size[48], int *payload_offset)
@@ -350,5 +353,4 @@ int opus_packet_parse(const unsigned char *data, opus_int32 len,
350 return opus_packet_parse_impl(data, len, 0, out_toc, 353 return opus_packet_parse_impl(data, len, 0, out_toc,
351 frames, size, payload_offset, NULL); 354 frames, size, payload_offset, NULL);
352} 355}
353#endif
354 356
diff --git a/lib/rbcodec/codecs/libopus/opus.h b/lib/rbcodec/codecs/libopus/opus.h
index 93a53a2ffc..d282f21d25 100644
--- a/lib/rbcodec/codecs/libopus/opus.h
+++ b/lib/rbcodec/codecs/libopus/opus.h
@@ -142,7 +142,7 @@ extern "C" {
142 * 142 *
143 * opus_encode() and opus_encode_float() return the number of bytes actually written to the packet. 143 * opus_encode() and opus_encode_float() return the number of bytes actually written to the packet.
144 * The return value <b>can be negative</b>, which indicates that an error has occurred. If the return value 144 * The return value <b>can be negative</b>, which indicates that an error has occurred. If the return value
145 * is 1 byte, then the packet does not need to be transmitted (DTX). 145 * is 2 bytes or less, then the packet does not need to be transmitted (DTX).
146 * 146 *
147 * Once the encoder state if no longer needed, it can be destroyed with 147 * Once the encoder state if no longer needed, it can be destroyed with
148 * 148 *
@@ -531,7 +531,7 @@ OPUS_EXPORT int opus_packet_parse(
531 const unsigned char *frames[48], 531 const unsigned char *frames[48],
532 opus_int16 size[48], 532 opus_int16 size[48],
533 int *payload_offset 533 int *payload_offset
534) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); 534) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5);
535 535
536/** Gets the bandwidth of an Opus packet. 536/** Gets the bandwidth of an Opus packet.
537 * @param [in] data <tt>char*</tt>: Opus packet 537 * @param [in] data <tt>char*</tt>: Opus packet
@@ -616,7 +616,10 @@ OPUS_EXPORT void opus_pcm_soft_clip(float *pcm, int frame_size, int channels, fl
616 * merged. Splitting valid Opus packets is always guaranteed to succeed, 616 * merged. Splitting valid Opus packets is always guaranteed to succeed,
617 * whereas merging valid packets only succeeds if all frames have the same 617 * whereas merging valid packets only succeeds if all frames have the same
618 * mode, bandwidth, and frame size, and when the total duration of the merged 618 * mode, bandwidth, and frame size, and when the total duration of the merged
619 * packet is no more than 120 ms. 619 * packet is no more than 120 ms. The 120 ms limit comes from the
620 * specification and limits decoder memory requirements at a point where
621 * framing overhead becomes negligible.
622 *
620 * The repacketizer currently only operates on elementary Opus 623 * The repacketizer currently only operates on elementary Opus
621 * streams. It will not manipualte multistream packets successfully, except in 624 * streams. It will not manipualte multistream packets successfully, except in
622 * the degenerate case where they consist of data from a single stream. 625 * the degenerate case where they consist of data from a single stream.
diff --git a/lib/rbcodec/codecs/libopus/opus_compare.c b/lib/rbcodec/codecs/libopus/opus_compare.c
new file mode 100644
index 0000000000..1956e08fa5
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/opus_compare.c
@@ -0,0 +1,382 @@
1/* Copyright (c) 2011-2012 Xiph.Org Foundation, Mozilla Corporation
2 Written by Jean-Marc Valin and Timothy B. Terriberry */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#include <stdio.h>
29#include <stdlib.h>
30#include <math.h>
31#include <string.h>
32
33#define OPUS_PI (3.14159265F)
34
35#define OPUS_COSF(_x) ((float)cos(_x))
36#define OPUS_SINF(_x) ((float)sin(_x))
37
38static void *check_alloc(void *_ptr){
39 if(_ptr==NULL){
40 fprintf(stderr,"Out of memory.\n");
41 exit(EXIT_FAILURE);
42 }
43 return _ptr;
44}
45
46static void *opus_malloc(size_t _size){
47 return check_alloc(malloc(_size));
48}
49
50static void *opus_realloc(void *_ptr,size_t _size){
51 return check_alloc(realloc(_ptr,_size));
52}
53
54static size_t read_pcm16(float **_samples,FILE *_fin,int _nchannels){
55 unsigned char buf[1024];
56 float *samples;
57 size_t nsamples;
58 size_t csamples;
59 size_t xi;
60 size_t nread;
61 samples=NULL;
62 nsamples=csamples=0;
63 for(;;){
64 nread=fread(buf,2*_nchannels,1024/(2*_nchannels),_fin);
65 if(nread<=0)break;
66 if(nsamples+nread>csamples){
67 do csamples=csamples<<1|1;
68 while(nsamples+nread>csamples);
69 samples=(float *)opus_realloc(samples,
70 _nchannels*csamples*sizeof(*samples));
71 }
72 for(xi=0;xi<nread;xi++){
73 int ci;
74 for(ci=0;ci<_nchannels;ci++){
75 int s;
76 s=buf[2*(xi*_nchannels+ci)+1]<<8|buf[2*(xi*_nchannels+ci)];
77 s=((s&0xFFFF)^0x8000)-0x8000;
78 samples[(nsamples+xi)*_nchannels+ci]=s;
79 }
80 }
81 nsamples+=nread;
82 }
83 *_samples=(float *)opus_realloc(samples,
84 _nchannels*nsamples*sizeof(*samples));
85 return nsamples;
86}
87
88static void band_energy(float *_out,float *_ps,const int *_bands,int _nbands,
89 const float *_in,int _nchannels,size_t _nframes,int _window_sz,
90 int _step,int _downsample){
91 float *window;
92 float *x;
93 float *c;
94 float *s;
95 size_t xi;
96 int xj;
97 int ps_sz;
98 window=(float *)opus_malloc((3+_nchannels)*_window_sz*sizeof(*window));
99 c=window+_window_sz;
100 s=c+_window_sz;
101 x=s+_window_sz;
102 ps_sz=_window_sz/2;
103 for(xj=0;xj<_window_sz;xj++){
104 window[xj]=0.5F-0.5F*OPUS_COSF((2*OPUS_PI/(_window_sz-1))*xj);
105 }
106 for(xj=0;xj<_window_sz;xj++){
107 c[xj]=OPUS_COSF((2*OPUS_PI/_window_sz)*xj);
108 }
109 for(xj=0;xj<_window_sz;xj++){
110 s[xj]=OPUS_SINF((2*OPUS_PI/_window_sz)*xj);
111 }
112 for(xi=0;xi<_nframes;xi++){
113 int ci;
114 int xk;
115 int bi;
116 for(ci=0;ci<_nchannels;ci++){
117 for(xk=0;xk<_window_sz;xk++){
118 x[ci*_window_sz+xk]=window[xk]*_in[(xi*_step+xk)*_nchannels+ci];
119 }
120 }
121 for(bi=xj=0;bi<_nbands;bi++){
122 float p[2]={0};
123 for(;xj<_bands[bi+1];xj++){
124 for(ci=0;ci<_nchannels;ci++){
125 float re;
126 float im;
127 int ti;
128 ti=0;
129 re=im=0;
130 for(xk=0;xk<_window_sz;xk++){
131 re+=c[ti]*x[ci*_window_sz+xk];
132 im-=s[ti]*x[ci*_window_sz+xk];
133 ti+=xj;
134 if(ti>=_window_sz)ti-=_window_sz;
135 }
136 re*=_downsample;
137 im*=_downsample;
138 _ps[(xi*ps_sz+xj)*_nchannels+ci]=re*re+im*im+100000;
139 p[ci]+=_ps[(xi*ps_sz+xj)*_nchannels+ci];
140 }
141 }
142 if(_out){
143 _out[(xi*_nbands+bi)*_nchannels]=p[0]/(_bands[bi+1]-_bands[bi]);
144 if(_nchannels==2){
145 _out[(xi*_nbands+bi)*_nchannels+1]=p[1]/(_bands[bi+1]-_bands[bi]);
146 }
147 }
148 }
149 }
150 free(window);
151}
152
153#define NBANDS (21)
154#define NFREQS (240)
155
156/*Bands on which we compute the pseudo-NMR (Bark-derived
157 CELT bands).*/
158static const int BANDS[NBANDS+1]={
159 0,2,4,6,8,10,12,14,16,20,24,28,32,40,48,56,68,80,96,120,156,200
160};
161
162#define TEST_WIN_SIZE (480)
163#define TEST_WIN_STEP (120)
164
165int main(int _argc,const char **_argv){
166 FILE *fin1;
167 FILE *fin2;
168 float *x;
169 float *y;
170 float *xb;
171 float *X;
172 float *Y;
173 double err;
174 float Q;
175 size_t xlength;
176 size_t ylength;
177 size_t nframes;
178 size_t xi;
179 int ci;
180 int xj;
181 int bi;
182 int nchannels;
183 unsigned rate;
184 int downsample;
185 int ybands;
186 int yfreqs;
187 int max_compare;
188 if(_argc<3||_argc>6){
189 fprintf(stderr,"Usage: %s [-s] [-r rate2] <file1.sw> <file2.sw>\n",
190 _argv[0]);
191 return EXIT_FAILURE;
192 }
193 nchannels=1;
194 if(strcmp(_argv[1],"-s")==0){
195 nchannels=2;
196 _argv++;
197 }
198 rate=48000;
199 ybands=NBANDS;
200 yfreqs=NFREQS;
201 downsample=1;
202 if(strcmp(_argv[1],"-r")==0){
203 rate=atoi(_argv[2]);
204 if(rate!=8000&&rate!=12000&&rate!=16000&&rate!=24000&&rate!=48000){
205 fprintf(stderr,
206 "Sampling rate must be 8000, 12000, 16000, 24000, or 48000\n");
207 return EXIT_FAILURE;
208 }
209 downsample=48000/rate;
210 switch(rate){
211 case 8000:ybands=13;break;
212 case 12000:ybands=15;break;
213 case 16000:ybands=17;break;
214 case 24000:ybands=19;break;
215 }
216 yfreqs=NFREQS/downsample;
217 _argv+=2;
218 }
219 fin1=fopen(_argv[1],"rb");
220 if(fin1==NULL){
221 fprintf(stderr,"Error opening '%s'.\n",_argv[1]);
222 return EXIT_FAILURE;
223 }
224 fin2=fopen(_argv[2],"rb");
225 if(fin2==NULL){
226 fprintf(stderr,"Error opening '%s'.\n",_argv[2]);
227 fclose(fin1);
228 return EXIT_FAILURE;
229 }
230 /*Read in the data and allocate scratch space.*/
231 xlength=read_pcm16(&x,fin1,2);
232 if(nchannels==1){
233 for(xi=0;xi<xlength;xi++)x[xi]=.5*(x[2*xi]+x[2*xi+1]);
234 }
235 fclose(fin1);
236 ylength=read_pcm16(&y,fin2,nchannels);
237 fclose(fin2);
238 if(xlength!=ylength*downsample){
239 fprintf(stderr,"Sample counts do not match (%lu!=%lu).\n",
240 (unsigned long)xlength,(unsigned long)ylength*downsample);
241 return EXIT_FAILURE;
242 }
243 if(xlength<TEST_WIN_SIZE){
244 fprintf(stderr,"Insufficient sample data (%lu<%i).\n",
245 (unsigned long)xlength,TEST_WIN_SIZE);
246 return EXIT_FAILURE;
247 }
248 nframes=(xlength-TEST_WIN_SIZE+TEST_WIN_STEP)/TEST_WIN_STEP;
249 xb=(float *)opus_malloc(nframes*NBANDS*nchannels*sizeof(*xb));
250 X=(float *)opus_malloc(nframes*NFREQS*nchannels*sizeof(*X));
251 Y=(float *)opus_malloc(nframes*yfreqs*nchannels*sizeof(*Y));
252 /*Compute the per-band spectral energy of the original signal
253 and the error.*/
254 band_energy(xb,X,BANDS,NBANDS,x,nchannels,nframes,
255 TEST_WIN_SIZE,TEST_WIN_STEP,1);
256 free(x);
257 band_energy(NULL,Y,BANDS,ybands,y,nchannels,nframes,
258 TEST_WIN_SIZE/downsample,TEST_WIN_STEP/downsample,downsample);
259 free(y);
260 for(xi=0;xi<nframes;xi++){
261 /*Frequency masking (low to high): 10 dB/Bark slope.*/
262 for(bi=1;bi<NBANDS;bi++){
263 for(ci=0;ci<nchannels;ci++){
264 xb[(xi*NBANDS+bi)*nchannels+ci]+=
265 0.1F*xb[(xi*NBANDS+bi-1)*nchannels+ci];
266 }
267 }
268 /*Frequency masking (high to low): 15 dB/Bark slope.*/
269 for(bi=NBANDS-1;bi-->0;){
270 for(ci=0;ci<nchannels;ci++){
271 xb[(xi*NBANDS+bi)*nchannels+ci]+=
272 0.03F*xb[(xi*NBANDS+bi+1)*nchannels+ci];
273 }
274 }
275 if(xi>0){
276 /*Temporal masking: -3 dB/2.5ms slope.*/
277 for(bi=0;bi<NBANDS;bi++){
278 for(ci=0;ci<nchannels;ci++){
279 xb[(xi*NBANDS+bi)*nchannels+ci]+=
280 0.5F*xb[((xi-1)*NBANDS+bi)*nchannels+ci];
281 }
282 }
283 }
284 /* Allowing some cross-talk */
285 if(nchannels==2){
286 for(bi=0;bi<NBANDS;bi++){
287 float l,r;
288 l=xb[(xi*NBANDS+bi)*nchannels+0];
289 r=xb[(xi*NBANDS+bi)*nchannels+1];
290 xb[(xi*NBANDS+bi)*nchannels+0]+=0.01F*r;
291 xb[(xi*NBANDS+bi)*nchannels+1]+=0.01F*l;
292 }
293 }
294
295 /* Apply masking */
296 for(bi=0;bi<ybands;bi++){
297 for(xj=BANDS[bi];xj<BANDS[bi+1];xj++){
298 for(ci=0;ci<nchannels;ci++){
299 X[(xi*NFREQS+xj)*nchannels+ci]+=
300 0.1F*xb[(xi*NBANDS+bi)*nchannels+ci];
301 Y[(xi*yfreqs+xj)*nchannels+ci]+=
302 0.1F*xb[(xi*NBANDS+bi)*nchannels+ci];
303 }
304 }
305 }
306 }
307
308 /* Average of consecutive frames to make comparison slightly less sensitive */
309 for(bi=0;bi<ybands;bi++){
310 for(xj=BANDS[bi];xj<BANDS[bi+1];xj++){
311 for(ci=0;ci<nchannels;ci++){
312 float xtmp;
313 float ytmp;
314 xtmp = X[xj*nchannels+ci];
315 ytmp = Y[xj*nchannels+ci];
316 for(xi=1;xi<nframes;xi++){
317 float xtmp2;
318 float ytmp2;
319 xtmp2 = X[(xi*NFREQS+xj)*nchannels+ci];
320 ytmp2 = Y[(xi*yfreqs+xj)*nchannels+ci];
321 X[(xi*NFREQS+xj)*nchannels+ci] += xtmp;
322 Y[(xi*yfreqs+xj)*nchannels+ci] += ytmp;
323 xtmp = xtmp2;
324 ytmp = ytmp2;
325 }
326 }
327 }
328 }
329
330 /*If working at a lower sampling rate, don't take into account the last
331 300 Hz to allow for different transition bands.
332 For 12 kHz, we don't skip anything, because the last band already skips
333 400 Hz.*/
334 if(rate==48000)max_compare=BANDS[NBANDS];
335 else if(rate==12000)max_compare=BANDS[ybands];
336 else max_compare=BANDS[ybands]-3;
337 err=0;
338 for(xi=0;xi<nframes;xi++){
339 double Ef;
340 Ef=0;
341 for(bi=0;bi<ybands;bi++){
342 double Eb;
343 Eb=0;
344 for(xj=BANDS[bi];xj<BANDS[bi+1]&&xj<max_compare;xj++){
345 for(ci=0;ci<nchannels;ci++){
346 float re;
347 float im;
348 re=Y[(xi*yfreqs+xj)*nchannels+ci]/X[(xi*NFREQS+xj)*nchannels+ci];
349 im=re-log(re)-1;
350 /*Make comparison less sensitive around the SILK/CELT cross-over to
351 allow for mode freedom in the filters.*/
352 if(xj>=79&&xj<=81)im*=0.1F;
353 if(xj==80)im*=0.1F;
354 Eb+=im;
355 }
356 }
357 Eb /= (BANDS[bi+1]-BANDS[bi])*nchannels;
358 Ef += Eb*Eb;
359 }
360 /*Using a fixed normalization value means we're willing to accept slightly
361 lower quality for lower sampling rates.*/
362 Ef/=NBANDS;
363 Ef*=Ef;
364 err+=Ef*Ef;
365 }
366 free(xb);
367 free(X);
368 free(Y);
369 err=pow(err/nframes,1.0/16);
370 Q=100*(1-0.5*log(1+err)/log(1.13));
371 if(Q<0){
372 fprintf(stderr,"Test vector FAILS\n");
373 fprintf(stderr,"Internal weighted error is %f\n",err);
374 return EXIT_FAILURE;
375 }
376 else{
377 fprintf(stderr,"Test vector PASSES\n");
378 fprintf(stderr,
379 "Opus quality metric: %.1f %% (internal weighted error is %f)\n",Q,err);
380 return EXIT_SUCCESS;
381 }
382}
diff --git a/lib/rbcodec/codecs/libopus/opus_decoder.c b/lib/rbcodec/codecs/libopus/opus_decoder.c
index 5d35ed2675..9113638a00 100644
--- a/lib/rbcodec/codecs/libopus/opus_decoder.c
+++ b/lib/rbcodec/codecs/libopus/opus_decoder.c
@@ -33,7 +33,7 @@
33# 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." 33# 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."
34#endif 34#endif
35 35
36#if defined(__GNUC__) && (__GNUC__ >= 2) && !defined(__OPTIMIZE__) 36#if defined(__GNUC__) && (__GNUC__ >= 2) && !defined(__OPTIMIZE__) && !defined(OPUS_WILL_BE_SLOW)
37# pragma message "You appear to be compiling without optimization, if so opus will be very slow." 37# pragma message "You appear to be compiling without optimization, if so opus will be very slow."
38#endif 38#endif
39 39
@@ -59,6 +59,7 @@ struct OpusDecoder {
59 opus_int32 Fs; /** Sampling rate (at the API level) */ 59 opus_int32 Fs; /** Sampling rate (at the API level) */
60 silk_DecControlStruct DecControl; 60 silk_DecControlStruct DecControl;
61 int decode_gain; 61 int decode_gain;
62 int arch;
62 63
63 /* Everything beyond this point gets cleared on a reset */ 64 /* Everything beyond this point gets cleared on a reset */
64#define OPUS_DECODER_RESET_START stream_channels 65#define OPUS_DECODER_RESET_START stream_channels
@@ -77,6 +78,26 @@ struct OpusDecoder {
77 opus_uint32 rangeFinal; 78 opus_uint32 rangeFinal;
78}; 79};
79 80
81#if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)
82static void validate_opus_decoder(OpusDecoder *st)
83{
84 celt_assert(st->channels == 1 || st->channels == 2);
85 celt_assert(st->Fs == 48000 || st->Fs == 24000 || st->Fs == 16000 || st->Fs == 12000 || st->Fs == 8000);
86 celt_assert(st->DecControl.API_sampleRate == st->Fs);
87 celt_assert(st->DecControl.internalSampleRate == 0 || st->DecControl.internalSampleRate == 16000 || st->DecControl.internalSampleRate == 12000 || st->DecControl.internalSampleRate == 8000);
88 celt_assert(st->DecControl.nChannelsAPI == st->channels);
89 celt_assert(st->DecControl.nChannelsInternal == 0 || st->DecControl.nChannelsInternal == 1 || st->DecControl.nChannelsInternal == 2);
90 celt_assert(st->DecControl.payloadSize_ms == 0 || st->DecControl.payloadSize_ms == 10 || st->DecControl.payloadSize_ms == 20 || st->DecControl.payloadSize_ms == 40 || st->DecControl.payloadSize_ms == 60);
91#ifdef OPUS_ARCHMASK
92 celt_assert(st->arch >= 0);
93 celt_assert(st->arch <= OPUS_ARCHMASK);
94#endif
95 celt_assert(st->stream_channels == 1 || st->stream_channels == 2);
96}
97#define VALIDATE_OPUS_DECODER(st) validate_opus_decoder(st)
98#else
99#define VALIDATE_OPUS_DECODER(st)
100#endif
80 101
81int opus_decoder_get_size(int channels) 102int opus_decoder_get_size(int channels)
82{ 103{
@@ -103,7 +124,7 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels)
103 return OPUS_BAD_ARG; 124 return OPUS_BAD_ARG;
104 125
105 OPUS_CLEAR((char*)st, opus_decoder_get_size(channels)); 126 OPUS_CLEAR((char*)st, opus_decoder_get_size(channels));
106 /* Initialize SILK encoder */ 127 /* Initialize SILK decoder */
107 ret = silk_Get_Decoder_Size(&silkDecSizeBytes); 128 ret = silk_Get_Decoder_Size(&silkDecSizeBytes);
108 if (ret) 129 if (ret)
109 return OPUS_INTERNAL_ERROR; 130 return OPUS_INTERNAL_ERROR;
@@ -131,16 +152,14 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels)
131 152
132 st->prev_mode = 0; 153 st->prev_mode = 0;
133 st->frame_size = Fs/400; 154 st->frame_size = Fs/400;
155 st->arch = opus_select_arch();
134 return OPUS_OK; 156 return OPUS_OK;
135} 157}
136 158
137#define STATIC_DECODER_SIZE 26540 /* 26540 for 64bit environment */
138static char s_dec[STATIC_DECODER_SIZE] IBSS_ATTR MEM_ALIGN_ATTR;
139
140OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error) 159OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error)
141{ 160{
142 int ret; 161 int ret;
143 OpusDecoder *st = NULL; 162 OpusDecoder *st;
144 if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000) 163 if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)
145 || (channels!=1&&channels!=2)) 164 || (channels!=1&&channels!=2))
146 { 165 {
@@ -148,11 +167,7 @@ OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error)
148 *error = OPUS_BAD_ARG; 167 *error = OPUS_BAD_ARG;
149 return NULL; 168 return NULL;
150 } 169 }
151 if (STATIC_DECODER_SIZE >= opus_decoder_get_size(channels)) 170 st = (OpusDecoder *)opus_alloc(opus_decoder_get_size(channels));
152 st = (OpusDecoder *)s_dec;
153 else
154 st = (OpusDecoder *)opus_alloc(opus_decoder_get_size(channels));
155
156 if (st == NULL) 171 if (st == NULL)
157 { 172 {
158 if (error) 173 if (error)
@@ -222,6 +237,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
222 237
223 int audiosize; 238 int audiosize;
224 int mode; 239 int mode;
240 int bandwidth;
225 int transition=0; 241 int transition=0;
226 int start_band; 242 int start_band;
227 int redundancy=0; 243 int redundancy=0;
@@ -258,10 +274,12 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
258 { 274 {
259 audiosize = st->frame_size; 275 audiosize = st->frame_size;
260 mode = st->mode; 276 mode = st->mode;
277 bandwidth = st->bandwidth;
261 ec_dec_init(&dec,(unsigned char*)data,len); 278 ec_dec_init(&dec,(unsigned char*)data,len);
262 } else { 279 } else {
263 audiosize = frame_size; 280 audiosize = frame_size;
264 mode = st->prev_mode; 281 mode = st->prev_mode;
282 bandwidth = 0;
265 283
266 if (mode == 0) 284 if (mode == 0)
267 { 285 {
@@ -360,15 +378,15 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
360 { 378 {
361 st->DecControl.nChannelsInternal = st->stream_channels; 379 st->DecControl.nChannelsInternal = st->stream_channels;
362 if( mode == MODE_SILK_ONLY ) { 380 if( mode == MODE_SILK_ONLY ) {
363 if( st->bandwidth == OPUS_BANDWIDTH_NARROWBAND ) { 381 if( bandwidth == OPUS_BANDWIDTH_NARROWBAND ) {
364 st->DecControl.internalSampleRate = 8000; 382 st->DecControl.internalSampleRate = 8000;
365 } else if( st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) { 383 } else if( bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) {
366 st->DecControl.internalSampleRate = 12000; 384 st->DecControl.internalSampleRate = 12000;
367 } else if( st->bandwidth == OPUS_BANDWIDTH_WIDEBAND ) { 385 } else if( bandwidth == OPUS_BANDWIDTH_WIDEBAND ) {
368 st->DecControl.internalSampleRate = 16000; 386 st->DecControl.internalSampleRate = 16000;
369 } else { 387 } else {
370 st->DecControl.internalSampleRate = 16000; 388 st->DecControl.internalSampleRate = 16000;
371 silk_assert( 0 ); 389 celt_assert( 0 );
372 } 390 }
373 } else { 391 } else {
374 /* Hybrid mode */ 392 /* Hybrid mode */
@@ -382,7 +400,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
382 /* Call SILK decoder */ 400 /* Call SILK decoder */
383 int first_frame = decoded_samples == 0; 401 int first_frame = decoded_samples == 0;
384 silk_ret = silk_Decode( silk_dec, &st->DecControl, 402 silk_ret = silk_Decode( silk_dec, &st->DecControl,
385 lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size ); 403 lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size, st->arch );
386 if( silk_ret ) { 404 if( silk_ret ) {
387 if (lost_flag) { 405 if (lost_flag) {
388 /* PLC failure should not be fatal */ 406 /* PLC failure should not be fatal */
@@ -432,10 +450,26 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
432 if (mode != MODE_CELT_ONLY) 450 if (mode != MODE_CELT_ONLY)
433 start_band = 17; 451 start_band = 17;
434 452
453 if (redundancy)
454 {
455 transition = 0;
456 pcm_transition_silk_size=ALLOC_NONE;
457 }
458
459 ALLOC(pcm_transition_silk, pcm_transition_silk_size, opus_val16);
460
461 if (transition && mode != MODE_CELT_ONLY)
462 {
463 pcm_transition = pcm_transition_silk;
464 opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);
465 }
466
467
468 if (bandwidth)
435 { 469 {
436 int endband=21; 470 int endband=21;
437 471
438 switch(st->bandwidth) 472 switch(bandwidth)
439 { 473 {
440 case OPUS_BANDWIDTH_NARROWBAND: 474 case OPUS_BANDWIDTH_NARROWBAND:
441 endband = 13; 475 endband = 13;
@@ -450,24 +484,13 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
450 case OPUS_BANDWIDTH_FULLBAND: 484 case OPUS_BANDWIDTH_FULLBAND:
451 endband = 21; 485 endband = 21;
452 break; 486 break;
487 default:
488 celt_assert(0);
489 break;
453 } 490 }
454 celt_decoder_ctl(celt_dec, CELT_SET_END_BAND(endband)); 491 MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_END_BAND(endband)));
455 celt_decoder_ctl(celt_dec, CELT_SET_CHANNELS(st->stream_channels));
456 }
457
458 if (redundancy)
459 {
460 transition = 0;
461 pcm_transition_silk_size=ALLOC_NONE;
462 }
463
464 ALLOC(pcm_transition_silk, pcm_transition_silk_size, opus_val16);
465
466 if (transition && mode != MODE_CELT_ONLY)
467 {
468 pcm_transition = pcm_transition_silk;
469 opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);
470 } 492 }
493 MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_CHANNELS(st->stream_channels)));
471 494
472 /* Only allocation memory for redundancy if/when needed */ 495 /* Only allocation memory for redundancy if/when needed */
473 redundant_audio_size = redundancy ? F5*st->channels : ALLOC_NONE; 496 redundant_audio_size = redundancy ? F5*st->channels : ALLOC_NONE;
@@ -476,21 +499,21 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
476 /* 5 ms redundant frame for CELT->SILK*/ 499 /* 5 ms redundant frame for CELT->SILK*/
477 if (redundancy && celt_to_silk) 500 if (redundancy && celt_to_silk)
478 { 501 {
479 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); 502 MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)));
480 celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, 503 celt_decode_with_ec(celt_dec, data+len, redundancy_bytes,
481 redundant_audio, F5, NULL, 0); 504 redundant_audio, F5, NULL, 0);
482 celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); 505 MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)));
483 } 506 }
484 507
485 /* MUST be after PLC */ 508 /* MUST be after PLC */
486 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band)); 509 MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band)));
487 510
488 if (mode != MODE_SILK_ONLY) 511 if (mode != MODE_SILK_ONLY)
489 { 512 {
490 int celt_frame_size = IMIN(F20, frame_size); 513 int celt_frame_size = IMIN(F20, frame_size);
491 /* Make sure to discard any previous CELT state */ 514 /* Make sure to discard any previous CELT state */
492 if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy) 515 if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy)
493 celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); 516 MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_RESET_STATE));
494 /* Decode CELT */ 517 /* Decode CELT */
495 celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data, 518 celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data,
496 len, pcm, celt_frame_size, &dec, celt_accum); 519 len, pcm, celt_frame_size, &dec, celt_accum);
@@ -505,7 +528,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
505 do a fade-out by decoding a silence frame */ 528 do a fade-out by decoding a silence frame */
506 if (st->prev_mode == MODE_HYBRID && !(redundancy && celt_to_silk && st->prev_redundancy) ) 529 if (st->prev_mode == MODE_HYBRID && !(redundancy && celt_to_silk && st->prev_redundancy) )
507 { 530 {
508 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); 531 MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)));
509 celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL, celt_accum); 532 celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL, celt_accum);
510 } 533 }
511 } 534 }
@@ -523,18 +546,18 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
523 546
524 { 547 {
525 const CELTMode *celt_mode; 548 const CELTMode *celt_mode;
526 celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode)); 549 MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode)));
527 window = celt_mode->window; 550 window = celt_mode->window;
528 } 551 }
529 552
530 /* 5 ms redundant frame for SILK->CELT */ 553 /* 5 ms redundant frame for SILK->CELT */
531 if (redundancy && !celt_to_silk) 554 if (redundancy && !celt_to_silk)
532 { 555 {
533 celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); 556 MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_RESET_STATE));
534 celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); 557 MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)));
535 558
536 celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL, 0); 559 celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL, 0);
537 celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); 560 MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)));
538 smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5, 561 smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5,
539 pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs); 562 pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs);
540 } 563 }
@@ -610,6 +633,7 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data,
610 int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels; 633 int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels;
611 /* 48 x 2.5 ms = 120 ms */ 634 /* 48 x 2.5 ms = 120 ms */
612 opus_int16 size[48]; 635 opus_int16 size[48];
636 VALIDATE_OPUS_DECODER(st);
613 if (decode_fec<0 || decode_fec>1) 637 if (decode_fec<0 || decode_fec>1)
614 return OPUS_BAD_ARG; 638 return OPUS_BAD_ARG;
615 /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */ 639 /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */
@@ -745,6 +769,7 @@ int opus_decode_float(OpusDecoder *st, const unsigned char *data,
745 else 769 else
746 return OPUS_INVALID_PACKET; 770 return OPUS_INVALID_PACKET;
747 } 771 }
772 celt_assert(st->channels == 1 || st->channels == 2);
748 ALLOC(out, frame_size*st->channels, opus_int16); 773 ALLOC(out, frame_size*st->channels, opus_int16);
749 774
750 ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0); 775 ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0);
@@ -782,6 +807,7 @@ int opus_decode(OpusDecoder *st, const unsigned char *data,
782 else 807 else
783 return OPUS_INVALID_PACKET; 808 return OPUS_INVALID_PACKET;
784 } 809 }
810 celt_assert(st->channels == 1 || st->channels == 2);
785 ALLOC(out, frame_size*st->channels, float); 811 ALLOC(out, frame_size*st->channels, float);
786 812
787 ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 1); 813 ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 1);
@@ -869,7 +895,7 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
869 goto bad_arg; 895 goto bad_arg;
870 } 896 }
871 if (st->prev_mode == MODE_CELT_ONLY) 897 if (st->prev_mode == MODE_CELT_ONLY)
872 celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value)); 898 ret = celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value));
873 else 899 else
874 *value = st->DecControl.prevPitchLag; 900 *value = st->DecControl.prevPitchLag;
875 } 901 }
@@ -896,7 +922,7 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
896 break; 922 break;
897 case OPUS_GET_LAST_PACKET_DURATION_REQUEST: 923 case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
898 { 924 {
899 opus_uint32 *value = va_arg(ap, opus_uint32*); 925 opus_int32 *value = va_arg(ap, opus_int32*);
900 if (!value) 926 if (!value)
901 { 927 {
902 goto bad_arg; 928 goto bad_arg;
@@ -904,6 +930,26 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
904 *value = st->last_packet_duration; 930 *value = st->last_packet_duration;
905 } 931 }
906 break; 932 break;
933 case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
934 {
935 opus_int32 value = va_arg(ap, opus_int32);
936 if(value<0 || value>1)
937 {
938 goto bad_arg;
939 }
940 ret = celt_decoder_ctl(celt_dec, OPUS_SET_PHASE_INVERSION_DISABLED(value));
941 }
942 break;
943 case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
944 {
945 opus_int32 *value = va_arg(ap, opus_int32*);
946 if (!value)
947 {
948 goto bad_arg;
949 }
950 ret = celt_decoder_ctl(celt_dec, OPUS_GET_PHASE_INVERSION_DISABLED(value));
951 }
952 break;
907 default: 953 default:
908 /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/ 954 /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/
909 ret = OPUS_UNIMPLEMENTED; 955 ret = OPUS_UNIMPLEMENTED;
diff --git a/lib/rbcodec/codecs/libopus/opus_defines.h b/lib/rbcodec/codecs/libopus/opus_defines.h
index 84df7c7a18..fbf5d0eb74 100644
--- a/lib/rbcodec/codecs/libopus/opus_defines.h
+++ b/lib/rbcodec/codecs/libopus/opus_defines.h
@@ -46,7 +46,7 @@ extern "C" {
46#define OPUS_OK 0 46#define OPUS_OK 0
47/** One or more invalid/out of range arguments @hideinitializer*/ 47/** One or more invalid/out of range arguments @hideinitializer*/
48#define OPUS_BAD_ARG -1 48#define OPUS_BAD_ARG -1
49/** The mode struct passed is invalid @hideinitializer*/ 49/** Not enough bytes allocated in the buffer @hideinitializer*/
50#define OPUS_BUFFER_TOO_SMALL -2 50#define OPUS_BUFFER_TOO_SMALL -2
51/** An internal error was detected @hideinitializer*/ 51/** An internal error was detected @hideinitializer*/
52#define OPUS_INTERNAL_ERROR -3 52#define OPUS_INTERNAL_ERROR -3
@@ -65,7 +65,7 @@ extern "C" {
65 65
66#ifndef OPUS_EXPORT 66#ifndef OPUS_EXPORT
67# if defined(WIN32) 67# if defined(WIN32)
68# ifdef OPUS_BUILD 68# if defined(OPUS_BUILD) && defined(DLL_EXPORT)
69# define OPUS_EXPORT __declspec(dllexport) 69# define OPUS_EXPORT __declspec(dllexport)
70# else 70# else
71# define OPUS_EXPORT 71# define OPUS_EXPORT
@@ -165,8 +165,12 @@ extern "C" {
165#define OPUS_GET_EXPERT_FRAME_DURATION_REQUEST 4041 165#define OPUS_GET_EXPERT_FRAME_DURATION_REQUEST 4041
166#define OPUS_SET_PREDICTION_DISABLED_REQUEST 4042 166#define OPUS_SET_PREDICTION_DISABLED_REQUEST 4042
167#define OPUS_GET_PREDICTION_DISABLED_REQUEST 4043 167#define OPUS_GET_PREDICTION_DISABLED_REQUEST 4043
168
169/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */ 168/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */
169#define OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST 4046
170#define OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST 4047
171
172/** Defines for the presence of extended APIs. */
173#define OPUS_HAVE_OPUS_PROJECTION_H
170 174
171/* Macros to trigger compilation errors when the wrong types are provided to a CTL */ 175/* Macros to trigger compilation errors when the wrong types are provided to a CTL */
172#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x)) 176#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
@@ -208,6 +212,9 @@ extern "C" {
208#define OPUS_FRAMESIZE_20_MS 5004 /**< Use 20 ms frames */ 212#define OPUS_FRAMESIZE_20_MS 5004 /**< Use 20 ms frames */
209#define OPUS_FRAMESIZE_40_MS 5005 /**< Use 40 ms frames */ 213#define OPUS_FRAMESIZE_40_MS 5005 /**< Use 40 ms frames */
210#define OPUS_FRAMESIZE_60_MS 5006 /**< Use 60 ms frames */ 214#define OPUS_FRAMESIZE_60_MS 5006 /**< Use 60 ms frames */
215#define OPUS_FRAMESIZE_80_MS 5007 /**< Use 80 ms frames */
216#define OPUS_FRAMESIZE_100_MS 5008 /**< Use 100 ms frames */
217#define OPUS_FRAMESIZE_120_MS 5009 /**< Use 120 ms frames */
211 218
212/**@}*/ 219/**@}*/
213 220
@@ -274,7 +281,6 @@ extern "C" {
274/** Enables or disables variable bitrate (VBR) in the encoder. 281/** Enables or disables variable bitrate (VBR) in the encoder.
275 * The configured bitrate may not be met exactly because frames must 282 * The configured bitrate may not be met exactly because frames must
276 * be an integer number of bytes in length. 283 * be an integer number of bytes in length.
277 * @warning Only the MDCT mode of Opus can provide hard CBR behavior.
278 * @see OPUS_GET_VBR 284 * @see OPUS_GET_VBR
279 * @see OPUS_SET_VBR_CONSTRAINT 285 * @see OPUS_SET_VBR_CONSTRAINT
280 * @param[in] x <tt>opus_int32</tt>: Allowed values: 286 * @param[in] x <tt>opus_int32</tt>: Allowed values:
@@ -490,9 +496,9 @@ extern "C" {
490#define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x) 496#define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x)
491 497
492/** Configures the encoder's expected packet loss percentage. 498/** Configures the encoder's expected packet loss percentage.
493 * Higher values with trigger progressively more loss resistant behavior in the encoder 499 * Higher values trigger progressively more loss resistant behavior in the encoder
494 * at the expense of quality at a given bitrate in the lossless case, but greater quality 500 * at the expense of quality at a given bitrate in the absence of packet loss, but
495 * under loss. 501 * greater quality under loss.
496 * @see OPUS_GET_PACKET_LOSS_PERC 502 * @see OPUS_GET_PACKET_LOSS_PERC
497 * @param[in] x <tt>opus_int32</tt>: Loss percentage in the range 0-100, inclusive (default: 0). 503 * @param[in] x <tt>opus_int32</tt>: Loss percentage in the range 0-100, inclusive (default: 0).
498 * @hideinitializer */ 504 * @hideinitializer */
@@ -524,7 +530,19 @@ extern "C" {
524 * @hideinitializer */ 530 * @hideinitializer */
525#define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x) 531#define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x)
526/** Configures the depth of signal being encoded. 532/** Configures the depth of signal being encoded.
533 *
527 * This is a hint which helps the encoder identify silence and near-silence. 534 * This is a hint which helps the encoder identify silence and near-silence.
535 * It represents the number of significant bits of linear intensity below
536 * which the signal contains ignorable quantization or other noise.
537 *
538 * For example, OPUS_SET_LSB_DEPTH(14) would be an appropriate setting
539 * for G.711 u-law input. OPUS_SET_LSB_DEPTH(16) would be appropriate
540 * for 16-bit linear pcm input with opus_encode_float().
541 *
542 * When using opus_encode() instead of opus_encode_float(), or when libopus
543 * is compiled for fixed-point, the encoder uses the minimum of the value
544 * set here and the value 16.
545 *
528 * @see OPUS_GET_LSB_DEPTH 546 * @see OPUS_GET_LSB_DEPTH
529 * @param[in] x <tt>opus_int32</tt>: Input precision in bits, between 8 and 24 547 * @param[in] x <tt>opus_int32</tt>: Input precision in bits, between 8 and 24
530 * (default: 24). 548 * (default: 24).
@@ -545,41 +563,57 @@ extern "C" {
545 * packet. The part of the audio that was not encoded needs to be resent to the 563 * packet. The part of the audio that was not encoded needs to be resent to the
546 * encoder for the next call. Do not use this option unless you <b>really</b> 564 * encoder for the next call. Do not use this option unless you <b>really</b>
547 * know what you are doing. 565 * know what you are doing.
548 * @see OPUS_GET_EXPERT_VARIABLE_DURATION 566 * @see OPUS_GET_EXPERT_FRAME_DURATION
549 * @param[in] x <tt>opus_int32</tt>: Allowed values: 567 * @param[in] x <tt>opus_int32</tt>: Allowed values:
550 * <dl> 568 * <dl>
551 * <dt>OPUS_FRAMESIZE_ARG</dt><dd>Select frame size from the argument (default).</dd> 569 * <dt>OPUS_FRAMESIZE_ARG</dt><dd>Select frame size from the argument (default).</dd>
552 * <dt>OPUS_FRAMESIZE_2_5_MS</dt><dd>Use 2.5 ms frames.</dd> 570 * <dt>OPUS_FRAMESIZE_2_5_MS</dt><dd>Use 2.5 ms frames.</dd>
553 * <dt>OPUS_FRAMESIZE_5_MS</dt><dd>Use 2.5 ms frames.</dd> 571 * <dt>OPUS_FRAMESIZE_5_MS</dt><dd>Use 5 ms frames.</dd>
554 * <dt>OPUS_FRAMESIZE_10_MS</dt><dd>Use 10 ms frames.</dd> 572 * <dt>OPUS_FRAMESIZE_10_MS</dt><dd>Use 10 ms frames.</dd>
555 * <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd> 573 * <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd>
556 * <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd> 574 * <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd>
557 * <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd> 575 * <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd>
558 * <dt>OPUS_FRAMESIZE_VARIABLE</dt><dd>Optimize the frame size dynamically.</dd> 576 * <dt>OPUS_FRAMESIZE_80_MS</dt><dd>Use 80 ms frames.</dd>
577 * <dt>OPUS_FRAMESIZE_100_MS</dt><dd>Use 100 ms frames.</dd>
578 * <dt>OPUS_FRAMESIZE_120_MS</dt><dd>Use 120 ms frames.</dd>
559 * </dl> 579 * </dl>
560 * @hideinitializer */ 580 * @hideinitializer */
561#define OPUS_SET_EXPERT_FRAME_DURATION(x) OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int(x) 581#define OPUS_SET_EXPERT_FRAME_DURATION(x) OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int(x)
562/** Gets the encoder's configured use of variable duration frames. 582/** Gets the encoder's configured use of variable duration frames.
563 * @see OPUS_SET_EXPERT_VARIABLE_DURATION 583 * @see OPUS_SET_EXPERT_FRAME_DURATION
564 * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values: 584 * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
565 * <dl> 585 * <dl>
566 * <dt>OPUS_FRAMESIZE_ARG</dt><dd>Select frame size from the argument (default).</dd> 586 * <dt>OPUS_FRAMESIZE_ARG</dt><dd>Select frame size from the argument (default).</dd>
567 * <dt>OPUS_FRAMESIZE_2_5_MS</dt><dd>Use 2.5 ms frames.</dd> 587 * <dt>OPUS_FRAMESIZE_2_5_MS</dt><dd>Use 2.5 ms frames.</dd>
568 * <dt>OPUS_FRAMESIZE_5_MS</dt><dd>Use 2.5 ms frames.</dd> 588 * <dt>OPUS_FRAMESIZE_5_MS</dt><dd>Use 5 ms frames.</dd>
569 * <dt>OPUS_FRAMESIZE_10_MS</dt><dd>Use 10 ms frames.</dd> 589 * <dt>OPUS_FRAMESIZE_10_MS</dt><dd>Use 10 ms frames.</dd>
570 * <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd> 590 * <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd>
571 * <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd> 591 * <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd>
572 * <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd> 592 * <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd>
573 * <dt>OPUS_FRAMESIZE_VARIABLE</dt><dd>Optimize the frame size dynamically.</dd> 593 * <dt>OPUS_FRAMESIZE_80_MS</dt><dd>Use 80 ms frames.</dd>
594 * <dt>OPUS_FRAMESIZE_100_MS</dt><dd>Use 100 ms frames.</dd>
595 * <dt>OPUS_FRAMESIZE_120_MS</dt><dd>Use 120 ms frames.</dd>
574 * </dl> 596 * </dl>
575 * @hideinitializer */ 597 * @hideinitializer */
576#define OPUS_GET_EXPERT_FRAME_DURATION(x) OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int_ptr(x) 598#define OPUS_GET_EXPERT_FRAME_DURATION(x) OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int_ptr(x)
577 599
578/** If set to 1, disables almost all use of prediction, making frames almost 600/** If set to 1, disables almost all use of prediction, making frames almost
579 completely independent. This reduces quality. (default : 0) 601 * completely independent. This reduces quality.
602 * @see OPUS_GET_PREDICTION_DISABLED
603 * @param[in] x <tt>opus_int32</tt>: Allowed values:
604 * <dl>
605 * <dt>0</dt><dd>Enable prediction (default).</dd>
606 * <dt>1</dt><dd>Disable prediction.</dd>
607 * </dl>
580 * @hideinitializer */ 608 * @hideinitializer */
581#define OPUS_SET_PREDICTION_DISABLED(x) OPUS_SET_PREDICTION_DISABLED_REQUEST, __opus_check_int(x) 609#define OPUS_SET_PREDICTION_DISABLED(x) OPUS_SET_PREDICTION_DISABLED_REQUEST, __opus_check_int(x)
582/** Gets the encoder's configured prediction status. 610/** Gets the encoder's configured prediction status.
611 * @see OPUS_SET_PREDICTION_DISABLED
612 * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
613 * <dl>
614 * <dt>0</dt><dd>Prediction enabled (default).</dd>
615 * <dt>1</dt><dd>Prediction disabled.</dd>
616 * </dl>
583 * @hideinitializer */ 617 * @hideinitializer */
584#define OPUS_GET_PREDICTION_DISABLED(x) OPUS_GET_PREDICTION_DISABLED_REQUEST, __opus_check_int_ptr(x) 618#define OPUS_GET_PREDICTION_DISABLED(x) OPUS_GET_PREDICTION_DISABLED_REQUEST, __opus_check_int_ptr(x)
585 619
@@ -658,6 +692,30 @@ extern "C" {
658 */ 692 */
659#define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x) 693#define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x)
660 694
695/** If set to 1, disables the use of phase inversion for intensity stereo,
696 * improving the quality of mono downmixes, but slightly reducing normal
697 * stereo quality. Disabling phase inversion in the decoder does not comply
698 * with RFC 6716, although it does not cause any interoperability issue and
699 * is expected to become part of the Opus standard once RFC 6716 is updated
700 * by draft-ietf-codec-opus-update.
701 * @see OPUS_GET_PHASE_INVERSION_DISABLED
702 * @param[in] x <tt>opus_int32</tt>: Allowed values:
703 * <dl>
704 * <dt>0</dt><dd>Enable phase inversion (default).</dd>
705 * <dt>1</dt><dd>Disable phase inversion.</dd>
706 * </dl>
707 * @hideinitializer */
708#define OPUS_SET_PHASE_INVERSION_DISABLED(x) OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, __opus_check_int(x)
709/** Gets the encoder's configured phase inversion status.
710 * @see OPUS_SET_PHASE_INVERSION_DISABLED
711 * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
712 * <dl>
713 * <dt>0</dt><dd>Stereo phase inversion enabled (default).</dd>
714 * <dt>1</dt><dd>Stereo phase inversion disabled.</dd>
715 * </dl>
716 * @hideinitializer */
717#define OPUS_GET_PHASE_INVERSION_DISABLED(x) OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, __opus_check_int_ptr(x)
718
661/**@}*/ 719/**@}*/
662 720
663/** @defgroup opus_decoderctls Decoder related CTLs 721/** @defgroup opus_decoderctls Decoder related CTLs
@@ -714,6 +772,10 @@ OPUS_EXPORT const char *opus_strerror(int error);
714 772
715/** Gets the libopus version string. 773/** Gets the libopus version string.
716 * 774 *
775 * Applications may look for the substring "-fixed" in the version string to
776 * determine whether they have a fixed-point or floating-point build at
777 * runtime.
778 *
717 * @returns Version string 779 * @returns Version string
718 */ 780 */
719OPUS_EXPORT const char *opus_get_version_string(void); 781OPUS_EXPORT const char *opus_get_version_string(void);
diff --git a/lib/rbcodec/codecs/libopus/opus_demo.c b/lib/rbcodec/codecs/libopus/opus_demo.c
new file mode 100644
index 0000000000..4cc26a6c77
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/opus_demo.c
@@ -0,0 +1,892 @@
1/* Copyright (c) 2007-2008 CSIRO
2 Copyright (c) 2007-2009 Xiph.Org Foundation
3 Written by Jean-Marc Valin */
4/*
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27*/
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include <stdio.h>
34#include <stdlib.h>
35#include <math.h>
36#include <string.h>
37#include "opus.h"
38#include "debug.h"
39#include "opus_types.h"
40#include "opus_private.h"
41#include "opus_multistream.h"
42
43#define MAX_PACKET 1500
44
45void print_usage( char* argv[] )
46{
47 fprintf(stderr, "Usage: %s [-e] <application> <sampling rate (Hz)> <channels (1/2)> "
48 "<bits per second> [options] <input> <output>\n", argv[0]);
49 fprintf(stderr, " %s -d <sampling rate (Hz)> <channels (1/2)> "
50 "[options] <input> <output>\n\n", argv[0]);
51 fprintf(stderr, "application: voip | audio | restricted-lowdelay\n" );
52 fprintf(stderr, "options:\n" );
53 fprintf(stderr, "-e : only runs the encoder (output the bit-stream)\n" );
54 fprintf(stderr, "-d : only runs the decoder (reads the bit-stream as input)\n" );
55 fprintf(stderr, "-cbr : enable constant bitrate; default: variable bitrate\n" );
56 fprintf(stderr, "-cvbr : enable constrained variable bitrate; default: unconstrained\n" );
57 fprintf(stderr, "-delayed-decision : use look-ahead for speech/music detection (experts only); default: disabled\n" );
58 fprintf(stderr, "-bandwidth <NB|MB|WB|SWB|FB> : audio bandwidth (from narrowband to fullband); default: sampling rate\n" );
59 fprintf(stderr, "-framesize <2.5|5|10|20|40|60|80|100|120> : frame size in ms; default: 20 \n" );
60 fprintf(stderr, "-max_payload <bytes> : maximum payload size in bytes, default: 1024\n" );
61 fprintf(stderr, "-complexity <comp> : complexity, 0 (lowest) ... 10 (highest); default: 10\n" );
62 fprintf(stderr, "-inbandfec : enable SILK inband FEC\n" );
63 fprintf(stderr, "-forcemono : force mono encoding, even for stereo input\n" );
64 fprintf(stderr, "-dtx : enable SILK DTX\n" );
65 fprintf(stderr, "-loss <perc> : simulate packet loss, in percent (0-100); default: 0\n" );
66}
67
68static void int_to_char(opus_uint32 i, unsigned char ch[4])
69{
70 ch[0] = i>>24;
71 ch[1] = (i>>16)&0xFF;
72 ch[2] = (i>>8)&0xFF;
73 ch[3] = i&0xFF;
74}
75
76static opus_uint32 char_to_int(unsigned char ch[4])
77{
78 return ((opus_uint32)ch[0]<<24) | ((opus_uint32)ch[1]<<16)
79 | ((opus_uint32)ch[2]<< 8) | (opus_uint32)ch[3];
80}
81
82#define check_encoder_option(decode_only, opt) do {if (decode_only) {fprintf(stderr, "option %s is only for encoding\n", opt); goto failure;}} while(0)
83
84static const int silk8_test[][4] = {
85 {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 1},
86 {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 1},
87 {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 1},
88 {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 1},
89 {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*3, 2},
90 {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960*2, 2},
91 {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 2},
92 {MODE_SILK_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 2}
93};
94
95static const int silk12_test[][4] = {
96 {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 1},
97 {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 1},
98 {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960, 1},
99 {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480, 1},
100 {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*3, 2},
101 {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960*2, 2},
102 {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 960, 2},
103 {MODE_SILK_ONLY, OPUS_BANDWIDTH_MEDIUMBAND, 480, 2}
104};
105
106static const int silk16_test[][4] = {
107 {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 1},
108 {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 1},
109 {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 1},
110 {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 1},
111 {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*3, 2},
112 {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960*2, 2},
113 {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 2},
114 {MODE_SILK_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 2}
115};
116
117static const int hybrid24_test[][4] = {
118 {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},
119 {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1},
120 {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2},
121 {MODE_SILK_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2}
122};
123
124static const int hybrid48_test[][4] = {
125 {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 1},
126 {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 1},
127 {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2},
128 {MODE_SILK_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2}
129};
130
131static const int celt_test[][4] = {
132 {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 1},
133 {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 1},
134 {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 1},
135 {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 1},
136
137 {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 1},
138 {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 1},
139 {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 1},
140 {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 1},
141
142 {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 240, 1},
143 {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 1},
144 {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 240, 1},
145 {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 240, 1},
146
147 {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 120, 1},
148 {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 1},
149 {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 120, 1},
150 {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 120, 1},
151
152 {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2},
153 {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 960, 2},
154 {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 960, 2},
155 {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 960, 2},
156
157 {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2},
158 {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 480, 2},
159 {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 480, 2},
160 {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 480, 2},
161
162 {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 240, 2},
163 {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 240, 2},
164 {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 240, 2},
165 {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 240, 2},
166
167 {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 120, 2},
168 {MODE_CELT_ONLY, OPUS_BANDWIDTH_SUPERWIDEBAND, 120, 2},
169 {MODE_CELT_ONLY, OPUS_BANDWIDTH_WIDEBAND, 120, 2},
170 {MODE_CELT_ONLY, OPUS_BANDWIDTH_NARROWBAND, 120, 2},
171
172};
173
174static const int celt_hq_test[][4] = {
175 {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 960, 2},
176 {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 480, 2},
177 {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 240, 2},
178 {MODE_CELT_ONLY, OPUS_BANDWIDTH_FULLBAND, 120, 2},
179};
180
181#if 0 /* This is a hack that replaces the normal encoder/decoder with the multistream version */
182#define OpusEncoder OpusMSEncoder
183#define OpusDecoder OpusMSDecoder
184#define opus_encode opus_multistream_encode
185#define opus_decode opus_multistream_decode
186#define opus_encoder_ctl opus_multistream_encoder_ctl
187#define opus_decoder_ctl opus_multistream_decoder_ctl
188#define opus_encoder_create ms_opus_encoder_create
189#define opus_decoder_create ms_opus_decoder_create
190#define opus_encoder_destroy opus_multistream_encoder_destroy
191#define opus_decoder_destroy opus_multistream_decoder_destroy
192
193static OpusEncoder *ms_opus_encoder_create(opus_int32 Fs, int channels, int application, int *error)
194{
195 int streams, coupled_streams;
196 unsigned char mapping[256];
197 return (OpusEncoder *)opus_multistream_surround_encoder_create(Fs, channels, 1, &streams, &coupled_streams, mapping, application, error);
198}
199static OpusDecoder *ms_opus_decoder_create(opus_int32 Fs, int channels, int *error)
200{
201 int streams;
202 int coupled_streams;
203 unsigned char mapping[256]={0,1};
204 streams = 1;
205 coupled_streams = channels==2;
206 return (OpusDecoder *)opus_multistream_decoder_create(Fs, channels, streams, coupled_streams, mapping, error);
207}
208#endif
209
210int main(int argc, char *argv[])
211{
212 int err;
213 char *inFile, *outFile;
214 FILE *fin=NULL;
215 FILE *fout=NULL;
216 OpusEncoder *enc=NULL;
217 OpusDecoder *dec=NULL;
218 int args;
219 int len[2];
220 int frame_size, channels;
221 opus_int32 bitrate_bps=0;
222 unsigned char *data[2] = {NULL, NULL};
223 unsigned char *fbytes=NULL;
224 opus_int32 sampling_rate;
225 int use_vbr;
226 int max_payload_bytes;
227 int complexity;
228 int use_inbandfec;
229 int use_dtx;
230 int forcechannels;
231 int cvbr = 0;
232 int packet_loss_perc;
233 opus_int32 count=0, count_act=0;
234 int k;
235 opus_int32 skip=0;
236 int stop=0;
237 short *in=NULL;
238 short *out=NULL;
239 int application=OPUS_APPLICATION_AUDIO;
240 double bits=0.0, bits_max=0.0, bits_act=0.0, bits2=0.0, nrg;
241 double tot_samples=0;
242 opus_uint64 tot_in, tot_out;
243 int bandwidth=OPUS_AUTO;
244 const char *bandwidth_string;
245 int lost = 0, lost_prev = 1;
246 int toggle = 0;
247 opus_uint32 enc_final_range[2];
248 opus_uint32 dec_final_range;
249 int encode_only=0, decode_only=0;
250 int max_frame_size = 48000*2;
251 size_t num_read;
252 int curr_read=0;
253 int sweep_bps = 0;
254 int random_framesize=0, newsize=0, delayed_celt=0;
255 int sweep_max=0, sweep_min=0;
256 int random_fec=0;
257 const int (*mode_list)[4]=NULL;
258 int nb_modes_in_list=0;
259 int curr_mode=0;
260 int curr_mode_count=0;
261 int mode_switch_time = 48000;
262 int nb_encoded=0;
263 int remaining=0;
264 int variable_duration=OPUS_FRAMESIZE_ARG;
265 int delayed_decision=0;
266 int ret = EXIT_FAILURE;
267
268 if (argc < 5 )
269 {
270 print_usage( argv );
271 goto failure;
272 }
273
274 tot_in=tot_out=0;
275 fprintf(stderr, "%s\n", opus_get_version_string());
276
277 args = 1;
278 if (strcmp(argv[args], "-e")==0)
279 {
280 encode_only = 1;
281 args++;
282 } else if (strcmp(argv[args], "-d")==0)
283 {
284 decode_only = 1;
285 args++;
286 }
287 if (!decode_only && argc < 7 )
288 {
289 print_usage( argv );
290 goto failure;
291 }
292
293 if (!decode_only)
294 {
295 if (strcmp(argv[args], "voip")==0)
296 application = OPUS_APPLICATION_VOIP;
297 else if (strcmp(argv[args], "restricted-lowdelay")==0)
298 application = OPUS_APPLICATION_RESTRICTED_LOWDELAY;
299 else if (strcmp(argv[args], "audio")!=0) {
300 fprintf(stderr, "unknown application: %s\n", argv[args]);
301 print_usage(argv);
302 goto failure;
303 }
304 args++;
305 }
306 sampling_rate = (opus_int32)atol(argv[args]);
307 args++;
308
309 if (sampling_rate != 8000 && sampling_rate != 12000
310 && sampling_rate != 16000 && sampling_rate != 24000
311 && sampling_rate != 48000)
312 {
313 fprintf(stderr, "Supported sampling rates are 8000, 12000, "
314 "16000, 24000 and 48000.\n");
315 goto failure;
316 }
317 frame_size = sampling_rate/50;
318
319 channels = atoi(argv[args]);
320 args++;
321
322 if (channels < 1 || channels > 2)
323 {
324 fprintf(stderr, "Opus_demo supports only 1 or 2 channels.\n");
325 goto failure;
326 }
327
328 if (!decode_only)
329 {
330 bitrate_bps = (opus_int32)atol(argv[args]);
331 args++;
332 }
333
334 /* defaults: */
335 use_vbr = 1;
336 max_payload_bytes = MAX_PACKET;
337 complexity = 10;
338 use_inbandfec = 0;
339 forcechannels = OPUS_AUTO;
340 use_dtx = 0;
341 packet_loss_perc = 0;
342
343 while( args < argc - 2 ) {
344 /* process command line options */
345 if( strcmp( argv[ args ], "-cbr" ) == 0 ) {
346 check_encoder_option(decode_only, "-cbr");
347 use_vbr = 0;
348 args++;
349 } else if( strcmp( argv[ args ], "-bandwidth" ) == 0 ) {
350 check_encoder_option(decode_only, "-bandwidth");
351 if (strcmp(argv[ args + 1 ], "NB")==0)
352 bandwidth = OPUS_BANDWIDTH_NARROWBAND;
353 else if (strcmp(argv[ args + 1 ], "MB")==0)
354 bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
355 else if (strcmp(argv[ args + 1 ], "WB")==0)
356 bandwidth = OPUS_BANDWIDTH_WIDEBAND;
357 else if (strcmp(argv[ args + 1 ], "SWB")==0)
358 bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
359 else if (strcmp(argv[ args + 1 ], "FB")==0)
360 bandwidth = OPUS_BANDWIDTH_FULLBAND;
361 else {
362 fprintf(stderr, "Unknown bandwidth %s. "
363 "Supported are NB, MB, WB, SWB, FB.\n",
364 argv[ args + 1 ]);
365 goto failure;
366 }
367 args += 2;
368 } else if( strcmp( argv[ args ], "-framesize" ) == 0 ) {
369 check_encoder_option(decode_only, "-framesize");
370 if (strcmp(argv[ args + 1 ], "2.5")==0)
371 frame_size = sampling_rate/400;
372 else if (strcmp(argv[ args + 1 ], "5")==0)
373 frame_size = sampling_rate/200;
374 else if (strcmp(argv[ args + 1 ], "10")==0)
375 frame_size = sampling_rate/100;
376 else if (strcmp(argv[ args + 1 ], "20")==0)
377 frame_size = sampling_rate/50;
378 else if (strcmp(argv[ args + 1 ], "40")==0)
379 frame_size = sampling_rate/25;
380 else if (strcmp(argv[ args + 1 ], "60")==0)
381 frame_size = 3*sampling_rate/50;
382 else if (strcmp(argv[ args + 1 ], "80")==0)
383 frame_size = 4*sampling_rate/50;
384 else if (strcmp(argv[ args + 1 ], "100")==0)
385 frame_size = 5*sampling_rate/50;
386 else if (strcmp(argv[ args + 1 ], "120")==0)
387 frame_size = 6*sampling_rate/50;
388 else {
389 fprintf(stderr, "Unsupported frame size: %s ms. "
390 "Supported are 2.5, 5, 10, 20, 40, 60, 80, 100, 120.\n",
391 argv[ args + 1 ]);
392 goto failure;
393 }
394 args += 2;
395 } else if( strcmp( argv[ args ], "-max_payload" ) == 0 ) {
396 check_encoder_option(decode_only, "-max_payload");
397 max_payload_bytes = atoi( argv[ args + 1 ] );
398 args += 2;
399 } else if( strcmp( argv[ args ], "-complexity" ) == 0 ) {
400 check_encoder_option(decode_only, "-complexity");
401 complexity = atoi( argv[ args + 1 ] );
402 args += 2;
403 } else if( strcmp( argv[ args ], "-inbandfec" ) == 0 ) {
404 use_inbandfec = 1;
405 args++;
406 } else if( strcmp( argv[ args ], "-forcemono" ) == 0 ) {
407 check_encoder_option(decode_only, "-forcemono");
408 forcechannels = 1;
409 args++;
410 } else if( strcmp( argv[ args ], "-cvbr" ) == 0 ) {
411 check_encoder_option(decode_only, "-cvbr");
412 cvbr = 1;
413 args++;
414 } else if( strcmp( argv[ args ], "-delayed-decision" ) == 0 ) {
415 check_encoder_option(decode_only, "-delayed-decision");
416 delayed_decision = 1;
417 args++;
418 } else if( strcmp( argv[ args ], "-dtx") == 0 ) {
419 check_encoder_option(decode_only, "-dtx");
420 use_dtx = 1;
421 args++;
422 } else if( strcmp( argv[ args ], "-loss" ) == 0 ) {
423 packet_loss_perc = atoi( argv[ args + 1 ] );
424 args += 2;
425 } else if( strcmp( argv[ args ], "-sweep" ) == 0 ) {
426 check_encoder_option(decode_only, "-sweep");
427 sweep_bps = atoi( argv[ args + 1 ] );
428 args += 2;
429 } else if( strcmp( argv[ args ], "-random_framesize" ) == 0 ) {
430 check_encoder_option(decode_only, "-random_framesize");
431 random_framesize = 1;
432 args++;
433 } else if( strcmp( argv[ args ], "-sweep_max" ) == 0 ) {
434 check_encoder_option(decode_only, "-sweep_max");
435 sweep_max = atoi( argv[ args + 1 ] );
436 args += 2;
437 } else if( strcmp( argv[ args ], "-random_fec" ) == 0 ) {
438 check_encoder_option(decode_only, "-random_fec");
439 random_fec = 1;
440 args++;
441 } else if( strcmp( argv[ args ], "-silk8k_test" ) == 0 ) {
442 check_encoder_option(decode_only, "-silk8k_test");
443 mode_list = silk8_test;
444 nb_modes_in_list = 8;
445 args++;
446 } else if( strcmp( argv[ args ], "-silk12k_test" ) == 0 ) {
447 check_encoder_option(decode_only, "-silk12k_test");
448 mode_list = silk12_test;
449 nb_modes_in_list = 8;
450 args++;
451 } else if( strcmp( argv[ args ], "-silk16k_test" ) == 0 ) {
452 check_encoder_option(decode_only, "-silk16k_test");
453 mode_list = silk16_test;
454 nb_modes_in_list = 8;
455 args++;
456 } else if( strcmp( argv[ args ], "-hybrid24k_test" ) == 0 ) {
457 check_encoder_option(decode_only, "-hybrid24k_test");
458 mode_list = hybrid24_test;
459 nb_modes_in_list = 4;
460 args++;
461 } else if( strcmp( argv[ args ], "-hybrid48k_test" ) == 0 ) {
462 check_encoder_option(decode_only, "-hybrid48k_test");
463 mode_list = hybrid48_test;
464 nb_modes_in_list = 4;
465 args++;
466 } else if( strcmp( argv[ args ], "-celt_test" ) == 0 ) {
467 check_encoder_option(decode_only, "-celt_test");
468 mode_list = celt_test;
469 nb_modes_in_list = 32;
470 args++;
471 } else if( strcmp( argv[ args ], "-celt_hq_test" ) == 0 ) {
472 check_encoder_option(decode_only, "-celt_hq_test");
473 mode_list = celt_hq_test;
474 nb_modes_in_list = 4;
475 args++;
476 } else {
477 printf( "Error: unrecognized setting: %s\n\n", argv[ args ] );
478 print_usage( argv );
479 goto failure;
480 }
481 }
482
483 if (sweep_max)
484 sweep_min = bitrate_bps;
485
486 if (max_payload_bytes < 0 || max_payload_bytes > MAX_PACKET)
487 {
488 fprintf (stderr, "max_payload_bytes must be between 0 and %d\n",
489 MAX_PACKET);
490 goto failure;
491 }
492
493 inFile = argv[argc-2];
494 fin = fopen(inFile, "rb");
495 if (!fin)
496 {
497 fprintf (stderr, "Could not open input file %s\n", argv[argc-2]);
498 goto failure;
499 }
500 if (mode_list)
501 {
502 int size;
503 fseek(fin, 0, SEEK_END);
504 size = ftell(fin);
505 fprintf(stderr, "File size is %d bytes\n", size);
506 fseek(fin, 0, SEEK_SET);
507 mode_switch_time = size/sizeof(short)/channels/nb_modes_in_list;
508 fprintf(stderr, "Switching mode every %d samples\n", mode_switch_time);
509 }
510
511 outFile = argv[argc-1];
512 fout = fopen(outFile, "wb+");
513 if (!fout)
514 {
515 fprintf (stderr, "Could not open output file %s\n", argv[argc-1]);
516 goto failure;
517 }
518
519 if (!decode_only)
520 {
521 enc = opus_encoder_create(sampling_rate, channels, application, &err);
522 if (err != OPUS_OK)
523 {
524 fprintf(stderr, "Cannot create encoder: %s\n", opus_strerror(err));
525 goto failure;
526 }
527 opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
528 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(bandwidth));
529 opus_encoder_ctl(enc, OPUS_SET_VBR(use_vbr));
530 opus_encoder_ctl(enc, OPUS_SET_VBR_CONSTRAINT(cvbr));
531 opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(complexity));
532 opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(use_inbandfec));
533 opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(forcechannels));
534 opus_encoder_ctl(enc, OPUS_SET_DTX(use_dtx));
535 opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(packet_loss_perc));
536
537 opus_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&skip));
538 opus_encoder_ctl(enc, OPUS_SET_LSB_DEPTH(16));
539 opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration));
540 }
541 if (!encode_only)
542 {
543 dec = opus_decoder_create(sampling_rate, channels, &err);
544 if (err != OPUS_OK)
545 {
546 fprintf(stderr, "Cannot create decoder: %s\n", opus_strerror(err));
547 goto failure;
548 }
549 }
550
551
552 switch(bandwidth)
553 {
554 case OPUS_BANDWIDTH_NARROWBAND:
555 bandwidth_string = "narrowband";
556 break;
557 case OPUS_BANDWIDTH_MEDIUMBAND:
558 bandwidth_string = "mediumband";
559 break;
560 case OPUS_BANDWIDTH_WIDEBAND:
561 bandwidth_string = "wideband";
562 break;
563 case OPUS_BANDWIDTH_SUPERWIDEBAND:
564 bandwidth_string = "superwideband";
565 break;
566 case OPUS_BANDWIDTH_FULLBAND:
567 bandwidth_string = "fullband";
568 break;
569 case OPUS_AUTO:
570 bandwidth_string = "auto bandwidth";
571 break;
572 default:
573 bandwidth_string = "unknown";
574 break;
575 }
576
577 if (decode_only)
578 fprintf(stderr, "Decoding with %ld Hz output (%d channels)\n",
579 (long)sampling_rate, channels);
580 else
581 fprintf(stderr, "Encoding %ld Hz input at %.3f kb/s "
582 "in %s with %d-sample frames.\n",
583 (long)sampling_rate, bitrate_bps*0.001,
584 bandwidth_string, frame_size);
585
586 in = (short*)malloc(max_frame_size*channels*sizeof(short));
587 out = (short*)malloc(max_frame_size*channels*sizeof(short));
588 /* We need to allocate for 16-bit PCM data, but we store it as unsigned char. */
589 fbytes = (unsigned char*)malloc(max_frame_size*channels*sizeof(short));
590 data[0] = (unsigned char*)calloc(max_payload_bytes,sizeof(unsigned char));
591 if ( use_inbandfec ) {
592 data[1] = (unsigned char*)calloc(max_payload_bytes,sizeof(unsigned char));
593 }
594 if(delayed_decision)
595 {
596 if (frame_size==sampling_rate/400)
597 variable_duration = OPUS_FRAMESIZE_2_5_MS;
598 else if (frame_size==sampling_rate/200)
599 variable_duration = OPUS_FRAMESIZE_5_MS;
600 else if (frame_size==sampling_rate/100)
601 variable_duration = OPUS_FRAMESIZE_10_MS;
602 else if (frame_size==sampling_rate/50)
603 variable_duration = OPUS_FRAMESIZE_20_MS;
604 else if (frame_size==sampling_rate/25)
605 variable_duration = OPUS_FRAMESIZE_40_MS;
606 else if (frame_size==3*sampling_rate/50)
607 variable_duration = OPUS_FRAMESIZE_60_MS;
608 else if (frame_size==4*sampling_rate/50)
609 variable_duration = OPUS_FRAMESIZE_80_MS;
610 else if (frame_size==5*sampling_rate/50)
611 variable_duration = OPUS_FRAMESIZE_100_MS;
612 else
613 variable_duration = OPUS_FRAMESIZE_120_MS;
614 opus_encoder_ctl(enc, OPUS_SET_EXPERT_FRAME_DURATION(variable_duration));
615 frame_size = 2*48000;
616 }
617 while (!stop)
618 {
619 if (delayed_celt)
620 {
621 frame_size = newsize;
622 delayed_celt = 0;
623 } else if (random_framesize && rand()%20==0)
624 {
625 newsize = rand()%6;
626 switch(newsize)
627 {
628 case 0: newsize=sampling_rate/400; break;
629 case 1: newsize=sampling_rate/200; break;
630 case 2: newsize=sampling_rate/100; break;
631 case 3: newsize=sampling_rate/50; break;
632 case 4: newsize=sampling_rate/25; break;
633 case 5: newsize=3*sampling_rate/50; break;
634 }
635 while (newsize < sampling_rate/25 && bitrate_bps-abs(sweep_bps) <= 3*12*sampling_rate/newsize)
636 newsize*=2;
637 if (newsize < sampling_rate/100 && frame_size >= sampling_rate/100)
638 {
639 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
640 delayed_celt=1;
641 } else {
642 frame_size = newsize;
643 }
644 }
645 if (random_fec && rand()%30==0)
646 {
647 opus_encoder_ctl(enc, OPUS_SET_INBAND_FEC(rand()%4==0));
648 }
649 if (decode_only)
650 {
651 unsigned char ch[4];
652 num_read = fread(ch, 1, 4, fin);
653 if (num_read!=4)
654 break;
655 len[toggle] = char_to_int(ch);
656 if (len[toggle]>max_payload_bytes || len[toggle]<0)
657 {
658 fprintf(stderr, "Invalid payload length: %d\n",len[toggle]);
659 break;
660 }
661 num_read = fread(ch, 1, 4, fin);
662 if (num_read!=4)
663 break;
664 enc_final_range[toggle] = char_to_int(ch);
665 num_read = fread(data[toggle], 1, len[toggle], fin);
666 if (num_read!=(size_t)len[toggle])
667 {
668 fprintf(stderr, "Ran out of input, "
669 "expecting %d bytes got %d\n",
670 len[toggle],(int)num_read);
671 break;
672 }
673 } else {
674 int i;
675 if (mode_list!=NULL)
676 {
677 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(mode_list[curr_mode][1]));
678 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(mode_list[curr_mode][0]));
679 opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(mode_list[curr_mode][3]));
680 frame_size = mode_list[curr_mode][2];
681 }
682 num_read = fread(fbytes, sizeof(short)*channels, frame_size-remaining, fin);
683 curr_read = (int)num_read;
684 tot_in += curr_read;
685 for(i=0;i<curr_read*channels;i++)
686 {
687 opus_int32 s;
688 s=fbytes[2*i+1]<<8|fbytes[2*i];
689 s=((s&0xFFFF)^0x8000)-0x8000;
690 in[i+remaining*channels]=s;
691 }
692 if (curr_read+remaining < frame_size)
693 {
694 for (i=(curr_read+remaining)*channels;i<frame_size*channels;i++)
695 in[i] = 0;
696 if (encode_only || decode_only)
697 stop = 1;
698 }
699 len[toggle] = opus_encode(enc, in, frame_size, data[toggle], max_payload_bytes);
700 nb_encoded = opus_packet_get_samples_per_frame(data[toggle], sampling_rate)*opus_packet_get_nb_frames(data[toggle], len[toggle]);
701 remaining = frame_size-nb_encoded;
702 for(i=0;i<remaining*channels;i++)
703 in[i] = in[nb_encoded*channels+i];
704 if (sweep_bps!=0)
705 {
706 bitrate_bps += sweep_bps;
707 if (sweep_max)
708 {
709 if (bitrate_bps > sweep_max)
710 sweep_bps = -sweep_bps;
711 else if (bitrate_bps < sweep_min)
712 sweep_bps = -sweep_bps;
713 }
714 /* safety */
715 if (bitrate_bps<1000)
716 bitrate_bps = 1000;
717 opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate_bps));
718 }
719 opus_encoder_ctl(enc, OPUS_GET_FINAL_RANGE(&enc_final_range[toggle]));
720 if (len[toggle] < 0)
721 {
722 fprintf (stderr, "opus_encode() returned %d\n", len[toggle]);
723 goto failure;
724 }
725 curr_mode_count += frame_size;
726 if (curr_mode_count > mode_switch_time && curr_mode < nb_modes_in_list-1)
727 {
728 curr_mode++;
729 curr_mode_count = 0;
730 }
731 }
732
733#if 0 /* This is for testing the padding code, do not enable by default */
734 if (len[toggle]<1275)
735 {
736 int new_len = len[toggle]+rand()%(max_payload_bytes-len[toggle]);
737 if ((err = opus_packet_pad(data[toggle], len[toggle], new_len)) != OPUS_OK)
738 {
739 fprintf(stderr, "padding failed: %s\n", opus_strerror(err));
740 goto failure;
741 }
742 len[toggle] = new_len;
743 }
744#endif
745 if (encode_only)
746 {
747 unsigned char int_field[4];
748 int_to_char(len[toggle], int_field);
749 if (fwrite(int_field, 1, 4, fout) != 4) {
750 fprintf(stderr, "Error writing.\n");
751 goto failure;
752 }
753 int_to_char(enc_final_range[toggle], int_field);
754 if (fwrite(int_field, 1, 4, fout) != 4) {
755 fprintf(stderr, "Error writing.\n");
756 goto failure;
757 }
758 if (fwrite(data[toggle], 1, len[toggle], fout) != (unsigned)len[toggle]) {
759 fprintf(stderr, "Error writing.\n");
760 goto failure;
761 }
762 tot_samples += nb_encoded;
763 } else {
764 opus_int32 output_samples;
765 lost = len[toggle]==0 || (packet_loss_perc>0 && rand()%100 < packet_loss_perc);
766 if (lost)
767 opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
768 else
769 output_samples = max_frame_size;
770 if( count >= use_inbandfec ) {
771 /* delay by one packet when using in-band FEC */
772 if( use_inbandfec ) {
773 if( lost_prev ) {
774 /* attempt to decode with in-band FEC from next packet */
775 opus_decoder_ctl(dec, OPUS_GET_LAST_PACKET_DURATION(&output_samples));
776 output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 1);
777 } else {
778 /* regular decode */
779 output_samples = max_frame_size;
780 output_samples = opus_decode(dec, data[1-toggle], len[1-toggle], out, output_samples, 0);
781 }
782 } else {
783 output_samples = opus_decode(dec, lost ? NULL : data[toggle], len[toggle], out, output_samples, 0);
784 }
785 if (output_samples>0)
786 {
787 if (!decode_only && tot_out + output_samples > tot_in)
788 {
789 stop=1;
790 output_samples = (opus_int32)(tot_in - tot_out);
791 }
792 if (output_samples>skip) {
793 int i;
794 for(i=0;i<(output_samples-skip)*channels;i++)
795 {
796 short s;
797 s=out[i+(skip*channels)];
798 fbytes[2*i]=s&0xFF;
799 fbytes[2*i+1]=(s>>8)&0xFF;
800 }
801 if (fwrite(fbytes, sizeof(short)*channels, output_samples-skip, fout) != (unsigned)(output_samples-skip)){
802 fprintf(stderr, "Error writing.\n");
803 goto failure;
804 }
805 tot_out += output_samples-skip;
806 }
807 if (output_samples<skip) skip -= output_samples;
808 else skip = 0;
809 } else {
810 fprintf(stderr, "error decoding frame: %s\n",
811 opus_strerror(output_samples));
812 }
813 tot_samples += output_samples;
814 }
815 }
816
817 if (!encode_only)
818 opus_decoder_ctl(dec, OPUS_GET_FINAL_RANGE(&dec_final_range));
819 /* compare final range encoder rng values of encoder and decoder */
820 if( enc_final_range[toggle^use_inbandfec]!=0 && !encode_only
821 && !lost && !lost_prev
822 && dec_final_range != enc_final_range[toggle^use_inbandfec] ) {
823 fprintf (stderr, "Error: Range coder state mismatch "
824 "between encoder and decoder "
825 "in frame %ld: 0x%8lx vs 0x%8lx\n",
826 (long)count,
827 (unsigned long)enc_final_range[toggle^use_inbandfec],
828 (unsigned long)dec_final_range);
829 goto failure;
830 }
831
832 lost_prev = lost;
833 if( count >= use_inbandfec ) {
834 /* count bits */
835 bits += len[toggle]*8;
836 bits_max = ( len[toggle]*8 > bits_max ) ? len[toggle]*8 : bits_max;
837 bits2 += len[toggle]*len[toggle]*64;
838 if (!decode_only)
839 {
840 nrg = 0.0;
841 for ( k = 0; k < frame_size * channels; k++ ) {
842 nrg += in[ k ] * (double)in[ k ];
843 }
844 nrg /= frame_size * channels;
845 if( nrg > 1e5 ) {
846 bits_act += len[toggle]*8;
847 count_act++;
848 }
849 }
850 }
851 count++;
852 toggle = (toggle + use_inbandfec) & 1;
853 }
854
855 if(decode_only && count > 0)
856 frame_size = (int)(tot_samples / count);
857 count -= use_inbandfec;
858 if (tot_samples >= 1 && count > 0 && frame_size)
859 {
860 /* Print out bitrate statistics */
861 double var;
862 fprintf (stderr, "average bitrate: %7.3f kb/s\n",
863 1e-3*bits*sampling_rate/tot_samples);
864 fprintf (stderr, "maximum bitrate: %7.3f kb/s\n",
865 1e-3*bits_max*sampling_rate/frame_size);
866 if (!decode_only)
867 fprintf (stderr, "active bitrate: %7.3f kb/s\n",
868 1e-3*bits_act*sampling_rate/(1e-15+frame_size*(double)count_act));
869 var = bits2/count - bits*bits/(count*(double)count);
870 if (var < 0)
871 var = 0;
872 fprintf (stderr, "bitrate standard deviation: %7.3f kb/s\n",
873 1e-3*sqrt(var)*sampling_rate/frame_size);
874 } else {
875 fprintf(stderr, "bitrate statistics are undefined\n");
876 }
877 silk_TimerSave("opus_timing.txt");
878 ret = EXIT_SUCCESS;
879failure:
880 opus_encoder_destroy(enc);
881 opus_decoder_destroy(dec);
882 free(data[0]);
883 free(data[1]);
884 if (fin)
885 fclose(fin);
886 if (fout)
887 fclose(fout);
888 free(in);
889 free(out);
890 free(fbytes);
891 return ret;
892}
diff --git a/lib/rbcodec/codecs/libopus/opus_encoder.c b/lib/rbcodec/codecs/libopus/opus_encoder.c
new file mode 100644
index 0000000000..cbeb40aebc
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/opus_encoder.c
@@ -0,0 +1,2754 @@
1/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited
2 Written by Jean-Marc Valin and Koen Vos */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <stdarg.h>
33#include "celt.h"
34#include "entenc.h"
35#include "modes.h"
36#include "API.h"
37#include "stack_alloc.h"
38#include "float_cast.h"
39#include "opus.h"
40#include "arch.h"
41#include "pitch.h"
42#include "opus_private.h"
43#include "os_support.h"
44#include "cpu_support.h"
45#include "analysis.h"
46#include "mathops.h"
47#include "tuning_parameters.h"
48#ifdef FIXED_POINT
49#include "fixed/structs_FIX.h"
50#else
51#include "float/structs_FLP.h"
52#endif
53
54#define MAX_ENCODER_BUFFER 480
55
56#ifndef DISABLE_FLOAT_API
57#define PSEUDO_SNR_THRESHOLD 316.23f /* 10^(25/10) */
58#endif
59
60typedef struct {
61 opus_val32 XX, XY, YY;
62 opus_val16 smoothed_width;
63 opus_val16 max_follower;
64} StereoWidthState;
65
66struct OpusEncoder {
67 int celt_enc_offset;
68 int silk_enc_offset;
69 silk_EncControlStruct silk_mode;
70 int application;
71 int channels;
72 int delay_compensation;
73 int force_channels;
74 int signal_type;
75 int user_bandwidth;
76 int max_bandwidth;
77 int user_forced_mode;
78 int voice_ratio;
79 opus_int32 Fs;
80 int use_vbr;
81 int vbr_constraint;
82 int variable_duration;
83 opus_int32 bitrate_bps;
84 opus_int32 user_bitrate_bps;
85 int lsb_depth;
86 int encoder_buffer;
87 int lfe;
88 int arch;
89 int use_dtx; /* general DTX for both SILK and CELT */
90#ifndef DISABLE_FLOAT_API
91 TonalityAnalysisState analysis;
92#endif
93
94#define OPUS_ENCODER_RESET_START stream_channels
95 int stream_channels;
96 opus_int16 hybrid_stereo_width_Q14;
97 opus_int32 variable_HP_smth2_Q15;
98 opus_val16 prev_HB_gain;
99 opus_val32 hp_mem[4];
100 int mode;
101 int prev_mode;
102 int prev_channels;
103 int prev_framesize;
104 int bandwidth;
105 /* Bandwidth determined automatically from the rate (before any other adjustment) */
106 int auto_bandwidth;
107 int silk_bw_switch;
108 /* Sampling rate (at the API level) */
109 int first;
110 opus_val16 * energy_masking;
111 StereoWidthState width_mem;
112 opus_val16 delay_buffer[MAX_ENCODER_BUFFER*2];
113#ifndef DISABLE_FLOAT_API
114 int detected_bandwidth;
115 int nb_no_activity_frames;
116 opus_val32 peak_signal_energy;
117#endif
118 int nonfinal_frame; /* current frame is not the final in a packet */
119 opus_uint32 rangeFinal;
120};
121
122/* Transition tables for the voice and music. First column is the
123 middle (memoriless) threshold. The second column is the hysteresis
124 (difference with the middle) */
125static const opus_int32 mono_voice_bandwidth_thresholds[8] = {
126 9000, 700, /* NB<->MB */
127 9000, 700, /* MB<->WB */
128 13500, 1000, /* WB<->SWB */
129 14000, 2000, /* SWB<->FB */
130};
131static const opus_int32 mono_music_bandwidth_thresholds[8] = {
132 9000, 700, /* NB<->MB */
133 9000, 700, /* MB<->WB */
134 11000, 1000, /* WB<->SWB */
135 12000, 2000, /* SWB<->FB */
136};
137static const opus_int32 stereo_voice_bandwidth_thresholds[8] = {
138 9000, 700, /* NB<->MB */
139 9000, 700, /* MB<->WB */
140 13500, 1000, /* WB<->SWB */
141 14000, 2000, /* SWB<->FB */
142};
143static const opus_int32 stereo_music_bandwidth_thresholds[8] = {
144 9000, 700, /* NB<->MB */
145 9000, 700, /* MB<->WB */
146 11000, 1000, /* WB<->SWB */
147 12000, 2000, /* SWB<->FB */
148};
149/* Threshold bit-rates for switching between mono and stereo */
150static const opus_int32 stereo_voice_threshold = 19000;
151static const opus_int32 stereo_music_threshold = 17000;
152
153/* Threshold bit-rate for switching between SILK/hybrid and CELT-only */
154static const opus_int32 mode_thresholds[2][2] = {
155 /* voice */ /* music */
156 { 64000, 10000}, /* mono */
157 { 44000, 10000}, /* stereo */
158};
159
160static const opus_int32 fec_thresholds[] = {
161 12000, 1000, /* NB */
162 14000, 1000, /* MB */
163 16000, 1000, /* WB */
164 20000, 1000, /* SWB */
165 22000, 1000, /* FB */
166};
167
168int opus_encoder_get_size(int channels)
169{
170 int silkEncSizeBytes, celtEncSizeBytes;
171 int ret;
172 if (channels<1 || channels > 2)
173 return 0;
174 ret = silk_Get_Encoder_Size( &silkEncSizeBytes );
175 if (ret)
176 return 0;
177 silkEncSizeBytes = align(silkEncSizeBytes);
178 celtEncSizeBytes = celt_encoder_get_size(channels);
179 return align(sizeof(OpusEncoder))+silkEncSizeBytes+celtEncSizeBytes;
180}
181
182int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int application)
183{
184 void *silk_enc;
185 CELTEncoder *celt_enc;
186 int err;
187 int ret, silkEncSizeBytes;
188
189 if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)||
190 (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO
191 && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY))
192 return OPUS_BAD_ARG;
193
194 OPUS_CLEAR((char*)st, opus_encoder_get_size(channels));
195 /* Create SILK encoder */
196 ret = silk_Get_Encoder_Size( &silkEncSizeBytes );
197 if (ret)
198 return OPUS_BAD_ARG;
199 silkEncSizeBytes = align(silkEncSizeBytes);
200 st->silk_enc_offset = align(sizeof(OpusEncoder));
201 st->celt_enc_offset = st->silk_enc_offset+silkEncSizeBytes;
202 silk_enc = (char*)st+st->silk_enc_offset;
203 celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
204
205 st->stream_channels = st->channels = channels;
206
207 st->Fs = Fs;
208
209 st->arch = opus_select_arch();
210
211 ret = silk_InitEncoder( silk_enc, st->arch, &st->silk_mode );
212 if(ret)return OPUS_INTERNAL_ERROR;
213
214 /* default SILK parameters */
215 st->silk_mode.nChannelsAPI = channels;
216 st->silk_mode.nChannelsInternal = channels;
217 st->silk_mode.API_sampleRate = st->Fs;
218 st->silk_mode.maxInternalSampleRate = 16000;
219 st->silk_mode.minInternalSampleRate = 8000;
220 st->silk_mode.desiredInternalSampleRate = 16000;
221 st->silk_mode.payloadSize_ms = 20;
222 st->silk_mode.bitRate = 25000;
223 st->silk_mode.packetLossPercentage = 0;
224 st->silk_mode.complexity = 9;
225 st->silk_mode.useInBandFEC = 0;
226 st->silk_mode.useDTX = 0;
227 st->silk_mode.useCBR = 0;
228 st->silk_mode.reducedDependency = 0;
229
230 /* Create CELT encoder */
231 /* Initialize CELT encoder */
232 err = celt_encoder_init(celt_enc, Fs, channels, st->arch);
233 if(err!=OPUS_OK)return OPUS_INTERNAL_ERROR;
234
235 celt_encoder_ctl(celt_enc, CELT_SET_SIGNALLING(0));
236 celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(st->silk_mode.complexity));
237
238 st->use_vbr = 1;
239 /* Makes constrained VBR the default (safer for real-time use) */
240 st->vbr_constraint = 1;
241 st->user_bitrate_bps = OPUS_AUTO;
242 st->bitrate_bps = 3000+Fs*channels;
243 st->application = application;
244 st->signal_type = OPUS_AUTO;
245 st->user_bandwidth = OPUS_AUTO;
246 st->max_bandwidth = OPUS_BANDWIDTH_FULLBAND;
247 st->force_channels = OPUS_AUTO;
248 st->user_forced_mode = OPUS_AUTO;
249 st->voice_ratio = -1;
250 st->encoder_buffer = st->Fs/100;
251 st->lsb_depth = 24;
252 st->variable_duration = OPUS_FRAMESIZE_ARG;
253
254 /* Delay compensation of 4 ms (2.5 ms for SILK's extra look-ahead
255 + 1.5 ms for SILK resamplers and stereo prediction) */
256 st->delay_compensation = st->Fs/250;
257
258 st->hybrid_stereo_width_Q14 = 1 << 14;
259 st->prev_HB_gain = Q15ONE;
260 st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
261 st->first = 1;
262 st->mode = MODE_HYBRID;
263 st->bandwidth = OPUS_BANDWIDTH_FULLBAND;
264
265#ifndef DISABLE_FLOAT_API
266 tonality_analysis_init(&st->analysis, st->Fs);
267 st->analysis.application = st->application;
268#endif
269
270 return OPUS_OK;
271}
272
273static unsigned char gen_toc(int mode, int framerate, int bandwidth, int channels)
274{
275 int period;
276 unsigned char toc;
277 period = 0;
278 while (framerate < 400)
279 {
280 framerate <<= 1;
281 period++;
282 }
283 if (mode == MODE_SILK_ONLY)
284 {
285 toc = (bandwidth-OPUS_BANDWIDTH_NARROWBAND)<<5;
286 toc |= (period-2)<<3;
287 } else if (mode == MODE_CELT_ONLY)
288 {
289 int tmp = bandwidth-OPUS_BANDWIDTH_MEDIUMBAND;
290 if (tmp < 0)
291 tmp = 0;
292 toc = 0x80;
293 toc |= tmp << 5;
294 toc |= period<<3;
295 } else /* Hybrid */
296 {
297 toc = 0x60;
298 toc |= (bandwidth-OPUS_BANDWIDTH_SUPERWIDEBAND)<<4;
299 toc |= (period-2)<<3;
300 }
301 toc |= (channels==2)<<2;
302 return toc;
303}
304
305#ifndef FIXED_POINT
306static void silk_biquad_float(
307 const opus_val16 *in, /* I: Input signal */
308 const opus_int32 *B_Q28, /* I: MA coefficients [3] */
309 const opus_int32 *A_Q28, /* I: AR coefficients [2] */
310 opus_val32 *S, /* I/O: State vector [2] */
311 opus_val16 *out, /* O: Output signal */
312 const opus_int32 len, /* I: Signal length (must be even) */
313 int stride
314)
315{
316 /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
317 opus_int k;
318 opus_val32 vout;
319 opus_val32 inval;
320 opus_val32 A[2], B[3];
321
322 A[0] = (opus_val32)(A_Q28[0] * (1.f/((opus_int32)1<<28)));
323 A[1] = (opus_val32)(A_Q28[1] * (1.f/((opus_int32)1<<28)));
324 B[0] = (opus_val32)(B_Q28[0] * (1.f/((opus_int32)1<<28)));
325 B[1] = (opus_val32)(B_Q28[1] * (1.f/((opus_int32)1<<28)));
326 B[2] = (opus_val32)(B_Q28[2] * (1.f/((opus_int32)1<<28)));
327
328 /* Negate A_Q28 values and split in two parts */
329
330 for( k = 0; k < len; k++ ) {
331 /* S[ 0 ], S[ 1 ]: Q12 */
332 inval = in[ k*stride ];
333 vout = S[ 0 ] + B[0]*inval;
334
335 S[ 0 ] = S[1] - vout*A[0] + B[1]*inval;
336
337 S[ 1 ] = - vout*A[1] + B[2]*inval + VERY_SMALL;
338
339 /* Scale back to Q0 and saturate */
340 out[ k*stride ] = vout;
341 }
342}
343#endif
344
345static 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, int arch)
346{
347 opus_int32 B_Q28[ 3 ], A_Q28[ 2 ];
348 opus_int32 Fc_Q19, r_Q28, r_Q22;
349 (void)arch;
350
351 silk_assert( cutoff_Hz <= silk_int32_MAX / SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ) );
352 Fc_Q19 = silk_DIV32_16( silk_SMULBB( SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ), cutoff_Hz ), Fs/1000 );
353 silk_assert( Fc_Q19 > 0 && Fc_Q19 < 32768 );
354
355 r_Q28 = SILK_FIX_CONST( 1.0, 28 ) - silk_MUL( SILK_FIX_CONST( 0.92, 9 ), Fc_Q19 );
356
357 /* b = r * [ 1; -2; 1 ]; */
358 /* a = [ 1; -2 * r * ( 1 - 0.5 * Fc^2 ); r^2 ]; */
359 B_Q28[ 0 ] = r_Q28;
360 B_Q28[ 1 ] = silk_LSHIFT( -r_Q28, 1 );
361 B_Q28[ 2 ] = r_Q28;
362
363 /* -r * ( 2 - Fc * Fc ); */
364 r_Q22 = silk_RSHIFT( r_Q28, 6 );
365 A_Q28[ 0 ] = silk_SMULWW( r_Q22, silk_SMULWW( Fc_Q19, Fc_Q19 ) - SILK_FIX_CONST( 2.0, 22 ) );
366 A_Q28[ 1 ] = silk_SMULWW( r_Q22, r_Q22 );
367
368#ifdef FIXED_POINT
369 if( channels == 1 ) {
370 silk_biquad_alt_stride1( in, B_Q28, A_Q28, hp_mem, out, len );
371 } else {
372 silk_biquad_alt_stride2( in, B_Q28, A_Q28, hp_mem, out, len, arch );
373 }
374#else
375 silk_biquad_float( in, B_Q28, A_Q28, hp_mem, out, len, channels );
376 if( channels == 2 ) {
377 silk_biquad_float( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels );
378 }
379#endif
380}
381
382#ifdef FIXED_POINT
383static 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)
384{
385 int c, i;
386 int shift;
387
388 /* Approximates -round(log2(6.3*cutoff_Hz/Fs)) */
389 shift=celt_ilog2(Fs/(cutoff_Hz*4));
390 for (c=0;c<channels;c++)
391 {
392 for (i=0;i<len;i++)
393 {
394 opus_val32 x, y;
395 x = SHL32(EXTEND32(in[channels*i+c]), 14);
396 y = x-hp_mem[2*c];
397 hp_mem[2*c] = hp_mem[2*c] + PSHR32(x - hp_mem[2*c], shift);
398 out[channels*i+c] = EXTRACT16(SATURATE(PSHR32(y, 14), 32767));
399 }
400 }
401}
402
403#else
404static 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)
405{
406 int i;
407 float coef, coef2;
408 coef = 6.3f*cutoff_Hz/Fs;
409 coef2 = 1-coef;
410 if (channels==2)
411 {
412 float m0, m2;
413 m0 = hp_mem[0];
414 m2 = hp_mem[2];
415 for (i=0;i<len;i++)
416 {
417 opus_val32 x0, x1, out0, out1;
418 x0 = in[2*i+0];
419 x1 = in[2*i+1];
420 out0 = x0-m0;
421 out1 = x1-m2;
422 m0 = coef*x0 + VERY_SMALL + coef2*m0;
423 m2 = coef*x1 + VERY_SMALL + coef2*m2;
424 out[2*i+0] = out0;
425 out[2*i+1] = out1;
426 }
427 hp_mem[0] = m0;
428 hp_mem[2] = m2;
429 } else {
430 float m0;
431 m0 = hp_mem[0];
432 for (i=0;i<len;i++)
433 {
434 opus_val32 x, y;
435 x = in[i];
436 y = x-m0;
437 m0 = coef*x + VERY_SMALL + coef2*m0;
438 out[i] = y;
439 }
440 hp_mem[0] = m0;
441 }
442}
443#endif
444
445static void stereo_fade(const opus_val16 *in, opus_val16 *out, opus_val16 g1, opus_val16 g2,
446 int overlap48, int frame_size, int channels, const opus_val16 *window, opus_int32 Fs)
447{
448 int i;
449 int overlap;
450 int inc;
451 inc = 48000/Fs;
452 overlap=overlap48/inc;
453 g1 = Q15ONE-g1;
454 g2 = Q15ONE-g2;
455 for (i=0;i<overlap;i++)
456 {
457 opus_val32 diff;
458 opus_val16 g, w;
459 w = MULT16_16_Q15(window[i*inc], window[i*inc]);
460 g = SHR32(MAC16_16(MULT16_16(w,g2),
461 Q15ONE-w, g1), 15);
462 diff = EXTRACT16(HALF32((opus_val32)in[i*channels] - (opus_val32)in[i*channels+1]));
463 diff = MULT16_16_Q15(g, diff);
464 out[i*channels] = out[i*channels] - diff;
465 out[i*channels+1] = out[i*channels+1] + diff;
466 }
467 for (;i<frame_size;i++)
468 {
469 opus_val32 diff;
470 diff = EXTRACT16(HALF32((opus_val32)in[i*channels] - (opus_val32)in[i*channels+1]));
471 diff = MULT16_16_Q15(g2, diff);
472 out[i*channels] = out[i*channels] - diff;
473 out[i*channels+1] = out[i*channels+1] + diff;
474 }
475}
476
477static void gain_fade(const opus_val16 *in, opus_val16 *out, opus_val16 g1, opus_val16 g2,
478 int overlap48, int frame_size, int channels, const opus_val16 *window, opus_int32 Fs)
479{
480 int i;
481 int inc;
482 int overlap;
483 int c;
484 inc = 48000/Fs;
485 overlap=overlap48/inc;
486 if (channels==1)
487 {
488 for (i=0;i<overlap;i++)
489 {
490 opus_val16 g, w;
491 w = MULT16_16_Q15(window[i*inc], window[i*inc]);
492 g = SHR32(MAC16_16(MULT16_16(w,g2),
493 Q15ONE-w, g1), 15);
494 out[i] = MULT16_16_Q15(g, in[i]);
495 }
496 } else {
497 for (i=0;i<overlap;i++)
498 {
499 opus_val16 g, w;
500 w = MULT16_16_Q15(window[i*inc], window[i*inc]);
501 g = SHR32(MAC16_16(MULT16_16(w,g2),
502 Q15ONE-w, g1), 15);
503 out[i*2] = MULT16_16_Q15(g, in[i*2]);
504 out[i*2+1] = MULT16_16_Q15(g, in[i*2+1]);
505 }
506 }
507 c=0;do {
508 for (i=overlap;i<frame_size;i++)
509 {
510 out[i*channels+c] = MULT16_16_Q15(g2, in[i*channels+c]);
511 }
512 }
513 while (++c<channels);
514}
515
516OpusEncoder *opus_encoder_create(opus_int32 Fs, int channels, int application, int *error)
517{
518 int ret;
519 OpusEncoder *st;
520 if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)||
521 (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO
522 && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY))
523 {
524 if (error)
525 *error = OPUS_BAD_ARG;
526 return NULL;
527 }
528 st = (OpusEncoder *)opus_alloc(opus_encoder_get_size(channels));
529 if (st == NULL)
530 {
531 if (error)
532 *error = OPUS_ALLOC_FAIL;
533 return NULL;
534 }
535 ret = opus_encoder_init(st, Fs, channels, application);
536 if (error)
537 *error = ret;
538 if (ret != OPUS_OK)
539 {
540 opus_free(st);
541 st = NULL;
542 }
543 return st;
544}
545
546static opus_int32 user_bitrate_to_bitrate(OpusEncoder *st, int frame_size, int max_data_bytes)
547{
548 if(!frame_size)frame_size=st->Fs/400;
549 if (st->user_bitrate_bps==OPUS_AUTO)
550 return 60*st->Fs/frame_size + st->Fs*st->channels;
551 else if (st->user_bitrate_bps==OPUS_BITRATE_MAX)
552 return max_data_bytes*8*st->Fs/frame_size;
553 else
554 return st->user_bitrate_bps;
555}
556
557#ifndef DISABLE_FLOAT_API
558#ifdef FIXED_POINT
559#define PCM2VAL(x) FLOAT2INT16(x)
560#else
561#define PCM2VAL(x) SCALEIN(x)
562#endif
563
564void downmix_float(const void *_x, opus_val32 *y, int subframe, int offset, int c1, int c2, int C)
565{
566 const float *x;
567 int j;
568
569 x = (const float *)_x;
570 for (j=0;j<subframe;j++)
571 y[j] = PCM2VAL(x[(j+offset)*C+c1]);
572 if (c2>-1)
573 {
574 for (j=0;j<subframe;j++)
575 y[j] += PCM2VAL(x[(j+offset)*C+c2]);
576 } else if (c2==-2)
577 {
578 int c;
579 for (c=1;c<C;c++)
580 {
581 for (j=0;j<subframe;j++)
582 y[j] += PCM2VAL(x[(j+offset)*C+c]);
583 }
584 }
585}
586#endif
587
588void downmix_int(const void *_x, opus_val32 *y, int subframe, int offset, int c1, int c2, int C)
589{
590 const opus_int16 *x;
591 int j;
592
593 x = (const opus_int16 *)_x;
594 for (j=0;j<subframe;j++)
595 y[j] = x[(j+offset)*C+c1];
596 if (c2>-1)
597 {
598 for (j=0;j<subframe;j++)
599 y[j] += x[(j+offset)*C+c2];
600 } else if (c2==-2)
601 {
602 int c;
603 for (c=1;c<C;c++)
604 {
605 for (j=0;j<subframe;j++)
606 y[j] += x[(j+offset)*C+c];
607 }
608 }
609}
610
611opus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs)
612{
613 int new_size;
614 if (frame_size<Fs/400)
615 return -1;
616 if (variable_duration == OPUS_FRAMESIZE_ARG)
617 new_size = frame_size;
618 else if (variable_duration >= OPUS_FRAMESIZE_2_5_MS && variable_duration <= OPUS_FRAMESIZE_120_MS)
619 {
620 if (variable_duration <= OPUS_FRAMESIZE_40_MS)
621 new_size = (Fs/400)<<(variable_duration-OPUS_FRAMESIZE_2_5_MS);
622 else
623 new_size = (variable_duration-OPUS_FRAMESIZE_2_5_MS-2)*Fs/50;
624 }
625 else
626 return -1;
627 if (new_size>frame_size)
628 return -1;
629 if (400*new_size!=Fs && 200*new_size!=Fs && 100*new_size!=Fs &&
630 50*new_size!=Fs && 25*new_size!=Fs && 50*new_size!=3*Fs &&
631 50*new_size!=4*Fs && 50*new_size!=5*Fs && 50*new_size!=6*Fs)
632 return -1;
633 return new_size;
634}
635
636opus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int32 Fs, StereoWidthState *mem)
637{
638 opus_val32 xx, xy, yy;
639 opus_val16 sqrt_xx, sqrt_yy;
640 opus_val16 qrrt_xx, qrrt_yy;
641 int frame_rate;
642 int i;
643 opus_val16 short_alpha;
644
645 frame_rate = Fs/frame_size;
646 short_alpha = Q15ONE - MULT16_16(25, Q15ONE)/IMAX(50,frame_rate);
647 xx=xy=yy=0;
648 /* Unroll by 4. The frame size is always a multiple of 4 *except* for
649 2.5 ms frames at 12 kHz. Since this setting is very rare (and very
650 stupid), we just discard the last two samples. */
651 for (i=0;i<frame_size-3;i+=4)
652 {
653 opus_val32 pxx=0;
654 opus_val32 pxy=0;
655 opus_val32 pyy=0;
656 opus_val16 x, y;
657 x = pcm[2*i];
658 y = pcm[2*i+1];
659 pxx = SHR32(MULT16_16(x,x),2);
660 pxy = SHR32(MULT16_16(x,y),2);
661 pyy = SHR32(MULT16_16(y,y),2);
662 x = pcm[2*i+2];
663 y = pcm[2*i+3];
664 pxx += SHR32(MULT16_16(x,x),2);
665 pxy += SHR32(MULT16_16(x,y),2);
666 pyy += SHR32(MULT16_16(y,y),2);
667 x = pcm[2*i+4];
668 y = pcm[2*i+5];
669 pxx += SHR32(MULT16_16(x,x),2);
670 pxy += SHR32(MULT16_16(x,y),2);
671 pyy += SHR32(MULT16_16(y,y),2);
672 x = pcm[2*i+6];
673 y = pcm[2*i+7];
674 pxx += SHR32(MULT16_16(x,x),2);
675 pxy += SHR32(MULT16_16(x,y),2);
676 pyy += SHR32(MULT16_16(y,y),2);
677
678 xx += SHR32(pxx, 10);
679 xy += SHR32(pxy, 10);
680 yy += SHR32(pyy, 10);
681 }
682#ifndef FIXED_POINT
683 if (!(xx < 1e9f) || celt_isnan(xx) || !(yy < 1e9f) || celt_isnan(yy))
684 {
685 xy = xx = yy = 0;
686 }
687#endif
688 mem->XX += MULT16_32_Q15(short_alpha, xx-mem->XX);
689 mem->XY += MULT16_32_Q15(short_alpha, xy-mem->XY);
690 mem->YY += MULT16_32_Q15(short_alpha, yy-mem->YY);
691 mem->XX = MAX32(0, mem->XX);
692 mem->XY = MAX32(0, mem->XY);
693 mem->YY = MAX32(0, mem->YY);
694 if (MAX32(mem->XX, mem->YY)>QCONST16(8e-4f, 18))
695 {
696 opus_val16 corr;
697 opus_val16 ldiff;
698 opus_val16 width;
699 sqrt_xx = celt_sqrt(mem->XX);
700 sqrt_yy = celt_sqrt(mem->YY);
701 qrrt_xx = celt_sqrt(sqrt_xx);
702 qrrt_yy = celt_sqrt(sqrt_yy);
703 /* Inter-channel correlation */
704 mem->XY = MIN32(mem->XY, sqrt_xx*sqrt_yy);
705 corr = SHR32(frac_div32(mem->XY,EPSILON+MULT16_16(sqrt_xx,sqrt_yy)),16);
706 /* Approximate loudness difference */
707 ldiff = MULT16_16(Q15ONE, ABS16(qrrt_xx-qrrt_yy))/(EPSILON+qrrt_xx+qrrt_yy);
708 width = MULT16_16_Q15(celt_sqrt(QCONST32(1.f,30)-MULT16_16(corr,corr)), ldiff);
709 /* Smoothing over one second */
710 mem->smoothed_width += (width-mem->smoothed_width)/frame_rate;
711 /* Peak follower */
712 mem->max_follower = MAX16(mem->max_follower-QCONST16(.02f,15)/frame_rate, mem->smoothed_width);
713 }
714 /*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);*/
715 return EXTRACT16(MIN32(Q15ONE, MULT16_16(20, mem->max_follower)));
716}
717
718static int decide_fec(int useInBandFEC, int PacketLoss_perc, int last_fec, int mode, int *bandwidth, opus_int32 rate)
719{
720 int orig_bandwidth;
721 if (!useInBandFEC || PacketLoss_perc == 0 || mode == MODE_CELT_ONLY)
722 return 0;
723 orig_bandwidth = *bandwidth;
724 for (;;)
725 {
726 opus_int32 hysteresis;
727 opus_int32 LBRR_rate_thres_bps;
728 /* Compute threshold for using FEC at the current bandwidth setting */
729 LBRR_rate_thres_bps = fec_thresholds[2*(*bandwidth - OPUS_BANDWIDTH_NARROWBAND)];
730 hysteresis = fec_thresholds[2*(*bandwidth - OPUS_BANDWIDTH_NARROWBAND) + 1];
731 if (last_fec == 1) LBRR_rate_thres_bps -= hysteresis;
732 if (last_fec == 0) LBRR_rate_thres_bps += hysteresis;
733 LBRR_rate_thres_bps = silk_SMULWB( silk_MUL( LBRR_rate_thres_bps,
734 125 - silk_min( PacketLoss_perc, 25 ) ), SILK_FIX_CONST( 0.01, 16 ) );
735 /* If loss <= 5%, we look at whether we have enough rate to enable FEC.
736 If loss > 5%, we decrease the bandwidth until we can enable FEC. */
737 if (rate > LBRR_rate_thres_bps)
738 return 1;
739 else if (PacketLoss_perc <= 5)
740 return 0;
741 else if (*bandwidth > OPUS_BANDWIDTH_NARROWBAND)
742 (*bandwidth)--;
743 else
744 break;
745 }
746 /* Couldn't find any bandwidth to enable FEC, keep original bandwidth. */
747 *bandwidth = orig_bandwidth;
748 return 0;
749}
750
751static int compute_silk_rate_for_hybrid(int rate, int bandwidth, int frame20ms, int vbr, int fec, int channels) {
752 int entry;
753 int i;
754 int N;
755 int silk_rate;
756 static int rate_table[][5] = {
757 /* |total| |-------- SILK------------|
758 |-- No FEC -| |--- FEC ---|
759 10ms 20ms 10ms 20ms */
760 { 0, 0, 0, 0, 0},
761 {12000, 10000, 10000, 11000, 11000},
762 {16000, 13500, 13500, 15000, 15000},
763 {20000, 16000, 16000, 18000, 18000},
764 {24000, 18000, 18000, 21000, 21000},
765 {32000, 22000, 22000, 28000, 28000},
766 {64000, 38000, 38000, 50000, 50000}
767 };
768 /* Do the allocation per-channel. */
769 rate /= channels;
770 entry = 1 + frame20ms + 2*fec;
771 N = sizeof(rate_table)/sizeof(rate_table[0]);
772 for (i=1;i<N;i++)
773 {
774 if (rate_table[i][0] > rate) break;
775 }
776 if (i == N)
777 {
778 silk_rate = rate_table[i-1][entry];
779 /* For now, just give 50% of the extra bits to SILK. */
780 silk_rate += (rate-rate_table[i-1][0])/2;
781 } else {
782 opus_int32 lo, hi, x0, x1;
783 lo = rate_table[i-1][entry];
784 hi = rate_table[i][entry];
785 x0 = rate_table[i-1][0];
786 x1 = rate_table[i][0];
787 silk_rate = (lo*(x1-rate) + hi*(rate-x0))/(x1-x0);
788 }
789 if (!vbr)
790 {
791 /* Tiny boost to SILK for CBR. We should probably tune this better. */
792 silk_rate += 100;
793 }
794 if (bandwidth==OPUS_BANDWIDTH_SUPERWIDEBAND)
795 silk_rate += 300;
796 silk_rate *= channels;
797 /* Small adjustment for stereo (calibrated for 32 kb/s, haven't tried other bitrates). */
798 if (channels == 2 && rate >= 12000)
799 silk_rate -= 1000;
800 return silk_rate;
801}
802
803/* Returns the equivalent bitrate corresponding to 20 ms frames,
804 complexity 10 VBR operation. */
805static opus_int32 compute_equiv_rate(opus_int32 bitrate, int channels,
806 int frame_rate, int vbr, int mode, int complexity, int loss)
807{
808 opus_int32 equiv;
809 equiv = bitrate;
810 /* Take into account overhead from smaller frames. */
811 if (frame_rate > 50)
812 equiv -= (40*channels+20)*(frame_rate - 50);
813 /* CBR is about a 8% penalty for both SILK and CELT. */
814 if (!vbr)
815 equiv -= equiv/12;
816 /* Complexity makes about 10% difference (from 0 to 10) in general. */
817 equiv = equiv * (90+complexity)/100;
818 if (mode == MODE_SILK_ONLY || mode == MODE_HYBRID)
819 {
820 /* SILK complexity 0-1 uses the non-delayed-decision NSQ, which
821 costs about 20%. */
822 if (complexity<2)
823 equiv = equiv*4/5;
824 equiv -= equiv*loss/(6*loss + 10);
825 } else if (mode == MODE_CELT_ONLY) {
826 /* CELT complexity 0-4 doesn't have the pitch filter, which costs
827 about 10%. */
828 if (complexity<5)
829 equiv = equiv*9/10;
830 } else {
831 /* Mode not known yet */
832 /* Half the SILK loss*/
833 equiv -= equiv*loss/(12*loss + 20);
834 }
835 return equiv;
836}
837
838#ifndef DISABLE_FLOAT_API
839
840static int is_digital_silence(const opus_val16* pcm, int frame_size, int channels, int lsb_depth)
841{
842 int silence = 0;
843 opus_val32 sample_max = 0;
844#ifdef MLP_TRAINING
845 return 0;
846#endif
847 sample_max = celt_maxabs16(pcm, frame_size*channels);
848
849#ifdef FIXED_POINT
850 silence = (sample_max == 0);
851 (void)lsb_depth;
852#else
853 silence = (sample_max <= (opus_val16) 1 / (1 << lsb_depth));
854#endif
855
856 return silence;
857}
858
859#ifdef FIXED_POINT
860static opus_val32 compute_frame_energy(const opus_val16 *pcm, int frame_size, int channels, int arch)
861{
862 int i;
863 opus_val32 sample_max;
864 int max_shift;
865 int shift;
866 opus_val32 energy = 0;
867 int len = frame_size*channels;
868 (void)arch;
869 /* Max amplitude in the signal */
870 sample_max = celt_maxabs16(pcm, len);
871
872 /* Compute the right shift required in the MAC to avoid an overflow */
873 max_shift = celt_ilog2(len);
874 shift = IMAX(0, (celt_ilog2(sample_max) << 1) + max_shift - 28);
875
876 /* Compute the energy */
877 for (i=0; i<len; i++)
878 energy += SHR32(MULT16_16(pcm[i], pcm[i]), shift);
879
880 /* Normalize energy by the frame size and left-shift back to the original position */
881 energy /= len;
882 energy = SHL32(energy, shift);
883
884 return energy;
885}
886#else
887static opus_val32 compute_frame_energy(const opus_val16 *pcm, int frame_size, int channels, int arch)
888{
889 int len = frame_size*channels;
890 return celt_inner_prod(pcm, pcm, len, arch)/len;
891}
892#endif
893
894/* Decides if DTX should be turned on (=1) or off (=0) */
895static int decide_dtx_mode(float activity_probability, /* probability that current frame contains speech/music */
896 int *nb_no_activity_frames, /* number of consecutive frames with no activity */
897 opus_val32 peak_signal_energy, /* peak energy of desired signal detected so far */
898 const opus_val16 *pcm, /* input pcm signal */
899 int frame_size, /* frame size */
900 int channels,
901 int is_silence, /* only digital silence detected in this frame */
902 int arch
903 )
904{
905 opus_val32 noise_energy;
906
907 if (!is_silence)
908 {
909 if (activity_probability < DTX_ACTIVITY_THRESHOLD) /* is noise */
910 {
911 noise_energy = compute_frame_energy(pcm, frame_size, channels, arch);
912
913 /* but is sufficiently quiet */
914 is_silence = peak_signal_energy >= (PSEUDO_SNR_THRESHOLD * noise_energy);
915 }
916 }
917
918 if (is_silence)
919 {
920 /* The number of consecutive DTX frames should be within the allowed bounds */
921 (*nb_no_activity_frames)++;
922
923 if (*nb_no_activity_frames > NB_SPEECH_FRAMES_BEFORE_DTX)
924 {
925 if (*nb_no_activity_frames <= (NB_SPEECH_FRAMES_BEFORE_DTX + MAX_CONSECUTIVE_DTX))
926 /* Valid frame for DTX! */
927 return 1;
928 else
929 (*nb_no_activity_frames) = NB_SPEECH_FRAMES_BEFORE_DTX;
930 }
931 } else
932 (*nb_no_activity_frames) = 0;
933
934 return 0;
935}
936
937#endif
938
939static opus_int32 encode_multiframe_packet(OpusEncoder *st,
940 const opus_val16 *pcm,
941 int nb_frames,
942 int frame_size,
943 unsigned char *data,
944 opus_int32 out_data_bytes,
945 int to_celt,
946 int lsb_depth,
947 int float_api)
948{
949 int i;
950 int ret = 0;
951 VARDECL(unsigned char, tmp_data);
952 int bak_mode, bak_bandwidth, bak_channels, bak_to_mono;
953 VARDECL(OpusRepacketizer, rp);
954 int max_header_bytes;
955 opus_int32 bytes_per_frame;
956 opus_int32 cbr_bytes;
957 opus_int32 repacketize_len;
958 int tmp_len;
959 ALLOC_STACK;
960
961 /* Worst cases:
962 * 2 frames: Code 2 with different compressed sizes
963 * >2 frames: Code 3 VBR */
964 max_header_bytes = nb_frames == 2 ? 3 : (2+(nb_frames-1)*2);
965
966 if (st->use_vbr || st->user_bitrate_bps==OPUS_BITRATE_MAX)
967 repacketize_len = out_data_bytes;
968 else {
969 cbr_bytes = 3*st->bitrate_bps/(3*8*st->Fs/(frame_size*nb_frames));
970 repacketize_len = IMIN(cbr_bytes, out_data_bytes);
971 }
972 bytes_per_frame = IMIN(1276, 1+(repacketize_len-max_header_bytes)/nb_frames);
973
974 ALLOC(tmp_data, nb_frames*bytes_per_frame, unsigned char);
975 ALLOC(rp, 1, OpusRepacketizer);
976 opus_repacketizer_init(rp);
977
978 bak_mode = st->user_forced_mode;
979 bak_bandwidth = st->user_bandwidth;
980 bak_channels = st->force_channels;
981
982 st->user_forced_mode = st->mode;
983 st->user_bandwidth = st->bandwidth;
984 st->force_channels = st->stream_channels;
985
986 bak_to_mono = st->silk_mode.toMono;
987 if (bak_to_mono)
988 st->force_channels = 1;
989 else
990 st->prev_channels = st->stream_channels;
991
992 for (i=0;i<nb_frames;i++)
993 {
994 st->silk_mode.toMono = 0;
995 st->nonfinal_frame = i<(nb_frames-1);
996
997 /* When switching from SILK/Hybrid to CELT, only ask for a switch at the last frame */
998 if (to_celt && i==nb_frames-1)
999 st->user_forced_mode = MODE_CELT_ONLY;
1000
1001 tmp_len = opus_encode_native(st, pcm+i*(st->channels*frame_size), frame_size,
1002 tmp_data+i*bytes_per_frame, bytes_per_frame, lsb_depth, NULL, 0, 0, 0, 0,
1003 NULL, float_api);
1004
1005 if (tmp_len<0)
1006 {
1007 RESTORE_STACK;
1008 return OPUS_INTERNAL_ERROR;
1009 }
1010
1011 ret = opus_repacketizer_cat(rp, tmp_data+i*bytes_per_frame, tmp_len);
1012
1013 if (ret<0)
1014 {
1015 RESTORE_STACK;
1016 return OPUS_INTERNAL_ERROR;
1017 }
1018 }
1019
1020 ret = opus_repacketizer_out_range_impl(rp, 0, nb_frames, data, repacketize_len, 0, !st->use_vbr);
1021
1022 if (ret<0)
1023 {
1024 RESTORE_STACK;
1025 return OPUS_INTERNAL_ERROR;
1026 }
1027
1028 /* Discard configs that were forced locally for the purpose of repacketization */
1029 st->user_forced_mode = bak_mode;
1030 st->user_bandwidth = bak_bandwidth;
1031 st->force_channels = bak_channels;
1032 st->silk_mode.toMono = bak_to_mono;
1033
1034 RESTORE_STACK;
1035 return ret;
1036}
1037
1038static int compute_redundancy_bytes(opus_int32 max_data_bytes, opus_int32 bitrate_bps, int frame_rate, int channels)
1039{
1040 int redundancy_bytes_cap;
1041 int redundancy_bytes;
1042 opus_int32 redundancy_rate;
1043 int base_bits;
1044 opus_int32 available_bits;
1045 base_bits = (40*channels+20);
1046
1047 /* Equivalent rate for 5 ms frames. */
1048 redundancy_rate = bitrate_bps + base_bits*(200 - frame_rate);
1049 /* For VBR, further increase the bitrate if we can afford it. It's pretty short
1050 and we'll avoid artefacts. */
1051 redundancy_rate = 3*redundancy_rate/2;
1052 redundancy_bytes = redundancy_rate/1600;
1053
1054 /* Compute the max rate we can use given CBR or VBR with cap. */
1055 available_bits = max_data_bytes*8 - 2*base_bits;
1056 redundancy_bytes_cap = (available_bits*240/(240+48000/frame_rate) + base_bits)/8;
1057 redundancy_bytes = IMIN(redundancy_bytes, redundancy_bytes_cap);
1058 /* It we can't get enough bits for redundancy to be worth it, rely on the decoder PLC. */
1059 if (redundancy_bytes > 4 + 8*channels)
1060 redundancy_bytes = IMIN(257, redundancy_bytes);
1061 else
1062 redundancy_bytes = 0;
1063 return redundancy_bytes;
1064}
1065
1066opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
1067 unsigned char *data, opus_int32 out_data_bytes, int lsb_depth,
1068 const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2,
1069 int analysis_channels, downmix_func downmix, int float_api)
1070{
1071 void *silk_enc;
1072 CELTEncoder *celt_enc;
1073 int i;
1074 int ret=0;
1075 opus_int32 nBytes;
1076 ec_enc enc;
1077 int bytes_target;
1078 int prefill=0;
1079 int start_band = 0;
1080 int redundancy = 0;
1081 int redundancy_bytes = 0; /* Number of bytes to use for redundancy frame */
1082 int celt_to_silk = 0;
1083 VARDECL(opus_val16, pcm_buf);
1084 int nb_compr_bytes;
1085 int to_celt = 0;
1086 opus_uint32 redundant_rng = 0;
1087 int cutoff_Hz, hp_freq_smth1;
1088 int voice_est; /* Probability of voice in Q7 */
1089 opus_int32 equiv_rate;
1090 int delay_compensation;
1091 int frame_rate;
1092 opus_int32 max_rate; /* Max bitrate we're allowed to use */
1093 int curr_bandwidth;
1094 opus_val16 HB_gain;
1095 opus_int32 max_data_bytes; /* Max number of bytes we're allowed to use */
1096 int total_buffer;
1097 opus_val16 stereo_width;
1098 const CELTMode *celt_mode;
1099#ifndef DISABLE_FLOAT_API
1100 AnalysisInfo analysis_info;
1101 int analysis_read_pos_bak=-1;
1102 int analysis_read_subframe_bak=-1;
1103 int is_silence = 0;
1104#endif
1105 VARDECL(opus_val16, tmp_prefill);
1106
1107 ALLOC_STACK;
1108
1109 max_data_bytes = IMIN(1276, out_data_bytes);
1110
1111 st->rangeFinal = 0;
1112 if (frame_size <= 0 || max_data_bytes <= 0)
1113 {
1114 RESTORE_STACK;
1115 return OPUS_BAD_ARG;
1116 }
1117
1118 /* Cannot encode 100 ms in 1 byte */
1119 if (max_data_bytes==1 && st->Fs==(frame_size*10))
1120 {
1121 RESTORE_STACK;
1122 return OPUS_BUFFER_TOO_SMALL;
1123 }
1124
1125 silk_enc = (char*)st+st->silk_enc_offset;
1126 celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
1127 if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
1128 delay_compensation = 0;
1129 else
1130 delay_compensation = st->delay_compensation;
1131
1132 lsb_depth = IMIN(lsb_depth, st->lsb_depth);
1133
1134 celt_encoder_ctl(celt_enc, CELT_GET_MODE(&celt_mode));
1135#ifndef DISABLE_FLOAT_API
1136 analysis_info.valid = 0;
1137#ifdef FIXED_POINT
1138 if (st->silk_mode.complexity >= 10 && st->Fs>=16000)
1139#else
1140 if (st->silk_mode.complexity >= 7 && st->Fs>=16000)
1141#endif
1142 {
1143 if (is_digital_silence(pcm, frame_size, st->channels, lsb_depth))
1144 {
1145 is_silence = 1;
1146 } else {
1147 analysis_read_pos_bak = st->analysis.read_pos;
1148 analysis_read_subframe_bak = st->analysis.read_subframe;
1149 run_analysis(&st->analysis, celt_mode, analysis_pcm, analysis_size, frame_size,
1150 c1, c2, analysis_channels, st->Fs,
1151 lsb_depth, downmix, &analysis_info);
1152 }
1153
1154 /* Track the peak signal energy */
1155 if (!is_silence && analysis_info.activity_probability > DTX_ACTIVITY_THRESHOLD)
1156 st->peak_signal_energy = MAX32(MULT16_32_Q15(QCONST16(0.999f, 15), st->peak_signal_energy),
1157 compute_frame_energy(pcm, frame_size, st->channels, st->arch));
1158 }
1159#else
1160 (void)analysis_pcm;
1161 (void)analysis_size;
1162 (void)c1;
1163 (void)c2;
1164 (void)analysis_channels;
1165 (void)downmix;
1166#endif
1167
1168#ifndef DISABLE_FLOAT_API
1169 /* Reset voice_ratio if this frame is not silent or if analysis is disabled.
1170 * Otherwise, preserve voice_ratio from the last non-silent frame */
1171 if (!is_silence)
1172 st->voice_ratio = -1;
1173
1174 st->detected_bandwidth = 0;
1175 if (analysis_info.valid)
1176 {
1177 int analysis_bandwidth;
1178 if (st->signal_type == OPUS_AUTO)
1179 {
1180 float prob;
1181 if (st->prev_mode == 0)
1182 prob = analysis_info.music_prob;
1183 else if (st->prev_mode == MODE_CELT_ONLY)
1184 prob = analysis_info.music_prob_max;
1185 else
1186 prob = analysis_info.music_prob_min;
1187 st->voice_ratio = (int)floor(.5+100*(1-prob));
1188 }
1189
1190 analysis_bandwidth = analysis_info.bandwidth;
1191 if (analysis_bandwidth<=12)
1192 st->detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND;
1193 else if (analysis_bandwidth<=14)
1194 st->detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
1195 else if (analysis_bandwidth<=16)
1196 st->detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
1197 else if (analysis_bandwidth<=18)
1198 st->detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
1199 else
1200 st->detected_bandwidth = OPUS_BANDWIDTH_FULLBAND;
1201 }
1202#else
1203 st->voice_ratio = -1;
1204#endif
1205
1206 if (st->channels==2 && st->force_channels!=1)
1207 stereo_width = compute_stereo_width(pcm, frame_size, st->Fs, &st->width_mem);
1208 else
1209 stereo_width = 0;
1210 total_buffer = delay_compensation;
1211 st->bitrate_bps = user_bitrate_to_bitrate(st, frame_size, max_data_bytes);
1212
1213 frame_rate = st->Fs/frame_size;
1214 if (!st->use_vbr)
1215 {
1216 int cbrBytes;
1217 /* Multiply by 12 to make sure the division is exact. */
1218 int frame_rate12 = 12*st->Fs/frame_size;
1219 /* We need to make sure that "int" values always fit in 16 bits. */
1220 cbrBytes = IMIN( (12*st->bitrate_bps/8 + frame_rate12/2)/frame_rate12, max_data_bytes);
1221 st->bitrate_bps = cbrBytes*(opus_int32)frame_rate12*8/12;
1222 /* Make sure we provide at least one byte to avoid failing. */
1223 max_data_bytes = IMAX(1, cbrBytes);
1224 }
1225 if (max_data_bytes<3 || st->bitrate_bps < 3*frame_rate*8
1226 || (frame_rate<50 && (max_data_bytes*frame_rate<300 || st->bitrate_bps < 2400)))
1227 {
1228 /*If the space is too low to do something useful, emit 'PLC' frames.*/
1229 int tocmode = st->mode;
1230 int bw = st->bandwidth == 0 ? OPUS_BANDWIDTH_NARROWBAND : st->bandwidth;
1231 int packet_code = 0;
1232 int num_multiframes = 0;
1233
1234 if (tocmode==0)
1235 tocmode = MODE_SILK_ONLY;
1236 if (frame_rate>100)
1237 tocmode = MODE_CELT_ONLY;
1238 /* 40 ms -> 2 x 20 ms if in CELT_ONLY or HYBRID mode */
1239 if (frame_rate==25 && tocmode!=MODE_SILK_ONLY)
1240 {
1241 frame_rate = 50;
1242 packet_code = 1;
1243 }
1244
1245 /* >= 60 ms frames */
1246 if (frame_rate<=16)
1247 {
1248 /* 1 x 60 ms, 2 x 40 ms, 2 x 60 ms */
1249 if (out_data_bytes==1 || (tocmode==MODE_SILK_ONLY && frame_rate!=10))
1250 {
1251 tocmode = MODE_SILK_ONLY;
1252
1253 packet_code = frame_rate <= 12;
1254 frame_rate = frame_rate == 12 ? 25 : 16;
1255 }
1256 else
1257 {
1258 num_multiframes = 50/frame_rate;
1259 frame_rate = 50;
1260 packet_code = 3;
1261 }
1262 }
1263
1264 if(tocmode==MODE_SILK_ONLY&&bw>OPUS_BANDWIDTH_WIDEBAND)
1265 bw=OPUS_BANDWIDTH_WIDEBAND;
1266 else if (tocmode==MODE_CELT_ONLY&&bw==OPUS_BANDWIDTH_MEDIUMBAND)
1267 bw=OPUS_BANDWIDTH_NARROWBAND;
1268 else if (tocmode==MODE_HYBRID&&bw<=OPUS_BANDWIDTH_SUPERWIDEBAND)
1269 bw=OPUS_BANDWIDTH_SUPERWIDEBAND;
1270
1271 data[0] = gen_toc(tocmode, frame_rate, bw, st->stream_channels);
1272 data[0] |= packet_code;
1273
1274 ret = packet_code <= 1 ? 1 : 2;
1275
1276 max_data_bytes = IMAX(max_data_bytes, ret);
1277
1278 if (packet_code==3)
1279 data[1] = num_multiframes;
1280
1281 if (!st->use_vbr)
1282 {
1283 ret = opus_packet_pad(data, ret, max_data_bytes);
1284 if (ret == OPUS_OK)
1285 ret = max_data_bytes;
1286 else
1287 ret = OPUS_INTERNAL_ERROR;
1288 }
1289 RESTORE_STACK;
1290 return ret;
1291 }
1292 max_rate = frame_rate*max_data_bytes*8;
1293
1294 /* Equivalent 20-ms rate for mode/channel/bandwidth decisions */
1295 equiv_rate = compute_equiv_rate(st->bitrate_bps, st->channels, st->Fs/frame_size,
1296 st->use_vbr, 0, st->silk_mode.complexity, st->silk_mode.packetLossPercentage);
1297
1298 if (st->signal_type == OPUS_SIGNAL_VOICE)
1299 voice_est = 127;
1300 else if (st->signal_type == OPUS_SIGNAL_MUSIC)
1301 voice_est = 0;
1302 else if (st->voice_ratio >= 0)
1303 {
1304 voice_est = st->voice_ratio*327>>8;
1305 /* For AUDIO, never be more than 90% confident of having speech */
1306 if (st->application == OPUS_APPLICATION_AUDIO)
1307 voice_est = IMIN(voice_est, 115);
1308 } else if (st->application == OPUS_APPLICATION_VOIP)
1309 voice_est = 115;
1310 else
1311 voice_est = 48;
1312
1313 if (st->force_channels!=OPUS_AUTO && st->channels == 2)
1314 {
1315 st->stream_channels = st->force_channels;
1316 } else {
1317#ifdef FUZZING
1318 /* Random mono/stereo decision */
1319 if (st->channels == 2 && (rand()&0x1F)==0)
1320 st->stream_channels = 3-st->stream_channels;
1321#else
1322 /* Rate-dependent mono-stereo decision */
1323 if (st->channels == 2)
1324 {
1325 opus_int32 stereo_threshold;
1326 stereo_threshold = stereo_music_threshold + ((voice_est*voice_est*(stereo_voice_threshold-stereo_music_threshold))>>14);
1327 if (st->stream_channels == 2)
1328 stereo_threshold -= 1000;
1329 else
1330 stereo_threshold += 1000;
1331 st->stream_channels = (equiv_rate > stereo_threshold) ? 2 : 1;
1332 } else {
1333 st->stream_channels = st->channels;
1334 }
1335#endif
1336 }
1337 /* Update equivalent rate for channels decision. */
1338 equiv_rate = compute_equiv_rate(st->bitrate_bps, st->stream_channels, st->Fs/frame_size,
1339 st->use_vbr, 0, st->silk_mode.complexity, st->silk_mode.packetLossPercentage);
1340
1341 /* Mode selection depending on application and signal type */
1342 if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
1343 {
1344 st->mode = MODE_CELT_ONLY;
1345 } else if (st->user_forced_mode == OPUS_AUTO)
1346 {
1347#ifdef FUZZING
1348 /* Random mode switching */
1349 if ((rand()&0xF)==0)
1350 {
1351 if ((rand()&0x1)==0)
1352 st->mode = MODE_CELT_ONLY;
1353 else
1354 st->mode = MODE_SILK_ONLY;
1355 } else {
1356 if (st->prev_mode==MODE_CELT_ONLY)
1357 st->mode = MODE_CELT_ONLY;
1358 else
1359 st->mode = MODE_SILK_ONLY;
1360 }
1361#else
1362 opus_int32 mode_voice, mode_music;
1363 opus_int32 threshold;
1364
1365 /* Interpolate based on stereo width */
1366 mode_voice = (opus_int32)(MULT16_32_Q15(Q15ONE-stereo_width,mode_thresholds[0][0])
1367 + MULT16_32_Q15(stereo_width,mode_thresholds[1][0]));
1368 mode_music = (opus_int32)(MULT16_32_Q15(Q15ONE-stereo_width,mode_thresholds[1][1])
1369 + MULT16_32_Q15(stereo_width,mode_thresholds[1][1]));
1370 /* Interpolate based on speech/music probability */
1371 threshold = mode_music + ((voice_est*voice_est*(mode_voice-mode_music))>>14);
1372 /* Bias towards SILK for VoIP because of some useful features */
1373 if (st->application == OPUS_APPLICATION_VOIP)
1374 threshold += 8000;
1375
1376 /*printf("%f %d\n", stereo_width/(float)Q15ONE, threshold);*/
1377 /* Hysteresis */
1378 if (st->prev_mode == MODE_CELT_ONLY)
1379 threshold -= 4000;
1380 else if (st->prev_mode>0)
1381 threshold += 4000;
1382
1383 st->mode = (equiv_rate >= threshold) ? MODE_CELT_ONLY: MODE_SILK_ONLY;
1384
1385 /* When FEC is enabled and there's enough packet loss, use SILK */
1386 if (st->silk_mode.useInBandFEC && st->silk_mode.packetLossPercentage > (128-voice_est)>>4)
1387 st->mode = MODE_SILK_ONLY;
1388 /* When encoding voice and DTX is enabled but the generalized DTX cannot be used,
1389 because of complexity and sampling frequency settings, switch to SILK DTX and
1390 set the encoder to SILK mode */
1391#ifndef DISABLE_FLOAT_API
1392 st->silk_mode.useDTX = st->use_dtx && !(analysis_info.valid || is_silence);
1393#else
1394 st->silk_mode.useDTX = st->use_dtx;
1395#endif
1396 if (st->silk_mode.useDTX && voice_est > 100)
1397 st->mode = MODE_SILK_ONLY;
1398#endif
1399
1400 /* If max_data_bytes represents less than 6 kb/s, switch to CELT-only mode */
1401 if (max_data_bytes < (frame_rate > 50 ? 9000 : 6000)*frame_size / (st->Fs * 8))
1402 st->mode = MODE_CELT_ONLY;
1403 } else {
1404 st->mode = st->user_forced_mode;
1405 }
1406
1407 /* Override the chosen mode to make sure we meet the requested frame size */
1408 if (st->mode != MODE_CELT_ONLY && frame_size < st->Fs/100)
1409 st->mode = MODE_CELT_ONLY;
1410 if (st->lfe)
1411 st->mode = MODE_CELT_ONLY;
1412
1413 if (st->prev_mode > 0 &&
1414 ((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ||
1415 (st->mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)))
1416 {
1417 redundancy = 1;
1418 celt_to_silk = (st->mode != MODE_CELT_ONLY);
1419 if (!celt_to_silk)
1420 {
1421 /* Switch to SILK/hybrid if frame size is 10 ms or more*/
1422 if (frame_size >= st->Fs/100)
1423 {
1424 st->mode = st->prev_mode;
1425 to_celt = 1;
1426 } else {
1427 redundancy=0;
1428 }
1429 }
1430 }
1431
1432 /* When encoding multiframes, we can ask for a switch to CELT only in the last frame. This switch
1433 * is processed above as the requested mode shouldn't interrupt stereo->mono transition. */
1434 if (st->stream_channels == 1 && st->prev_channels ==2 && st->silk_mode.toMono==0
1435 && st->mode != MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)
1436 {
1437 /* Delay stereo->mono transition by two frames so that SILK can do a smooth downmix */
1438 st->silk_mode.toMono = 1;
1439 st->stream_channels = 2;
1440 } else {
1441 st->silk_mode.toMono = 0;
1442 }
1443
1444 /* Update equivalent rate with mode decision. */
1445 equiv_rate = compute_equiv_rate(st->bitrate_bps, st->stream_channels, st->Fs/frame_size,
1446 st->use_vbr, st->mode, st->silk_mode.complexity, st->silk_mode.packetLossPercentage);
1447
1448 if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
1449 {
1450 silk_EncControlStruct dummy;
1451 silk_InitEncoder( silk_enc, st->arch, &dummy);
1452 prefill=1;
1453 }
1454
1455 /* Automatic (rate-dependent) bandwidth selection */
1456 if (st->mode == MODE_CELT_ONLY || st->first || st->silk_mode.allowBandwidthSwitch)
1457 {
1458 const opus_int32 *voice_bandwidth_thresholds, *music_bandwidth_thresholds;
1459 opus_int32 bandwidth_thresholds[8];
1460 int bandwidth = OPUS_BANDWIDTH_FULLBAND;
1461
1462 if (st->channels==2 && st->force_channels!=1)
1463 {
1464 voice_bandwidth_thresholds = stereo_voice_bandwidth_thresholds;
1465 music_bandwidth_thresholds = stereo_music_bandwidth_thresholds;
1466 } else {
1467 voice_bandwidth_thresholds = mono_voice_bandwidth_thresholds;
1468 music_bandwidth_thresholds = mono_music_bandwidth_thresholds;
1469 }
1470 /* Interpolate bandwidth thresholds depending on voice estimation */
1471 for (i=0;i<8;i++)
1472 {
1473 bandwidth_thresholds[i] = music_bandwidth_thresholds[i]
1474 + ((voice_est*voice_est*(voice_bandwidth_thresholds[i]-music_bandwidth_thresholds[i]))>>14);
1475 }
1476 do {
1477 int threshold, hysteresis;
1478 threshold = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)];
1479 hysteresis = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)+1];
1480 if (!st->first)
1481 {
1482 if (st->auto_bandwidth >= bandwidth)
1483 threshold -= hysteresis;
1484 else
1485 threshold += hysteresis;
1486 }
1487 if (equiv_rate >= threshold)
1488 break;
1489 } while (--bandwidth>OPUS_BANDWIDTH_NARROWBAND);
1490 /* We don't use mediumband anymore, except when explicitly requested or during
1491 mode transitions. */
1492 if (bandwidth == OPUS_BANDWIDTH_MEDIUMBAND)
1493 bandwidth = OPUS_BANDWIDTH_WIDEBAND;
1494 st->bandwidth = st->auto_bandwidth = bandwidth;
1495 /* Prevents any transition to SWB/FB until the SILK layer has fully
1496 switched to WB mode and turned the variable LP filter off */
1497 if (!st->first && st->mode != MODE_CELT_ONLY && !st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND)
1498 st->bandwidth = OPUS_BANDWIDTH_WIDEBAND;
1499 }
1500
1501 if (st->bandwidth>st->max_bandwidth)
1502 st->bandwidth = st->max_bandwidth;
1503
1504 if (st->user_bandwidth != OPUS_AUTO)
1505 st->bandwidth = st->user_bandwidth;
1506
1507 /* This prevents us from using hybrid at unsafe CBR/max rates */
1508 if (st->mode != MODE_CELT_ONLY && max_rate < 15000)
1509 {
1510 st->bandwidth = IMIN(st->bandwidth, OPUS_BANDWIDTH_WIDEBAND);
1511 }
1512
1513 /* Prevents Opus from wasting bits on frequencies that are above
1514 the Nyquist rate of the input signal */
1515 if (st->Fs <= 24000 && st->bandwidth > OPUS_BANDWIDTH_SUPERWIDEBAND)
1516 st->bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
1517 if (st->Fs <= 16000 && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND)
1518 st->bandwidth = OPUS_BANDWIDTH_WIDEBAND;
1519 if (st->Fs <= 12000 && st->bandwidth > OPUS_BANDWIDTH_MEDIUMBAND)
1520 st->bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
1521 if (st->Fs <= 8000 && st->bandwidth > OPUS_BANDWIDTH_NARROWBAND)
1522 st->bandwidth = OPUS_BANDWIDTH_NARROWBAND;
1523#ifndef DISABLE_FLOAT_API
1524 /* Use detected bandwidth to reduce the encoded bandwidth. */
1525 if (st->detected_bandwidth && st->user_bandwidth == OPUS_AUTO)
1526 {
1527 int min_detected_bandwidth;
1528 /* Makes bandwidth detection more conservative just in case the detector
1529 gets it wrong when we could have coded a high bandwidth transparently.
1530 When operating in SILK/hybrid mode, we don't go below wideband to avoid
1531 more complicated switches that require redundancy. */
1532 if (equiv_rate <= 18000*st->stream_channels && st->mode == MODE_CELT_ONLY)
1533 min_detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND;
1534 else if (equiv_rate <= 24000*st->stream_channels && st->mode == MODE_CELT_ONLY)
1535 min_detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
1536 else if (equiv_rate <= 30000*st->stream_channels)
1537 min_detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
1538 else if (equiv_rate <= 44000*st->stream_channels)
1539 min_detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
1540 else
1541 min_detected_bandwidth = OPUS_BANDWIDTH_FULLBAND;
1542
1543 st->detected_bandwidth = IMAX(st->detected_bandwidth, min_detected_bandwidth);
1544 st->bandwidth = IMIN(st->bandwidth, st->detected_bandwidth);
1545 }
1546#endif
1547 st->silk_mode.LBRR_coded = decide_fec(st->silk_mode.useInBandFEC, st->silk_mode.packetLossPercentage,
1548 st->silk_mode.LBRR_coded, st->mode, &st->bandwidth, equiv_rate);
1549 celt_encoder_ctl(celt_enc, OPUS_SET_LSB_DEPTH(lsb_depth));
1550
1551 /* CELT mode doesn't support mediumband, use wideband instead */
1552 if (st->mode == MODE_CELT_ONLY && st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND)
1553 st->bandwidth = OPUS_BANDWIDTH_WIDEBAND;
1554 if (st->lfe)
1555 st->bandwidth = OPUS_BANDWIDTH_NARROWBAND;
1556
1557 curr_bandwidth = st->bandwidth;
1558
1559 /* Chooses the appropriate mode for speech
1560 *NEVER* switch to/from CELT-only mode here as this will invalidate some assumptions */
1561 if (st->mode == MODE_SILK_ONLY && curr_bandwidth > OPUS_BANDWIDTH_WIDEBAND)
1562 st->mode = MODE_HYBRID;
1563 if (st->mode == MODE_HYBRID && curr_bandwidth <= OPUS_BANDWIDTH_WIDEBAND)
1564 st->mode = MODE_SILK_ONLY;
1565
1566 /* Can't support higher than >60 ms frames, and >20 ms when in Hybrid or CELT-only modes */
1567 if ((frame_size > st->Fs/50 && (st->mode != MODE_SILK_ONLY)) || frame_size > 3*st->Fs/50)
1568 {
1569 int enc_frame_size;
1570 int nb_frames;
1571
1572 if (st->mode == MODE_SILK_ONLY)
1573 {
1574 if (frame_size == 2*st->Fs/25) /* 80 ms -> 2x 40 ms */
1575 enc_frame_size = st->Fs/25;
1576 else if (frame_size == 3*st->Fs/25) /* 120 ms -> 2x 60 ms */
1577 enc_frame_size = 3*st->Fs/50;
1578 else /* 100 ms -> 5x 20 ms */
1579 enc_frame_size = st->Fs/50;
1580 }
1581 else
1582 enc_frame_size = st->Fs/50;
1583
1584 nb_frames = frame_size/enc_frame_size;
1585
1586#ifndef DISABLE_FLOAT_API
1587 if (analysis_read_pos_bak!= -1)
1588 {
1589 st->analysis.read_pos = analysis_read_pos_bak;
1590 st->analysis.read_subframe = analysis_read_subframe_bak;
1591 }
1592#endif
1593
1594 ret = encode_multiframe_packet(st, pcm, nb_frames, enc_frame_size, data,
1595 out_data_bytes, to_celt, lsb_depth, float_api);
1596
1597 RESTORE_STACK;
1598 return ret;
1599 }
1600
1601 /* For the first frame at a new SILK bandwidth */
1602 if (st->silk_bw_switch)
1603 {
1604 redundancy = 1;
1605 celt_to_silk = 1;
1606 st->silk_bw_switch = 0;
1607 /* Do a prefill without reseting the sampling rate control. */
1608 prefill=2;
1609 }
1610
1611 /* If we decided to go with CELT, make sure redundancy is off, no matter what
1612 we decided earlier. */
1613 if (st->mode == MODE_CELT_ONLY)
1614 redundancy = 0;
1615
1616 if (redundancy)
1617 {
1618 redundancy_bytes = compute_redundancy_bytes(max_data_bytes, st->bitrate_bps, frame_rate, st->stream_channels);
1619 if (redundancy_bytes == 0)
1620 redundancy = 0;
1621 }
1622
1623 /* printf("%d %d %d %d\n", st->bitrate_bps, st->stream_channels, st->mode, curr_bandwidth); */
1624 bytes_target = IMIN(max_data_bytes-redundancy_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1;
1625
1626 data += 1;
1627
1628 ec_enc_init(&enc, data, max_data_bytes-1);
1629
1630 ALLOC(pcm_buf, (total_buffer+frame_size)*st->channels, opus_val16);
1631 OPUS_COPY(pcm_buf, &st->delay_buffer[(st->encoder_buffer-total_buffer)*st->channels], total_buffer*st->channels);
1632
1633 if (st->mode == MODE_CELT_ONLY)
1634 hp_freq_smth1 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
1635 else
1636 hp_freq_smth1 = ((silk_encoder*)silk_enc)->state_Fxx[0].sCmn.variable_HP_smth1_Q15;
1637
1638 st->variable_HP_smth2_Q15 = silk_SMLAWB( st->variable_HP_smth2_Q15,
1639 hp_freq_smth1 - st->variable_HP_smth2_Q15, SILK_FIX_CONST( VARIABLE_HP_SMTH_COEF2, 16 ) );
1640
1641 /* convert from log scale to Hertz */
1642 cutoff_Hz = silk_log2lin( silk_RSHIFT( st->variable_HP_smth2_Q15, 8 ) );
1643
1644 if (st->application == OPUS_APPLICATION_VOIP)
1645 {
1646 hp_cutoff(pcm, cutoff_Hz, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs, st->arch);
1647 } else {
1648 dc_reject(pcm, 3, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs);
1649 }
1650#ifndef FIXED_POINT
1651 if (float_api)
1652 {
1653 opus_val32 sum;
1654 sum = celt_inner_prod(&pcm_buf[total_buffer*st->channels], &pcm_buf[total_buffer*st->channels], frame_size*st->channels, st->arch);
1655 /* This should filter out both NaNs and ridiculous signals that could
1656 cause NaNs further down. */
1657 if (!(sum < 1e9f) || celt_isnan(sum))
1658 {
1659 OPUS_CLEAR(&pcm_buf[total_buffer*st->channels], frame_size*st->channels);
1660 st->hp_mem[0] = st->hp_mem[1] = st->hp_mem[2] = st->hp_mem[3] = 0;
1661 }
1662 }
1663#endif
1664
1665
1666 /* SILK processing */
1667 HB_gain = Q15ONE;
1668 if (st->mode != MODE_CELT_ONLY)
1669 {
1670 opus_int32 total_bitRate, celt_rate;
1671 opus_int activity;
1672#ifdef FIXED_POINT
1673 const opus_int16 *pcm_silk;
1674#else
1675 VARDECL(opus_int16, pcm_silk);
1676 ALLOC(pcm_silk, st->channels*frame_size, opus_int16);
1677#endif
1678
1679 activity = VAD_NO_DECISION;
1680#ifndef DISABLE_FLOAT_API
1681 if( analysis_info.valid ) {
1682 /* Inform SILK about the Opus VAD decision */
1683 activity = ( analysis_info.activity_probability >= DTX_ACTIVITY_THRESHOLD );
1684 }
1685#endif
1686
1687 /* Distribute bits between SILK and CELT */
1688 total_bitRate = 8 * bytes_target * frame_rate;
1689 if( st->mode == MODE_HYBRID ) {
1690 /* Base rate for SILK */
1691 st->silk_mode.bitRate = compute_silk_rate_for_hybrid(total_bitRate,
1692 curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded,
1693 st->stream_channels);
1694 if (!st->energy_masking)
1695 {
1696 /* Increasingly attenuate high band when it gets allocated fewer bits */
1697 celt_rate = total_bitRate - st->silk_mode.bitRate;
1698 HB_gain = Q15ONE - SHR32(celt_exp2(-celt_rate * QCONST16(1.f/1024, 10)), 1);
1699 }
1700 } else {
1701 /* SILK gets all bits */
1702 st->silk_mode.bitRate = total_bitRate;
1703 }
1704
1705 /* Surround masking for SILK */
1706 if (st->energy_masking && st->use_vbr && !st->lfe)
1707 {
1708 opus_val32 mask_sum=0;
1709 opus_val16 masking_depth;
1710 opus_int32 rate_offset;
1711 int c;
1712 int end = 17;
1713 opus_int16 srate = 16000;
1714 if (st->bandwidth == OPUS_BANDWIDTH_NARROWBAND)
1715 {
1716 end = 13;
1717 srate = 8000;
1718 } else if (st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND)
1719 {
1720 end = 15;
1721 srate = 12000;
1722 }
1723 for (c=0;c<st->channels;c++)
1724 {
1725 for(i=0;i<end;i++)
1726 {
1727 opus_val16 mask;
1728 mask = MAX16(MIN16(st->energy_masking[21*c+i],
1729 QCONST16(.5f, DB_SHIFT)), -QCONST16(2.0f, DB_SHIFT));
1730 if (mask > 0)
1731 mask = HALF16(mask);
1732 mask_sum += mask;
1733 }
1734 }
1735 /* Conservative rate reduction, we cut the masking in half */
1736 masking_depth = mask_sum / end*st->channels;
1737 masking_depth += QCONST16(.2f, DB_SHIFT);
1738 rate_offset = (opus_int32)PSHR32(MULT16_16(srate, masking_depth), DB_SHIFT);
1739 rate_offset = MAX32(rate_offset, -2*st->silk_mode.bitRate/3);
1740 /* Split the rate change between the SILK and CELT part for hybrid. */
1741 if (st->bandwidth==OPUS_BANDWIDTH_SUPERWIDEBAND || st->bandwidth==OPUS_BANDWIDTH_FULLBAND)
1742 st->silk_mode.bitRate += 3*rate_offset/5;
1743 else
1744 st->silk_mode.bitRate += rate_offset;
1745 }
1746
1747 st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs;
1748 st->silk_mode.nChannelsAPI = st->channels;
1749 st->silk_mode.nChannelsInternal = st->stream_channels;
1750 if (curr_bandwidth == OPUS_BANDWIDTH_NARROWBAND) {
1751 st->silk_mode.desiredInternalSampleRate = 8000;
1752 } else if (curr_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {
1753 st->silk_mode.desiredInternalSampleRate = 12000;
1754 } else {
1755 celt_assert( st->mode == MODE_HYBRID || curr_bandwidth == OPUS_BANDWIDTH_WIDEBAND );
1756 st->silk_mode.desiredInternalSampleRate = 16000;
1757 }
1758 if( st->mode == MODE_HYBRID ) {
1759 /* Don't allow bandwidth reduction at lowest bitrates in hybrid mode */
1760 st->silk_mode.minInternalSampleRate = 16000;
1761 } else {
1762 st->silk_mode.minInternalSampleRate = 8000;
1763 }
1764
1765 st->silk_mode.maxInternalSampleRate = 16000;
1766 if (st->mode == MODE_SILK_ONLY)
1767 {
1768 opus_int32 effective_max_rate = max_rate;
1769 if (frame_rate > 50)
1770 effective_max_rate = effective_max_rate*2/3;
1771 if (effective_max_rate < 8000)
1772 {
1773 st->silk_mode.maxInternalSampleRate = 12000;
1774 st->silk_mode.desiredInternalSampleRate = IMIN(12000, st->silk_mode.desiredInternalSampleRate);
1775 }
1776 if (effective_max_rate < 7000)
1777 {
1778 st->silk_mode.maxInternalSampleRate = 8000;
1779 st->silk_mode.desiredInternalSampleRate = IMIN(8000, st->silk_mode.desiredInternalSampleRate);
1780 }
1781 }
1782
1783 st->silk_mode.useCBR = !st->use_vbr;
1784
1785 /* Call SILK encoder for the low band */
1786
1787 /* Max bits for SILK, counting ToC, redundancy bytes, and optionally redundancy. */
1788 st->silk_mode.maxBits = (max_data_bytes-1)*8;
1789 if (redundancy && redundancy_bytes >= 2)
1790 {
1791 /* Counting 1 bit for redundancy position and 20 bits for flag+size (only for hybrid). */
1792 st->silk_mode.maxBits -= redundancy_bytes*8 + 1;
1793 if (st->mode == MODE_HYBRID)
1794 st->silk_mode.maxBits -= 20;
1795 }
1796 if (st->silk_mode.useCBR)
1797 {
1798 if (st->mode == MODE_HYBRID)
1799 {
1800 st->silk_mode.maxBits = IMIN(st->silk_mode.maxBits, st->silk_mode.bitRate * frame_size / st->Fs);
1801 }
1802 } else {
1803 /* Constrained VBR. */
1804 if (st->mode == MODE_HYBRID)
1805 {
1806 /* Compute SILK bitrate corresponding to the max total bits available */
1807 opus_int32 maxBitRate = compute_silk_rate_for_hybrid(st->silk_mode.maxBits*st->Fs / frame_size,
1808 curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded,
1809 st->stream_channels);
1810 st->silk_mode.maxBits = maxBitRate * frame_size / st->Fs;
1811 }
1812 }
1813
1814 if (prefill)
1815 {
1816 opus_int32 zero=0;
1817 int prefill_offset;
1818 /* Use a smooth onset for the SILK prefill to avoid the encoder trying to encode
1819 a discontinuity. The exact location is what we need to avoid leaving any "gap"
1820 in the audio when mixing with the redundant CELT frame. Here we can afford to
1821 overwrite st->delay_buffer because the only thing that uses it before it gets
1822 rewritten is tmp_prefill[] and even then only the part after the ramp really
1823 gets used (rather than sent to the encoder and discarded) */
1824 prefill_offset = st->channels*(st->encoder_buffer-st->delay_compensation-st->Fs/400);
1825 gain_fade(st->delay_buffer+prefill_offset, st->delay_buffer+prefill_offset,
1826 0, Q15ONE, celt_mode->overlap, st->Fs/400, st->channels, celt_mode->window, st->Fs);
1827 OPUS_CLEAR(st->delay_buffer, prefill_offset);
1828#ifdef FIXED_POINT
1829 pcm_silk = st->delay_buffer;
1830#else
1831 for (i=0;i<st->encoder_buffer*st->channels;i++)
1832 pcm_silk[i] = FLOAT2INT16(st->delay_buffer[i]);
1833#endif
1834 silk_Encode( silk_enc, &st->silk_mode, pcm_silk, st->encoder_buffer, NULL, &zero, prefill, activity );
1835 /* Prevent a second switch in the real encode call. */
1836 st->silk_mode.opusCanSwitch = 0;
1837 }
1838
1839#ifdef FIXED_POINT
1840 pcm_silk = pcm_buf+total_buffer*st->channels;
1841#else
1842 for (i=0;i<frame_size*st->channels;i++)
1843 pcm_silk[i] = FLOAT2INT16(pcm_buf[total_buffer*st->channels + i]);
1844#endif
1845 ret = silk_Encode( silk_enc, &st->silk_mode, pcm_silk, frame_size, &enc, &nBytes, 0, activity );
1846 if( ret ) {
1847 /*fprintf (stderr, "SILK encode error: %d\n", ret);*/
1848 /* Handle error */
1849 RESTORE_STACK;
1850 return OPUS_INTERNAL_ERROR;
1851 }
1852
1853 /* Extract SILK internal bandwidth for signaling in first byte */
1854 if( st->mode == MODE_SILK_ONLY ) {
1855 if( st->silk_mode.internalSampleRate == 8000 ) {
1856 curr_bandwidth = OPUS_BANDWIDTH_NARROWBAND;
1857 } else if( st->silk_mode.internalSampleRate == 12000 ) {
1858 curr_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
1859 } else if( st->silk_mode.internalSampleRate == 16000 ) {
1860 curr_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
1861 }
1862 } else {
1863 celt_assert( st->silk_mode.internalSampleRate == 16000 );
1864 }
1865
1866 st->silk_mode.opusCanSwitch = st->silk_mode.switchReady && !st->nonfinal_frame;
1867
1868 if (nBytes==0)
1869 {
1870 st->rangeFinal = 0;
1871 data[-1] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);
1872 RESTORE_STACK;
1873 return 1;
1874 }
1875
1876 /* FIXME: How do we allocate the redundancy for CBR? */
1877 if (st->silk_mode.opusCanSwitch)
1878 {
1879 redundancy_bytes = compute_redundancy_bytes(max_data_bytes, st->bitrate_bps, frame_rate, st->stream_channels);
1880 redundancy = (redundancy_bytes != 0);
1881 celt_to_silk = 0;
1882 st->silk_bw_switch = 1;
1883 }
1884 }
1885
1886 /* CELT processing */
1887 {
1888 int endband=21;
1889
1890 switch(curr_bandwidth)
1891 {
1892 case OPUS_BANDWIDTH_NARROWBAND:
1893 endband = 13;
1894 break;
1895 case OPUS_BANDWIDTH_MEDIUMBAND:
1896 case OPUS_BANDWIDTH_WIDEBAND:
1897 endband = 17;
1898 break;
1899 case OPUS_BANDWIDTH_SUPERWIDEBAND:
1900 endband = 19;
1901 break;
1902 case OPUS_BANDWIDTH_FULLBAND:
1903 endband = 21;
1904 break;
1905 }
1906 celt_encoder_ctl(celt_enc, CELT_SET_END_BAND(endband));
1907 celt_encoder_ctl(celt_enc, CELT_SET_CHANNELS(st->stream_channels));
1908 }
1909 celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX));
1910 if (st->mode != MODE_SILK_ONLY)
1911 {
1912 opus_val32 celt_pred=2;
1913 celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));
1914 /* We may still decide to disable prediction later */
1915 if (st->silk_mode.reducedDependency)
1916 celt_pred = 0;
1917 celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(celt_pred));
1918
1919 if (st->mode == MODE_HYBRID)
1920 {
1921 if( st->use_vbr ) {
1922 celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps-st->silk_mode.bitRate));
1923 celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(0));
1924 }
1925 } else {
1926 if (st->use_vbr)
1927 {
1928 celt_encoder_ctl(celt_enc, OPUS_SET_VBR(1));
1929 celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(st->vbr_constraint));
1930 celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps));
1931 }
1932 }
1933 }
1934
1935 ALLOC(tmp_prefill, st->channels*st->Fs/400, opus_val16);
1936 if (st->mode != MODE_SILK_ONLY && st->mode != st->prev_mode && st->prev_mode > 0)
1937 {
1938 OPUS_COPY(tmp_prefill, &st->delay_buffer[(st->encoder_buffer-total_buffer-st->Fs/400)*st->channels], st->channels*st->Fs/400);
1939 }
1940
1941 if (st->channels*(st->encoder_buffer-(frame_size+total_buffer)) > 0)
1942 {
1943 OPUS_MOVE(st->delay_buffer, &st->delay_buffer[st->channels*frame_size], st->channels*(st->encoder_buffer-frame_size-total_buffer));
1944 OPUS_COPY(&st->delay_buffer[st->channels*(st->encoder_buffer-frame_size-total_buffer)],
1945 &pcm_buf[0],
1946 (frame_size+total_buffer)*st->channels);
1947 } else {
1948 OPUS_COPY(st->delay_buffer, &pcm_buf[(frame_size+total_buffer-st->encoder_buffer)*st->channels], st->encoder_buffer*st->channels);
1949 }
1950 /* gain_fade() and stereo_fade() need to be after the buffer copying
1951 because we don't want any of this to affect the SILK part */
1952 if( st->prev_HB_gain < Q15ONE || HB_gain < Q15ONE ) {
1953 gain_fade(pcm_buf, pcm_buf,
1954 st->prev_HB_gain, HB_gain, celt_mode->overlap, frame_size, st->channels, celt_mode->window, st->Fs);
1955 }
1956 st->prev_HB_gain = HB_gain;
1957 if (st->mode != MODE_HYBRID || st->stream_channels==1)
1958 {
1959 if (equiv_rate > 32000)
1960 st->silk_mode.stereoWidth_Q14 = 16384;
1961 else if (equiv_rate < 16000)
1962 st->silk_mode.stereoWidth_Q14 = 0;
1963 else
1964 st->silk_mode.stereoWidth_Q14 = 16384 - 2048*(opus_int32)(32000-equiv_rate)/(equiv_rate-14000);
1965 }
1966 if( !st->energy_masking && st->channels == 2 ) {
1967 /* Apply stereo width reduction (at low bitrates) */
1968 if( st->hybrid_stereo_width_Q14 < (1 << 14) || st->silk_mode.stereoWidth_Q14 < (1 << 14) ) {
1969 opus_val16 g1, g2;
1970 g1 = st->hybrid_stereo_width_Q14;
1971 g2 = (opus_val16)(st->silk_mode.stereoWidth_Q14);
1972#ifdef FIXED_POINT
1973 g1 = g1==16384 ? Q15ONE : SHL16(g1,1);
1974 g2 = g2==16384 ? Q15ONE : SHL16(g2,1);
1975#else
1976 g1 *= (1.f/16384);
1977 g2 *= (1.f/16384);
1978#endif
1979 stereo_fade(pcm_buf, pcm_buf, g1, g2, celt_mode->overlap,
1980 frame_size, st->channels, celt_mode->window, st->Fs);
1981 st->hybrid_stereo_width_Q14 = st->silk_mode.stereoWidth_Q14;
1982 }
1983 }
1984
1985 if ( st->mode != MODE_CELT_ONLY && ec_tell(&enc)+17+20*(st->mode == MODE_HYBRID) <= 8*(max_data_bytes-1))
1986 {
1987 /* For SILK mode, the redundancy is inferred from the length */
1988 if (st->mode == MODE_HYBRID)
1989 ec_enc_bit_logp(&enc, redundancy, 12);
1990 if (redundancy)
1991 {
1992 int max_redundancy;
1993 ec_enc_bit_logp(&enc, celt_to_silk, 1);
1994 if (st->mode == MODE_HYBRID)
1995 {
1996 /* Reserve the 8 bits needed for the redundancy length,
1997 and at least a few bits for CELT if possible */
1998 max_redundancy = (max_data_bytes-1)-((ec_tell(&enc)+8+3+7)>>3);
1999 }
2000 else
2001 max_redundancy = (max_data_bytes-1)-((ec_tell(&enc)+7)>>3);
2002 /* Target the same bit-rate for redundancy as for the rest,
2003 up to a max of 257 bytes */
2004 redundancy_bytes = IMIN(max_redundancy, redundancy_bytes);
2005 redundancy_bytes = IMIN(257, IMAX(2, redundancy_bytes));
2006 if (st->mode == MODE_HYBRID)
2007 ec_enc_uint(&enc, redundancy_bytes-2, 256);
2008 }
2009 } else {
2010 redundancy = 0;
2011 }
2012
2013 if (!redundancy)
2014 {
2015 st->silk_bw_switch = 0;
2016 redundancy_bytes = 0;
2017 }
2018 if (st->mode != MODE_CELT_ONLY)start_band=17;
2019
2020 if (st->mode == MODE_SILK_ONLY)
2021 {
2022 ret = (ec_tell(&enc)+7)>>3;
2023 ec_enc_done(&enc);
2024 nb_compr_bytes = ret;
2025 } else {
2026 nb_compr_bytes = (max_data_bytes-1)-redundancy_bytes;
2027 ec_enc_shrink(&enc, nb_compr_bytes);
2028 }
2029
2030#ifndef DISABLE_FLOAT_API
2031 if (redundancy || st->mode != MODE_SILK_ONLY)
2032 celt_encoder_ctl(celt_enc, CELT_SET_ANALYSIS(&analysis_info));
2033#endif
2034 if (st->mode == MODE_HYBRID) {
2035 SILKInfo info;
2036 info.signalType = st->silk_mode.signalType;
2037 info.offset = st->silk_mode.offset;
2038 celt_encoder_ctl(celt_enc, CELT_SET_SILK_INFO(&info));
2039 }
2040
2041 /* 5 ms redundant frame for CELT->SILK */
2042 if (redundancy && celt_to_silk)
2043 {
2044 int err;
2045 celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
2046 celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));
2047 celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX));
2048 err = celt_encode_with_ec(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes, NULL);
2049 if (err < 0)
2050 {
2051 RESTORE_STACK;
2052 return OPUS_INTERNAL_ERROR;
2053 }
2054 celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng));
2055 celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
2056 }
2057
2058 celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(start_band));
2059
2060 if (st->mode != MODE_SILK_ONLY)
2061 {
2062 if (st->mode != st->prev_mode && st->prev_mode > 0)
2063 {
2064 unsigned char dummy[2];
2065 celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
2066
2067 /* Prefilling */
2068 celt_encode_with_ec(celt_enc, tmp_prefill, st->Fs/400, dummy, 2, NULL);
2069 celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
2070 }
2071 /* If false, we already busted the budget and we'll end up with a "PLC frame" */
2072 if (ec_tell(&enc) <= 8*nb_compr_bytes)
2073 {
2074 /* Set the bitrate again if it was overridden in the redundancy code above*/
2075 if (redundancy && celt_to_silk && st->mode==MODE_HYBRID && st->use_vbr)
2076 celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps-st->silk_mode.bitRate));
2077 celt_encoder_ctl(celt_enc, OPUS_SET_VBR(st->use_vbr));
2078 ret = celt_encode_with_ec(celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc);
2079 if (ret < 0)
2080 {
2081 RESTORE_STACK;
2082 return OPUS_INTERNAL_ERROR;
2083 }
2084 /* Put CELT->SILK redundancy data in the right place. */
2085 if (redundancy && celt_to_silk && st->mode==MODE_HYBRID && st->use_vbr)
2086 {
2087 OPUS_MOVE(data+ret, data+nb_compr_bytes, redundancy_bytes);
2088 nb_compr_bytes = nb_compr_bytes+redundancy_bytes;
2089 }
2090 }
2091 }
2092
2093 /* 5 ms redundant frame for SILK->CELT */
2094 if (redundancy && !celt_to_silk)
2095 {
2096 int err;
2097 unsigned char dummy[2];
2098 int N2, N4;
2099 N2 = st->Fs/200;
2100 N4 = st->Fs/400;
2101
2102 celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
2103 celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
2104 celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
2105 celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));
2106 celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX));
2107
2108 if (st->mode == MODE_HYBRID)
2109 {
2110 /* Shrink packet to what the encoder actually used. */
2111 nb_compr_bytes = ret;
2112 ec_enc_shrink(&enc, nb_compr_bytes);
2113 }
2114 /* NOTE: We could speed this up slightly (at the expense of code size) by just adding a function that prefills the buffer */
2115 celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, dummy, 2, NULL);
2116
2117 err = celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes, NULL);
2118 if (err < 0)
2119 {
2120 RESTORE_STACK;
2121 return OPUS_INTERNAL_ERROR;
2122 }
2123 celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng));
2124 }
2125
2126
2127
2128 /* Signalling the mode in the first byte */
2129 data--;
2130 data[0] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);
2131
2132 st->rangeFinal = enc.rng ^ redundant_rng;
2133
2134 if (to_celt)
2135 st->prev_mode = MODE_CELT_ONLY;
2136 else
2137 st->prev_mode = st->mode;
2138 st->prev_channels = st->stream_channels;
2139 st->prev_framesize = frame_size;
2140
2141 st->first = 0;
2142
2143 /* DTX decision */
2144#ifndef DISABLE_FLOAT_API
2145 if (st->use_dtx && (analysis_info.valid || is_silence))
2146 {
2147 if (decide_dtx_mode(analysis_info.activity_probability, &st->nb_no_activity_frames,
2148 st->peak_signal_energy, pcm, frame_size, st->channels, is_silence, st->arch))
2149 {
2150 st->rangeFinal = 0;
2151 data[0] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);
2152 RESTORE_STACK;
2153 return 1;
2154 }
2155 }
2156#endif
2157
2158 /* In the unlikely case that the SILK encoder busted its target, tell
2159 the decoder to call the PLC */
2160 if (ec_tell(&enc) > (max_data_bytes-1)*8)
2161 {
2162 if (max_data_bytes < 2)
2163 {
2164 RESTORE_STACK;
2165 return OPUS_BUFFER_TOO_SMALL;
2166 }
2167 data[1] = 0;
2168 ret = 1;
2169 st->rangeFinal = 0;
2170 } else if (st->mode==MODE_SILK_ONLY&&!redundancy)
2171 {
2172 /*When in LPC only mode it's perfectly
2173 reasonable to strip off trailing zero bytes as
2174 the required range decoder behavior is to
2175 fill these in. This can't be done when the MDCT
2176 modes are used because the decoder needs to know
2177 the actual length for allocation purposes.*/
2178 while(ret>2&&data[ret]==0)ret--;
2179 }
2180 /* Count ToC and redundancy */
2181 ret += 1+redundancy_bytes;
2182 if (!st->use_vbr)
2183 {
2184 if (opus_packet_pad(data, ret, max_data_bytes) != OPUS_OK)
2185 {
2186 RESTORE_STACK;
2187 return OPUS_INTERNAL_ERROR;
2188 }
2189 ret = max_data_bytes;
2190 }
2191 RESTORE_STACK;
2192 return ret;
2193}
2194
2195#ifdef FIXED_POINT
2196
2197#ifndef DISABLE_FLOAT_API
2198opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_frame_size,
2199 unsigned char *data, opus_int32 max_data_bytes)
2200{
2201 int i, ret;
2202 int frame_size;
2203 VARDECL(opus_int16, in);
2204 ALLOC_STACK;
2205
2206 frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
2207 if (frame_size <= 0)
2208 {
2209 RESTORE_STACK;
2210 return OPUS_BAD_ARG;
2211 }
2212 ALLOC(in, frame_size*st->channels, opus_int16);
2213
2214 for (i=0;i<frame_size*st->channels;i++)
2215 in[i] = FLOAT2INT16(pcm[i]);
2216 ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, 16,
2217 pcm, analysis_frame_size, 0, -2, st->channels, downmix_float, 1);
2218 RESTORE_STACK;
2219 return ret;
2220}
2221#endif
2222
2223opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_frame_size,
2224 unsigned char *data, opus_int32 out_data_bytes)
2225{
2226 int frame_size;
2227 frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
2228 return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 16,
2229 pcm, analysis_frame_size, 0, -2, st->channels, downmix_int, 0);
2230}
2231
2232#else
2233opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_frame_size,
2234 unsigned char *data, opus_int32 max_data_bytes)
2235{
2236 int i, ret;
2237 int frame_size;
2238 VARDECL(float, in);
2239 ALLOC_STACK;
2240
2241 frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
2242 if (frame_size <= 0)
2243 {
2244 RESTORE_STACK;
2245 return OPUS_BAD_ARG;
2246 }
2247 ALLOC(in, frame_size*st->channels, float);
2248
2249 for (i=0;i<frame_size*st->channels;i++)
2250 in[i] = (1.0f/32768)*pcm[i];
2251 ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, 16,
2252 pcm, analysis_frame_size, 0, -2, st->channels, downmix_int, 0);
2253 RESTORE_STACK;
2254 return ret;
2255}
2256opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_frame_size,
2257 unsigned char *data, opus_int32 out_data_bytes)
2258{
2259 int frame_size;
2260 frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
2261 return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 24,
2262 pcm, analysis_frame_size, 0, -2, st->channels, downmix_float, 1);
2263}
2264#endif
2265
2266
2267int opus_encoder_ctl(OpusEncoder *st, int request, ...)
2268{
2269 int ret;
2270 CELTEncoder *celt_enc;
2271 va_list ap;
2272
2273 ret = OPUS_OK;
2274 va_start(ap, request);
2275
2276 celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
2277
2278 switch (request)
2279 {
2280 case OPUS_SET_APPLICATION_REQUEST:
2281 {
2282 opus_int32 value = va_arg(ap, opus_int32);
2283 if ( (value != OPUS_APPLICATION_VOIP && value != OPUS_APPLICATION_AUDIO
2284 && value != OPUS_APPLICATION_RESTRICTED_LOWDELAY)
2285 || (!st->first && st->application != value))
2286 {
2287 ret = OPUS_BAD_ARG;
2288 break;
2289 }
2290 st->application = value;
2291#ifndef DISABLE_FLOAT_API
2292 st->analysis.application = value;
2293#endif
2294 }
2295 break;
2296 case OPUS_GET_APPLICATION_REQUEST:
2297 {
2298 opus_int32 *value = va_arg(ap, opus_int32*);
2299 if (!value)
2300 {
2301 goto bad_arg;
2302 }
2303 *value = st->application;
2304 }
2305 break;
2306 case OPUS_SET_BITRATE_REQUEST:
2307 {
2308 opus_int32 value = va_arg(ap, opus_int32);
2309 if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX)
2310 {
2311 if (value <= 0)
2312 goto bad_arg;
2313 else if (value <= 500)
2314 value = 500;
2315 else if (value > (opus_int32)300000*st->channels)
2316 value = (opus_int32)300000*st->channels;
2317 }
2318 st->user_bitrate_bps = value;
2319 }
2320 break;
2321 case OPUS_GET_BITRATE_REQUEST:
2322 {
2323 opus_int32 *value = va_arg(ap, opus_int32*);
2324 if (!value)
2325 {
2326 goto bad_arg;
2327 }
2328 *value = user_bitrate_to_bitrate(st, st->prev_framesize, 1276);
2329 }
2330 break;
2331 case OPUS_SET_FORCE_CHANNELS_REQUEST:
2332 {
2333 opus_int32 value = va_arg(ap, opus_int32);
2334 if((value<1 || value>st->channels) && value != OPUS_AUTO)
2335 {
2336 goto bad_arg;
2337 }
2338 st->force_channels = value;
2339 }
2340 break;
2341 case OPUS_GET_FORCE_CHANNELS_REQUEST:
2342 {
2343 opus_int32 *value = va_arg(ap, opus_int32*);
2344 if (!value)
2345 {
2346 goto bad_arg;
2347 }
2348 *value = st->force_channels;
2349 }
2350 break;
2351 case OPUS_SET_MAX_BANDWIDTH_REQUEST:
2352 {
2353 opus_int32 value = va_arg(ap, opus_int32);
2354 if (value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND)
2355 {
2356 goto bad_arg;
2357 }
2358 st->max_bandwidth = value;
2359 if (st->max_bandwidth == OPUS_BANDWIDTH_NARROWBAND) {
2360 st->silk_mode.maxInternalSampleRate = 8000;
2361 } else if (st->max_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {
2362 st->silk_mode.maxInternalSampleRate = 12000;
2363 } else {
2364 st->silk_mode.maxInternalSampleRate = 16000;
2365 }
2366 }
2367 break;
2368 case OPUS_GET_MAX_BANDWIDTH_REQUEST:
2369 {
2370 opus_int32 *value = va_arg(ap, opus_int32*);
2371 if (!value)
2372 {
2373 goto bad_arg;
2374 }
2375 *value = st->max_bandwidth;
2376 }
2377 break;
2378 case OPUS_SET_BANDWIDTH_REQUEST:
2379 {
2380 opus_int32 value = va_arg(ap, opus_int32);
2381 if ((value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND) && value != OPUS_AUTO)
2382 {
2383 goto bad_arg;
2384 }
2385 st->user_bandwidth = value;
2386 if (st->user_bandwidth == OPUS_BANDWIDTH_NARROWBAND) {
2387 st->silk_mode.maxInternalSampleRate = 8000;
2388 } else if (st->user_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {
2389 st->silk_mode.maxInternalSampleRate = 12000;
2390 } else {
2391 st->silk_mode.maxInternalSampleRate = 16000;
2392 }
2393 }
2394 break;
2395 case OPUS_GET_BANDWIDTH_REQUEST:
2396 {
2397 opus_int32 *value = va_arg(ap, opus_int32*);
2398 if (!value)
2399 {
2400 goto bad_arg;
2401 }
2402 *value = st->bandwidth;
2403 }
2404 break;
2405 case OPUS_SET_DTX_REQUEST:
2406 {
2407 opus_int32 value = va_arg(ap, opus_int32);
2408 if(value<0 || value>1)
2409 {
2410 goto bad_arg;
2411 }
2412 st->use_dtx = value;
2413 }
2414 break;
2415 case OPUS_GET_DTX_REQUEST:
2416 {
2417 opus_int32 *value = va_arg(ap, opus_int32*);
2418 if (!value)
2419 {
2420 goto bad_arg;
2421 }
2422 *value = st->use_dtx;
2423 }
2424 break;
2425 case OPUS_SET_COMPLEXITY_REQUEST:
2426 {
2427 opus_int32 value = va_arg(ap, opus_int32);
2428 if(value<0 || value>10)
2429 {
2430 goto bad_arg;
2431 }
2432 st->silk_mode.complexity = value;
2433 celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(value));
2434 }
2435 break;
2436 case OPUS_GET_COMPLEXITY_REQUEST:
2437 {
2438 opus_int32 *value = va_arg(ap, opus_int32*);
2439 if (!value)
2440 {
2441 goto bad_arg;
2442 }
2443 *value = st->silk_mode.complexity;
2444 }
2445 break;
2446 case OPUS_SET_INBAND_FEC_REQUEST:
2447 {
2448 opus_int32 value = va_arg(ap, opus_int32);
2449 if(value<0 || value>1)
2450 {
2451 goto bad_arg;
2452 }
2453 st->silk_mode.useInBandFEC = value;
2454 }
2455 break;
2456 case OPUS_GET_INBAND_FEC_REQUEST:
2457 {
2458 opus_int32 *value = va_arg(ap, opus_int32*);
2459 if (!value)
2460 {
2461 goto bad_arg;
2462 }
2463 *value = st->silk_mode.useInBandFEC;
2464 }
2465 break;
2466 case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
2467 {
2468 opus_int32 value = va_arg(ap, opus_int32);
2469 if (value < 0 || value > 100)
2470 {
2471 goto bad_arg;
2472 }
2473 st->silk_mode.packetLossPercentage = value;
2474 celt_encoder_ctl(celt_enc, OPUS_SET_PACKET_LOSS_PERC(value));
2475 }
2476 break;
2477 case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
2478 {
2479 opus_int32 *value = va_arg(ap, opus_int32*);
2480 if (!value)
2481 {
2482 goto bad_arg;
2483 }
2484 *value = st->silk_mode.packetLossPercentage;
2485 }
2486 break;
2487 case OPUS_SET_VBR_REQUEST:
2488 {
2489 opus_int32 value = va_arg(ap, opus_int32);
2490 if(value<0 || value>1)
2491 {
2492 goto bad_arg;
2493 }
2494 st->use_vbr = value;
2495 st->silk_mode.useCBR = 1-value;
2496 }
2497 break;
2498 case OPUS_GET_VBR_REQUEST:
2499 {
2500 opus_int32 *value = va_arg(ap, opus_int32*);
2501 if (!value)
2502 {
2503 goto bad_arg;
2504 }
2505 *value = st->use_vbr;
2506 }
2507 break;
2508 case OPUS_SET_VOICE_RATIO_REQUEST:
2509 {
2510 opus_int32 value = va_arg(ap, opus_int32);
2511 if (value<-1 || value>100)
2512 {
2513 goto bad_arg;
2514 }
2515 st->voice_ratio = value;
2516 }
2517 break;
2518 case OPUS_GET_VOICE_RATIO_REQUEST:
2519 {
2520 opus_int32 *value = va_arg(ap, opus_int32*);
2521 if (!value)
2522 {
2523 goto bad_arg;
2524 }
2525 *value = st->voice_ratio;
2526 }
2527 break;
2528 case OPUS_SET_VBR_CONSTRAINT_REQUEST:
2529 {
2530 opus_int32 value = va_arg(ap, opus_int32);
2531 if(value<0 || value>1)
2532 {
2533 goto bad_arg;
2534 }
2535 st->vbr_constraint = value;
2536 }
2537 break;
2538 case OPUS_GET_VBR_CONSTRAINT_REQUEST:
2539 {
2540 opus_int32 *value = va_arg(ap, opus_int32*);
2541 if (!value)
2542 {
2543 goto bad_arg;
2544 }
2545 *value = st->vbr_constraint;
2546 }
2547 break;
2548 case OPUS_SET_SIGNAL_REQUEST:
2549 {
2550 opus_int32 value = va_arg(ap, opus_int32);
2551 if(value!=OPUS_AUTO && value!=OPUS_SIGNAL_VOICE && value!=OPUS_SIGNAL_MUSIC)
2552 {
2553 goto bad_arg;
2554 }
2555 st->signal_type = value;
2556 }
2557 break;
2558 case OPUS_GET_SIGNAL_REQUEST:
2559 {
2560 opus_int32 *value = va_arg(ap, opus_int32*);
2561 if (!value)
2562 {
2563 goto bad_arg;
2564 }
2565 *value = st->signal_type;
2566 }
2567 break;
2568 case OPUS_GET_LOOKAHEAD_REQUEST:
2569 {
2570 opus_int32 *value = va_arg(ap, opus_int32*);
2571 if (!value)
2572 {
2573 goto bad_arg;
2574 }
2575 *value = st->Fs/400;
2576 if (st->application != OPUS_APPLICATION_RESTRICTED_LOWDELAY)
2577 *value += st->delay_compensation;
2578 }
2579 break;
2580 case OPUS_GET_SAMPLE_RATE_REQUEST:
2581 {
2582 opus_int32 *value = va_arg(ap, opus_int32*);
2583 if (!value)
2584 {
2585 goto bad_arg;
2586 }
2587 *value = st->Fs;
2588 }
2589 break;
2590 case OPUS_GET_FINAL_RANGE_REQUEST:
2591 {
2592 opus_uint32 *value = va_arg(ap, opus_uint32*);
2593 if (!value)
2594 {
2595 goto bad_arg;
2596 }
2597 *value = st->rangeFinal;
2598 }
2599 break;
2600 case OPUS_SET_LSB_DEPTH_REQUEST:
2601 {
2602 opus_int32 value = va_arg(ap, opus_int32);
2603 if (value<8 || value>24)
2604 {
2605 goto bad_arg;
2606 }
2607 st->lsb_depth=value;
2608 }
2609 break;
2610 case OPUS_GET_LSB_DEPTH_REQUEST:
2611 {
2612 opus_int32 *value = va_arg(ap, opus_int32*);
2613 if (!value)
2614 {
2615 goto bad_arg;
2616 }
2617 *value = st->lsb_depth;
2618 }
2619 break;
2620 case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
2621 {
2622 opus_int32 value = va_arg(ap, opus_int32);
2623 if (value != OPUS_FRAMESIZE_ARG && value != OPUS_FRAMESIZE_2_5_MS &&
2624 value != OPUS_FRAMESIZE_5_MS && value != OPUS_FRAMESIZE_10_MS &&
2625 value != OPUS_FRAMESIZE_20_MS && value != OPUS_FRAMESIZE_40_MS &&
2626 value != OPUS_FRAMESIZE_60_MS && value != OPUS_FRAMESIZE_80_MS &&
2627 value != OPUS_FRAMESIZE_100_MS && value != OPUS_FRAMESIZE_120_MS)
2628 {
2629 goto bad_arg;
2630 }
2631 st->variable_duration = value;
2632 }
2633 break;
2634 case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
2635 {
2636 opus_int32 *value = va_arg(ap, opus_int32*);
2637 if (!value)
2638 {
2639 goto bad_arg;
2640 }
2641 *value = st->variable_duration;
2642 }
2643 break;
2644 case OPUS_SET_PREDICTION_DISABLED_REQUEST:
2645 {
2646 opus_int32 value = va_arg(ap, opus_int32);
2647 if (value > 1 || value < 0)
2648 goto bad_arg;
2649 st->silk_mode.reducedDependency = value;
2650 }
2651 break;
2652 case OPUS_GET_PREDICTION_DISABLED_REQUEST:
2653 {
2654 opus_int32 *value = va_arg(ap, opus_int32*);
2655 if (!value)
2656 goto bad_arg;
2657 *value = st->silk_mode.reducedDependency;
2658 }
2659 break;
2660 case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
2661 {
2662 opus_int32 value = va_arg(ap, opus_int32);
2663 if(value<0 || value>1)
2664 {
2665 goto bad_arg;
2666 }
2667 celt_encoder_ctl(celt_enc, OPUS_SET_PHASE_INVERSION_DISABLED(value));
2668 }
2669 break;
2670 case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
2671 {
2672 opus_int32 *value = va_arg(ap, opus_int32*);
2673 if (!value)
2674 {
2675 goto bad_arg;
2676 }
2677 celt_encoder_ctl(celt_enc, OPUS_GET_PHASE_INVERSION_DISABLED(value));
2678 }
2679 break;
2680 case OPUS_RESET_STATE:
2681 {
2682 void *silk_enc;
2683 silk_EncControlStruct dummy;
2684 char *start;
2685 silk_enc = (char*)st+st->silk_enc_offset;
2686#ifndef DISABLE_FLOAT_API
2687 tonality_analysis_reset(&st->analysis);
2688#endif
2689
2690 start = (char*)&st->OPUS_ENCODER_RESET_START;
2691 OPUS_CLEAR(start, sizeof(OpusEncoder) - (start - (char*)st));
2692
2693 celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
2694 silk_InitEncoder( silk_enc, st->arch, &dummy );
2695 st->stream_channels = st->channels;
2696 st->hybrid_stereo_width_Q14 = 1 << 14;
2697 st->prev_HB_gain = Q15ONE;
2698 st->first = 1;
2699 st->mode = MODE_HYBRID;
2700 st->bandwidth = OPUS_BANDWIDTH_FULLBAND;
2701 st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
2702 }
2703 break;
2704 case OPUS_SET_FORCE_MODE_REQUEST:
2705 {
2706 opus_int32 value = va_arg(ap, opus_int32);
2707 if ((value < MODE_SILK_ONLY || value > MODE_CELT_ONLY) && value != OPUS_AUTO)
2708 {
2709 goto bad_arg;
2710 }
2711 st->user_forced_mode = value;
2712 }
2713 break;
2714 case OPUS_SET_LFE_REQUEST:
2715 {
2716 opus_int32 value = va_arg(ap, opus_int32);
2717 st->lfe = value;
2718 ret = celt_encoder_ctl(celt_enc, OPUS_SET_LFE(value));
2719 }
2720 break;
2721 case OPUS_SET_ENERGY_MASK_REQUEST:
2722 {
2723 opus_val16 *value = va_arg(ap, opus_val16*);
2724 st->energy_masking = value;
2725 ret = celt_encoder_ctl(celt_enc, OPUS_SET_ENERGY_MASK(value));
2726 }
2727 break;
2728
2729 case CELT_GET_MODE_REQUEST:
2730 {
2731 const CELTMode ** value = va_arg(ap, const CELTMode**);
2732 if (!value)
2733 {
2734 goto bad_arg;
2735 }
2736 ret = celt_encoder_ctl(celt_enc, CELT_GET_MODE(value));
2737 }
2738 break;
2739 default:
2740 /* fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);*/
2741 ret = OPUS_UNIMPLEMENTED;
2742 break;
2743 }
2744 va_end(ap);
2745 return ret;
2746bad_arg:
2747 va_end(ap);
2748 return OPUS_BAD_ARG;
2749}
2750
2751void opus_encoder_destroy(OpusEncoder *st)
2752{
2753 opus_free(st);
2754}
diff --git a/lib/rbcodec/codecs/libopus/opus_header.c b/lib/rbcodec/codecs/libopus/opus_header.c
index d00d4fba23..5fe5a7a4f9 100644
--- a/lib/rbcodec/codecs/libopus/opus_header.c
+++ b/lib/rbcodec/codecs/libopus/opus_header.c
@@ -44,7 +44,7 @@
44 2..254: reserved, 255: multistream with no mapping) 44 2..254: reserved, 255: multistream with no mapping)
45 45
46 - if (mapping != 0) 46 - if (mapping != 0)
47 - N = totel number of streams (8 bits) 47 - N = total number of streams (8 bits)
48 - M = number of paired streams (8 bits) 48 - M = number of paired streams (8 bits)
49 - C times channel origin 49 - C times channel origin
50 - if (C<2*M) 50 - if (C<2*M)
@@ -58,49 +58,11 @@
58*/ 58*/
59 59
60typedef struct { 60typedef struct {
61 unsigned char *data;
62 int maxlen;
63 int pos;
64} Packet;
65
66typedef struct {
67 const unsigned char *data; 61 const unsigned char *data;
68 int maxlen; 62 int maxlen;
69 int pos; 63 int pos;
70} ROPacket; 64} ROPacket;
71 65
72static int write_uint32(Packet *p, ogg_uint32_t val)
73{
74 if (p->pos>p->maxlen-4)
75 return 0;
76 p->data[p->pos ] = (val ) & 0xFF;
77 p->data[p->pos+1] = (val>> 8) & 0xFF;
78 p->data[p->pos+2] = (val>>16) & 0xFF;
79 p->data[p->pos+3] = (val>>24) & 0xFF;
80 p->pos += 4;
81 return 1;
82}
83
84static int write_uint16(Packet *p, ogg_uint16_t val)
85{
86 if (p->pos>p->maxlen-2)
87 return 0;
88 p->data[p->pos ] = (val ) & 0xFF;
89 p->data[p->pos+1] = (val>> 8) & 0xFF;
90 p->pos += 2;
91 return 1;
92}
93
94static int write_chars(Packet *p, const unsigned char *str, int nb_chars)
95{
96 int i;
97 if (p->pos>p->maxlen-nb_chars)
98 return 0;
99 for (i=0;i<nb_chars;i++)
100 p->data[p->pos++] = str[i];
101 return 1;
102}
103
104static int read_uint32(ROPacket *p, ogg_uint32_t *val) 66static int read_uint32(ROPacket *p, ogg_uint32_t *val)
105{ 67{
106 if (p->pos>p->maxlen-4) 68 if (p->pos>p->maxlen-4)
@@ -194,12 +156,28 @@ int opus_header_parse(const unsigned char *packet, int len, OpusHeader *h)
194 h->nb_coupled = ch; 156 h->nb_coupled = ch;
195 157
196 /* Multi-stream support */ 158 /* Multi-stream support */
197 for (i=0;i<h->channels;i++) 159 if (h->channel_mapping == 3)
198 { 160 {
199 if (!read_chars(&p, &h->stream_map[i], 1)) 161 int dmatrix_size = h->channels * (h->nb_streams + h->nb_coupled) * 2;
162 if (dmatrix_size > len - p.pos)
200 return 0; 163 return 0;
201 if (h->stream_map[i]>(h->nb_streams+h->nb_coupled) && h->stream_map[i]!=255) 164 if (dmatrix_size > OPUS_DEMIXING_MATRIX_SIZE_MAX)
165 p.pos += dmatrix_size;
166 else if (!read_chars(&p, h->dmatrix, dmatrix_size))
202 return 0; 167 return 0;
168 for (i=0;i<h->channels;i++) {
169 h->stream_map[i] = i;
170 }
171 }
172 else
173 {
174 for (i=0;i<h->channels;i++)
175 {
176 if (!read_chars(&p, &h->stream_map[i], 1))
177 return 0;
178 if (h->stream_map[i]>(h->nb_streams+h->nb_coupled) && h->stream_map[i]!=255)
179 return 0;
180 }
203 } 181 }
204 } else { 182 } else {
205 if(h->channels>2) 183 if(h->channels>2)
@@ -216,61 +194,6 @@ int opus_header_parse(const unsigned char *packet, int len, OpusHeader *h)
216 return 1; 194 return 1;
217} 195}
218 196
219int opus_header_to_packet(const OpusHeader *h, unsigned char *packet, int len)
220{
221 int i;
222 Packet p;
223 unsigned char ch;
224
225 p.data = packet;
226 p.maxlen = len;
227 p.pos = 0;
228 if (len<19)return 0;
229 if (!write_chars(&p, (const unsigned char*)"OpusHead", 8))
230 return 0;
231 /* Version is 1 */
232 ch = 1;
233 if (!write_chars(&p, &ch, 1))
234 return 0;
235
236 ch = h->channels;
237 if (!write_chars(&p, &ch, 1))
238 return 0;
239
240 if (!write_uint16(&p, h->preskip))
241 return 0;
242
243 if (!write_uint32(&p, h->input_sample_rate))
244 return 0;
245
246 if (!write_uint16(&p, h->gain))
247 return 0;
248
249 ch = h->channel_mapping;
250 if (!write_chars(&p, &ch, 1))
251 return 0;
252
253 if (h->channel_mapping != 0)
254 {
255 ch = h->nb_streams;
256 if (!write_chars(&p, &ch, 1))
257 return 0;
258
259 ch = h->nb_coupled;
260 if (!write_chars(&p, &ch, 1))
261 return 0;
262
263 /* Multi-stream support */
264 for (i=0;i<h->channels;i++)
265 {
266 if (!write_chars(&p, &h->stream_map[i], 1))
267 return 0;
268 }
269 }
270
271 return p.pos;
272}
273
274/* This is just here because it's a convenient file linked by both opusenc and 197/* This is just here because it's a convenient file linked by both opusenc and
275 opusdec (to guarantee this maps stays in sync). */ 198 opusdec (to guarantee this maps stays in sync). */
276const int wav_permute_matrix[8][8] = 199const int wav_permute_matrix[8][8] =
diff --git a/lib/rbcodec/codecs/libopus/opus_header.h b/lib/rbcodec/codecs/libopus/opus_header.h
index 7bfacfe48c..2d97d0739c 100644
--- a/lib/rbcodec/codecs/libopus/opus_header.h
+++ b/lib/rbcodec/codecs/libopus/opus_header.h
@@ -30,6 +30,8 @@
30 30
31#include "ogg/ogg.h" 31#include "ogg/ogg.h"
32 32
33#define OPUS_DEMIXING_MATRIX_SIZE_MAX (18 * 18 * 2)
34
33typedef struct { 35typedef struct {
34 int version; 36 int version;
35 int channels; /* Number of channels: 1..255 */ 37 int channels; /* Number of channels: 1..255 */
@@ -41,10 +43,10 @@ typedef struct {
41 int nb_streams; 43 int nb_streams;
42 int nb_coupled; 44 int nb_coupled;
43 unsigned char stream_map[255]; 45 unsigned char stream_map[255];
46 unsigned char dmatrix[OPUS_DEMIXING_MATRIX_SIZE_MAX];
44} OpusHeader; 47} OpusHeader;
45 48
46int opus_header_parse(const unsigned char *header, int len, OpusHeader *h); 49int opus_header_parse(const unsigned char *header, int len, OpusHeader *h);
47int opus_header_to_packet(const OpusHeader *h, unsigned char *packet, int len);
48 50
49extern const int wav_permute_matrix[8][8]; 51extern const int wav_permute_matrix[8][8];
50 52
diff --git a/lib/rbcodec/codecs/libopus/opus_multistream.c b/lib/rbcodec/codecs/libopus/opus_multistream.c
new file mode 100644
index 0000000000..09c3639b7f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/opus_multistream.c
@@ -0,0 +1,92 @@
1/* Copyright (c) 2011 Xiph.Org Foundation
2 Written by Jean-Marc Valin */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "opus_multistream.h"
33#include "opus.h"
34#include "opus_private.h"
35#include "stack_alloc.h"
36#include <stdarg.h>
37#include "float_cast.h"
38#include "os_support.h"
39
40
41int validate_layout(const ChannelLayout *layout)
42{
43 int i, max_channel;
44
45 max_channel = layout->nb_streams+layout->nb_coupled_streams;
46 if (max_channel>255)
47 return 0;
48 for (i=0;i<layout->nb_channels;i++)
49 {
50 if (layout->mapping[i] >= max_channel && layout->mapping[i] != 255)
51 return 0;
52 }
53 return 1;
54}
55
56
57int get_left_channel(const ChannelLayout *layout, int stream_id, int prev)
58{
59 int i;
60 i = (prev<0) ? 0 : prev+1;
61 for (;i<layout->nb_channels;i++)
62 {
63 if (layout->mapping[i]==stream_id*2)
64 return i;
65 }
66 return -1;
67}
68
69int get_right_channel(const ChannelLayout *layout, int stream_id, int prev)
70{
71 int i;
72 i = (prev<0) ? 0 : prev+1;
73 for (;i<layout->nb_channels;i++)
74 {
75 if (layout->mapping[i]==stream_id*2+1)
76 return i;
77 }
78 return -1;
79}
80
81int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev)
82{
83 int i;
84 i = (prev<0) ? 0 : prev+1;
85 for (;i<layout->nb_channels;i++)
86 {
87 if (layout->mapping[i]==stream_id+layout->nb_coupled_streams)
88 return i;
89 }
90 return -1;
91}
92
diff --git a/lib/rbcodec/codecs/libopus/opus_multistream.h b/lib/rbcodec/codecs/libopus/opus_multistream.h
new file mode 100644
index 0000000000..babcee6905
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/opus_multistream.h
@@ -0,0 +1,660 @@
1/* Copyright (c) 2011 Xiph.Org Foundation
2 Written by Jean-Marc Valin */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28/**
29 * @file opus_multistream.h
30 * @brief Opus reference implementation multistream API
31 */
32
33#ifndef OPUS_MULTISTREAM_H
34#define OPUS_MULTISTREAM_H
35
36#include "opus.h"
37
38#ifdef __cplusplus
39extern "C" {
40#endif
41
42/** @cond OPUS_INTERNAL_DOC */
43
44/** Macros to trigger compilation errors when the wrong types are provided to a
45 * CTL. */
46/**@{*/
47#define __opus_check_encstate_ptr(ptr) ((ptr) + ((ptr) - (OpusEncoder**)(ptr)))
48#define __opus_check_decstate_ptr(ptr) ((ptr) + ((ptr) - (OpusDecoder**)(ptr)))
49/**@}*/
50
51/** These are the actual encoder and decoder CTL ID numbers.
52 * They should not be used directly by applications.
53 * In general, SETs should be even and GETs should be odd.*/
54/**@{*/
55#define OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST 5120
56#define OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST 5122
57/**@}*/
58
59/** @endcond */
60
61/** @defgroup opus_multistream_ctls Multistream specific encoder and decoder CTLs
62 *
63 * These are convenience macros that are specific to the
64 * opus_multistream_encoder_ctl() and opus_multistream_decoder_ctl()
65 * interface.
66 * The CTLs from @ref opus_genericctls, @ref opus_encoderctls, and
67 * @ref opus_decoderctls may be applied to a multistream encoder or decoder as
68 * well.
69 * In addition, you may retrieve the encoder or decoder state for an specific
70 * stream via #OPUS_MULTISTREAM_GET_ENCODER_STATE or
71 * #OPUS_MULTISTREAM_GET_DECODER_STATE and apply CTLs to it individually.
72 */
73/**@{*/
74
75/** Gets the encoder state for an individual stream of a multistream encoder.
76 * @param[in] x <tt>opus_int32</tt>: The index of the stream whose encoder you
77 * wish to retrieve.
78 * This must be non-negative and less than
79 * the <code>streams</code> parameter used
80 * to initialize the encoder.
81 * @param[out] y <tt>OpusEncoder**</tt>: Returns a pointer to the given
82 * encoder state.
83 * @retval OPUS_BAD_ARG The index of the requested stream was out of range.
84 * @hideinitializer
85 */
86#define OPUS_MULTISTREAM_GET_ENCODER_STATE(x,y) OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, __opus_check_int(x), __opus_check_encstate_ptr(y)
87
88/** Gets the decoder state for an individual stream of a multistream decoder.
89 * @param[in] x <tt>opus_int32</tt>: The index of the stream whose decoder you
90 * wish to retrieve.
91 * This must be non-negative and less than
92 * the <code>streams</code> parameter used
93 * to initialize the decoder.
94 * @param[out] y <tt>OpusDecoder**</tt>: Returns a pointer to the given
95 * decoder state.
96 * @retval OPUS_BAD_ARG The index of the requested stream was out of range.
97 * @hideinitializer
98 */
99#define OPUS_MULTISTREAM_GET_DECODER_STATE(x,y) OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST, __opus_check_int(x), __opus_check_decstate_ptr(y)
100
101/**@}*/
102
103/** @defgroup opus_multistream Opus Multistream API
104 * @{
105 *
106 * The multistream API allows individual Opus streams to be combined into a
107 * single packet, enabling support for up to 255 channels. Unlike an
108 * elementary Opus stream, the encoder and decoder must negotiate the channel
109 * configuration before the decoder can successfully interpret the data in the
110 * packets produced by the encoder. Some basic information, such as packet
111 * duration, can be computed without any special negotiation.
112 *
113 * The format for multistream Opus packets is defined in
114 * <a href="https://tools.ietf.org/html/rfc7845">RFC 7845</a>
115 * and is based on the self-delimited Opus framing described in Appendix B of
116 * <a href="https://tools.ietf.org/html/rfc6716">RFC 6716</a>.
117 * Normal Opus packets are just a degenerate case of multistream Opus packets,
118 * and can be encoded or decoded with the multistream API by setting
119 * <code>streams</code> to <code>1</code> when initializing the encoder or
120 * decoder.
121 *
122 * Multistream Opus streams can contain up to 255 elementary Opus streams.
123 * These may be either "uncoupled" or "coupled", indicating that the decoder
124 * is configured to decode them to either 1 or 2 channels, respectively.
125 * The streams are ordered so that all coupled streams appear at the
126 * beginning.
127 *
128 * A <code>mapping</code> table defines which decoded channel <code>i</code>
129 * should be used for each input/output (I/O) channel <code>j</code>. This table is
130 * typically provided as an unsigned char array.
131 * Let <code>i = mapping[j]</code> be the index for I/O channel <code>j</code>.
132 * If <code>i < 2*coupled_streams</code>, then I/O channel <code>j</code> is
133 * encoded as the left channel of stream <code>(i/2)</code> if <code>i</code>
134 * is even, or as the right channel of stream <code>(i/2)</code> if
135 * <code>i</code> is odd. Otherwise, I/O channel <code>j</code> is encoded as
136 * mono in stream <code>(i - coupled_streams)</code>, unless it has the special
137 * value 255, in which case it is omitted from the encoding entirely (the
138 * decoder will reproduce it as silence). Each value <code>i</code> must either
139 * be the special value 255 or be less than <code>streams + coupled_streams</code>.
140 *
141 * The output channels specified by the encoder
142 * should use the
143 * <a href="https://www.xiph.org/vorbis/doc/Vorbis_I_spec.html#x1-810004.3.9">Vorbis
144 * channel ordering</a>. A decoder may wish to apply an additional permutation
145 * to the mapping the encoder used to achieve a different output channel
146 * order (e.g. for outputing in WAV order).
147 *
148 * Each multistream packet contains an Opus packet for each stream, and all of
149 * the Opus packets in a single multistream packet must have the same
150 * duration. Therefore the duration of a multistream packet can be extracted
151 * from the TOC sequence of the first stream, which is located at the
152 * beginning of the packet, just like an elementary Opus stream:
153 *
154 * @code
155 * int nb_samples;
156 * int nb_frames;
157 * nb_frames = opus_packet_get_nb_frames(data, len);
158 * if (nb_frames < 1)
159 * return nb_frames;
160 * nb_samples = opus_packet_get_samples_per_frame(data, 48000) * nb_frames;
161 * @endcode
162 *
163 * The general encoding and decoding process proceeds exactly the same as in
164 * the normal @ref opus_encoder and @ref opus_decoder APIs.
165 * See their documentation for an overview of how to use the corresponding
166 * multistream functions.
167 */
168
169/** Opus multistream encoder state.
170 * This contains the complete state of a multistream Opus encoder.
171 * It is position independent and can be freely copied.
172 * @see opus_multistream_encoder_create
173 * @see opus_multistream_encoder_init
174 */
175typedef struct OpusMSEncoder OpusMSEncoder;
176
177/** Opus multistream decoder state.
178 * This contains the complete state of a multistream Opus decoder.
179 * It is position independent and can be freely copied.
180 * @see opus_multistream_decoder_create
181 * @see opus_multistream_decoder_init
182 */
183typedef struct OpusMSDecoder OpusMSDecoder;
184
185/**\name Multistream encoder functions */
186/**@{*/
187
188/** Gets the size of an OpusMSEncoder structure.
189 * @param streams <tt>int</tt>: The total number of streams to encode from the
190 * input.
191 * This must be no more than 255.
192 * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
193 * to encode.
194 * This must be no larger than the total
195 * number of streams.
196 * Additionally, The total number of
197 * encoded channels (<code>streams +
198 * coupled_streams</code>) must be no
199 * more than 255.
200 * @returns The size in bytes on success, or a negative error code
201 * (see @ref opus_errorcodes) on error.
202 */
203OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_encoder_get_size(
204 int streams,
205 int coupled_streams
206);
207
208OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_surround_encoder_get_size(
209 int channels,
210 int mapping_family
211);
212
213
214/** Allocates and initializes a multistream encoder state.
215 * Call opus_multistream_encoder_destroy() to release
216 * this object when finished.
217 * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
218 * This must be one of 8000, 12000, 16000,
219 * 24000, or 48000.
220 * @param channels <tt>int</tt>: Number of channels in the input signal.
221 * This must be at most 255.
222 * It may be greater than the number of
223 * coded channels (<code>streams +
224 * coupled_streams</code>).
225 * @param streams <tt>int</tt>: The total number of streams to encode from the
226 * input.
227 * This must be no more than the number of channels.
228 * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
229 * to encode.
230 * This must be no larger than the total
231 * number of streams.
232 * Additionally, The total number of
233 * encoded channels (<code>streams +
234 * coupled_streams</code>) must be no
235 * more than the number of input channels.
236 * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
237 * encoded channels to input channels, as described in
238 * @ref opus_multistream. As an extra constraint, the
239 * multistream encoder does not allow encoding coupled
240 * streams for which one channel is unused since this
241 * is never a good idea.
242 * @param application <tt>int</tt>: The target encoder application.
243 * This must be one of the following:
244 * <dl>
245 * <dt>#OPUS_APPLICATION_VOIP</dt>
246 * <dd>Process signal for improved speech intelligibility.</dd>
247 * <dt>#OPUS_APPLICATION_AUDIO</dt>
248 * <dd>Favor faithfulness to the original input.</dd>
249 * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
250 * <dd>Configure the minimum possible coding delay by disabling certain modes
251 * of operation.</dd>
252 * </dl>
253 * @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error
254 * code (see @ref opus_errorcodes) on
255 * failure.
256 */
257OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_encoder_create(
258 opus_int32 Fs,
259 int channels,
260 int streams,
261 int coupled_streams,
262 const unsigned char *mapping,
263 int application,
264 int *error
265) OPUS_ARG_NONNULL(5);
266
267OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_surround_encoder_create(
268 opus_int32 Fs,
269 int channels,
270 int mapping_family,
271 int *streams,
272 int *coupled_streams,
273 unsigned char *mapping,
274 int application,
275 int *error
276) OPUS_ARG_NONNULL(4) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6);
277
278/** Initialize a previously allocated multistream encoder state.
279 * The memory pointed to by \a st must be at least the size returned by
280 * opus_multistream_encoder_get_size().
281 * This is intended for applications which use their own allocator instead of
282 * malloc.
283 * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
284 * @see opus_multistream_encoder_create
285 * @see opus_multistream_encoder_get_size
286 * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to initialize.
287 * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
288 * This must be one of 8000, 12000, 16000,
289 * 24000, or 48000.
290 * @param channels <tt>int</tt>: Number of channels in the input signal.
291 * This must be at most 255.
292 * It may be greater than the number of
293 * coded channels (<code>streams +
294 * coupled_streams</code>).
295 * @param streams <tt>int</tt>: The total number of streams to encode from the
296 * input.
297 * This must be no more than the number of channels.
298 * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
299 * to encode.
300 * This must be no larger than the total
301 * number of streams.
302 * Additionally, The total number of
303 * encoded channels (<code>streams +
304 * coupled_streams</code>) must be no
305 * more than the number of input channels.
306 * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
307 * encoded channels to input channels, as described in
308 * @ref opus_multistream. As an extra constraint, the
309 * multistream encoder does not allow encoding coupled
310 * streams for which one channel is unused since this
311 * is never a good idea.
312 * @param application <tt>int</tt>: The target encoder application.
313 * This must be one of the following:
314 * <dl>
315 * <dt>#OPUS_APPLICATION_VOIP</dt>
316 * <dd>Process signal for improved speech intelligibility.</dd>
317 * <dt>#OPUS_APPLICATION_AUDIO</dt>
318 * <dd>Favor faithfulness to the original input.</dd>
319 * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
320 * <dd>Configure the minimum possible coding delay by disabling certain modes
321 * of operation.</dd>
322 * </dl>
323 * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
324 * on failure.
325 */
326OPUS_EXPORT int opus_multistream_encoder_init(
327 OpusMSEncoder *st,
328 opus_int32 Fs,
329 int channels,
330 int streams,
331 int coupled_streams,
332 const unsigned char *mapping,
333 int application
334) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
335
336OPUS_EXPORT int opus_multistream_surround_encoder_init(
337 OpusMSEncoder *st,
338 opus_int32 Fs,
339 int channels,
340 int mapping_family,
341 int *streams,
342 int *coupled_streams,
343 unsigned char *mapping,
344 int application
345) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6) OPUS_ARG_NONNULL(7);
346
347/** Encodes a multistream Opus frame.
348 * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
349 * @param[in] pcm <tt>const opus_int16*</tt>: The input signal as interleaved
350 * samples.
351 * This must contain
352 * <code>frame_size*channels</code>
353 * samples.
354 * @param frame_size <tt>int</tt>: Number of samples per channel in the input
355 * signal.
356 * This must be an Opus frame size for the
357 * encoder's sampling rate.
358 * For example, at 48 kHz the permitted values
359 * are 120, 240, 480, 960, 1920, and 2880.
360 * Passing in a duration of less than 10 ms
361 * (480 samples at 48 kHz) will prevent the
362 * encoder from using the LPC or hybrid modes.
363 * @param[out] data <tt>unsigned char*</tt>: Output payload.
364 * This must contain storage for at
365 * least \a max_data_bytes.
366 * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
367 * memory for the output
368 * payload. This may be
369 * used to impose an upper limit on
370 * the instant bitrate, but should
371 * not be used as the only bitrate
372 * control. Use #OPUS_SET_BITRATE to
373 * control the bitrate.
374 * @returns The length of the encoded packet (in bytes) on success or a
375 * negative error code (see @ref opus_errorcodes) on failure.
376 */
377OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode(
378 OpusMSEncoder *st,
379 const opus_int16 *pcm,
380 int frame_size,
381 unsigned char *data,
382 opus_int32 max_data_bytes
383) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
384
385/** Encodes a multistream Opus frame from floating point input.
386 * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
387 * @param[in] pcm <tt>const float*</tt>: The input signal as interleaved
388 * samples with a normal range of
389 * +/-1.0.
390 * Samples with a range beyond +/-1.0
391 * are supported but will be clipped by
392 * decoders using the integer API and
393 * should only be used if it is known
394 * that the far end supports extended
395 * dynamic range.
396 * This must contain
397 * <code>frame_size*channels</code>
398 * samples.
399 * @param frame_size <tt>int</tt>: Number of samples per channel in the input
400 * signal.
401 * This must be an Opus frame size for the
402 * encoder's sampling rate.
403 * For example, at 48 kHz the permitted values
404 * are 120, 240, 480, 960, 1920, and 2880.
405 * Passing in a duration of less than 10 ms
406 * (480 samples at 48 kHz) will prevent the
407 * encoder from using the LPC or hybrid modes.
408 * @param[out] data <tt>unsigned char*</tt>: Output payload.
409 * This must contain storage for at
410 * least \a max_data_bytes.
411 * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
412 * memory for the output
413 * payload. This may be
414 * used to impose an upper limit on
415 * the instant bitrate, but should
416 * not be used as the only bitrate
417 * control. Use #OPUS_SET_BITRATE to
418 * control the bitrate.
419 * @returns The length of the encoded packet (in bytes) on success or a
420 * negative error code (see @ref opus_errorcodes) on failure.
421 */
422OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode_float(
423 OpusMSEncoder *st,
424 const float *pcm,
425 int frame_size,
426 unsigned char *data,
427 opus_int32 max_data_bytes
428) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
429
430/** Frees an <code>OpusMSEncoder</code> allocated by
431 * opus_multistream_encoder_create().
432 * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to be freed.
433 */
434OPUS_EXPORT void opus_multistream_encoder_destroy(OpusMSEncoder *st);
435
436/** Perform a CTL function on a multistream Opus encoder.
437 *
438 * Generally the request and subsequent arguments are generated by a
439 * convenience macro.
440 * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
441 * @param request This and all remaining parameters should be replaced by one
442 * of the convenience macros in @ref opus_genericctls,
443 * @ref opus_encoderctls, or @ref opus_multistream_ctls.
444 * @see opus_genericctls
445 * @see opus_encoderctls
446 * @see opus_multistream_ctls
447 */
448OPUS_EXPORT int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) OPUS_ARG_NONNULL(1);
449
450/**@}*/
451
452/**\name Multistream decoder functions */
453/**@{*/
454
455/** Gets the size of an <code>OpusMSDecoder</code> structure.
456 * @param streams <tt>int</tt>: The total number of streams coded in the
457 * input.
458 * This must be no more than 255.
459 * @param coupled_streams <tt>int</tt>: Number streams to decode as coupled
460 * (2 channel) streams.
461 * This must be no larger than the total
462 * number of streams.
463 * Additionally, The total number of
464 * coded channels (<code>streams +
465 * coupled_streams</code>) must be no
466 * more than 255.
467 * @returns The size in bytes on success, or a negative error code
468 * (see @ref opus_errorcodes) on error.
469 */
470OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_decoder_get_size(
471 int streams,
472 int coupled_streams
473);
474
475/** Allocates and initializes a multistream decoder state.
476 * Call opus_multistream_decoder_destroy() to release
477 * this object when finished.
478 * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
479 * This must be one of 8000, 12000, 16000,
480 * 24000, or 48000.
481 * @param channels <tt>int</tt>: Number of channels to output.
482 * This must be at most 255.
483 * It may be different from the number of coded
484 * channels (<code>streams +
485 * coupled_streams</code>).
486 * @param streams <tt>int</tt>: The total number of streams coded in the
487 * input.
488 * This must be no more than 255.
489 * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
490 * (2 channel) streams.
491 * This must be no larger than the total
492 * number of streams.
493 * Additionally, The total number of
494 * coded channels (<code>streams +
495 * coupled_streams</code>) must be no
496 * more than 255.
497 * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
498 * coded channels to output channels, as described in
499 * @ref opus_multistream.
500 * @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error
501 * code (see @ref opus_errorcodes) on
502 * failure.
503 */
504OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSDecoder *opus_multistream_decoder_create(
505 opus_int32 Fs,
506 int channels,
507 int streams,
508 int coupled_streams,
509 const unsigned char *mapping,
510 int *error
511) OPUS_ARG_NONNULL(5);
512
513/** Intialize a previously allocated decoder state object.
514 * The memory pointed to by \a st must be at least the size returned by
515 * opus_multistream_encoder_get_size().
516 * This is intended for applications which use their own allocator instead of
517 * malloc.
518 * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
519 * @see opus_multistream_decoder_create
520 * @see opus_multistream_deocder_get_size
521 * @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state to initialize.
522 * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
523 * This must be one of 8000, 12000, 16000,
524 * 24000, or 48000.
525 * @param channels <tt>int</tt>: Number of channels to output.
526 * This must be at most 255.
527 * It may be different from the number of coded
528 * channels (<code>streams +
529 * coupled_streams</code>).
530 * @param streams <tt>int</tt>: The total number of streams coded in the
531 * input.
532 * This must be no more than 255.
533 * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
534 * (2 channel) streams.
535 * This must be no larger than the total
536 * number of streams.
537 * Additionally, The total number of
538 * coded channels (<code>streams +
539 * coupled_streams</code>) must be no
540 * more than 255.
541 * @param[in] mapping <code>const unsigned char[channels]</code>: Mapping from
542 * coded channels to output channels, as described in
543 * @ref opus_multistream.
544 * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
545 * on failure.
546 */
547OPUS_EXPORT int opus_multistream_decoder_init(
548 OpusMSDecoder *st,
549 opus_int32 Fs,
550 int channels,
551 int streams,
552 int coupled_streams,
553 const unsigned char *mapping
554) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
555
556/** Decode a multistream Opus packet.
557 * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
558 * @param[in] data <tt>const unsigned char*</tt>: Input payload.
559 * Use a <code>NULL</code>
560 * pointer to indicate packet
561 * loss.
562 * @param len <tt>opus_int32</tt>: Number of bytes in payload.
563 * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
564 * samples.
565 * This must contain room for
566 * <code>frame_size*channels</code>
567 * samples.
568 * @param frame_size <tt>int</tt>: The number of samples per channel of
569 * available space in \a pcm.
570 * If this is less than the maximum packet duration
571 * (120 ms; 5760 for 48kHz), this function will not be capable
572 * of decoding some packets. In the case of PLC (data==NULL)
573 * or FEC (decode_fec=1), then frame_size needs to be exactly
574 * the duration of audio that is missing, otherwise the
575 * decoder will not be in the optimal state to decode the
576 * next incoming packet. For the PLC and FEC cases, frame_size
577 * <b>must</b> be a multiple of 2.5 ms.
578 * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
579 * forward error correction data be decoded.
580 * If no such data is available, the frame is
581 * decoded as if it were lost.
582 * @returns Number of samples decoded on success or a negative error code
583 * (see @ref opus_errorcodes) on failure.
584 */
585OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode(
586 OpusMSDecoder *st,
587 const unsigned char *data,
588 opus_int32 len,
589 opus_int16 *pcm,
590 int frame_size,
591 int decode_fec
592) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
593
594/** Decode a multistream Opus packet with floating point output.
595 * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
596 * @param[in] data <tt>const unsigned char*</tt>: Input payload.
597 * Use a <code>NULL</code>
598 * pointer to indicate packet
599 * loss.
600 * @param len <tt>opus_int32</tt>: Number of bytes in payload.
601 * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
602 * samples.
603 * This must contain room for
604 * <code>frame_size*channels</code>
605 * samples.
606 * @param frame_size <tt>int</tt>: The number of samples per channel of
607 * available space in \a pcm.
608 * If this is less than the maximum packet duration
609 * (120 ms; 5760 for 48kHz), this function will not be capable
610 * of decoding some packets. In the case of PLC (data==NULL)
611 * or FEC (decode_fec=1), then frame_size needs to be exactly
612 * the duration of audio that is missing, otherwise the
613 * decoder will not be in the optimal state to decode the
614 * next incoming packet. For the PLC and FEC cases, frame_size
615 * <b>must</b> be a multiple of 2.5 ms.
616 * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
617 * forward error correction data be decoded.
618 * If no such data is available, the frame is
619 * decoded as if it were lost.
620 * @returns Number of samples decoded on success or a negative error code
621 * (see @ref opus_errorcodes) on failure.
622 */
623OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode_float(
624 OpusMSDecoder *st,
625 const unsigned char *data,
626 opus_int32 len,
627 float *pcm,
628 int frame_size,
629 int decode_fec
630) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
631
632/** Perform a CTL function on a multistream Opus decoder.
633 *
634 * Generally the request and subsequent arguments are generated by a
635 * convenience macro.
636 * @param st <tt>OpusMSDecoder*</tt>: Multistream decoder state.
637 * @param request This and all remaining parameters should be replaced by one
638 * of the convenience macros in @ref opus_genericctls,
639 * @ref opus_decoderctls, or @ref opus_multistream_ctls.
640 * @see opus_genericctls
641 * @see opus_decoderctls
642 * @see opus_multistream_ctls
643 */
644OPUS_EXPORT int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) OPUS_ARG_NONNULL(1);
645
646/** Frees an <code>OpusMSDecoder</code> allocated by
647 * opus_multistream_decoder_create().
648 * @param st <tt>OpusMSDecoder</tt>: Multistream decoder state to be freed.
649 */
650OPUS_EXPORT void opus_multistream_decoder_destroy(OpusMSDecoder *st);
651
652/**@}*/
653
654/**@}*/
655
656#ifdef __cplusplus
657}
658#endif
659
660#endif /* OPUS_MULTISTREAM_H */
diff --git a/lib/rbcodec/codecs/libopus/opus_multistream_decoder.c b/lib/rbcodec/codecs/libopus/opus_multistream_decoder.c
new file mode 100644
index 0000000000..562103cd0a
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/opus_multistream_decoder.c
@@ -0,0 +1,549 @@
1/* Copyright (c) 2011 Xiph.Org Foundation
2 Written by Jean-Marc Valin */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "opus_multistream.h"
33#include "opus.h"
34#include "opus_private.h"
35#include "stack_alloc.h"
36#include <stdarg.h>
37#include "float_cast.h"
38#include "os_support.h"
39
40/* DECODER */
41
42#if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)
43static void validate_ms_decoder(OpusMSDecoder *st)
44{
45 validate_layout(&st->layout);
46}
47#define VALIDATE_MS_DECODER(st) validate_ms_decoder(st)
48#else
49#define VALIDATE_MS_DECODER(st)
50#endif
51
52
53opus_int32 opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams)
54{
55 int coupled_size;
56 int mono_size;
57
58 if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
59 coupled_size = opus_decoder_get_size(2);
60 mono_size = opus_decoder_get_size(1);
61 return align(sizeof(OpusMSDecoder))
62 + nb_coupled_streams * align(coupled_size)
63 + (nb_streams-nb_coupled_streams) * align(mono_size);
64}
65
66int opus_multistream_decoder_init(
67 OpusMSDecoder *st,
68 opus_int32 Fs,
69 int channels,
70 int streams,
71 int coupled_streams,
72 const unsigned char *mapping
73)
74{
75 int coupled_size;
76 int mono_size;
77 int i, ret;
78 char *ptr;
79
80 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
81 (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))
82 return OPUS_BAD_ARG;
83
84 st->layout.nb_channels = channels;
85 st->layout.nb_streams = streams;
86 st->layout.nb_coupled_streams = coupled_streams;
87
88 for (i=0;i<st->layout.nb_channels;i++)
89 st->layout.mapping[i] = mapping[i];
90 if (!validate_layout(&st->layout))
91 return OPUS_BAD_ARG;
92
93 ptr = (char*)st + align(sizeof(OpusMSDecoder));
94 coupled_size = opus_decoder_get_size(2);
95 mono_size = opus_decoder_get_size(1);
96
97 for (i=0;i<st->layout.nb_coupled_streams;i++)
98 {
99 ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 2);
100 if(ret!=OPUS_OK)return ret;
101 ptr += align(coupled_size);
102 }
103 for (;i<st->layout.nb_streams;i++)
104 {
105 ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 1);
106 if(ret!=OPUS_OK)return ret;
107 ptr += align(mono_size);
108 }
109 return OPUS_OK;
110}
111
112
113OpusMSDecoder *opus_multistream_decoder_create(
114 opus_int32 Fs,
115 int channels,
116 int streams,
117 int coupled_streams,
118 const unsigned char *mapping,
119 int *error
120)
121{
122 int ret;
123 OpusMSDecoder *st;
124 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
125 (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))
126 {
127 if (error)
128 *error = OPUS_BAD_ARG;
129 return NULL;
130 }
131 st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams));
132 if (st==NULL)
133 {
134 if (error)
135 *error = OPUS_ALLOC_FAIL;
136 return NULL;
137 }
138 ret = opus_multistream_decoder_init(st, Fs, channels, streams, coupled_streams, mapping);
139 if (error)
140 *error = ret;
141 if (ret != OPUS_OK)
142 {
143 opus_free(st);
144 st = NULL;
145 }
146 return st;
147}
148
149static int opus_multistream_packet_validate(const unsigned char *data,
150 opus_int32 len, int nb_streams, opus_int32 Fs)
151{
152 int s;
153 int count;
154 unsigned char toc;
155 opus_int16 size[48];
156 int samples=0;
157 opus_int32 packet_offset;
158
159 for (s=0;s<nb_streams;s++)
160 {
161 int tmp_samples;
162 if (len<=0)
163 return OPUS_INVALID_PACKET;
164 count = opus_packet_parse_impl(data, len, s!=nb_streams-1, &toc, NULL,
165 size, NULL, &packet_offset);
166 if (count<0)
167 return count;
168 tmp_samples = opus_packet_get_nb_samples(data, packet_offset, Fs);
169 if (s!=0 && samples != tmp_samples)
170 return OPUS_INVALID_PACKET;
171 samples = tmp_samples;
172 data += packet_offset;
173 len -= packet_offset;
174 }
175 return samples;
176}
177
178int opus_multistream_decode_native(
179 OpusMSDecoder *st,
180 const unsigned char *data,
181 opus_int32 len,
182 void *pcm,
183 opus_copy_channel_out_func copy_channel_out,
184 int frame_size,
185 int decode_fec,
186 int soft_clip,
187 void *user_data
188)
189{
190 opus_int32 Fs;
191 int coupled_size;
192 int mono_size;
193 int s, c;
194 char *ptr;
195 int do_plc=0;
196 VARDECL(opus_val16, buf);
197 ALLOC_STACK;
198
199 VALIDATE_MS_DECODER(st);
200 if (frame_size <= 0)
201 {
202 RESTORE_STACK;
203 return OPUS_BAD_ARG;
204 }
205 /* Limit frame_size to avoid excessive stack allocations. */
206 MUST_SUCCEED(opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs)));
207 frame_size = IMIN(frame_size, Fs/25*3);
208 ALLOC(buf, 2*frame_size, opus_val16);
209 ptr = (char*)st + align(sizeof(OpusMSDecoder));
210 coupled_size = opus_decoder_get_size(2);
211 mono_size = opus_decoder_get_size(1);
212
213 if (len==0)
214 do_plc = 1;
215 if (len < 0)
216 {
217 RESTORE_STACK;
218 return OPUS_BAD_ARG;
219 }
220 if (!do_plc && len < 2*st->layout.nb_streams-1)
221 {
222 RESTORE_STACK;
223 return OPUS_INVALID_PACKET;
224 }
225 if (!do_plc)
226 {
227 int ret = opus_multistream_packet_validate(data, len, st->layout.nb_streams, Fs);
228 if (ret < 0)
229 {
230 RESTORE_STACK;
231 return ret;
232 } else if (ret > frame_size)
233 {
234 RESTORE_STACK;
235 return OPUS_BUFFER_TOO_SMALL;
236 }
237 }
238 for (s=0;s<st->layout.nb_streams;s++)
239 {
240 OpusDecoder *dec;
241 opus_int32 packet_offset;
242 int ret;
243
244 dec = (OpusDecoder*)ptr;
245 ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size);
246
247 if (!do_plc && len<=0)
248 {
249 RESTORE_STACK;
250 return OPUS_INTERNAL_ERROR;
251 }
252 packet_offset = 0;
253 ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset, soft_clip);
254 data += packet_offset;
255 len -= packet_offset;
256 if (ret <= 0)
257 {
258 RESTORE_STACK;
259 return ret;
260 }
261 frame_size = ret;
262 if (s < st->layout.nb_coupled_streams)
263 {
264 int chan, prev;
265 prev = -1;
266 /* Copy "left" audio to the channel(s) where it belongs */
267 while ( (chan = get_left_channel(&st->layout, s, prev)) != -1)
268 {
269 (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
270 buf, 2, frame_size, user_data);
271 prev = chan;
272 }
273 prev = -1;
274 /* Copy "right" audio to the channel(s) where it belongs */
275 while ( (chan = get_right_channel(&st->layout, s, prev)) != -1)
276 {
277 (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
278 buf+1, 2, frame_size, user_data);
279 prev = chan;
280 }
281 } else {
282 int chan, prev;
283 prev = -1;
284 /* Copy audio to the channel(s) where it belongs */
285 while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1)
286 {
287 (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
288 buf, 1, frame_size, user_data);
289 prev = chan;
290 }
291 }
292 }
293 /* Handle muted channels */
294 for (c=0;c<st->layout.nb_channels;c++)
295 {
296 if (st->layout.mapping[c] == 255)
297 {
298 (*copy_channel_out)(pcm, st->layout.nb_channels, c,
299 NULL, 0, frame_size, user_data);
300 }
301 }
302 RESTORE_STACK;
303 return frame_size;
304}
305
306#if !defined(DISABLE_FLOAT_API)
307static void opus_copy_channel_out_float(
308 void *dst,
309 int dst_stride,
310 int dst_channel,
311 const opus_val16 *src,
312 int src_stride,
313 int frame_size,
314 void *user_data
315)
316{
317 float *float_dst;
318 opus_int32 i;
319 (void)user_data;
320 float_dst = (float*)dst;
321 if (src != NULL)
322 {
323 for (i=0;i<frame_size;i++)
324#if defined(FIXED_POINT)
325 float_dst[i*dst_stride+dst_channel] = (1/32768.f)*src[i*src_stride];
326#else
327 float_dst[i*dst_stride+dst_channel] = src[i*src_stride];
328#endif
329 }
330 else
331 {
332 for (i=0;i<frame_size;i++)
333 float_dst[i*dst_stride+dst_channel] = 0;
334 }
335}
336#endif
337
338static void opus_copy_channel_out_short(
339 void *dst,
340 int dst_stride,
341 int dst_channel,
342 const opus_val16 *src,
343 int src_stride,
344 int frame_size,
345 void *user_data
346)
347{
348 opus_int16 *short_dst;
349 opus_int32 i;
350 (void)user_data;
351 short_dst = (opus_int16*)dst;
352 if (src != NULL)
353 {
354 for (i=0;i<frame_size;i++)
355#if defined(FIXED_POINT)
356 short_dst[i*dst_stride+dst_channel] = src[i*src_stride];
357#else
358 short_dst[i*dst_stride+dst_channel] = FLOAT2INT16(src[i*src_stride]);
359#endif
360 }
361 else
362 {
363 for (i=0;i<frame_size;i++)
364 short_dst[i*dst_stride+dst_channel] = 0;
365 }
366}
367
368
369
370#ifdef FIXED_POINT
371int opus_multistream_decode(
372 OpusMSDecoder *st,
373 const unsigned char *data,
374 opus_int32 len,
375 opus_int16 *pcm,
376 int frame_size,
377 int decode_fec
378)
379{
380 return opus_multistream_decode_native(st, data, len,
381 pcm, opus_copy_channel_out_short, frame_size, decode_fec, 0, NULL);
382}
383
384#ifndef DISABLE_FLOAT_API
385int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data,
386 opus_int32 len, float *pcm, int frame_size, int decode_fec)
387{
388 return opus_multistream_decode_native(st, data, len,
389 pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0, NULL);
390}
391#endif
392
393#else
394
395int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data,
396 opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
397{
398 return opus_multistream_decode_native(st, data, len,
399 pcm, opus_copy_channel_out_short, frame_size, decode_fec, 1, NULL);
400}
401
402int opus_multistream_decode_float(
403 OpusMSDecoder *st,
404 const unsigned char *data,
405 opus_int32 len,
406 opus_val16 *pcm,
407 int frame_size,
408 int decode_fec
409)
410{
411 return opus_multistream_decode_native(st, data, len,
412 pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0, NULL);
413}
414#endif
415
416int opus_multistream_decoder_ctl_va_list(OpusMSDecoder *st, int request,
417 va_list ap)
418{
419 int coupled_size, mono_size;
420 char *ptr;
421 int ret = OPUS_OK;
422
423 coupled_size = opus_decoder_get_size(2);
424 mono_size = opus_decoder_get_size(1);
425 ptr = (char*)st + align(sizeof(OpusMSDecoder));
426 switch (request)
427 {
428 case OPUS_GET_BANDWIDTH_REQUEST:
429 case OPUS_GET_SAMPLE_RATE_REQUEST:
430 case OPUS_GET_GAIN_REQUEST:
431 case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
432 case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
433 {
434 OpusDecoder *dec;
435 /* For int32* GET params, just query the first stream */
436 opus_int32 *value = va_arg(ap, opus_int32*);
437 dec = (OpusDecoder*)ptr;
438 ret = opus_decoder_ctl(dec, request, value);
439 }
440 break;
441 case OPUS_GET_FINAL_RANGE_REQUEST:
442 {
443 int s;
444 opus_uint32 *value = va_arg(ap, opus_uint32*);
445 opus_uint32 tmp;
446 if (!value)
447 {
448 goto bad_arg;
449 }
450 *value = 0;
451 for (s=0;s<st->layout.nb_streams;s++)
452 {
453 OpusDecoder *dec;
454 dec = (OpusDecoder*)ptr;
455 if (s < st->layout.nb_coupled_streams)
456 ptr += align(coupled_size);
457 else
458 ptr += align(mono_size);
459 ret = opus_decoder_ctl(dec, request, &tmp);
460 if (ret != OPUS_OK) break;
461 *value ^= tmp;
462 }
463 }
464 break;
465 case OPUS_RESET_STATE:
466 {
467 int s;
468 for (s=0;s<st->layout.nb_streams;s++)
469 {
470 OpusDecoder *dec;
471
472 dec = (OpusDecoder*)ptr;
473 if (s < st->layout.nb_coupled_streams)
474 ptr += align(coupled_size);
475 else
476 ptr += align(mono_size);
477 ret = opus_decoder_ctl(dec, OPUS_RESET_STATE);
478 if (ret != OPUS_OK)
479 break;
480 }
481 }
482 break;
483 case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST:
484 {
485 int s;
486 opus_int32 stream_id;
487 OpusDecoder **value;
488 stream_id = va_arg(ap, opus_int32);
489 if (stream_id<0 || stream_id >= st->layout.nb_streams)
490 ret = OPUS_BAD_ARG;
491 value = va_arg(ap, OpusDecoder**);
492 if (!value)
493 {
494 goto bad_arg;
495 }
496 for (s=0;s<stream_id;s++)
497 {
498 if (s < st->layout.nb_coupled_streams)
499 ptr += align(coupled_size);
500 else
501 ptr += align(mono_size);
502 }
503 *value = (OpusDecoder*)ptr;
504 }
505 break;
506 case OPUS_SET_GAIN_REQUEST:
507 case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
508 {
509 int s;
510 /* This works for int32 params */
511 opus_int32 value = va_arg(ap, opus_int32);
512 for (s=0;s<st->layout.nb_streams;s++)
513 {
514 OpusDecoder *dec;
515
516 dec = (OpusDecoder*)ptr;
517 if (s < st->layout.nb_coupled_streams)
518 ptr += align(coupled_size);
519 else
520 ptr += align(mono_size);
521 ret = opus_decoder_ctl(dec, request, value);
522 if (ret != OPUS_OK)
523 break;
524 }
525 }
526 break;
527 default:
528 ret = OPUS_UNIMPLEMENTED;
529 break;
530 }
531 return ret;
532bad_arg:
533 return OPUS_BAD_ARG;
534}
535
536int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
537{
538 int ret;
539 va_list ap;
540 va_start(ap, request);
541 ret = opus_multistream_decoder_ctl_va_list(st, request, ap);
542 va_end(ap);
543 return ret;
544}
545
546void opus_multistream_decoder_destroy(OpusMSDecoder *st)
547{
548 opus_free(st);
549}
diff --git a/lib/rbcodec/codecs/libopus/opus_multistream_encoder.c b/lib/rbcodec/codecs/libopus/opus_multistream_encoder.c
new file mode 100644
index 0000000000..9cb9bf3458
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/opus_multistream_encoder.c
@@ -0,0 +1,1328 @@
1/* Copyright (c) 2011 Xiph.Org Foundation
2 Written by Jean-Marc Valin */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "opus_multistream.h"
33#include "opus.h"
34#include "opus_private.h"
35#include "stack_alloc.h"
36#include <stdarg.h>
37#include "float_cast.h"
38#include "os_support.h"
39#include "mathops.h"
40#include "mdct.h"
41#include "modes.h"
42#include "bands.h"
43#include "quant_bands.h"
44#include "pitch.h"
45
46typedef struct {
47 int nb_streams;
48 int nb_coupled_streams;
49 unsigned char mapping[8];
50} VorbisLayout;
51
52/* Index is nb_channel-1*/
53static const VorbisLayout vorbis_mappings[8] = {
54 {1, 0, {0}}, /* 1: mono */
55 {1, 1, {0, 1}}, /* 2: stereo */
56 {2, 1, {0, 2, 1}}, /* 3: 1-d surround */
57 {2, 2, {0, 1, 2, 3}}, /* 4: quadraphonic surround */
58 {3, 2, {0, 4, 1, 2, 3}}, /* 5: 5-channel surround */
59 {4, 2, {0, 4, 1, 2, 3, 5}}, /* 6: 5.1 surround */
60 {4, 3, {0, 4, 1, 2, 3, 5, 6}}, /* 7: 6.1 surround */
61 {5, 3, {0, 6, 1, 2, 3, 4, 5, 7}}, /* 8: 7.1 surround */
62};
63
64static opus_val32 *ms_get_preemph_mem(OpusMSEncoder *st)
65{
66 int s;
67 char *ptr;
68 int coupled_size, mono_size;
69
70 coupled_size = opus_encoder_get_size(2);
71 mono_size = opus_encoder_get_size(1);
72 ptr = (char*)st + align(sizeof(OpusMSEncoder));
73 for (s=0;s<st->layout.nb_streams;s++)
74 {
75 if (s < st->layout.nb_coupled_streams)
76 ptr += align(coupled_size);
77 else
78 ptr += align(mono_size);
79 }
80 /* void* cast avoids clang -Wcast-align warning */
81 return (opus_val32*)(void*)(ptr+st->layout.nb_channels*120*sizeof(opus_val32));
82}
83
84static opus_val32 *ms_get_window_mem(OpusMSEncoder *st)
85{
86 int s;
87 char *ptr;
88 int coupled_size, mono_size;
89
90 coupled_size = opus_encoder_get_size(2);
91 mono_size = opus_encoder_get_size(1);
92 ptr = (char*)st + align(sizeof(OpusMSEncoder));
93 for (s=0;s<st->layout.nb_streams;s++)
94 {
95 if (s < st->layout.nb_coupled_streams)
96 ptr += align(coupled_size);
97 else
98 ptr += align(mono_size);
99 }
100 /* void* cast avoids clang -Wcast-align warning */
101 return (opus_val32*)(void*)ptr;
102}
103
104static int validate_ambisonics(int nb_channels, int *nb_streams, int *nb_coupled_streams)
105{
106 int order_plus_one;
107 int acn_channels;
108 int nondiegetic_channels;
109
110 if (nb_channels < 1 || nb_channels > 227)
111 return 0;
112
113 order_plus_one = isqrt32(nb_channels);
114 acn_channels = order_plus_one * order_plus_one;
115 nondiegetic_channels = nb_channels - acn_channels;
116
117 if (nondiegetic_channels != 0 && nondiegetic_channels != 2)
118 return 0;
119
120 if (nb_streams)
121 *nb_streams = acn_channels + (nondiegetic_channels != 0);
122 if (nb_coupled_streams)
123 *nb_coupled_streams = nondiegetic_channels != 0;
124 return 1;
125}
126
127static int validate_encoder_layout(const ChannelLayout *layout)
128{
129 int s;
130 for (s=0;s<layout->nb_streams;s++)
131 {
132 if (s < layout->nb_coupled_streams)
133 {
134 if (get_left_channel(layout, s, -1)==-1)
135 return 0;
136 if (get_right_channel(layout, s, -1)==-1)
137 return 0;
138 } else {
139 if (get_mono_channel(layout, s, -1)==-1)
140 return 0;
141 }
142 }
143 return 1;
144}
145
146static void channel_pos(int channels, int pos[8])
147{
148 /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */
149 if (channels==4)
150 {
151 pos[0]=1;
152 pos[1]=3;
153 pos[2]=1;
154 pos[3]=3;
155 } else if (channels==3||channels==5||channels==6)
156 {
157 pos[0]=1;
158 pos[1]=2;
159 pos[2]=3;
160 pos[3]=1;
161 pos[4]=3;
162 pos[5]=0;
163 } else if (channels==7)
164 {
165 pos[0]=1;
166 pos[1]=2;
167 pos[2]=3;
168 pos[3]=1;
169 pos[4]=3;
170 pos[5]=2;
171 pos[6]=0;
172 } else if (channels==8)
173 {
174 pos[0]=1;
175 pos[1]=2;
176 pos[2]=3;
177 pos[3]=1;
178 pos[4]=3;
179 pos[5]=1;
180 pos[6]=3;
181 pos[7]=0;
182 }
183}
184
185#if 1
186/* Computes a rough approximation of log2(2^a + 2^b) */
187static opus_val16 logSum(opus_val16 a, opus_val16 b)
188{
189 opus_val16 max;
190 opus_val32 diff;
191 opus_val16 frac;
192 static const opus_val16 diff_table[17] = {
193 QCONST16(0.5000000f, DB_SHIFT), QCONST16(0.2924813f, DB_SHIFT), QCONST16(0.1609640f, DB_SHIFT), QCONST16(0.0849625f, DB_SHIFT),
194 QCONST16(0.0437314f, DB_SHIFT), QCONST16(0.0221971f, DB_SHIFT), QCONST16(0.0111839f, DB_SHIFT), QCONST16(0.0056136f, DB_SHIFT),
195 QCONST16(0.0028123f, DB_SHIFT)
196 };
197 int low;
198 if (a>b)
199 {
200 max = a;
201 diff = SUB32(EXTEND32(a),EXTEND32(b));
202 } else {
203 max = b;
204 diff = SUB32(EXTEND32(b),EXTEND32(a));
205 }
206 if (!(diff < QCONST16(8.f, DB_SHIFT))) /* inverted to catch NaNs */
207 return max;
208#ifdef FIXED_POINT
209 low = SHR32(diff, DB_SHIFT-1);
210 frac = SHL16(diff - SHL16(low, DB_SHIFT-1), 16-DB_SHIFT);
211#else
212 low = (int)floor(2*diff);
213 frac = 2*diff - low;
214#endif
215 return max + diff_table[low] + MULT16_16_Q15(frac, SUB16(diff_table[low+1], diff_table[low]));
216}
217#else
218opus_val16 logSum(opus_val16 a, opus_val16 b)
219{
220 return log2(pow(4, a)+ pow(4, b))/2;
221}
222#endif
223
224void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *bandLogE, opus_val32 *mem, opus_val32 *preemph_mem,
225 int len, int overlap, int channels, int rate, opus_copy_channel_in_func copy_channel_in, int arch
226)
227{
228 int c;
229 int i;
230 int LM;
231 int pos[8] = {0};
232 int upsample;
233 int frame_size;
234 int freq_size;
235 opus_val16 channel_offset;
236 opus_val32 bandE[21];
237 opus_val16 maskLogE[3][21];
238 VARDECL(opus_val32, in);
239 VARDECL(opus_val16, x);
240 VARDECL(opus_val32, freq);
241 SAVE_STACK;
242
243 upsample = resampling_factor(rate);
244 frame_size = len*upsample;
245 freq_size = IMIN(960, frame_size);
246
247 /* LM = log2(frame_size / 120) */
248 for (LM=0;LM<celt_mode->maxLM;LM++)
249 if (celt_mode->shortMdctSize<<LM==frame_size)
250 break;
251
252 ALLOC(in, frame_size+overlap, opus_val32);
253 ALLOC(x, len, opus_val16);
254 ALLOC(freq, freq_size, opus_val32);
255
256 channel_pos(channels, pos);
257
258 for (c=0;c<3;c++)
259 for (i=0;i<21;i++)
260 maskLogE[c][i] = -QCONST16(28.f, DB_SHIFT);
261
262 for (c=0;c<channels;c++)
263 {
264 int frame;
265 int nb_frames = frame_size/freq_size;
266 celt_assert(nb_frames*freq_size == frame_size);
267 OPUS_COPY(in, mem+c*overlap, overlap);
268 (*copy_channel_in)(x, 1, pcm, channels, c, len, NULL);
269 celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0);
270#ifndef FIXED_POINT
271 {
272 opus_val32 sum;
273 sum = celt_inner_prod(in, in, frame_size+overlap, 0);
274 /* This should filter out both NaNs and ridiculous signals that could
275 cause NaNs further down. */
276 if (!(sum < 1e18f) || celt_isnan(sum))
277 {
278 OPUS_CLEAR(in, frame_size+overlap);
279 preemph_mem[c] = 0;
280 }
281 }
282#endif
283 OPUS_CLEAR(bandE, 21);
284 for (frame=0;frame<nb_frames;frame++)
285 {
286 opus_val32 tmpE[21];
287 clt_mdct_forward(&celt_mode->mdct, in+960*frame, freq, celt_mode->window,
288 overlap, celt_mode->maxLM-LM, 1, arch);
289 if (upsample != 1)
290 {
291 int bound = freq_size/upsample;
292 for (i=0;i<bound;i++)
293 freq[i] *= upsample;
294 for (;i<freq_size;i++)
295 freq[i] = 0;
296 }
297
298 compute_band_energies(celt_mode, freq, tmpE, 21, 1, LM, arch);
299 /* If we have multiple frames, take the max energy. */
300 for (i=0;i<21;i++)
301 bandE[i] = MAX32(bandE[i], tmpE[i]);
302 }
303 amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1);
304 /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */
305 for (i=1;i<21;i++)
306 bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i-1]-QCONST16(1.f, DB_SHIFT));
307 for (i=19;i>=0;i--)
308 bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i+1]-QCONST16(2.f, DB_SHIFT));
309 if (pos[c]==1)
310 {
311 for (i=0;i<21;i++)
312 maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]);
313 } else if (pos[c]==3)
314 {
315 for (i=0;i<21;i++)
316 maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]);
317 } else if (pos[c]==2)
318 {
319 for (i=0;i<21;i++)
320 {
321 maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT));
322 maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT));
323 }
324 }
325#if 0
326 for (i=0;i<21;i++)
327 printf("%f ", bandLogE[21*c+i]);
328 float sum=0;
329 for (i=0;i<21;i++)
330 sum += bandLogE[21*c+i];
331 printf("%f ", sum/21);
332#endif
333 OPUS_COPY(mem+c*overlap, in+frame_size, overlap);
334 }
335 for (i=0;i<21;i++)
336 maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]);
337 channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1)));
338 for (c=0;c<3;c++)
339 for (i=0;i<21;i++)
340 maskLogE[c][i] += channel_offset;
341#if 0
342 for (c=0;c<3;c++)
343 {
344 for (i=0;i<21;i++)
345 printf("%f ", maskLogE[c][i]);
346 }
347#endif
348 for (c=0;c<channels;c++)
349 {
350 opus_val16 *mask;
351 if (pos[c]!=0)
352 {
353 mask = &maskLogE[pos[c]-1][0];
354 for (i=0;i<21;i++)
355 bandLogE[21*c+i] = bandLogE[21*c+i] - mask[i];
356 } else {
357 for (i=0;i<21;i++)
358 bandLogE[21*c+i] = 0;
359 }
360#if 0
361 for (i=0;i<21;i++)
362 printf("%f ", bandLogE[21*c+i]);
363 printf("\n");
364#endif
365#if 0
366 float sum=0;
367 for (i=0;i<21;i++)
368 sum += bandLogE[21*c+i];
369 printf("%f ", sum/(float)QCONST32(21.f, DB_SHIFT));
370 printf("\n");
371#endif
372 }
373 RESTORE_STACK;
374}
375
376opus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams)
377{
378 int coupled_size;
379 int mono_size;
380
381 if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
382 coupled_size = opus_encoder_get_size(2);
383 mono_size = opus_encoder_get_size(1);
384 return align(sizeof(OpusMSEncoder))
385 + nb_coupled_streams * align(coupled_size)
386 + (nb_streams-nb_coupled_streams) * align(mono_size);
387}
388
389opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_family)
390{
391 int nb_streams;
392 int nb_coupled_streams;
393 opus_int32 size;
394
395 if (mapping_family==0)
396 {
397 if (channels==1)
398 {
399 nb_streams=1;
400 nb_coupled_streams=0;
401 } else if (channels==2)
402 {
403 nb_streams=1;
404 nb_coupled_streams=1;
405 } else
406 return 0;
407 } else if (mapping_family==1 && channels<=8 && channels>=1)
408 {
409 nb_streams=vorbis_mappings[channels-1].nb_streams;
410 nb_coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
411 } else if (mapping_family==255)
412 {
413 nb_streams=channels;
414 nb_coupled_streams=0;
415 } else if (mapping_family==2)
416 {
417 if (!validate_ambisonics(channels, &nb_streams, &nb_coupled_streams))
418 return 0;
419 } else
420 return 0;
421 size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
422 if (channels>2)
423 {
424 size += channels*(120*sizeof(opus_val32) + sizeof(opus_val32));
425 }
426 return size;
427}
428
429static int opus_multistream_encoder_init_impl(
430 OpusMSEncoder *st,
431 opus_int32 Fs,
432 int channels,
433 int streams,
434 int coupled_streams,
435 const unsigned char *mapping,
436 int application,
437 MappingType mapping_type
438)
439{
440 int coupled_size;
441 int mono_size;
442 int i, ret;
443 char *ptr;
444
445 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
446 (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))
447 return OPUS_BAD_ARG;
448
449 st->arch = opus_select_arch();
450 st->layout.nb_channels = channels;
451 st->layout.nb_streams = streams;
452 st->layout.nb_coupled_streams = coupled_streams;
453 if (mapping_type != MAPPING_TYPE_SURROUND)
454 st->lfe_stream = -1;
455 st->bitrate_bps = OPUS_AUTO;
456 st->application = application;
457 st->variable_duration = OPUS_FRAMESIZE_ARG;
458 for (i=0;i<st->layout.nb_channels;i++)
459 st->layout.mapping[i] = mapping[i];
460 if (!validate_layout(&st->layout))
461 return OPUS_BAD_ARG;
462 if (mapping_type == MAPPING_TYPE_SURROUND &&
463 !validate_encoder_layout(&st->layout))
464 return OPUS_BAD_ARG;
465 if (mapping_type == MAPPING_TYPE_AMBISONICS &&
466 !validate_ambisonics(st->layout.nb_channels, NULL, NULL))
467 return OPUS_BAD_ARG;
468 ptr = (char*)st + align(sizeof(OpusMSEncoder));
469 coupled_size = opus_encoder_get_size(2);
470 mono_size = opus_encoder_get_size(1);
471
472 for (i=0;i<st->layout.nb_coupled_streams;i++)
473 {
474 ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);
475 if(ret!=OPUS_OK)return ret;
476 if (i==st->lfe_stream)
477 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
478 ptr += align(coupled_size);
479 }
480 for (;i<st->layout.nb_streams;i++)
481 {
482 ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);
483 if (i==st->lfe_stream)
484 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
485 if(ret!=OPUS_OK)return ret;
486 ptr += align(mono_size);
487 }
488 if (mapping_type == MAPPING_TYPE_SURROUND)
489 {
490 OPUS_CLEAR(ms_get_preemph_mem(st), channels);
491 OPUS_CLEAR(ms_get_window_mem(st), channels*120);
492 }
493 st->mapping_type = mapping_type;
494 return OPUS_OK;
495}
496
497int opus_multistream_encoder_init(
498 OpusMSEncoder *st,
499 opus_int32 Fs,
500 int channels,
501 int streams,
502 int coupled_streams,
503 const unsigned char *mapping,
504 int application
505)
506{
507 return opus_multistream_encoder_init_impl(st, Fs, channels, streams,
508 coupled_streams, mapping,
509 application, MAPPING_TYPE_NONE);
510}
511
512int opus_multistream_surround_encoder_init(
513 OpusMSEncoder *st,
514 opus_int32 Fs,
515 int channels,
516 int mapping_family,
517 int *streams,
518 int *coupled_streams,
519 unsigned char *mapping,
520 int application
521)
522{
523 MappingType mapping_type;
524
525 if ((channels>255) || (channels<1))
526 return OPUS_BAD_ARG;
527 st->lfe_stream = -1;
528 if (mapping_family==0)
529 {
530 if (channels==1)
531 {
532 *streams=1;
533 *coupled_streams=0;
534 mapping[0]=0;
535 } else if (channels==2)
536 {
537 *streams=1;
538 *coupled_streams=1;
539 mapping[0]=0;
540 mapping[1]=1;
541 } else
542 return OPUS_UNIMPLEMENTED;
543 } else if (mapping_family==1 && channels<=8 && channels>=1)
544 {
545 int i;
546 *streams=vorbis_mappings[channels-1].nb_streams;
547 *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
548 for (i=0;i<channels;i++)
549 mapping[i] = vorbis_mappings[channels-1].mapping[i];
550 if (channels>=6)
551 st->lfe_stream = *streams-1;
552 } else if (mapping_family==255)
553 {
554 int i;
555 *streams=channels;
556 *coupled_streams=0;
557 for(i=0;i<channels;i++)
558 mapping[i] = i;
559 } else if (mapping_family==2)
560 {
561 int i;
562 if (!validate_ambisonics(channels, streams, coupled_streams))
563 return OPUS_BAD_ARG;
564 for(i = 0; i < (*streams - *coupled_streams); i++)
565 mapping[i] = i + (*coupled_streams * 2);
566 for(i = 0; i < *coupled_streams * 2; i++)
567 mapping[i + (*streams - *coupled_streams)] = i;
568 } else
569 return OPUS_UNIMPLEMENTED;
570
571 if (channels>2 && mapping_family==1) {
572 mapping_type = MAPPING_TYPE_SURROUND;
573 } else if (mapping_family==2)
574 {
575 mapping_type = MAPPING_TYPE_AMBISONICS;
576 } else
577 {
578 mapping_type = MAPPING_TYPE_NONE;
579 }
580 return opus_multistream_encoder_init_impl(st, Fs, channels, *streams,
581 *coupled_streams, mapping,
582 application, mapping_type);
583}
584
585OpusMSEncoder *opus_multistream_encoder_create(
586 opus_int32 Fs,
587 int channels,
588 int streams,
589 int coupled_streams,
590 const unsigned char *mapping,
591 int application,
592 int *error
593)
594{
595 int ret;
596 OpusMSEncoder *st;
597 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
598 (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))
599 {
600 if (error)
601 *error = OPUS_BAD_ARG;
602 return NULL;
603 }
604 st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
605 if (st==NULL)
606 {
607 if (error)
608 *error = OPUS_ALLOC_FAIL;
609 return NULL;
610 }
611 ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application);
612 if (ret != OPUS_OK)
613 {
614 opus_free(st);
615 st = NULL;
616 }
617 if (error)
618 *error = ret;
619 return st;
620}
621
622OpusMSEncoder *opus_multistream_surround_encoder_create(
623 opus_int32 Fs,
624 int channels,
625 int mapping_family,
626 int *streams,
627 int *coupled_streams,
628 unsigned char *mapping,
629 int application,
630 int *error
631)
632{
633 int ret;
634 opus_int32 size;
635 OpusMSEncoder *st;
636 if ((channels>255) || (channels<1))
637 {
638 if (error)
639 *error = OPUS_BAD_ARG;
640 return NULL;
641 }
642 size = opus_multistream_surround_encoder_get_size(channels, mapping_family);
643 if (!size)
644 {
645 if (error)
646 *error = OPUS_UNIMPLEMENTED;
647 return NULL;
648 }
649 st = (OpusMSEncoder *)opus_alloc(size);
650 if (st==NULL)
651 {
652 if (error)
653 *error = OPUS_ALLOC_FAIL;
654 return NULL;
655 }
656 ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application);
657 if (ret != OPUS_OK)
658 {
659 opus_free(st);
660 st = NULL;
661 }
662 if (error)
663 *error = ret;
664 return st;
665}
666
667static void surround_rate_allocation(
668 OpusMSEncoder *st,
669 opus_int32 *rate,
670 int frame_size,
671 opus_int32 Fs
672 )
673{
674 int i;
675 opus_int32 channel_rate;
676 int stream_offset;
677 int lfe_offset;
678 int coupled_ratio; /* Q8 */
679 int lfe_ratio; /* Q8 */
680 int nb_lfe;
681 int nb_uncoupled;
682 int nb_coupled;
683 int nb_normal;
684 opus_int32 channel_offset;
685 opus_int32 bitrate;
686 int total;
687
688 nb_lfe = (st->lfe_stream!=-1);
689 nb_coupled = st->layout.nb_coupled_streams;
690 nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
691 nb_normal = 2*nb_coupled + nb_uncoupled;
692
693 /* Give each non-LFE channel enough bits per channel for coding band energy. */
694 channel_offset = 40*IMAX(50, Fs/frame_size);
695
696 if (st->bitrate_bps==OPUS_AUTO)
697 {
698 bitrate = nb_normal*(channel_offset + Fs + 10000) + 8000*nb_lfe;
699 } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
700 {
701 bitrate = nb_normal*300000 + nb_lfe*128000;
702 } else {
703 bitrate = st->bitrate_bps;
704 }
705
706 /* Give LFE some basic stream_channel allocation but never exceed 1/20 of the
707 total rate for the non-energy part to avoid problems at really low rate. */
708 lfe_offset = IMIN(bitrate/20, 3000) + 15*IMAX(50, Fs/frame_size);
709
710 /* We give each stream (coupled or uncoupled) a starting bitrate.
711 This models the main saving of coupled channels over uncoupled. */
712 stream_offset = (bitrate - channel_offset*nb_normal - lfe_offset*nb_lfe)/nb_normal/2;
713 stream_offset = IMAX(0, IMIN(20000, stream_offset));
714
715 /* Coupled streams get twice the mono rate after the offset is allocated. */
716 coupled_ratio = 512;
717 /* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of mono */
718 lfe_ratio = 32;
719
720 total = (nb_uncoupled<<8) /* mono */
721 + coupled_ratio*nb_coupled /* stereo */
722 + nb_lfe*lfe_ratio;
723 channel_rate = 256*(opus_int64)(bitrate - lfe_offset*nb_lfe - stream_offset*(nb_coupled+nb_uncoupled) - channel_offset*nb_normal)/total;
724
725 for (i=0;i<st->layout.nb_streams;i++)
726 {
727 if (i<st->layout.nb_coupled_streams)
728 rate[i] = 2*channel_offset + IMAX(0, stream_offset+(channel_rate*coupled_ratio>>8));
729 else if (i!=st->lfe_stream)
730 rate[i] = channel_offset + IMAX(0, stream_offset + channel_rate);
731 else
732 rate[i] = IMAX(0, lfe_offset+(channel_rate*lfe_ratio>>8));
733 }
734}
735
736static void ambisonics_rate_allocation(
737 OpusMSEncoder *st,
738 opus_int32 *rate,
739 int frame_size,
740 opus_int32 Fs
741 )
742{
743 int i;
744 opus_int32 total_rate;
745 opus_int32 per_stream_rate;
746
747 const int nb_channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
748
749 if (st->bitrate_bps==OPUS_AUTO)
750 {
751 total_rate = (st->layout.nb_coupled_streams + st->layout.nb_streams) *
752 (Fs+60*Fs/frame_size) + st->layout.nb_streams * (opus_int32)15000;
753 } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
754 {
755 total_rate = nb_channels * 320000;
756 } else
757 {
758 total_rate = st->bitrate_bps;
759 }
760
761 /* Allocate equal number of bits to Ambisonic (uncoupled) and non-diegetic
762 * (coupled) streams */
763 per_stream_rate = total_rate / st->layout.nb_streams;
764 for (i = 0; i < st->layout.nb_streams; i++)
765 {
766 rate[i] = per_stream_rate;
767 }
768}
769
770static opus_int32 rate_allocation(
771 OpusMSEncoder *st,
772 opus_int32 *rate,
773 int frame_size
774 )
775{
776 int i;
777 opus_int32 rate_sum=0;
778 opus_int32 Fs;
779 char *ptr;
780
781 ptr = (char*)st + align(sizeof(OpusMSEncoder));
782 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
783
784 if (st->mapping_type == MAPPING_TYPE_AMBISONICS) {
785 ambisonics_rate_allocation(st, rate, frame_size, Fs);
786 } else
787 {
788 surround_rate_allocation(st, rate, frame_size, Fs);
789 }
790
791 for (i=0;i<st->layout.nb_streams;i++)
792 {
793 rate[i] = IMAX(rate[i], 500);
794 rate_sum += rate[i];
795 }
796 return rate_sum;
797}
798
799/* Max size in case the encoder decides to return six frames (6 x 20 ms = 120 ms) */
800#define MS_FRAME_TMP (6*1275+12)
801int opus_multistream_encode_native
802(
803 OpusMSEncoder *st,
804 opus_copy_channel_in_func copy_channel_in,
805 const void *pcm,
806 int analysis_frame_size,
807 unsigned char *data,
808 opus_int32 max_data_bytes,
809 int lsb_depth,
810 downmix_func downmix,
811 int float_api,
812 void *user_data
813)
814{
815 opus_int32 Fs;
816 int coupled_size;
817 int mono_size;
818 int s;
819 char *ptr;
820 int tot_size;
821 VARDECL(opus_val16, buf);
822 VARDECL(opus_val16, bandSMR);
823 unsigned char tmp_data[MS_FRAME_TMP];
824 OpusRepacketizer rp;
825 opus_int32 vbr;
826 const CELTMode *celt_mode;
827 opus_int32 bitrates[256];
828 opus_val16 bandLogE[42];
829 opus_val32 *mem = NULL;
830 opus_val32 *preemph_mem=NULL;
831 int frame_size;
832 opus_int32 rate_sum;
833 opus_int32 smallest_packet;
834 ALLOC_STACK;
835
836 if (st->mapping_type == MAPPING_TYPE_SURROUND)
837 {
838 preemph_mem = ms_get_preemph_mem(st);
839 mem = ms_get_window_mem(st);
840 }
841
842 ptr = (char*)st + align(sizeof(OpusMSEncoder));
843 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
844 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr));
845 opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
846
847 frame_size = frame_size_select(analysis_frame_size, st->variable_duration, Fs);
848 if (frame_size <= 0)
849 {
850 RESTORE_STACK;
851 return OPUS_BAD_ARG;
852 }
853
854 /* Smallest packet the encoder can produce. */
855 smallest_packet = st->layout.nb_streams*2-1;
856 /* 100 ms needs an extra byte per stream for the ToC. */
857 if (Fs/frame_size == 10)
858 smallest_packet += st->layout.nb_streams;
859 if (max_data_bytes < smallest_packet)
860 {
861 RESTORE_STACK;
862 return OPUS_BUFFER_TOO_SMALL;
863 }
864 ALLOC(buf, 2*frame_size, opus_val16);
865 coupled_size = opus_encoder_get_size(2);
866 mono_size = opus_encoder_get_size(1);
867
868 ALLOC(bandSMR, 21*st->layout.nb_channels, opus_val16);
869 if (st->mapping_type == MAPPING_TYPE_SURROUND)
870 {
871 surround_analysis(celt_mode, pcm, bandSMR, mem, preemph_mem, frame_size, 120, st->layout.nb_channels, Fs, copy_channel_in, st->arch);
872 }
873
874 /* Compute bitrate allocation between streams (this could be a lot better) */
875 rate_sum = rate_allocation(st, bitrates, frame_size);
876
877 if (!vbr)
878 {
879 if (st->bitrate_bps == OPUS_AUTO)
880 {
881 max_data_bytes = IMIN(max_data_bytes, 3*rate_sum/(3*8*Fs/frame_size));
882 } else if (st->bitrate_bps != OPUS_BITRATE_MAX)
883 {
884 max_data_bytes = IMIN(max_data_bytes, IMAX(smallest_packet,
885 3*st->bitrate_bps/(3*8*Fs/frame_size)));
886 }
887 }
888 ptr = (char*)st + align(sizeof(OpusMSEncoder));
889 for (s=0;s<st->layout.nb_streams;s++)
890 {
891 OpusEncoder *enc;
892 enc = (OpusEncoder*)ptr;
893 if (s < st->layout.nb_coupled_streams)
894 ptr += align(coupled_size);
895 else
896 ptr += align(mono_size);
897 opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s]));
898 if (st->mapping_type == MAPPING_TYPE_SURROUND)
899 {
900 opus_int32 equiv_rate;
901 equiv_rate = st->bitrate_bps;
902 if (frame_size*50 < Fs)
903 equiv_rate -= 60*(Fs/frame_size - 50)*st->layout.nb_channels;
904 if (equiv_rate > 10000*st->layout.nb_channels)
905 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
906 else if (equiv_rate > 7000*st->layout.nb_channels)
907 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));
908 else if (equiv_rate > 5000*st->layout.nb_channels)
909 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND));
910 else
911 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
912 if (s < st->layout.nb_coupled_streams)
913 {
914 /* To preserve the spatial image, force stereo CELT on coupled streams */
915 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
916 opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
917 }
918 }
919 else if (st->mapping_type == MAPPING_TYPE_AMBISONICS) {
920 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
921 }
922 }
923
924 ptr = (char*)st + align(sizeof(OpusMSEncoder));
925 /* Counting ToC */
926 tot_size = 0;
927 for (s=0;s<st->layout.nb_streams;s++)
928 {
929 OpusEncoder *enc;
930 int len;
931 int curr_max;
932 int c1, c2;
933 int ret;
934
935 opus_repacketizer_init(&rp);
936 enc = (OpusEncoder*)ptr;
937 if (s < st->layout.nb_coupled_streams)
938 {
939 int i;
940 int left, right;
941 left = get_left_channel(&st->layout, s, -1);
942 right = get_right_channel(&st->layout, s, -1);
943 (*copy_channel_in)(buf, 2,
944 pcm, st->layout.nb_channels, left, frame_size, user_data);
945 (*copy_channel_in)(buf+1, 2,
946 pcm, st->layout.nb_channels, right, frame_size, user_data);
947 ptr += align(coupled_size);
948 if (st->mapping_type == MAPPING_TYPE_SURROUND)
949 {
950 for (i=0;i<21;i++)
951 {
952 bandLogE[i] = bandSMR[21*left+i];
953 bandLogE[21+i] = bandSMR[21*right+i];
954 }
955 }
956 c1 = left;
957 c2 = right;
958 } else {
959 int i;
960 int chan = get_mono_channel(&st->layout, s, -1);
961 (*copy_channel_in)(buf, 1,
962 pcm, st->layout.nb_channels, chan, frame_size, user_data);
963 ptr += align(mono_size);
964 if (st->mapping_type == MAPPING_TYPE_SURROUND)
965 {
966 for (i=0;i<21;i++)
967 bandLogE[i] = bandSMR[21*chan+i];
968 }
969 c1 = chan;
970 c2 = -1;
971 }
972 if (st->mapping_type == MAPPING_TYPE_SURROUND)
973 opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE));
974 /* number of bytes left (+Toc) */
975 curr_max = max_data_bytes - tot_size;
976 /* Reserve one byte for the last stream and two for the others */
977 curr_max -= IMAX(0,2*(st->layout.nb_streams-s-1)-1);
978 /* For 100 ms, reserve an extra byte per stream for the ToC */
979 if (Fs/frame_size == 10)
980 curr_max -= st->layout.nb_streams-s-1;
981 curr_max = IMIN(curr_max,MS_FRAME_TMP);
982 /* Repacketizer will add one or two bytes for self-delimited frames */
983 if (s != st->layout.nb_streams-1) curr_max -= curr_max>253 ? 2 : 1;
984 if (!vbr && s == st->layout.nb_streams-1)
985 opus_encoder_ctl(enc, OPUS_SET_BITRATE(curr_max*(8*Fs/frame_size)));
986 len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth,
987 pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix, float_api);
988 if (len<0)
989 {
990 RESTORE_STACK;
991 return len;
992 }
993 /* We need to use the repacketizer to add the self-delimiting lengths
994 while taking into account the fact that the encoder can now return
995 more than one frame at a time (e.g. 60 ms CELT-only) */
996 ret = opus_repacketizer_cat(&rp, tmp_data, len);
997 /* If the opus_repacketizer_cat() fails, then something's seriously wrong
998 with the encoder. */
999 if (ret != OPUS_OK)
1000 {
1001 RESTORE_STACK;
1002 return OPUS_INTERNAL_ERROR;
1003 }
1004 len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp),
1005 data, max_data_bytes-tot_size, s != st->layout.nb_streams-1, !vbr && s == st->layout.nb_streams-1);
1006 data += len;
1007 tot_size += len;
1008 }
1009 /*printf("\n");*/
1010 RESTORE_STACK;
1011 return tot_size;
1012}
1013
1014#if !defined(DISABLE_FLOAT_API)
1015static void opus_copy_channel_in_float(
1016 opus_val16 *dst,
1017 int dst_stride,
1018 const void *src,
1019 int src_stride,
1020 int src_channel,
1021 int frame_size,
1022 void *user_data
1023)
1024{
1025 const float *float_src;
1026 opus_int32 i;
1027 (void)user_data;
1028 float_src = (const float *)src;
1029 for (i=0;i<frame_size;i++)
1030#if defined(FIXED_POINT)
1031 dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
1032#else
1033 dst[i*dst_stride] = float_src[i*src_stride+src_channel];
1034#endif
1035}
1036#endif
1037
1038static void opus_copy_channel_in_short(
1039 opus_val16 *dst,
1040 int dst_stride,
1041 const void *src,
1042 int src_stride,
1043 int src_channel,
1044 int frame_size,
1045 void *user_data
1046)
1047{
1048 const opus_int16 *short_src;
1049 opus_int32 i;
1050 (void)user_data;
1051 short_src = (const opus_int16 *)src;
1052 for (i=0;i<frame_size;i++)
1053#if defined(FIXED_POINT)
1054 dst[i*dst_stride] = short_src[i*src_stride+src_channel];
1055#else
1056 dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
1057#endif
1058}
1059
1060
1061#ifdef FIXED_POINT
1062int opus_multistream_encode(
1063 OpusMSEncoder *st,
1064 const opus_val16 *pcm,
1065 int frame_size,
1066 unsigned char *data,
1067 opus_int32 max_data_bytes
1068)
1069{
1070 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
1071 pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0, NULL);
1072}
1073
1074#ifndef DISABLE_FLOAT_API
1075int opus_multistream_encode_float(
1076 OpusMSEncoder *st,
1077 const float *pcm,
1078 int frame_size,
1079 unsigned char *data,
1080 opus_int32 max_data_bytes
1081)
1082{
1083 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
1084 pcm, frame_size, data, max_data_bytes, 16, downmix_float, 1, NULL);
1085}
1086#endif
1087
1088#else
1089
1090int opus_multistream_encode_float
1091(
1092 OpusMSEncoder *st,
1093 const opus_val16 *pcm,
1094 int frame_size,
1095 unsigned char *data,
1096 opus_int32 max_data_bytes
1097)
1098{
1099 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
1100 pcm, frame_size, data, max_data_bytes, 24, downmix_float, 1, NULL);
1101}
1102
1103int opus_multistream_encode(
1104 OpusMSEncoder *st,
1105 const opus_int16 *pcm,
1106 int frame_size,
1107 unsigned char *data,
1108 opus_int32 max_data_bytes
1109)
1110{
1111 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
1112 pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0, NULL);
1113}
1114#endif
1115
1116int opus_multistream_encoder_ctl_va_list(OpusMSEncoder *st, int request,
1117 va_list ap)
1118{
1119 int coupled_size, mono_size;
1120 char *ptr;
1121 int ret = OPUS_OK;
1122
1123 coupled_size = opus_encoder_get_size(2);
1124 mono_size = opus_encoder_get_size(1);
1125 ptr = (char*)st + align(sizeof(OpusMSEncoder));
1126 switch (request)
1127 {
1128 case OPUS_SET_BITRATE_REQUEST:
1129 {
1130 opus_int32 value = va_arg(ap, opus_int32);
1131 if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX)
1132 {
1133 if (value <= 0)
1134 goto bad_arg;
1135 value = IMIN(300000*st->layout.nb_channels, IMAX(500*st->layout.nb_channels, value));
1136 }
1137 st->bitrate_bps = value;
1138 }
1139 break;
1140 case OPUS_GET_BITRATE_REQUEST:
1141 {
1142 int s;
1143 opus_int32 *value = va_arg(ap, opus_int32*);
1144 if (!value)
1145 {
1146 goto bad_arg;
1147 }
1148 *value = 0;
1149 for (s=0;s<st->layout.nb_streams;s++)
1150 {
1151 opus_int32 rate;
1152 OpusEncoder *enc;
1153 enc = (OpusEncoder*)ptr;
1154 if (s < st->layout.nb_coupled_streams)
1155 ptr += align(coupled_size);
1156 else
1157 ptr += align(mono_size);
1158 opus_encoder_ctl(enc, request, &rate);
1159 *value += rate;
1160 }
1161 }
1162 break;
1163 case OPUS_GET_LSB_DEPTH_REQUEST:
1164 case OPUS_GET_VBR_REQUEST:
1165 case OPUS_GET_APPLICATION_REQUEST:
1166 case OPUS_GET_BANDWIDTH_REQUEST:
1167 case OPUS_GET_COMPLEXITY_REQUEST:
1168 case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
1169 case OPUS_GET_DTX_REQUEST:
1170 case OPUS_GET_VOICE_RATIO_REQUEST:
1171 case OPUS_GET_VBR_CONSTRAINT_REQUEST:
1172 case OPUS_GET_SIGNAL_REQUEST:
1173 case OPUS_GET_LOOKAHEAD_REQUEST:
1174 case OPUS_GET_SAMPLE_RATE_REQUEST:
1175 case OPUS_GET_INBAND_FEC_REQUEST:
1176 case OPUS_GET_FORCE_CHANNELS_REQUEST:
1177 case OPUS_GET_PREDICTION_DISABLED_REQUEST:
1178 case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
1179 {
1180 OpusEncoder *enc;
1181 /* For int32* GET params, just query the first stream */
1182 opus_int32 *value = va_arg(ap, opus_int32*);
1183 enc = (OpusEncoder*)ptr;
1184 ret = opus_encoder_ctl(enc, request, value);
1185 }
1186 break;
1187 case OPUS_GET_FINAL_RANGE_REQUEST:
1188 {
1189 int s;
1190 opus_uint32 *value = va_arg(ap, opus_uint32*);
1191 opus_uint32 tmp;
1192 if (!value)
1193 {
1194 goto bad_arg;
1195 }
1196 *value=0;
1197 for (s=0;s<st->layout.nb_streams;s++)
1198 {
1199 OpusEncoder *enc;
1200 enc = (OpusEncoder*)ptr;
1201 if (s < st->layout.nb_coupled_streams)
1202 ptr += align(coupled_size);
1203 else
1204 ptr += align(mono_size);
1205 ret = opus_encoder_ctl(enc, request, &tmp);
1206 if (ret != OPUS_OK) break;
1207 *value ^= tmp;
1208 }
1209 }
1210 break;
1211 case OPUS_SET_LSB_DEPTH_REQUEST:
1212 case OPUS_SET_COMPLEXITY_REQUEST:
1213 case OPUS_SET_VBR_REQUEST:
1214 case OPUS_SET_VBR_CONSTRAINT_REQUEST:
1215 case OPUS_SET_MAX_BANDWIDTH_REQUEST:
1216 case OPUS_SET_BANDWIDTH_REQUEST:
1217 case OPUS_SET_SIGNAL_REQUEST:
1218 case OPUS_SET_APPLICATION_REQUEST:
1219 case OPUS_SET_INBAND_FEC_REQUEST:
1220 case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
1221 case OPUS_SET_DTX_REQUEST:
1222 case OPUS_SET_FORCE_MODE_REQUEST:
1223 case OPUS_SET_FORCE_CHANNELS_REQUEST:
1224 case OPUS_SET_PREDICTION_DISABLED_REQUEST:
1225 case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
1226 {
1227 int s;
1228 /* This works for int32 params */
1229 opus_int32 value = va_arg(ap, opus_int32);
1230 for (s=0;s<st->layout.nb_streams;s++)
1231 {
1232 OpusEncoder *enc;
1233
1234 enc = (OpusEncoder*)ptr;
1235 if (s < st->layout.nb_coupled_streams)
1236 ptr += align(coupled_size);
1237 else
1238 ptr += align(mono_size);
1239 ret = opus_encoder_ctl(enc, request, value);
1240 if (ret != OPUS_OK)
1241 break;
1242 }
1243 }
1244 break;
1245 case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
1246 {
1247 int s;
1248 opus_int32 stream_id;
1249 OpusEncoder **value;
1250 stream_id = va_arg(ap, opus_int32);
1251 if (stream_id<0 || stream_id >= st->layout.nb_streams)
1252 ret = OPUS_BAD_ARG;
1253 value = va_arg(ap, OpusEncoder**);
1254 if (!value)
1255 {
1256 goto bad_arg;
1257 }
1258 for (s=0;s<stream_id;s++)
1259 {
1260 if (s < st->layout.nb_coupled_streams)
1261 ptr += align(coupled_size);
1262 else
1263 ptr += align(mono_size);
1264 }
1265 *value = (OpusEncoder*)ptr;
1266 }
1267 break;
1268 case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
1269 {
1270 opus_int32 value = va_arg(ap, opus_int32);
1271 st->variable_duration = value;
1272 }
1273 break;
1274 case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
1275 {
1276 opus_int32 *value = va_arg(ap, opus_int32*);
1277 if (!value)
1278 {
1279 goto bad_arg;
1280 }
1281 *value = st->variable_duration;
1282 }
1283 break;
1284 case OPUS_RESET_STATE:
1285 {
1286 int s;
1287 if (st->mapping_type == MAPPING_TYPE_SURROUND)
1288 {
1289 OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels);
1290 OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*120);
1291 }
1292 for (s=0;s<st->layout.nb_streams;s++)
1293 {
1294 OpusEncoder *enc;
1295 enc = (OpusEncoder*)ptr;
1296 if (s < st->layout.nb_coupled_streams)
1297 ptr += align(coupled_size);
1298 else
1299 ptr += align(mono_size);
1300 ret = opus_encoder_ctl(enc, OPUS_RESET_STATE);
1301 if (ret != OPUS_OK)
1302 break;
1303 }
1304 }
1305 break;
1306 default:
1307 ret = OPUS_UNIMPLEMENTED;
1308 break;
1309 }
1310 return ret;
1311bad_arg:
1312 return OPUS_BAD_ARG;
1313}
1314
1315int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
1316{
1317 int ret;
1318 va_list ap;
1319 va_start(ap, request);
1320 ret = opus_multistream_encoder_ctl_va_list(st, request, ap);
1321 va_end(ap);
1322 return ret;
1323}
1324
1325void opus_multistream_encoder_destroy(OpusMSEncoder *st)
1326{
1327 opus_free(st);
1328}
diff --git a/lib/rbcodec/codecs/libopus/opus_private.h b/lib/rbcodec/codecs/libopus/opus_private.h
index 3177f52442..09783ceefc 100644
--- a/lib/rbcodec/codecs/libopus/opus_private.h
+++ b/lib/rbcodec/codecs/libopus/opus_private.h
@@ -33,6 +33,9 @@
33#include "opus.h" 33#include "opus.h"
34#include "celt.h" 34#include "celt.h"
35 35
36#include <stdarg.h> /* va_list */
37#include <stddef.h> /* offsetof */
38
36struct OpusRepacketizer { 39struct OpusRepacketizer {
37 unsigned char toc; 40 unsigned char toc;
38 int nb_frames; 41 int nb_frames;
@@ -48,12 +51,59 @@ typedef struct ChannelLayout {
48 unsigned char mapping[256]; 51 unsigned char mapping[256];
49} ChannelLayout; 52} ChannelLayout;
50 53
54typedef enum {
55 MAPPING_TYPE_NONE,
56 MAPPING_TYPE_SURROUND,
57 MAPPING_TYPE_AMBISONICS
58} MappingType;
59
60struct OpusMSEncoder {
61 ChannelLayout layout;
62 int arch;
63 int lfe_stream;
64 int application;
65 int variable_duration;
66 MappingType mapping_type;
67 opus_int32 bitrate_bps;
68 /* Encoder states go here */
69 /* then opus_val32 window_mem[channels*120]; */
70 /* then opus_val32 preemph_mem[channels]; */
71};
72
73struct OpusMSDecoder {
74 ChannelLayout layout;
75 /* Decoder states go here */
76};
77
78int opus_multistream_encoder_ctl_va_list(struct OpusMSEncoder *st, int request,
79 va_list ap);
80int opus_multistream_decoder_ctl_va_list(struct OpusMSDecoder *st, int request,
81 va_list ap);
82
51int validate_layout(const ChannelLayout *layout); 83int validate_layout(const ChannelLayout *layout);
52int get_left_channel(const ChannelLayout *layout, int stream_id, int prev); 84int get_left_channel(const ChannelLayout *layout, int stream_id, int prev);
53int get_right_channel(const ChannelLayout *layout, int stream_id, int prev); 85int get_right_channel(const ChannelLayout *layout, int stream_id, int prev);
54int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev); 86int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev);
55 87
56 88typedef void (*opus_copy_channel_in_func)(
89 opus_val16 *dst,
90 int dst_stride,
91 const void *src,
92 int src_stride,
93 int src_channel,
94 int frame_size,
95 void *user_data
96);
97
98typedef void (*opus_copy_channel_out_func)(
99 void *dst,
100 int dst_stride,
101 int dst_channel,
102 const opus_val16 *src,
103 int src_stride,
104 int frame_size,
105 void *user_data
106);
57 107
58#define MODE_SILK_ONLY 1000 108#define MODE_SILK_ONLY 1000
59#define MODE_HYBRID 1001 109#define MODE_HYBRID 1001
@@ -90,14 +140,6 @@ int encode_size(int size, unsigned char *data);
90 140
91opus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs); 141opus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs);
92 142
93opus_int32 compute_frame_size(const void *analysis_pcm, int frame_size,
94 int variable_duration, int C, opus_int32 Fs, int bitrate_bps,
95 int delay_compensation, downmix_func downmix
96#ifndef DISABLE_FLOAT_API
97 , float *subframe_mem
98#endif
99 );
100
101opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size, 143opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
102 unsigned char *data, opus_int32 out_data_bytes, int lsb_depth, 144 unsigned char *data, opus_int32 out_data_bytes, int lsb_depth,
103 const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2, 145 const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2,
@@ -107,10 +149,16 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data, opus_int32 le
107 opus_val16 *pcm, int frame_size, int decode_fec, int self_delimited, 149 opus_val16 *pcm, int frame_size, int decode_fec, int self_delimited,
108 opus_int32 *packet_offset, int soft_clip); 150 opus_int32 *packet_offset, int soft_clip);
109 151
110/* Make sure everything's aligned to sizeof(void *) bytes */ 152/* Make sure everything is properly aligned. */
111static OPUS_INLINE int align(int i) 153static OPUS_INLINE int align(int i)
112{ 154{
113 return (i+(int)sizeof(void *)-1)&-(int)sizeof(void *); 155 struct foo {char c; union { void* p; opus_int32 i; opus_val32 v; } u;};
156
157 unsigned int alignment = offsetof(struct foo, u);
158
159 /* Optimizing compilers should optimize div and multiply into and
160 for all sensible alignment values. */
161 return ((i + alignment - 1) / alignment) * alignment;
114} 162}
115 163
116int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, 164int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
@@ -123,4 +171,30 @@ opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int
123 171
124int pad_frame(unsigned char *data, opus_int32 len, opus_int32 new_len); 172int pad_frame(unsigned char *data, opus_int32 len, opus_int32 new_len);
125 173
174int opus_multistream_encode_native
175(
176 struct OpusMSEncoder *st,
177 opus_copy_channel_in_func copy_channel_in,
178 const void *pcm,
179 int analysis_frame_size,
180 unsigned char *data,
181 opus_int32 max_data_bytes,
182 int lsb_depth,
183 downmix_func downmix,
184 int float_api,
185 void *user_data
186);
187
188int opus_multistream_decode_native(
189 struct OpusMSDecoder *st,
190 const unsigned char *data,
191 opus_int32 len,
192 void *pcm,
193 opus_copy_channel_out_func copy_channel_out,
194 int frame_size,
195 int decode_fec,
196 int soft_clip,
197 void *user_data
198);
199
126#endif /* OPUS_PRIVATE_H */ 200#endif /* OPUS_PRIVATE_H */
diff --git a/lib/rbcodec/codecs/libopus/opus_projection.h b/lib/rbcodec/codecs/libopus/opus_projection.h
new file mode 100644
index 0000000000..9dabf4e85c
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/opus_projection.h
@@ -0,0 +1,568 @@
1/* Copyright (c) 2017 Google Inc.
2 Written by Andrew Allen */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28/**
29 * @file opus_projection.h
30 * @brief Opus projection reference API
31 */
32
33#ifndef OPUS_PROJECTION_H
34#define OPUS_PROJECTION_H
35
36#include "opus_multistream.h"
37
38#ifdef __cplusplus
39extern "C" {
40#endif
41
42/** @cond OPUS_INTERNAL_DOC */
43
44/** These are the actual encoder and decoder CTL ID numbers.
45 * They should not be used directly by applications.c
46 * In general, SETs should be even and GETs should be odd.*/
47/**@{*/
48#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST 6001
49#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST 6003
50#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST 6005
51/**@}*/
52
53
54/** @endcond */
55
56/** @defgroup opus_projection_ctls Projection specific encoder and decoder CTLs
57 *
58 * These are convenience macros that are specific to the
59 * opus_projection_encoder_ctl() and opus_projection_decoder_ctl()
60 * interface.
61 * The CTLs from @ref opus_genericctls, @ref opus_encoderctls,
62 * @ref opus_decoderctls, and @ref opus_multistream_ctls may be applied to a
63 * projection encoder or decoder as well.
64 */
65/**@{*/
66
67/** Gets the gain (in dB. S7.8-format) of the demixing matrix from the encoder.
68 * @param[out] x <tt>opus_int32 *</tt>: Returns the gain (in dB. S7.8-format)
69 * of the demixing matrix.
70 * @hideinitializer
71 */
72#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN(x) OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST, __opus_check_int_ptr(x)
73
74
75/** Gets the size in bytes of the demixing matrix from the encoder.
76 * @param[out] x <tt>opus_int32 *</tt>: Returns the size in bytes of the
77 * demixing matrix.
78 * @hideinitializer
79 */
80#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE(x) OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST, __opus_check_int_ptr(x)
81
82
83/** Copies the demixing matrix to the supplied pointer location.
84 * @param[out] x <tt>unsigned char *</tt>: Returns the demixing matrix to the
85 * supplied pointer location.
86 * @param y <tt>opus_int32</tt>: The size in bytes of the reserved memory at the
87 * pointer location.
88 * @hideinitializer
89 */
90#define OPUS_PROJECTION_GET_DEMIXING_MATRIX(x,y) OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST, x, __opus_check_int(y)
91
92
93/**@}*/
94
95/** Opus projection encoder state.
96 * This contains the complete state of a projection Opus encoder.
97 * It is position independent and can be freely copied.
98 * @see opus_projection_ambisonics_encoder_create
99 */
100typedef struct OpusProjectionEncoder OpusProjectionEncoder;
101
102
103/** Opus projection decoder state.
104 * This contains the complete state of a projection Opus decoder.
105 * It is position independent and can be freely copied.
106 * @see opus_projection_decoder_create
107 * @see opus_projection_decoder_init
108 */
109typedef struct OpusProjectionDecoder OpusProjectionDecoder;
110
111
112/**\name Projection encoder functions */
113/**@{*/
114
115/** Gets the size of an OpusProjectionEncoder structure.
116 * @param channels <tt>int</tt>: The total number of input channels to encode.
117 * This must be no more than 255.
118 * @param mapping_family <tt>int</tt>: The mapping family to use for selecting
119 * the appropriate projection.
120 * @returns The size in bytes on success, or a negative error code
121 * (see @ref opus_errorcodes) on error.
122 */
123OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_projection_ambisonics_encoder_get_size(
124 int channels,
125 int mapping_family
126);
127
128
129/** Allocates and initializes a projection encoder state.
130 * Call opus_projection_encoder_destroy() to release
131 * this object when finished.
132 * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
133 * This must be one of 8000, 12000, 16000,
134 * 24000, or 48000.
135 * @param channels <tt>int</tt>: Number of channels in the input signal.
136 * This must be at most 255.
137 * It may be greater than the number of
138 * coded channels (<code>streams +
139 * coupled_streams</code>).
140 * @param mapping_family <tt>int</tt>: The mapping family to use for selecting
141 * the appropriate projection.
142 * @param[out] streams <tt>int *</tt>: The total number of streams that will
143 * be encoded from the input.
144 * @param[out] coupled_streams <tt>int *</tt>: Number of coupled (2 channel)
145 * streams that will be encoded from the input.
146 * @param application <tt>int</tt>: The target encoder application.
147 * This must be one of the following:
148 * <dl>
149 * <dt>#OPUS_APPLICATION_VOIP</dt>
150 * <dd>Process signal for improved speech intelligibility.</dd>
151 * <dt>#OPUS_APPLICATION_AUDIO</dt>
152 * <dd>Favor faithfulness to the original input.</dd>
153 * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
154 * <dd>Configure the minimum possible coding delay by disabling certain modes
155 * of operation.</dd>
156 * </dl>
157 * @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error
158 * code (see @ref opus_errorcodes) on
159 * failure.
160 */
161OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusProjectionEncoder *opus_projection_ambisonics_encoder_create(
162 opus_int32 Fs,
163 int channels,
164 int mapping_family,
165 int *streams,
166 int *coupled_streams,
167 int application,
168 int *error
169) OPUS_ARG_NONNULL(4) OPUS_ARG_NONNULL(5);
170
171
172/** Initialize a previously allocated projection encoder state.
173 * The memory pointed to by \a st must be at least the size returned by
174 * opus_projection_ambisonics_encoder_get_size().
175 * This is intended for applications which use their own allocator instead of
176 * malloc.
177 * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
178 * @see opus_projection_ambisonics_encoder_create
179 * @see opus_projection_ambisonics_encoder_get_size
180 * @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state to initialize.
181 * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
182 * This must be one of 8000, 12000, 16000,
183 * 24000, or 48000.
184 * @param channels <tt>int</tt>: Number of channels in the input signal.
185 * This must be at most 255.
186 * It may be greater than the number of
187 * coded channels (<code>streams +
188 * coupled_streams</code>).
189 * @param streams <tt>int</tt>: The total number of streams to encode from the
190 * input.
191 * This must be no more than the number of channels.
192 * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
193 * to encode.
194 * This must be no larger than the total
195 * number of streams.
196 * Additionally, The total number of
197 * encoded channels (<code>streams +
198 * coupled_streams</code>) must be no
199 * more than the number of input channels.
200 * @param application <tt>int</tt>: The target encoder application.
201 * This must be one of the following:
202 * <dl>
203 * <dt>#OPUS_APPLICATION_VOIP</dt>
204 * <dd>Process signal for improved speech intelligibility.</dd>
205 * <dt>#OPUS_APPLICATION_AUDIO</dt>
206 * <dd>Favor faithfulness to the original input.</dd>
207 * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
208 * <dd>Configure the minimum possible coding delay by disabling certain modes
209 * of operation.</dd>
210 * </dl>
211 * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
212 * on failure.
213 */
214OPUS_EXPORT int opus_projection_ambisonics_encoder_init(
215 OpusProjectionEncoder *st,
216 opus_int32 Fs,
217 int channels,
218 int mapping_family,
219 int *streams,
220 int *coupled_streams,
221 int application
222) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6);
223
224
225/** Encodes a projection Opus frame.
226 * @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state.
227 * @param[in] pcm <tt>const opus_int16*</tt>: The input signal as interleaved
228 * samples.
229 * This must contain
230 * <code>frame_size*channels</code>
231 * samples.
232 * @param frame_size <tt>int</tt>: Number of samples per channel in the input
233 * signal.
234 * This must be an Opus frame size for the
235 * encoder's sampling rate.
236 * For example, at 48 kHz the permitted values
237 * are 120, 240, 480, 960, 1920, and 2880.
238 * Passing in a duration of less than 10 ms
239 * (480 samples at 48 kHz) will prevent the
240 * encoder from using the LPC or hybrid modes.
241 * @param[out] data <tt>unsigned char*</tt>: Output payload.
242 * This must contain storage for at
243 * least \a max_data_bytes.
244 * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
245 * memory for the output
246 * payload. This may be
247 * used to impose an upper limit on
248 * the instant bitrate, but should
249 * not be used as the only bitrate
250 * control. Use #OPUS_SET_BITRATE to
251 * control the bitrate.
252 * @returns The length of the encoded packet (in bytes) on success or a
253 * negative error code (see @ref opus_errorcodes) on failure.
254 */
255OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_encode(
256 OpusProjectionEncoder *st,
257 const opus_int16 *pcm,
258 int frame_size,
259 unsigned char *data,
260 opus_int32 max_data_bytes
261) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
262
263
264/** Encodes a projection Opus frame from floating point input.
265 * @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state.
266 * @param[in] pcm <tt>const float*</tt>: The input signal as interleaved
267 * samples with a normal range of
268 * +/-1.0.
269 * Samples with a range beyond +/-1.0
270 * are supported but will be clipped by
271 * decoders using the integer API and
272 * should only be used if it is known
273 * that the far end supports extended
274 * dynamic range.
275 * This must contain
276 * <code>frame_size*channels</code>
277 * samples.
278 * @param frame_size <tt>int</tt>: Number of samples per channel in the input
279 * signal.
280 * This must be an Opus frame size for the
281 * encoder's sampling rate.
282 * For example, at 48 kHz the permitted values
283 * are 120, 240, 480, 960, 1920, and 2880.
284 * Passing in a duration of less than 10 ms
285 * (480 samples at 48 kHz) will prevent the
286 * encoder from using the LPC or hybrid modes.
287 * @param[out] data <tt>unsigned char*</tt>: Output payload.
288 * This must contain storage for at
289 * least \a max_data_bytes.
290 * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
291 * memory for the output
292 * payload. This may be
293 * used to impose an upper limit on
294 * the instant bitrate, but should
295 * not be used as the only bitrate
296 * control. Use #OPUS_SET_BITRATE to
297 * control the bitrate.
298 * @returns The length of the encoded packet (in bytes) on success or a
299 * negative error code (see @ref opus_errorcodes) on failure.
300 */
301OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_encode_float(
302 OpusProjectionEncoder *st,
303 const float *pcm,
304 int frame_size,
305 unsigned char *data,
306 opus_int32 max_data_bytes
307) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
308
309
310/** Frees an <code>OpusProjectionEncoder</code> allocated by
311 * opus_projection_ambisonics_encoder_create().
312 * @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state to be freed.
313 */
314OPUS_EXPORT void opus_projection_encoder_destroy(OpusProjectionEncoder *st);
315
316
317/** Perform a CTL function on a projection Opus encoder.
318 *
319 * Generally the request and subsequent arguments are generated by a
320 * convenience macro.
321 * @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state.
322 * @param request This and all remaining parameters should be replaced by one
323 * of the convenience macros in @ref opus_genericctls,
324 * @ref opus_encoderctls, @ref opus_multistream_ctls, or
325 * @ref opus_projection_ctls
326 * @see opus_genericctls
327 * @see opus_encoderctls
328 * @see opus_multistream_ctls
329 * @see opus_projection_ctls
330 */
331OPUS_EXPORT int opus_projection_encoder_ctl(OpusProjectionEncoder *st, int request, ...) OPUS_ARG_NONNULL(1);
332
333
334/**@}*/
335
336/**\name Projection decoder functions */
337/**@{*/
338
339/** Gets the size of an <code>OpusProjectionDecoder</code> structure.
340 * @param channels <tt>int</tt>: The total number of output channels.
341 * This must be no more than 255.
342 * @param streams <tt>int</tt>: The total number of streams coded in the
343 * input.
344 * This must be no more than 255.
345 * @param coupled_streams <tt>int</tt>: Number streams to decode as coupled
346 * (2 channel) streams.
347 * This must be no larger than the total
348 * number of streams.
349 * Additionally, The total number of
350 * coded channels (<code>streams +
351 * coupled_streams</code>) must be no
352 * more than 255.
353 * @returns The size in bytes on success, or a negative error code
354 * (see @ref opus_errorcodes) on error.
355 */
356OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_projection_decoder_get_size(
357 int channels,
358 int streams,
359 int coupled_streams
360);
361
362
363/** Allocates and initializes a projection decoder state.
364 * Call opus_projection_decoder_destroy() to release
365 * this object when finished.
366 * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
367 * This must be one of 8000, 12000, 16000,
368 * 24000, or 48000.
369 * @param channels <tt>int</tt>: Number of channels to output.
370 * This must be at most 255.
371 * It may be different from the number of coded
372 * channels (<code>streams +
373 * coupled_streams</code>).
374 * @param streams <tt>int</tt>: The total number of streams coded in the
375 * input.
376 * This must be no more than 255.
377 * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
378 * (2 channel) streams.
379 * This must be no larger than the total
380 * number of streams.
381 * Additionally, The total number of
382 * coded channels (<code>streams +
383 * coupled_streams</code>) must be no
384 * more than 255.
385 * @param[in] demixing_matrix <tt>const unsigned char[demixing_matrix_size]</tt>: Demixing matrix
386 * that mapping from coded channels to output channels,
387 * as described in @ref opus_projection and
388 * @ref opus_projection_ctls.
389 * @param demixing_matrix_size <tt>opus_int32</tt>: The size in bytes of the
390 * demixing matrix, as
391 * described in @ref
392 * opus_projection_ctls.
393 * @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error
394 * code (see @ref opus_errorcodes) on
395 * failure.
396 */
397OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusProjectionDecoder *opus_projection_decoder_create(
398 opus_int32 Fs,
399 int channels,
400 int streams,
401 int coupled_streams,
402 unsigned char *demixing_matrix,
403 opus_int32 demixing_matrix_size,
404 int *error
405) OPUS_ARG_NONNULL(5);
406
407
408/** Intialize a previously allocated projection decoder state object.
409 * The memory pointed to by \a st must be at least the size returned by
410 * opus_projection_decoder_get_size().
411 * This is intended for applications which use their own allocator instead of
412 * malloc.
413 * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
414 * @see opus_projection_decoder_create
415 * @see opus_projection_deocder_get_size
416 * @param st <tt>OpusProjectionDecoder*</tt>: Projection encoder state to initialize.
417 * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
418 * This must be one of 8000, 12000, 16000,
419 * 24000, or 48000.
420 * @param channels <tt>int</tt>: Number of channels to output.
421 * This must be at most 255.
422 * It may be different from the number of coded
423 * channels (<code>streams +
424 * coupled_streams</code>).
425 * @param streams <tt>int</tt>: The total number of streams coded in the
426 * input.
427 * This must be no more than 255.
428 * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
429 * (2 channel) streams.
430 * This must be no larger than the total
431 * number of streams.
432 * Additionally, The total number of
433 * coded channels (<code>streams +
434 * coupled_streams</code>) must be no
435 * more than 255.
436 * @param[in] demixing_matrix <tt>const unsigned char[demixing_matrix_size]</tt>: Demixing matrix
437 * that mapping from coded channels to output channels,
438 * as described in @ref opus_projection and
439 * @ref opus_projection_ctls.
440 * @param demixing_matrix_size <tt>opus_int32</tt>: The size in bytes of the
441 * demixing matrix, as
442 * described in @ref
443 * opus_projection_ctls.
444 * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
445 * on failure.
446 */
447OPUS_EXPORT int opus_projection_decoder_init(
448 OpusProjectionDecoder *st,
449 opus_int32 Fs,
450 int channels,
451 int streams,
452 int coupled_streams,
453 unsigned char *demixing_matrix,
454 opus_int32 demixing_matrix_size
455) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
456
457
458/** Decode a projection Opus packet.
459 * @param st <tt>OpusProjectionDecoder*</tt>: Projection decoder state.
460 * @param[in] data <tt>const unsigned char*</tt>: Input payload.
461 * Use a <code>NULL</code>
462 * pointer to indicate packet
463 * loss.
464 * @param len <tt>opus_int32</tt>: Number of bytes in payload.
465 * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
466 * samples.
467 * This must contain room for
468 * <code>frame_size*channels</code>
469 * samples.
470 * @param frame_size <tt>int</tt>: The number of samples per channel of
471 * available space in \a pcm.
472 * If this is less than the maximum packet duration
473 * (120 ms; 5760 for 48kHz), this function will not be capable
474 * of decoding some packets. In the case of PLC (data==NULL)
475 * or FEC (decode_fec=1), then frame_size needs to be exactly
476 * the duration of audio that is missing, otherwise the
477 * decoder will not be in the optimal state to decode the
478 * next incoming packet. For the PLC and FEC cases, frame_size
479 * <b>must</b> be a multiple of 2.5 ms.
480 * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
481 * forward error correction data be decoded.
482 * If no such data is available, the frame is
483 * decoded as if it were lost.
484 * @returns Number of samples decoded on success or a negative error code
485 * (see @ref opus_errorcodes) on failure.
486 */
487OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_decode(
488 OpusProjectionDecoder *st,
489 const unsigned char *data,
490 opus_int32 len,
491 opus_int16 *pcm,
492 int frame_size,
493 int decode_fec
494) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
495
496
497/** Decode a projection Opus packet with floating point output.
498 * @param st <tt>OpusProjectionDecoder*</tt>: Projection decoder state.
499 * @param[in] data <tt>const unsigned char*</tt>: Input payload.
500 * Use a <code>NULL</code>
501 * pointer to indicate packet
502 * loss.
503 * @param len <tt>opus_int32</tt>: Number of bytes in payload.
504 * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
505 * samples.
506 * This must contain room for
507 * <code>frame_size*channels</code>
508 * samples.
509 * @param frame_size <tt>int</tt>: The number of samples per channel of
510 * available space in \a pcm.
511 * If this is less than the maximum packet duration
512 * (120 ms; 5760 for 48kHz), this function will not be capable
513 * of decoding some packets. In the case of PLC (data==NULL)
514 * or FEC (decode_fec=1), then frame_size needs to be exactly
515 * the duration of audio that is missing, otherwise the
516 * decoder will not be in the optimal state to decode the
517 * next incoming packet. For the PLC and FEC cases, frame_size
518 * <b>must</b> be a multiple of 2.5 ms.
519 * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
520 * forward error correction data be decoded.
521 * If no such data is available, the frame is
522 * decoded as if it were lost.
523 * @returns Number of samples decoded on success or a negative error code
524 * (see @ref opus_errorcodes) on failure.
525 */
526OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_decode_float(
527 OpusProjectionDecoder *st,
528 const unsigned char *data,
529 opus_int32 len,
530 float *pcm,
531 int frame_size,
532 int decode_fec
533) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
534
535
536/** Perform a CTL function on a projection Opus decoder.
537 *
538 * Generally the request and subsequent arguments are generated by a
539 * convenience macro.
540 * @param st <tt>OpusProjectionDecoder*</tt>: Projection decoder state.
541 * @param request This and all remaining parameters should be replaced by one
542 * of the convenience macros in @ref opus_genericctls,
543 * @ref opus_decoderctls, @ref opus_multistream_ctls, or
544 * @ref opus_projection_ctls.
545 * @see opus_genericctls
546 * @see opus_decoderctls
547 * @see opus_multistream_ctls
548 * @see opus_projection_ctls
549 */
550OPUS_EXPORT int opus_projection_decoder_ctl(OpusProjectionDecoder *st, int request, ...) OPUS_ARG_NONNULL(1);
551
552
553/** Frees an <code>OpusProjectionDecoder</code> allocated by
554 * opus_projection_decoder_create().
555 * @param st <tt>OpusProjectionDecoder</tt>: Projection decoder state to be freed.
556 */
557OPUS_EXPORT void opus_projection_decoder_destroy(OpusProjectionDecoder *st);
558
559
560/**@}*/
561
562/**@}*/
563
564#ifdef __cplusplus
565}
566#endif
567
568#endif /* OPUS_PROJECTION_H */
diff --git a/lib/rbcodec/codecs/libopus/opus_projection_decoder.c b/lib/rbcodec/codecs/libopus/opus_projection_decoder.c
new file mode 100644
index 0000000000..c2e07d5bcf
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/opus_projection_decoder.c
@@ -0,0 +1,258 @@
1/* Copyright (c) 2017 Google Inc.
2 Written by Andrew Allen */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "mathops.h"
33#include "os_support.h"
34#include "opus_private.h"
35#include "opus_defines.h"
36#include "opus_projection.h"
37#include "opus_multistream.h"
38#include "mapping_matrix.h"
39#include "stack_alloc.h"
40
41struct OpusProjectionDecoder
42{
43 opus_int32 demixing_matrix_size_in_bytes;
44 /* Encoder states go here */
45};
46
47#if !defined(DISABLE_FLOAT_API)
48static void opus_projection_copy_channel_out_float(
49 void *dst,
50 int dst_stride,
51 int dst_channel,
52 const opus_val16 *src,
53 int src_stride,
54 int frame_size,
55 void *user_data)
56{
57 float *float_dst;
58 const MappingMatrix *matrix;
59 float_dst = (float *)dst;
60 matrix = (const MappingMatrix *)user_data;
61
62 if (dst_channel == 0)
63 OPUS_CLEAR(float_dst, frame_size * dst_stride);
64
65 if (src != NULL)
66 mapping_matrix_multiply_channel_out_float(matrix, src, dst_channel,
67 src_stride, float_dst, dst_stride, frame_size);
68}
69#endif
70
71static void opus_projection_copy_channel_out_short(
72 void *dst,
73 int dst_stride,
74 int dst_channel,
75 const opus_val16 *src,
76 int src_stride,
77 int frame_size,
78 void *user_data)
79{
80 opus_int16 *short_dst;
81 const MappingMatrix *matrix;
82 short_dst = (opus_int16 *)dst;
83 matrix = (const MappingMatrix *)user_data;
84 if (dst_channel == 0)
85 OPUS_CLEAR(short_dst, frame_size * dst_stride);
86
87 if (src != NULL)
88 mapping_matrix_multiply_channel_out_short(matrix, src, dst_channel,
89 src_stride, short_dst, dst_stride, frame_size);
90}
91
92static MappingMatrix *get_dec_demixing_matrix(OpusProjectionDecoder *st)
93{
94 /* void* cast avoids clang -Wcast-align warning */
95 return (MappingMatrix*)(void*)((char*)st +
96 align(sizeof(OpusProjectionDecoder)));
97}
98
99static OpusMSDecoder *get_multistream_decoder(OpusProjectionDecoder *st)
100{
101 /* void* cast avoids clang -Wcast-align warning */
102 return (OpusMSDecoder*)(void*)((char*)st +
103 align(sizeof(OpusProjectionDecoder) +
104 st->demixing_matrix_size_in_bytes));
105}
106
107opus_int32 opus_projection_decoder_get_size(int channels, int streams,
108 int coupled_streams)
109{
110 opus_int32 matrix_size;
111 opus_int32 decoder_size;
112
113 matrix_size =
114 mapping_matrix_get_size(streams + coupled_streams, channels);
115 if (!matrix_size)
116 return 0;
117
118 decoder_size = opus_multistream_decoder_get_size(streams, coupled_streams);
119 if (!decoder_size)
120 return 0;
121
122 return align(sizeof(OpusProjectionDecoder)) + matrix_size + decoder_size;
123}
124
125int opus_projection_decoder_init(OpusProjectionDecoder *st, opus_int32 Fs,
126 int channels, int streams, int coupled_streams,
127 unsigned char *demixing_matrix, opus_int32 demixing_matrix_size)
128{
129 int nb_input_streams;
130 opus_int32 expected_matrix_size;
131 int i, ret;
132 unsigned char mapping[255];
133 VARDECL(opus_int16, buf);
134 ALLOC_STACK;
135
136 /* Verify supplied matrix size. */
137 nb_input_streams = streams + coupled_streams;
138 expected_matrix_size = nb_input_streams * channels * sizeof(opus_int16);
139 if (expected_matrix_size != demixing_matrix_size)
140 {
141 RESTORE_STACK;
142 return OPUS_BAD_ARG;
143 }
144
145 /* Convert demixing matrix input into internal format. */
146 ALLOC(buf, nb_input_streams * channels, opus_int16);
147 for (i = 0; i < nb_input_streams * channels; i++)
148 {
149 int s = demixing_matrix[2*i + 1] << 8 | demixing_matrix[2*i];
150 s = ((s & 0xFFFF) ^ 0x8000) - 0x8000;
151 buf[i] = (opus_int16)s;
152 }
153
154 /* Assign demixing matrix. */
155 st->demixing_matrix_size_in_bytes =
156 mapping_matrix_get_size(channels, nb_input_streams);
157 if (!st->demixing_matrix_size_in_bytes)
158 {
159 RESTORE_STACK;
160 return OPUS_BAD_ARG;
161 }
162
163 mapping_matrix_init(get_dec_demixing_matrix(st), channels, nb_input_streams, 0,
164 buf, demixing_matrix_size);
165
166 /* Set trivial mapping so each input channel pairs with a matrix column. */
167 for (i = 0; i < channels; i++)
168 mapping[i] = i;
169
170 ret = opus_multistream_decoder_init(
171 get_multistream_decoder(st), Fs, channels, streams, coupled_streams, mapping);
172 RESTORE_STACK;
173 return ret;
174}
175
176OpusProjectionDecoder *opus_projection_decoder_create(
177 opus_int32 Fs, int channels, int streams, int coupled_streams,
178 unsigned char *demixing_matrix, opus_int32 demixing_matrix_size, int *error)
179{
180 int size;
181 int ret;
182 OpusProjectionDecoder *st;
183
184 /* Allocate space for the projection decoder. */
185 size = opus_projection_decoder_get_size(channels, streams, coupled_streams);
186 if (!size) {
187 if (error)
188 *error = OPUS_ALLOC_FAIL;
189 return NULL;
190 }
191 st = (OpusProjectionDecoder *)opus_alloc(size);
192 if (!st)
193 {
194 if (error)
195 *error = OPUS_ALLOC_FAIL;
196 return NULL;
197 }
198
199 /* Initialize projection decoder with provided settings. */
200 ret = opus_projection_decoder_init(st, Fs, channels, streams, coupled_streams,
201 demixing_matrix, demixing_matrix_size);
202 if (ret != OPUS_OK)
203 {
204 opus_free(st);
205 st = NULL;
206 }
207 if (error)
208 *error = ret;
209 return st;
210}
211
212#ifdef FIXED_POINT
213int opus_projection_decode(OpusProjectionDecoder *st, const unsigned char *data,
214 opus_int32 len, opus_int16 *pcm, int frame_size,
215 int decode_fec)
216{
217 return opus_multistream_decode_native(get_multistream_decoder(st), data, len,
218 pcm, opus_projection_copy_channel_out_short, frame_size, decode_fec, 0,
219 get_dec_demixing_matrix(st));
220}
221#else
222int opus_projection_decode(OpusProjectionDecoder *st, const unsigned char *data,
223 opus_int32 len, opus_int16 *pcm, int frame_size,
224 int decode_fec)
225{
226 return opus_multistream_decode_native(get_multistream_decoder(st), data, len,
227 pcm, opus_projection_copy_channel_out_short, frame_size, decode_fec, 1,
228 get_dec_demixing_matrix(st));
229}
230#endif
231
232#ifndef DISABLE_FLOAT_API
233int opus_projection_decode_float(OpusProjectionDecoder *st, const unsigned char *data,
234 opus_int32 len, float *pcm, int frame_size, int decode_fec)
235{
236 return opus_multistream_decode_native(get_multistream_decoder(st), data, len,
237 pcm, opus_projection_copy_channel_out_float, frame_size, decode_fec, 0,
238 get_dec_demixing_matrix(st));
239}
240#endif
241
242int opus_projection_decoder_ctl(OpusProjectionDecoder *st, int request, ...)
243{
244 va_list ap;
245 int ret = OPUS_OK;
246
247 va_start(ap, request);
248 ret = opus_multistream_decoder_ctl_va_list(get_multistream_decoder(st),
249 request, ap);
250 va_end(ap);
251 return ret;
252}
253
254void opus_projection_decoder_destroy(OpusProjectionDecoder *st)
255{
256 opus_free(st);
257}
258
diff --git a/lib/rbcodec/codecs/libopus/opus_projection_encoder.c b/lib/rbcodec/codecs/libopus/opus_projection_encoder.c
new file mode 100644
index 0000000000..06fb2d2526
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/opus_projection_encoder.c
@@ -0,0 +1,468 @@
1/* Copyright (c) 2017 Google Inc.
2 Written by Andrew Allen */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "mathops.h"
33#include "os_support.h"
34#include "opus_private.h"
35#include "opus_defines.h"
36#include "opus_projection.h"
37#include "opus_multistream.h"
38#include "stack_alloc.h"
39#include "mapping_matrix.h"
40
41struct OpusProjectionEncoder
42{
43 opus_int32 mixing_matrix_size_in_bytes;
44 opus_int32 demixing_matrix_size_in_bytes;
45 /* Encoder states go here */
46};
47
48#if !defined(DISABLE_FLOAT_API)
49static void opus_projection_copy_channel_in_float(
50 opus_val16 *dst,
51 int dst_stride,
52 const void *src,
53 int src_stride,
54 int src_channel,
55 int frame_size,
56 void *user_data
57)
58{
59 mapping_matrix_multiply_channel_in_float((const MappingMatrix*)user_data,
60 (const float*)src, src_stride, dst, src_channel, dst_stride, frame_size);
61}
62#endif
63
64static void opus_projection_copy_channel_in_short(
65 opus_val16 *dst,
66 int dst_stride,
67 const void *src,
68 int src_stride,
69 int src_channel,
70 int frame_size,
71 void *user_data
72)
73{
74 mapping_matrix_multiply_channel_in_short((const MappingMatrix*)user_data,
75 (const opus_int16*)src, src_stride, dst, src_channel, dst_stride, frame_size);
76}
77
78static int get_order_plus_one_from_channels(int channels, int *order_plus_one)
79{
80 int order_plus_one_;
81 int acn_channels;
82 int nondiegetic_channels;
83
84 /* Allowed numbers of channels:
85 * (1 + n)^2 + 2j, for n = 0...14 and j = 0 or 1.
86 */
87 if (channels < 1 || channels > 227)
88 return OPUS_BAD_ARG;
89
90 order_plus_one_ = isqrt32(channels);
91 acn_channels = order_plus_one_ * order_plus_one_;
92 nondiegetic_channels = channels - acn_channels;
93 if (nondiegetic_channels != 0 && nondiegetic_channels != 2)
94 return OPUS_BAD_ARG;
95
96 if (order_plus_one)
97 *order_plus_one = order_plus_one_;
98 return OPUS_OK;
99}
100
101static int get_streams_from_channels(int channels, int mapping_family,
102 int *streams, int *coupled_streams,
103 int *order_plus_one)
104{
105 if (mapping_family == 3)
106 {
107 if (get_order_plus_one_from_channels(channels, order_plus_one) != OPUS_OK)
108 return OPUS_BAD_ARG;
109 if (streams)
110 *streams = (channels + 1) / 2;
111 if (coupled_streams)
112 *coupled_streams = channels / 2;
113 return OPUS_OK;
114 }
115 return OPUS_BAD_ARG;
116}
117
118static MappingMatrix *get_mixing_matrix(OpusProjectionEncoder *st)
119{
120 /* void* cast avoids clang -Wcast-align warning */
121 return (MappingMatrix *)(void*)((char*)st +
122 align(sizeof(OpusProjectionEncoder)));
123}
124
125static MappingMatrix *get_enc_demixing_matrix(OpusProjectionEncoder *st)
126{
127 /* void* cast avoids clang -Wcast-align warning */
128 return (MappingMatrix *)(void*)((char*)st +
129 align(sizeof(OpusProjectionEncoder) +
130 st->mixing_matrix_size_in_bytes));
131}
132
133static OpusMSEncoder *get_multistream_encoder(OpusProjectionEncoder *st)
134{
135 /* void* cast avoids clang -Wcast-align warning */
136 return (OpusMSEncoder *)(void*)((char*)st +
137 align(sizeof(OpusProjectionEncoder) +
138 st->mixing_matrix_size_in_bytes +
139 st->demixing_matrix_size_in_bytes));
140}
141
142opus_int32 opus_projection_ambisonics_encoder_get_size(int channels,
143 int mapping_family)
144{
145 int nb_streams;
146 int nb_coupled_streams;
147 int order_plus_one;
148 int mixing_matrix_rows, mixing_matrix_cols;
149 int demixing_matrix_rows, demixing_matrix_cols;
150 opus_int32 mixing_matrix_size, demixing_matrix_size;
151 opus_int32 encoder_size;
152 int ret;
153
154 ret = get_streams_from_channels(channels, mapping_family, &nb_streams,
155 &nb_coupled_streams, &order_plus_one);
156 if (ret != OPUS_OK)
157 return 0;
158
159 if (order_plus_one == 2)
160 {
161 mixing_matrix_rows = mapping_matrix_foa_mixing.rows;
162 mixing_matrix_cols = mapping_matrix_foa_mixing.cols;
163 demixing_matrix_rows = mapping_matrix_foa_demixing.rows;
164 demixing_matrix_cols = mapping_matrix_foa_demixing.cols;
165 }
166 else if (order_plus_one == 3)
167 {
168 mixing_matrix_rows = mapping_matrix_soa_mixing.rows;
169 mixing_matrix_cols = mapping_matrix_soa_mixing.cols;
170 demixing_matrix_rows = mapping_matrix_soa_demixing.rows;
171 demixing_matrix_cols = mapping_matrix_soa_demixing.cols;
172 }
173 else if (order_plus_one == 4)
174 {
175 mixing_matrix_rows = mapping_matrix_toa_mixing.rows;
176 mixing_matrix_cols = mapping_matrix_toa_mixing.cols;
177 demixing_matrix_rows = mapping_matrix_toa_demixing.rows;
178 demixing_matrix_cols = mapping_matrix_toa_demixing.cols;
179 }
180 else
181 return 0;
182
183 mixing_matrix_size =
184 mapping_matrix_get_size(mixing_matrix_rows, mixing_matrix_cols);
185 if (!mixing_matrix_size)
186 return 0;
187
188 demixing_matrix_size =
189 mapping_matrix_get_size(demixing_matrix_rows, demixing_matrix_cols);
190 if (!demixing_matrix_size)
191 return 0;
192
193 encoder_size =
194 opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
195 if (!encoder_size)
196 return 0;
197
198 return align(sizeof(OpusProjectionEncoder)) +
199 mixing_matrix_size + demixing_matrix_size + encoder_size;
200}
201
202int opus_projection_ambisonics_encoder_init(OpusProjectionEncoder *st, opus_int32 Fs,
203 int channels, int mapping_family,
204 int *streams, int *coupled_streams,
205 int application)
206{
207 MappingMatrix *mixing_matrix;
208 MappingMatrix *demixing_matrix;
209 OpusMSEncoder *ms_encoder;
210 int i;
211 int ret;
212 int order_plus_one;
213 unsigned char mapping[255];
214
215 if (streams == NULL || coupled_streams == NULL) {
216 return OPUS_BAD_ARG;
217 }
218
219 if (get_streams_from_channels(channels, mapping_family, streams,
220 coupled_streams, &order_plus_one) != OPUS_OK)
221 return OPUS_BAD_ARG;
222
223 if (mapping_family == 3)
224 {
225 /* Assign mixing matrix based on available pre-computed matrices. */
226 mixing_matrix = get_mixing_matrix(st);
227 if (order_plus_one == 2)
228 {
229 mapping_matrix_init(mixing_matrix, mapping_matrix_foa_mixing.rows,
230 mapping_matrix_foa_mixing.cols, mapping_matrix_foa_mixing.gain,
231 mapping_matrix_foa_mixing_data,
232 sizeof(mapping_matrix_foa_mixing_data));
233 }
234 else if (order_plus_one == 3)
235 {
236 mapping_matrix_init(mixing_matrix, mapping_matrix_soa_mixing.rows,
237 mapping_matrix_soa_mixing.cols, mapping_matrix_soa_mixing.gain,
238 mapping_matrix_soa_mixing_data,
239 sizeof(mapping_matrix_soa_mixing_data));
240 }
241 else if (order_plus_one == 4)
242 {
243 mapping_matrix_init(mixing_matrix, mapping_matrix_toa_mixing.rows,
244 mapping_matrix_toa_mixing.cols, mapping_matrix_toa_mixing.gain,
245 mapping_matrix_toa_mixing_data,
246 sizeof(mapping_matrix_toa_mixing_data));
247 }
248 else
249 return OPUS_BAD_ARG;
250
251 st->mixing_matrix_size_in_bytes = mapping_matrix_get_size(
252 mixing_matrix->rows, mixing_matrix->cols);
253 if (!st->mixing_matrix_size_in_bytes)
254 return OPUS_BAD_ARG;
255
256 /* Assign demixing matrix based on available pre-computed matrices. */
257 demixing_matrix = get_enc_demixing_matrix(st);
258 if (order_plus_one == 2)
259 {
260 mapping_matrix_init(demixing_matrix, mapping_matrix_foa_demixing.rows,
261 mapping_matrix_foa_demixing.cols, mapping_matrix_foa_demixing.gain,
262 mapping_matrix_foa_demixing_data,
263 sizeof(mapping_matrix_foa_demixing_data));
264 }
265 else if (order_plus_one == 3)
266 {
267 mapping_matrix_init(demixing_matrix, mapping_matrix_soa_demixing.rows,
268 mapping_matrix_soa_demixing.cols, mapping_matrix_soa_demixing.gain,
269 mapping_matrix_soa_demixing_data,
270 sizeof(mapping_matrix_soa_demixing_data));
271 }
272 else if (order_plus_one == 4)
273 {
274 mapping_matrix_init(demixing_matrix, mapping_matrix_toa_demixing.rows,
275 mapping_matrix_toa_demixing.cols, mapping_matrix_toa_demixing.gain,
276 mapping_matrix_toa_demixing_data,
277 sizeof(mapping_matrix_toa_demixing_data));
278 }
279 else
280 return OPUS_BAD_ARG;
281
282 st->demixing_matrix_size_in_bytes = mapping_matrix_get_size(
283 demixing_matrix->rows, demixing_matrix->cols);
284 if (!st->demixing_matrix_size_in_bytes)
285 return OPUS_BAD_ARG;
286 }
287 else
288 return OPUS_UNIMPLEMENTED;
289
290 /* Ensure matrices are large enough for desired coding scheme. */
291 if (*streams + *coupled_streams > mixing_matrix->rows ||
292 channels > mixing_matrix->cols ||
293 channels > demixing_matrix->rows ||
294 *streams + *coupled_streams > demixing_matrix->cols)
295 return OPUS_BAD_ARG;
296
297 /* Set trivial mapping so each input channel pairs with a matrix column. */
298 for (i = 0; i < channels; i++)
299 mapping[i] = i;
300
301 /* Initialize multistream encoder with provided settings. */
302 ms_encoder = get_multistream_encoder(st);
303 ret = opus_multistream_encoder_init(ms_encoder, Fs, channels, *streams,
304 *coupled_streams, mapping, application);
305 return ret;
306}
307
308OpusProjectionEncoder *opus_projection_ambisonics_encoder_create(
309 opus_int32 Fs, int channels, int mapping_family, int *streams,
310 int *coupled_streams, int application, int *error)
311{
312 int size;
313 int ret;
314 OpusProjectionEncoder *st;
315
316 /* Allocate space for the projection encoder. */
317 size = opus_projection_ambisonics_encoder_get_size(channels, mapping_family);
318 if (!size) {
319 if (error)
320 *error = OPUS_ALLOC_FAIL;
321 return NULL;
322 }
323 st = (OpusProjectionEncoder *)opus_alloc(size);
324 if (!st)
325 {
326 if (error)
327 *error = OPUS_ALLOC_FAIL;
328 return NULL;
329 }
330
331 /* Initialize projection encoder with provided settings. */
332 ret = opus_projection_ambisonics_encoder_init(st, Fs, channels,
333 mapping_family, streams, coupled_streams, application);
334 if (ret != OPUS_OK)
335 {
336 opus_free(st);
337 st = NULL;
338 }
339 if (error)
340 *error = ret;
341 return st;
342}
343
344int opus_projection_encode(OpusProjectionEncoder *st, const opus_int16 *pcm,
345 int frame_size, unsigned char *data,
346 opus_int32 max_data_bytes)
347{
348 return opus_multistream_encode_native(get_multistream_encoder(st),
349 opus_projection_copy_channel_in_short, pcm, frame_size, data,
350 max_data_bytes, 16, downmix_int, 0, get_mixing_matrix(st));
351}
352
353#ifndef DISABLE_FLOAT_API
354#ifdef FIXED_POINT
355int opus_projection_encode_float(OpusProjectionEncoder *st, const float *pcm,
356 int frame_size, unsigned char *data,
357 opus_int32 max_data_bytes)
358{
359 return opus_multistream_encode_native(get_multistream_encoder(st),
360 opus_projection_copy_channel_in_float, pcm, frame_size, data,
361 max_data_bytes, 16, downmix_float, 1, get_mixing_matrix(st));
362}
363#else
364int opus_projection_encode_float(OpusProjectionEncoder *st, const float *pcm,
365 int frame_size, unsigned char *data,
366 opus_int32 max_data_bytes)
367{
368 return opus_multistream_encode_native(get_multistream_encoder(st),
369 opus_projection_copy_channel_in_float, pcm, frame_size, data,
370 max_data_bytes, 24, downmix_float, 1, get_mixing_matrix(st));
371}
372#endif
373#endif
374
375void opus_projection_encoder_destroy(OpusProjectionEncoder *st)
376{
377 opus_free(st);
378}
379
380int opus_projection_encoder_ctl(OpusProjectionEncoder *st, int request, ...)
381{
382 va_list ap;
383 MappingMatrix *demixing_matrix;
384 OpusMSEncoder *ms_encoder;
385 int ret = OPUS_OK;
386
387 ms_encoder = get_multistream_encoder(st);
388 demixing_matrix = get_enc_demixing_matrix(st);
389
390 va_start(ap, request);
391 switch(request)
392 {
393 case OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST:
394 {
395 opus_int32 *value = va_arg(ap, opus_int32*);
396 if (!value)
397 {
398 goto bad_arg;
399 }
400 *value =
401 ms_encoder->layout.nb_channels * (ms_encoder->layout.nb_streams
402 + ms_encoder->layout.nb_coupled_streams) * sizeof(opus_int16);
403 }
404 break;
405 case OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST:
406 {
407 opus_int32 *value = va_arg(ap, opus_int32*);
408 if (!value)
409 {
410 goto bad_arg;
411 }
412 *value = demixing_matrix->gain;
413 }
414 break;
415 case OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST:
416 {
417 int i, j, k, l;
418 int nb_input_streams;
419 int nb_output_streams;
420 unsigned char *external_char;
421 opus_int16 *internal_short;
422 opus_int32 external_size;
423 opus_int32 internal_size;
424
425 /* (I/O is in relation to the decoder's perspective). */
426 nb_input_streams = ms_encoder->layout.nb_streams +
427 ms_encoder->layout.nb_coupled_streams;
428 nb_output_streams = ms_encoder->layout.nb_channels;
429
430 external_char = va_arg(ap, unsigned char *);
431 external_size = va_arg(ap, opus_int32);
432 if (!external_char)
433 {
434 goto bad_arg;
435 }
436 internal_short = mapping_matrix_get_data(demixing_matrix);
437 internal_size = nb_input_streams * nb_output_streams * sizeof(opus_int16);
438 if (external_size != internal_size)
439 {
440 goto bad_arg;
441 }
442
443 /* Copy demixing matrix subset to output destination. */
444 l = 0;
445 for (i = 0; i < nb_input_streams; i++) {
446 for (j = 0; j < nb_output_streams; j++) {
447 k = demixing_matrix->rows * i + j;
448 external_char[2*l] = (unsigned char)internal_short[k];
449 external_char[2*l+1] = (unsigned char)(internal_short[k] >> 8);
450 l++;
451 }
452 }
453 }
454 break;
455 default:
456 {
457 ret = opus_multistream_encoder_ctl_va_list(ms_encoder, request, ap);
458 }
459 break;
460 }
461 va_end(ap);
462 return ret;
463
464bad_arg:
465 va_end(ap);
466 return OPUS_BAD_ARG;
467}
468
diff --git a/lib/rbcodec/codecs/libopus/opus_types.h b/lib/rbcodec/codecs/libopus/opus_types.h
index b28e03aea2..7cf675580f 100644
--- a/lib/rbcodec/codecs/libopus/opus_types.h
+++ b/lib/rbcodec/codecs/libopus/opus_types.h
@@ -33,14 +33,29 @@
33#ifndef OPUS_TYPES_H 33#ifndef OPUS_TYPES_H
34#define OPUS_TYPES_H 34#define OPUS_TYPES_H
35 35
36#define opus_int int /* used for counters etc; at least 16 bits */
37#define opus_int64 long long
38#define opus_int8 signed char
39
40#define opus_uint unsigned int /* used for counters etc; at least 16 bits */
41#define opus_uint64 unsigned long long
42#define opus_uint8 unsigned char
43
36/* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h) */ 44/* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h) */
37#if (defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H)) 45#if (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H))
38#include <stdint.h> 46#include <stdint.h>
39 47# undef opus_int64
48# undef opus_int8
49# undef opus_uint64
50# undef opus_uint8
51 typedef int8_t opus_int8;
52 typedef uint8_t opus_uint8;
40 typedef int16_t opus_int16; 53 typedef int16_t opus_int16;
41 typedef uint16_t opus_uint16; 54 typedef uint16_t opus_uint16;
42 typedef int32_t opus_int32; 55 typedef int32_t opus_int32;
43 typedef uint32_t opus_uint32; 56 typedef uint32_t opus_uint32;
57 typedef int64_t opus_int64;
58 typedef uint64_t opus_uint64;
44#elif defined(_WIN32) 59#elif defined(_WIN32)
45 60
46# if defined(__CYGWIN__) 61# if defined(__CYGWIN__)
@@ -148,12 +163,4 @@
148 163
149#endif 164#endif
150 165
151#define opus_int int /* used for counters etc; at least 16 bits */
152#define opus_int64 long long
153#define opus_int8 signed char
154
155#define opus_uint unsigned int /* used for counters etc; at least 16 bits */
156#define opus_uint64 unsigned long long
157#define opus_uint8 unsigned char
158
159#endif /* OPUS_TYPES_H */ 166#endif /* OPUS_TYPES_H */
diff --git a/lib/rbcodec/codecs/libopus/repacketizer.c b/lib/rbcodec/codecs/libopus/repacketizer.c
new file mode 100644
index 0000000000..bda44a148a
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/repacketizer.c
@@ -0,0 +1,349 @@
1/* Copyright (c) 2011 Xiph.Org Foundation
2 Written by Jean-Marc Valin */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "opus.h"
33#include "opus_private.h"
34#include "os_support.h"
35
36
37int opus_repacketizer_get_size(void)
38{
39 return sizeof(OpusRepacketizer);
40}
41
42OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp)
43{
44 rp->nb_frames = 0;
45 return rp;
46}
47
48OpusRepacketizer *opus_repacketizer_create(void)
49{
50 OpusRepacketizer *rp;
51 rp=(OpusRepacketizer *)opus_alloc(opus_repacketizer_get_size());
52 if(rp==NULL)return NULL;
53 return opus_repacketizer_init(rp);
54}
55
56void opus_repacketizer_destroy(OpusRepacketizer *rp)
57{
58 opus_free(rp);
59}
60
61static int opus_repacketizer_cat_impl(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len, int self_delimited)
62{
63 unsigned char tmp_toc;
64 int curr_nb_frames,ret;
65 /* Set of check ToC */
66 if (len<1) return OPUS_INVALID_PACKET;
67 if (rp->nb_frames == 0)
68 {
69 rp->toc = data[0];
70 rp->framesize = opus_packet_get_samples_per_frame(data, 8000);
71 } else if ((rp->toc&0xFC) != (data[0]&0xFC))
72 {
73 /*fprintf(stderr, "toc mismatch: 0x%x vs 0x%x\n", rp->toc, data[0]);*/
74 return OPUS_INVALID_PACKET;
75 }
76 curr_nb_frames = opus_packet_get_nb_frames(data, len);
77 if(curr_nb_frames<1) return OPUS_INVALID_PACKET;
78
79 /* Check the 120 ms maximum packet size */
80 if ((curr_nb_frames+rp->nb_frames)*rp->framesize > 960)
81 {
82 return OPUS_INVALID_PACKET;
83 }
84
85 ret=opus_packet_parse_impl(data, len, self_delimited, &tmp_toc, &rp->frames[rp->nb_frames], &rp->len[rp->nb_frames], NULL, NULL);
86 if(ret<1)return ret;
87
88 rp->nb_frames += curr_nb_frames;
89 return OPUS_OK;
90}
91
92int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len)
93{
94 return opus_repacketizer_cat_impl(rp, data, len, 0);
95}
96
97int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp)
98{
99 return rp->nb_frames;
100}
101
102opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end,
103 unsigned char *data, opus_int32 maxlen, int self_delimited, int pad)
104{
105 int i, count;
106 opus_int32 tot_size;
107 opus_int16 *len;
108 const unsigned char **frames;
109 unsigned char * ptr;
110
111 if (begin<0 || begin>=end || end>rp->nb_frames)
112 {
113 /*fprintf(stderr, "%d %d %d\n", begin, end, rp->nb_frames);*/
114 return OPUS_BAD_ARG;
115 }
116 count = end-begin;
117
118 len = rp->len+begin;
119 frames = rp->frames+begin;
120 if (self_delimited)
121 tot_size = 1 + (len[count-1]>=252);
122 else
123 tot_size = 0;
124
125 ptr = data;
126 if (count==1)
127 {
128 /* Code 0 */
129 tot_size += len[0]+1;
130 if (tot_size > maxlen)
131 return OPUS_BUFFER_TOO_SMALL;
132 *ptr++ = rp->toc&0xFC;
133 } else if (count==2)
134 {
135 if (len[1] == len[0])
136 {
137 /* Code 1 */
138 tot_size += 2*len[0]+1;
139 if (tot_size > maxlen)
140 return OPUS_BUFFER_TOO_SMALL;
141 *ptr++ = (rp->toc&0xFC) | 0x1;
142 } else {
143 /* Code 2 */
144 tot_size += len[0]+len[1]+2+(len[0]>=252);
145 if (tot_size > maxlen)
146 return OPUS_BUFFER_TOO_SMALL;
147 *ptr++ = (rp->toc&0xFC) | 0x2;
148 ptr += encode_size(len[0], ptr);
149 }
150 }
151 if (count > 2 || (pad && tot_size < maxlen))
152 {
153 /* Code 3 */
154 int vbr;
155 int pad_amount=0;
156
157 /* Restart the process for the padding case */
158 ptr = data;
159 if (self_delimited)
160 tot_size = 1 + (len[count-1]>=252);
161 else
162 tot_size = 0;
163 vbr = 0;
164 for (i=1;i<count;i++)
165 {
166 if (len[i] != len[0])
167 {
168 vbr=1;
169 break;
170 }
171 }
172 if (vbr)
173 {
174 tot_size += 2;
175 for (i=0;i<count-1;i++)
176 tot_size += 1 + (len[i]>=252) + len[i];
177 tot_size += len[count-1];
178
179 if (tot_size > maxlen)
180 return OPUS_BUFFER_TOO_SMALL;
181 *ptr++ = (rp->toc&0xFC) | 0x3;
182 *ptr++ = count | 0x80;
183 } else {
184 tot_size += count*len[0]+2;
185 if (tot_size > maxlen)
186 return OPUS_BUFFER_TOO_SMALL;
187 *ptr++ = (rp->toc&0xFC) | 0x3;
188 *ptr++ = count;
189 }
190 pad_amount = pad ? (maxlen-tot_size) : 0;
191 if (pad_amount != 0)
192 {
193 int nb_255s;
194 data[1] |= 0x40;
195 nb_255s = (pad_amount-1)/255;
196 for (i=0;i<nb_255s;i++)
197 *ptr++ = 255;
198 *ptr++ = pad_amount-255*nb_255s-1;
199 tot_size += pad_amount;
200 }
201 if (vbr)
202 {
203 for (i=0;i<count-1;i++)
204 ptr += encode_size(len[i], ptr);
205 }
206 }
207 if (self_delimited) {
208 int sdlen = encode_size(len[count-1], ptr);
209 ptr += sdlen;
210 }
211 /* Copy the actual data */
212 for (i=0;i<count;i++)
213 {
214 /* Using OPUS_MOVE() instead of OPUS_COPY() in case we're doing in-place
215 padding from opus_packet_pad or opus_packet_unpad(). */
216 /* assert disabled because it's not valid in C. */
217 /* celt_assert(frames[i] + len[i] <= data || ptr <= frames[i]); */
218 OPUS_MOVE(ptr, frames[i], len[i]);
219 ptr += len[i];
220 }
221 if (pad)
222 {
223 /* Fill padding with zeros. */
224 while (ptr<data+maxlen)
225 *ptr++=0;
226 }
227 return tot_size;
228}
229
230opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen)
231{
232 return opus_repacketizer_out_range_impl(rp, begin, end, data, maxlen, 0, 0);
233}
234
235opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen)
236{
237 return opus_repacketizer_out_range_impl(rp, 0, rp->nb_frames, data, maxlen, 0, 0);
238}
239
240int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len)
241{
242 OpusRepacketizer rp;
243 opus_int32 ret;
244 if (len < 1)
245 return OPUS_BAD_ARG;
246 if (len==new_len)
247 return OPUS_OK;
248 else if (len > new_len)
249 return OPUS_BAD_ARG;
250 opus_repacketizer_init(&rp);
251 /* Moving payload to the end of the packet so we can do in-place padding */
252 OPUS_MOVE(data+new_len-len, data, len);
253 ret = opus_repacketizer_cat(&rp, data+new_len-len, len);
254 if (ret != OPUS_OK)
255 return ret;
256 ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, new_len, 0, 1);
257 if (ret > 0)
258 return OPUS_OK;
259 else
260 return ret;
261}
262
263opus_int32 opus_packet_unpad(unsigned char *data, opus_int32 len)
264{
265 OpusRepacketizer rp;
266 opus_int32 ret;
267 if (len < 1)
268 return OPUS_BAD_ARG;
269 opus_repacketizer_init(&rp);
270 ret = opus_repacketizer_cat(&rp, data, len);
271 if (ret < 0)
272 return ret;
273 ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, len, 0, 0);
274 celt_assert(ret > 0 && ret <= len);
275 return ret;
276}
277
278int opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len, int nb_streams)
279{
280 int s;
281 int count;
282 unsigned char toc;
283 opus_int16 size[48];
284 opus_int32 packet_offset;
285 opus_int32 amount;
286
287 if (len < 1)
288 return OPUS_BAD_ARG;
289 if (len==new_len)
290 return OPUS_OK;
291 else if (len > new_len)
292 return OPUS_BAD_ARG;
293 amount = new_len - len;
294 /* Seek to last stream */
295 for (s=0;s<nb_streams-1;s++)
296 {
297 if (len<=0)
298 return OPUS_INVALID_PACKET;
299 count = opus_packet_parse_impl(data, len, 1, &toc, NULL,
300 size, NULL, &packet_offset);
301 if (count<0)
302 return count;
303 data += packet_offset;
304 len -= packet_offset;
305 }
306 return opus_packet_pad(data, len, len+amount);
307}
308
309opus_int32 opus_multistream_packet_unpad(unsigned char *data, opus_int32 len, int nb_streams)
310{
311 int s;
312 unsigned char toc;
313 opus_int16 size[48];
314 opus_int32 packet_offset;
315 OpusRepacketizer rp;
316 unsigned char *dst;
317 opus_int32 dst_len;
318
319 if (len < 1)
320 return OPUS_BAD_ARG;
321 dst = data;
322 dst_len = 0;
323 /* Unpad all frames */
324 for (s=0;s<nb_streams;s++)
325 {
326 opus_int32 ret;
327 int self_delimited = s!=nb_streams-1;
328 if (len<=0)
329 return OPUS_INVALID_PACKET;
330 opus_repacketizer_init(&rp);
331 ret = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL,
332 size, NULL, &packet_offset);
333 if (ret<0)
334 return ret;
335 ret = opus_repacketizer_cat_impl(&rp, data, packet_offset, self_delimited);
336 if (ret < 0)
337 return ret;
338 ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, dst, len, self_delimited, 0);
339 if (ret < 0)
340 return ret;
341 else
342 dst_len += ret;
343 dst += ret;
344 data += packet_offset;
345 len -= packet_offset;
346 }
347 return dst_len;
348}
349
diff --git a/lib/rbcodec/codecs/libopus/repacketizer_demo.c b/lib/rbcodec/codecs/libopus/repacketizer_demo.c
new file mode 100644
index 0000000000..dc05c1b359
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/repacketizer_demo.c
@@ -0,0 +1,217 @@
1/* Copyright (c) 2011 Xiph.Org Foundation
2 Written by Jean-Marc Valin */
3/*
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "opus.h"
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36
37#define MAX_PACKETOUT 32000
38
39void usage(char *argv0)
40{
41 fprintf(stderr, "usage: %s [options] input_file output_file\n", argv0);
42}
43
44static void int_to_char(opus_uint32 i, unsigned char ch[4])
45{
46 ch[0] = i>>24;
47 ch[1] = (i>>16)&0xFF;
48 ch[2] = (i>>8)&0xFF;
49 ch[3] = i&0xFF;
50}
51
52static opus_uint32 char_to_int(unsigned char ch[4])
53{
54 return ((opus_uint32)ch[0]<<24) | ((opus_uint32)ch[1]<<16)
55 | ((opus_uint32)ch[2]<< 8) | (opus_uint32)ch[3];
56}
57
58int main(int argc, char *argv[])
59{
60 int i, eof=0;
61 FILE *fin, *fout;
62 unsigned char packets[48][1500];
63 int len[48];
64 int rng[48];
65 OpusRepacketizer *rp;
66 unsigned char output_packet[MAX_PACKETOUT];
67 int merge = 1, split=0;
68
69 if (argc < 3)
70 {
71 usage(argv[0]);
72 return EXIT_FAILURE;
73 }
74 for (i=1;i<argc-2;i++)
75 {
76 if (strcmp(argv[i], "-merge")==0)
77 {
78 merge = atoi(argv[i+1]);
79 if(merge<1)
80 {
81 fprintf(stderr, "-merge parameter must be at least 1.\n");
82 return EXIT_FAILURE;
83 }
84 if(merge>48)
85 {
86 fprintf(stderr, "-merge parameter must be less than 48.\n");
87 return EXIT_FAILURE;
88 }
89 i++;
90 } else if (strcmp(argv[i], "-split")==0)
91 split = 1;
92 else
93 {
94 fprintf(stderr, "Unknown option: %s\n", argv[i]);
95 usage(argv[0]);
96 return EXIT_FAILURE;
97 }
98 }
99 fin = fopen(argv[argc-2], "r");
100 if(fin==NULL)
101 {
102 fprintf(stderr, "Error opening input file: %s\n", argv[argc-2]);
103 return EXIT_FAILURE;
104 }
105 fout = fopen(argv[argc-1], "w");
106 if(fout==NULL)
107 {
108 fprintf(stderr, "Error opening output file: %s\n", argv[argc-1]);
109 fclose(fin);
110 return EXIT_FAILURE;
111 }
112
113 rp = opus_repacketizer_create();
114 while (!eof)
115 {
116 int err;
117 int nb_packets=merge;
118 opus_repacketizer_init(rp);
119 for (i=0;i<nb_packets;i++)
120 {
121 unsigned char ch[4];
122 err = fread(ch, 1, 4, fin);
123 len[i] = char_to_int(ch);
124 /*fprintf(stderr, "in len = %d\n", len[i]);*/
125 if (len[i]>1500 || len[i]<0)
126 {
127 if (feof(fin))
128 {
129 eof = 1;
130 } else {
131 fprintf(stderr, "Invalid payload length\n");
132 fclose(fin);
133 fclose(fout);
134 return EXIT_FAILURE;
135 }
136 break;
137 }
138 err = fread(ch, 1, 4, fin);
139 rng[i] = char_to_int(ch);
140 err = fread(packets[i], 1, len[i], fin);
141 if (feof(fin))
142 {
143 eof = 1;
144 break;
145 }
146 err = opus_repacketizer_cat(rp, packets[i], len[i]);
147 if (err!=OPUS_OK)
148 {
149 fprintf(stderr, "opus_repacketizer_cat() failed: %s\n", opus_strerror(err));
150 break;
151 }
152 }
153 nb_packets = i;
154
155 if (eof)
156 break;
157
158 if (!split)
159 {
160 err = opus_repacketizer_out(rp, output_packet, MAX_PACKETOUT);
161 if (err>0) {
162 unsigned char int_field[4];
163 int_to_char(err, int_field);
164 if(fwrite(int_field, 1, 4, fout)!=4){
165 fprintf(stderr, "Error writing.\n");
166 return EXIT_FAILURE;
167 }
168 int_to_char(rng[nb_packets-1], int_field);
169 if (fwrite(int_field, 1, 4, fout)!=4) {
170 fprintf(stderr, "Error writing.\n");
171 return EXIT_FAILURE;
172 }
173 if (fwrite(output_packet, 1, err, fout)!=(unsigned)err) {
174 fprintf(stderr, "Error writing.\n");
175 return EXIT_FAILURE;
176 }
177 /*fprintf(stderr, "out len = %d\n", err);*/
178 } else {
179 fprintf(stderr, "opus_repacketizer_out() failed: %s\n", opus_strerror(err));
180 }
181 } else {
182 int nb_frames = opus_repacketizer_get_nb_frames(rp);
183 for (i=0;i<nb_frames;i++)
184 {
185 err = opus_repacketizer_out_range(rp, i, i+1, output_packet, MAX_PACKETOUT);
186 if (err>0) {
187 unsigned char int_field[4];
188 int_to_char(err, int_field);
189 if (fwrite(int_field, 1, 4, fout)!=4) {
190 fprintf(stderr, "Error writing.\n");
191 return EXIT_FAILURE;
192 }
193 if (i==nb_frames-1)
194 int_to_char(rng[nb_packets-1], int_field);
195 else
196 int_to_char(0, int_field);
197 if (fwrite(int_field, 1, 4, fout)!=4) {
198 fprintf(stderr, "Error writing.\n");
199 return EXIT_FAILURE;
200 }
201 if (fwrite(output_packet, 1, err, fout)!=(unsigned)err) {
202 fprintf(stderr, "Error writing.\n");
203 return EXIT_FAILURE;
204 }
205 /*fprintf(stderr, "out len = %d\n", err);*/
206 } else {
207 fprintf(stderr, "opus_repacketizer_out() failed: %s\n", opus_strerror(err));
208 }
209
210 }
211 }
212 }
213
214 fclose(fin);
215 fclose(fout);
216 return EXIT_SUCCESS;
217}
diff --git a/lib/rbcodec/codecs/libopus/silk/A2NLSF.c b/lib/rbcodec/codecs/libopus/silk/A2NLSF.c
new file mode 100644
index 0000000000..b487686ff9
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/A2NLSF.c
@@ -0,0 +1,267 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28/* Conversion between prediction filter coefficients and NLSFs */
29/* Requires the order to be an even number */
30/* A piecewise linear approximation maps LSF <-> cos(LSF) */
31/* Therefore the result is not accurate NLSFs, but the two */
32/* functions are accurate inverses of each other */
33
34#ifdef HAVE_CONFIG_H
35#include "config.h"
36#endif
37
38#include "SigProc_FIX.h"
39#include "tables.h"
40
41/* Number of binary divisions, when not in low complexity mode */
42#define BIN_DIV_STEPS_A2NLSF_FIX 3 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */
43#define MAX_ITERATIONS_A2NLSF_FIX 16
44
45/* Helper function for A2NLSF(..) */
46/* Transforms polynomials from cos(n*f) to cos(f)^n */
47static OPUS_INLINE void silk_A2NLSF_trans_poly(
48 opus_int32 *p, /* I/O Polynomial */
49 const opus_int dd /* I Polynomial order (= filter order / 2 ) */
50)
51{
52 opus_int k, n;
53
54 for( k = 2; k <= dd; k++ ) {
55 for( n = dd; n > k; n-- ) {
56 p[ n - 2 ] -= p[ n ];
57 }
58 p[ k - 2 ] -= silk_LSHIFT( p[ k ], 1 );
59 }
60}
61/* Helper function for A2NLSF(..) */
62/* Polynomial evaluation */
63static OPUS_INLINE opus_int32 silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in Q16 */
64 opus_int32 *p, /* I Polynomial, Q16 */
65 const opus_int32 x, /* I Evaluation point, Q12 */
66 const opus_int dd /* I Order */
67)
68{
69 opus_int n;
70 opus_int32 x_Q16, y32;
71
72 y32 = p[ dd ]; /* Q16 */
73 x_Q16 = silk_LSHIFT( x, 4 );
74
75 if ( opus_likely( 8 == dd ) )
76 {
77 y32 = silk_SMLAWW( p[ 7 ], y32, x_Q16 );
78 y32 = silk_SMLAWW( p[ 6 ], y32, x_Q16 );
79 y32 = silk_SMLAWW( p[ 5 ], y32, x_Q16 );
80 y32 = silk_SMLAWW( p[ 4 ], y32, x_Q16 );
81 y32 = silk_SMLAWW( p[ 3 ], y32, x_Q16 );
82 y32 = silk_SMLAWW( p[ 2 ], y32, x_Q16 );
83 y32 = silk_SMLAWW( p[ 1 ], y32, x_Q16 );
84 y32 = silk_SMLAWW( p[ 0 ], y32, x_Q16 );
85 }
86 else
87 {
88 for( n = dd - 1; n >= 0; n-- ) {
89 y32 = silk_SMLAWW( p[ n ], y32, x_Q16 ); /* Q16 */
90 }
91 }
92 return y32;
93}
94
95static OPUS_INLINE void silk_A2NLSF_init(
96 const opus_int32 *a_Q16,
97 opus_int32 *P,
98 opus_int32 *Q,
99 const opus_int dd
100)
101{
102 opus_int k;
103
104 /* Convert filter coefs to even and odd polynomials */
105 P[dd] = silk_LSHIFT( 1, 16 );
106 Q[dd] = silk_LSHIFT( 1, 16 );
107 for( k = 0; k < dd; k++ ) {
108 P[ k ] = -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ]; /* Q16 */
109 Q[ k ] = -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ]; /* Q16 */
110 }
111
112 /* Divide out zeros as we have that for even filter orders, */
113 /* z = 1 is always a root in Q, and */
114 /* z = -1 is always a root in P */
115 for( k = dd; k > 0; k-- ) {
116 P[ k - 1 ] -= P[ k ];
117 Q[ k - 1 ] += Q[ k ];
118 }
119
120 /* Transform polynomials from cos(n*f) to cos(f)^n */
121 silk_A2NLSF_trans_poly( P, dd );
122 silk_A2NLSF_trans_poly( Q, dd );
123}
124
125/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */
126/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */
127void silk_A2NLSF(
128 opus_int16 *NLSF, /* O Normalized Line Spectral Frequencies in Q15 (0..2^15-1) [d] */
129 opus_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */
130 const opus_int d /* I Filter order (must be even) */
131)
132{
133 opus_int i, k, m, dd, root_ix, ffrac;
134 opus_int32 xlo, xhi, xmid;
135 opus_int32 ylo, yhi, ymid, thr;
136 opus_int32 nom, den;
137 opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ];
138 opus_int32 Q[ SILK_MAX_ORDER_LPC / 2 + 1 ];
139 opus_int32 *PQ[ 2 ];
140 opus_int32 *p;
141
142 /* Store pointers to array */
143 PQ[ 0 ] = P;
144 PQ[ 1 ] = Q;
145
146 dd = silk_RSHIFT( d, 1 );
147
148 silk_A2NLSF_init( a_Q16, P, Q, dd );
149
150 /* Find roots, alternating between P and Q */
151 p = P; /* Pointer to polynomial */
152
153 xlo = silk_LSFCosTab_FIX_Q12[ 0 ]; /* Q12*/
154 ylo = silk_A2NLSF_eval_poly( p, xlo, dd );
155
156 if( ylo < 0 ) {
157 /* Set the first NLSF to zero and move on to the next */
158 NLSF[ 0 ] = 0;
159 p = Q; /* Pointer to polynomial */
160 ylo = silk_A2NLSF_eval_poly( p, xlo, dd );
161 root_ix = 1; /* Index of current root */
162 } else {
163 root_ix = 0; /* Index of current root */
164 }
165 k = 1; /* Loop counter */
166 i = 0; /* Counter for bandwidth expansions applied */
167 thr = 0;
168 while( 1 ) {
169 /* Evaluate polynomial */
170 xhi = silk_LSFCosTab_FIX_Q12[ k ]; /* Q12 */
171 yhi = silk_A2NLSF_eval_poly( p, xhi, dd );
172
173 /* Detect zero crossing */
174 if( ( ylo <= 0 && yhi >= thr ) || ( ylo >= 0 && yhi <= -thr ) ) {
175 if( yhi == 0 ) {
176 /* If the root lies exactly at the end of the current */
177 /* interval, look for the next root in the next interval */
178 thr = 1;
179 } else {
180 thr = 0;
181 }
182 /* Binary division */
183 ffrac = -256;
184 for( m = 0; m < BIN_DIV_STEPS_A2NLSF_FIX; m++ ) {
185 /* Evaluate polynomial */
186 xmid = silk_RSHIFT_ROUND( xlo + xhi, 1 );
187 ymid = silk_A2NLSF_eval_poly( p, xmid, dd );
188
189 /* Detect zero crossing */
190 if( ( ylo <= 0 && ymid >= 0 ) || ( ylo >= 0 && ymid <= 0 ) ) {
191 /* Reduce frequency */
192 xhi = xmid;
193 yhi = ymid;
194 } else {
195 /* Increase frequency */
196 xlo = xmid;
197 ylo = ymid;
198 ffrac = silk_ADD_RSHIFT( ffrac, 128, m );
199 }
200 }
201
202 /* Interpolate */
203 if( silk_abs( ylo ) < 65536 ) {
204 /* Avoid dividing by zero */
205 den = ylo - yhi;
206 nom = silk_LSHIFT( ylo, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) + silk_RSHIFT( den, 1 );
207 if( den != 0 ) {
208 ffrac += silk_DIV32( nom, den );
209 }
210 } else {
211 /* No risk of dividing by zero because abs(ylo - yhi) >= abs(ylo) >= 65536 */
212 ffrac += silk_DIV32( ylo, silk_RSHIFT( ylo - yhi, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) );
213 }
214 NLSF[ root_ix ] = (opus_int16)silk_min_32( silk_LSHIFT( (opus_int32)k, 8 ) + ffrac, silk_int16_MAX );
215
216 silk_assert( NLSF[ root_ix ] >= 0 );
217
218 root_ix++; /* Next root */
219 if( root_ix >= d ) {
220 /* Found all roots */
221 break;
222 }
223 /* Alternate pointer to polynomial */
224 p = PQ[ root_ix & 1 ];
225
226 /* Evaluate polynomial */
227 xlo = silk_LSFCosTab_FIX_Q12[ k - 1 ]; /* Q12*/
228 ylo = silk_LSHIFT( 1 - ( root_ix & 2 ), 12 );
229 } else {
230 /* Increment loop counter */
231 k++;
232 xlo = xhi;
233 ylo = yhi;
234 thr = 0;
235
236 if( k > LSF_COS_TAB_SZ_FIX ) {
237 i++;
238 if( i > MAX_ITERATIONS_A2NLSF_FIX ) {
239 /* Set NLSFs to white spectrum and exit */
240 NLSF[ 0 ] = (opus_int16)silk_DIV32_16( 1 << 15, d + 1 );
241 for( k = 1; k < d; k++ ) {
242 NLSF[ k ] = (opus_int16)silk_ADD16( NLSF[ k-1 ], NLSF[ 0 ] );
243 }
244 return;
245 }
246
247 /* Error: Apply progressively more bandwidth expansion and run again */
248 silk_bwexpander_32( a_Q16, d, 65536 - silk_LSHIFT( 1, i ) );
249
250 silk_A2NLSF_init( a_Q16, P, Q, dd );
251 p = P; /* Pointer to polynomial */
252 xlo = silk_LSFCosTab_FIX_Q12[ 0 ]; /* Q12*/
253 ylo = silk_A2NLSF_eval_poly( p, xlo, dd );
254 if( ylo < 0 ) {
255 /* Set the first NLSF to zero and move on to the next */
256 NLSF[ 0 ] = 0;
257 p = Q; /* Pointer to polynomial */
258 ylo = silk_A2NLSF_eval_poly( p, xlo, dd );
259 root_ix = 1; /* Index of current root */
260 } else {
261 root_ix = 0; /* Index of current root */
262 }
263 k = 1; /* Reset loop counter */
264 }
265 }
266 }
267}
diff --git a/lib/rbcodec/codecs/libopus/silk/API.h b/lib/rbcodec/codecs/libopus/silk/API.h
index f0601bcf6b..4d90ff9aa3 100644
--- a/lib/rbcodec/codecs/libopus/silk/API.h
+++ b/lib/rbcodec/codecs/libopus/silk/API.h
@@ -80,7 +80,8 @@ opus_int silk_Encode( /* O Returns error co
80 opus_int nSamplesIn, /* I Number of samples in input vector */ 80 opus_int nSamplesIn, /* I Number of samples in input vector */
81 ec_enc *psRangeEnc, /* I/O Compressor data structure */ 81 ec_enc *psRangeEnc, /* I/O Compressor data structure */
82 opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */ 82 opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */
83 const opus_int prefillFlag /* I Flag to indicate prefilling buffers no coding */ 83 const opus_int prefillFlag, /* I Flag to indicate prefilling buffers no coding */
84 int activity /* I Decision of Opus voice activity detector */
84); 85);
85 86
86/****************************************/ 87/****************************************/
@@ -111,7 +112,8 @@ opus_int silk_Decode( /* O Returns error co
111 opus_int newPacketFlag, /* I Indicates first decoder call for this packet */ 112 opus_int newPacketFlag, /* I Indicates first decoder call for this packet */
112 ec_dec *psRangeDec, /* I/O Compressor data structure */ 113 ec_dec *psRangeDec, /* I/O Compressor data structure */
113 opus_int16 *samplesOut, /* O Decoded output speech vector */ 114 opus_int16 *samplesOut, /* O Decoded output speech vector */
114 opus_int32 *nSamplesOut /* O Number of samples decoded */ 115 opus_int32 *nSamplesOut, /* O Number of samples decoded */
116 int arch /* I Run-time architecture */
115); 117);
116 118
117#if 0 119#if 0
diff --git a/lib/rbcodec/codecs/libopus/silk/CNG.c b/lib/rbcodec/codecs/libopus/silk/CNG.c
index bb30a7ccf2..ef8e38df9f 100644
--- a/lib/rbcodec/codecs/libopus/silk/CNG.c
+++ b/lib/rbcodec/codecs/libopus/silk/CNG.c
@@ -34,9 +34,8 @@ POSSIBILITY OF SUCH DAMAGE.
34 34
35/* Generates excitation for CNG LPC synthesis */ 35/* Generates excitation for CNG LPC synthesis */
36static OPUS_INLINE void silk_CNG_exc( 36static OPUS_INLINE void silk_CNG_exc(
37 opus_int32 exc_Q10[], /* O CNG excitation signal Q10 */ 37 opus_int32 exc_Q14[], /* O CNG excitation signal Q10 */
38 opus_int32 exc_buf_Q14[], /* I Random samples buffer Q10 */ 38 opus_int32 exc_buf_Q14[], /* I Random samples buffer Q10 */
39 opus_int32 Gain_Q16, /* I Gain to apply */
40 opus_int length, /* I Length */ 39 opus_int length, /* I Length */
41 opus_int32 *rand_seed /* I/O Seed to random index generator */ 40 opus_int32 *rand_seed /* I/O Seed to random index generator */
42) 41)
@@ -55,7 +54,7 @@ static OPUS_INLINE void silk_CNG_exc(
55 idx = (opus_int)( silk_RSHIFT( seed, 24 ) & exc_mask ); 54 idx = (opus_int)( silk_RSHIFT( seed, 24 ) & exc_mask );
56 silk_assert( idx >= 0 ); 55 silk_assert( idx >= 0 );
57 silk_assert( idx <= CNG_BUF_MASK_MAX ); 56 silk_assert( idx <= CNG_BUF_MASK_MAX );
58 exc_Q10[ i ] = (opus_int16)silk_SAT16( silk_SMULWW( exc_buf_Q14[ idx ], Gain_Q16 >> 4 ) ); 57 exc_Q14[ i ] = exc_buf_Q14[ idx ];
59 } 58 }
60 *rand_seed = seed; 59 *rand_seed = seed;
61} 60}
@@ -85,7 +84,7 @@ void silk_CNG(
85) 84)
86{ 85{
87 opus_int i, subfr; 86 opus_int i, subfr;
88 opus_int32 sum_Q6, max_Gain_Q16, gain_Q16; 87 opus_int32 LPC_pred_Q10, max_Gain_Q16, gain_Q16, gain_Q10;
89 opus_int16 A_Q12[ MAX_LPC_ORDER ]; 88 opus_int16 A_Q12[ MAX_LPC_ORDER ];
90 silk_CNG_struct *psCNG = &psDec->sCNG; 89 silk_CNG_struct *psCNG = &psDec->sCNG;
91 SAVE_STACK; 90 SAVE_STACK;
@@ -124,56 +123,60 @@ void silk_CNG(
124 123
125 /* Add CNG when packet is lost or during DTX */ 124 /* Add CNG when packet is lost or during DTX */
126 if( psDec->lossCnt ) { 125 if( psDec->lossCnt ) {
127 VARDECL( opus_int32, CNG_sig_Q10 ); 126 VARDECL( opus_int32, CNG_sig_Q14 );
128 ALLOC( CNG_sig_Q10, length + MAX_LPC_ORDER, opus_int32 ); 127 ALLOC( CNG_sig_Q14, length + MAX_LPC_ORDER, opus_int32 );
129 128
130 /* Generate CNG excitation */ 129 /* Generate CNG excitation */
131 gain_Q16 = silk_SMULWW( psDec->sPLC.randScale_Q14, psDec->sPLC.prevGain_Q16[1] ); 130 gain_Q16 = silk_SMULWW( psDec->sPLC.randScale_Q14, psDec->sPLC.prevGain_Q16[1] );
132 if( gain_Q16 >= (1 << 21) || psCNG->CNG_smth_Gain_Q16 > (1 << 23) ) { 131 if( gain_Q16 >= (1 << 21) || psCNG->CNG_smth_Gain_Q16 > (1 << 23) ) {
133 gain_Q16 = silk_SMULTT( gain_Q16, gain_Q16 ); 132 gain_Q16 = silk_SMULTT( gain_Q16, gain_Q16 );
134 gain_Q16 = silk_SUB_LSHIFT32(silk_SMULTT( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 ); 133 gain_Q16 = silk_SUB_LSHIFT32(silk_SMULTT( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 );
135 gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 16 ); 134 gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 16 );
136 } else { 135 } else {
137 gain_Q16 = silk_SMULWW( gain_Q16, gain_Q16 ); 136 gain_Q16 = silk_SMULWW( gain_Q16, gain_Q16 );
138 gain_Q16 = silk_SUB_LSHIFT32(silk_SMULWW( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 ); 137 gain_Q16 = silk_SUB_LSHIFT32(silk_SMULWW( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 );
139 gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 8 ); 138 gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 8 );
140 } 139 }
141 silk_CNG_exc( CNG_sig_Q10 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, gain_Q16, length, &psCNG->rand_seed ); 140 gain_Q10 = silk_RSHIFT( gain_Q16, 6 );
141
142 silk_CNG_exc( CNG_sig_Q14 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, length, &psCNG->rand_seed );
142 143
143 /* Convert CNG NLSF to filter representation */ 144 /* Convert CNG NLSF to filter representation */
144 silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order ); 145 silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order, psDec->arch );
145 146
146 /* Generate CNG signal, by synthesis filtering */ 147 /* Generate CNG signal, by synthesis filtering */
147 silk_memcpy( CNG_sig_Q10, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( opus_int32 ) ); 148 silk_memcpy( CNG_sig_Q14, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( opus_int32 ) );
149 celt_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
148 for( i = 0; i < length; i++ ) { 150 for( i = 0; i < length; i++ ) {
149 silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
150 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ 151 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
151 sum_Q6 = silk_RSHIFT( psDec->LPC_order, 1 ); 152 LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 );
152 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] ); 153 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] );
153 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] ); 154 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] );
154 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] ); 155 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] );
155 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 4 ], A_Q12[ 3 ] ); 156 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 4 ], A_Q12[ 3 ] );
156 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 5 ], A_Q12[ 4 ] ); 157 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 5 ], A_Q12[ 4 ] );
157 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 6 ], A_Q12[ 5 ] ); 158 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 6 ], A_Q12[ 5 ] );
158 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 7 ], A_Q12[ 6 ] ); 159 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 7 ], A_Q12[ 6 ] );
159 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] ); 160 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] );
160 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] ); 161 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] );
161 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] ); 162 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] );
162 if( psDec->LPC_order == 16 ) { 163 if( psDec->LPC_order == 16 ) {
163 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 11 ], A_Q12[ 10 ] ); 164 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 11 ], A_Q12[ 10 ] );
164 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 12 ], A_Q12[ 11 ] ); 165 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 12 ], A_Q12[ 11 ] );
165 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 13 ], A_Q12[ 12 ] ); 166 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 13 ], A_Q12[ 12 ] );
166 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 14 ], A_Q12[ 13 ] ); 167 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 14 ], A_Q12[ 13 ] );
167 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 15 ], A_Q12[ 14 ] ); 168 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 15 ], A_Q12[ 14 ] );
168 sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 16 ], A_Q12[ 15 ] ); 169 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 16 ], A_Q12[ 15 ] );
169 } 170 }
170 171
171 /* Update states */ 172 /* Update states */
172 CNG_sig_Q10[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT( CNG_sig_Q10[ MAX_LPC_ORDER + i ], sum_Q6, 4 ); 173 CNG_sig_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_SAT32( CNG_sig_Q14[ MAX_LPC_ORDER + i ], silk_LSHIFT_SAT32( LPC_pred_Q10, 4 ) );
174
175 /* Scale with Gain and add to input signal */
176 frame[ i ] = (opus_int16)silk_ADD_SAT16( frame[ i ], silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( CNG_sig_Q14[ MAX_LPC_ORDER + i ], gain_Q10 ), 8 ) ) );
173 177
174 frame[ i ] = silk_ADD_SAT16( frame[ i ], silk_RSHIFT_ROUND( CNG_sig_Q10[ MAX_LPC_ORDER + i ], 10 ) );
175 } 178 }
176 silk_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q10[ length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); 179 silk_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q14[ length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );
177 } else { 180 } else {
178 silk_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( opus_int32 ) ); 181 silk_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( opus_int32 ) );
179 } 182 }
diff --git a/lib/rbcodec/codecs/libopus/silk/HP_variable_cutoff.c b/lib/rbcodec/codecs/libopus/silk/HP_variable_cutoff.c
new file mode 100644
index 0000000000..bbe10f04ce
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/HP_variable_cutoff.c
@@ -0,0 +1,77 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31#ifdef FIXED_POINT
32#include "main_FIX.h"
33#else
34#include "main_FLP.h"
35#endif
36#include "tuning_parameters.h"
37
38/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */
39void silk_HP_variable_cutoff(
40 silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */
41)
42{
43 opus_int quality_Q15;
44 opus_int32 pitch_freq_Hz_Q16, pitch_freq_log_Q7, delta_freq_Q7;
45 silk_encoder_state *psEncC1 = &state_Fxx[ 0 ].sCmn;
46
47 /* Adaptive cutoff frequency: estimate low end of pitch frequency range */
48 if( psEncC1->prevSignalType == TYPE_VOICED ) {
49 /* difference, in log domain */
50 pitch_freq_Hz_Q16 = silk_DIV32_16( silk_LSHIFT( silk_MUL( psEncC1->fs_kHz, 1000 ), 16 ), psEncC1->prevLag );
51 pitch_freq_log_Q7 = silk_lin2log( pitch_freq_Hz_Q16 ) - ( 16 << 7 );
52
53 /* adjustment based on quality */
54 quality_Q15 = psEncC1->input_quality_bands_Q15[ 0 ];
55 pitch_freq_log_Q7 = silk_SMLAWB( pitch_freq_log_Q7, silk_SMULWB( silk_LSHIFT( -quality_Q15, 2 ), quality_Q15 ),
56 pitch_freq_log_Q7 - ( silk_lin2log( SILK_FIX_CONST( VARIABLE_HP_MIN_CUTOFF_HZ, 16 ) ) - ( 16 << 7 ) ) );
57
58 /* delta_freq = pitch_freq_log - psEnc->variable_HP_smth1; */
59 delta_freq_Q7 = pitch_freq_log_Q7 - silk_RSHIFT( psEncC1->variable_HP_smth1_Q15, 8 );
60 if( delta_freq_Q7 < 0 ) {
61 /* less smoothing for decreasing pitch frequency, to track something close to the minimum */
62 delta_freq_Q7 = silk_MUL( delta_freq_Q7, 3 );
63 }
64
65 /* limit delta, to reduce impact of outliers in pitch estimation */
66 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 ) );
67
68 /* update smoother */
69 psEncC1->variable_HP_smth1_Q15 = silk_SMLAWB( psEncC1->variable_HP_smth1_Q15,
70 silk_SMULBB( psEncC1->speech_activity_Q8, delta_freq_Q7 ), SILK_FIX_CONST( VARIABLE_HP_SMTH_COEF1, 16 ) );
71
72 /* limit frequency range */
73 psEncC1->variable_HP_smth1_Q15 = silk_LIMIT_32( psEncC1->variable_HP_smth1_Q15,
74 silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ),
75 silk_LSHIFT( silk_lin2log( VARIABLE_HP_MAX_CUTOFF_HZ ), 8 ) );
76 }
77}
diff --git a/lib/rbcodec/codecs/libopus/silk/LPC_analysis_filter.c b/lib/rbcodec/codecs/libopus/silk/LPC_analysis_filter.c
index 9d1f16cb7d..d34b5eb709 100644
--- a/lib/rbcodec/codecs/libopus/silk/LPC_analysis_filter.c
+++ b/lib/rbcodec/codecs/libopus/silk/LPC_analysis_filter.c
@@ -39,17 +39,24 @@ POSSIBILITY OF SUCH DAMAGE.
39/* first d output samples are set to zero */ 39/* first d output samples are set to zero */
40/*******************************************/ 40/*******************************************/
41 41
42/* OPT: Using celt_fir() for this function should be faster, but it may cause
43 integer overflows in intermediate values (not final results), which the
44 current implementation silences by casting to unsigned. Enabling
45 this should be safe in pretty much all cases, even though it is not technically
46 C89-compliant. */
47#define USE_CELT_FIR 0
48
42void silk_LPC_analysis_filter( 49void silk_LPC_analysis_filter(
43 opus_int16 *out, /* O Output signal */ 50 opus_int16 *out, /* O Output signal */
44 const opus_int16 *in, /* I Input signal */ 51 const opus_int16 *in, /* I Input signal */
45 const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */ 52 const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */
46 const opus_int32 len, /* I Signal length */ 53 const opus_int32 len, /* I Signal length */
47 const opus_int32 d /* I Filter order */ 54 const opus_int32 d, /* I Filter order */
55 int arch /* I Run-time architecture */
48) 56)
49{ 57{
50 opus_int j; 58 opus_int j;
51#ifdef FIXED_POINT 59#if defined(FIXED_POINT) && USE_CELT_FIR
52 opus_int16 mem[SILK_MAX_ORDER_LPC];
53 opus_int16 num[SILK_MAX_ORDER_LPC]; 60 opus_int16 num[SILK_MAX_ORDER_LPC];
54#else 61#else
55 int ix; 62 int ix;
@@ -57,23 +64,21 @@ void silk_LPC_analysis_filter(
57 const opus_int16 *in_ptr; 64 const opus_int16 *in_ptr;
58#endif 65#endif
59 66
60 silk_assert( d >= 6 ); 67 celt_assert( d >= 6 );
61 silk_assert( (d & 1) == 0 ); 68 celt_assert( (d & 1) == 0 );
62 silk_assert( d <= len ); 69 celt_assert( d <= len );
63 70
64#ifdef FIXED_POINT 71#if defined(FIXED_POINT) && USE_CELT_FIR
65 silk_assert( d <= SILK_MAX_ORDER_LPC ); 72 celt_assert( d <= SILK_MAX_ORDER_LPC );
66 for ( j = 0; j < d; j++ ) { 73 for ( j = 0; j < d; j++ ) {
67 num[ j ] = -B[ j ]; 74 num[ j ] = -B[ j ];
68 } 75 }
69 for (j=0;j<d;j++) { 76 celt_fir( in + d, num, out + d, len - d, d, arch );
70 mem[ j ] = in[ d - j - 1 ];
71 }
72 celt_fir( in + d, num, out + d, len - d, d, mem );
73 for ( j = 0; j < d; j++ ) { 77 for ( j = 0; j < d; j++ ) {
74 out[ j ] = 0; 78 out[ j ] = 0;
75 } 79 }
76#else 80#else
81 (void)arch;
77 for( ix = d; ix < len; ix++ ) { 82 for( ix = d; ix < len; ix++ ) {
78 in_ptr = &in[ ix - 1 ]; 83 in_ptr = &in[ ix - 1 ];
79 84
diff --git a/lib/rbcodec/codecs/libopus/silk/LPC_fit.c b/lib/rbcodec/codecs/libopus/silk/LPC_fit.c
new file mode 100644
index 0000000000..cdea4f3abc
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/LPC_fit.c
@@ -0,0 +1,81 @@
1/***********************************************************************
2Copyright (c) 2013, Koen Vos. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33
34/* Convert int32 coefficients to int16 coefs and make sure there's no wrap-around */
35void silk_LPC_fit(
36 opus_int16 *a_QOUT, /* O Output signal */
37 opus_int32 *a_QIN, /* I/O Input signal */
38 const opus_int QOUT, /* I Input Q domain */
39 const opus_int QIN, /* I Input Q domain */
40 const opus_int d /* I Filter order */
41)
42{
43 opus_int i, k, idx = 0;
44 opus_int32 maxabs, absval, chirp_Q16;
45
46 /* Limit the maximum absolute value of the prediction coefficients, so that they'll fit in int16 */
47 for( i = 0; i < 10; i++ ) {
48 /* Find maximum absolute value and its index */
49 maxabs = 0;
50 for( k = 0; k < d; k++ ) {
51 absval = silk_abs( a_QIN[k] );
52 if( absval > maxabs ) {
53 maxabs = absval;
54 idx = k;
55 }
56 }
57 maxabs = silk_RSHIFT_ROUND( maxabs, QIN - QOUT );
58
59 if( maxabs > silk_int16_MAX ) {
60 /* Reduce magnitude of prediction coefficients */
61 maxabs = silk_min( maxabs, 163838 ); /* ( silk_int32_MAX >> 14 ) + silk_int16_MAX = 163838 */
62 chirp_Q16 = SILK_FIX_CONST( 0.999, 16 ) - silk_DIV32( silk_LSHIFT( maxabs - silk_int16_MAX, 14 ),
63 silk_RSHIFT32( silk_MUL( maxabs, idx + 1), 2 ) );
64 silk_bwexpander_32( a_QIN, d, chirp_Q16 );
65 } else {
66 break;
67 }
68 }
69
70 if( i == 10 ) {
71 /* Reached the last iteration, clip the coefficients */
72 for( k = 0; k < d; k++ ) {
73 a_QOUT[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a_QIN[ k ], QIN - QOUT ) );
74 a_QIN[ k ] = silk_LSHIFT( (opus_int32)a_QOUT[ k ], QIN - QOUT );
75 }
76 } else {
77 for( k = 0; k < d; k++ ) {
78 a_QOUT[ k ] = (opus_int16)silk_RSHIFT_ROUND( a_QIN[ k ], QIN - QOUT );
79 }
80 }
81}
diff --git a/lib/rbcodec/codecs/libopus/silk/LPC_inv_pred_gain.c b/lib/rbcodec/codecs/libopus/silk/LPC_inv_pred_gain.c
index dd14d4bca6..a3746a6ef9 100644
--- a/lib/rbcodec/codecs/libopus/silk/LPC_inv_pred_gain.c
+++ b/lib/rbcodec/codecs/libopus/silk/LPC_inv_pred_gain.c
@@ -30,6 +30,7 @@ POSSIBILITY OF SUCH DAMAGE.
30#endif 30#endif
31 31
32#include "SigProc_FIX.h" 32#include "SigProc_FIX.h"
33#include "define.h"
33 34
34#define QA 24 35#define QA 24
35#define A_LIMIT SILK_FIX_CONST( 0.99975, QA ) 36#define A_LIMIT SILK_FIX_CONST( 0.99975, QA )
@@ -38,119 +39,103 @@ POSSIBILITY OF SUCH DAMAGE.
38 39
39/* Compute inverse of LPC prediction gain, and */ 40/* Compute inverse of LPC prediction gain, and */
40/* test if LPC coefficients are stable (all poles within unit circle) */ 41/* test if LPC coefficients are stable (all poles within unit circle) */
41static opus_int32 LPC_inverse_pred_gain_QA( /* O Returns inverse prediction gain in energy domain, Q30 */ 42static opus_int32 LPC_inverse_pred_gain_QA_c( /* O Returns inverse prediction gain in energy domain, Q30 */
42 opus_int32 A_QA[ 2 ][ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */ 43 opus_int32 A_QA[ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */
43 const opus_int order /* I Prediction order */ 44 const opus_int order /* I Prediction order */
44) 45)
45{ 46{
46 opus_int k, n, mult2Q; 47 opus_int k, n, mult2Q;
47 opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp_QA; 48 opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp1, tmp2;
48 opus_int32 *Aold_QA, *Anew_QA;
49 49
50 Anew_QA = A_QA[ order & 1 ]; 50 invGain_Q30 = SILK_FIX_CONST( 1, 30 );
51
52 invGain_Q30 = (opus_int32)1 << 30;
53 for( k = order - 1; k > 0; k-- ) { 51 for( k = order - 1; k > 0; k-- ) {
54 /* Check for stability */ 52 /* Check for stability */
55 if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) { 53 if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) {
56 return 0; 54 return 0;
57 } 55 }
58 56
59 /* Set RC equal to negated AR coef */ 57 /* Set RC equal to negated AR coef */
60 rc_Q31 = -silk_LSHIFT( Anew_QA[ k ], 31 - QA ); 58 rc_Q31 = -silk_LSHIFT( A_QA[ k ], 31 - QA );
61 59
62 /* rc_mult1_Q30 range: [ 1 : 2^30 ] */ 60 /* rc_mult1_Q30 range: [ 1 : 2^30 ] */
63 rc_mult1_Q30 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 ); 61 rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) );
64 silk_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */ 62 silk_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */
65 silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) ); 63 silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) );
66 64
67 /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */
68 mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) );
69 rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 );
70
71 /* Update inverse gain */ 65 /* Update inverse gain */
72 /* invGain_Q30 range: [ 0 : 2^30 ] */ 66 /* invGain_Q30 range: [ 0 : 2^30 ] */
73 invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); 67 invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
74 silk_assert( invGain_Q30 >= 0 ); 68 silk_assert( invGain_Q30 >= 0 );
75 silk_assert( invGain_Q30 <= ( 1 << 30 ) ); 69 silk_assert( invGain_Q30 <= ( 1 << 30 ) );
70 if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
71 return 0;
72 }
76 73
77 /* Swap pointers */ 74 /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */
78 Aold_QA = Anew_QA; 75 mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) );
79 Anew_QA = A_QA[ k & 1 ]; 76 rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 );
80 77
81 /* Update AR coefficient */ 78 /* Update AR coefficient */
82 for( n = 0; n < k; n++ ) { 79 for( n = 0; n < (k + 1) >> 1; n++ ) {
83 tmp_QA = Aold_QA[ n ] - MUL32_FRAC_Q( Aold_QA[ k - n - 1 ], rc_Q31, 31 ); 80 opus_int64 tmp64;
84 Anew_QA[ n ] = MUL32_FRAC_Q( tmp_QA, rc_mult2 , mult2Q ); 81 tmp1 = A_QA[ n ];
82 tmp2 = A_QA[ k - n - 1 ];
83 tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp1,
84 MUL32_FRAC_Q( tmp2, rc_Q31, 31 ) ), rc_mult2 ), mult2Q);
85 if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
86 return 0;
87 }
88 A_QA[ n ] = ( opus_int32 )tmp64;
89 tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp2,
90 MUL32_FRAC_Q( tmp1, rc_Q31, 31 ) ), rc_mult2), mult2Q);
91 if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
92 return 0;
93 }
94 A_QA[ k - n - 1 ] = ( opus_int32 )tmp64;
85 } 95 }
86 } 96 }
87 97
88 /* Check for stability */ 98 /* Check for stability */
89 if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) { 99 if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) {
90 return 0; 100 return 0;
91 } 101 }
92 102
93 /* Set RC equal to negated AR coef */ 103 /* Set RC equal to negated AR coef */
94 rc_Q31 = -silk_LSHIFT( Anew_QA[ 0 ], 31 - QA ); 104 rc_Q31 = -silk_LSHIFT( A_QA[ 0 ], 31 - QA );
95 105
96 /* Range: [ 1 : 2^30 ] */ 106 /* Range: [ 1 : 2^30 ] */
97 rc_mult1_Q30 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 ); 107 rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) );
98 108
99 /* Update inverse gain */ 109 /* Update inverse gain */
100 /* Range: [ 0 : 2^30 ] */ 110 /* Range: [ 0 : 2^30 ] */
101 invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); 111 invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
102 silk_assert( invGain_Q30 >= 0 ); 112 silk_assert( invGain_Q30 >= 0 );
103 silk_assert( invGain_Q30 <= 1<<30 ); 113 silk_assert( invGain_Q30 <= ( 1 << 30 ) );
114 if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
115 return 0;
116 }
104 117
105 return invGain_Q30; 118 return invGain_Q30;
106} 119}
107 120
108/* For input in Q12 domain */ 121/* For input in Q12 domain */
109opus_int32 silk_LPC_inverse_pred_gain( /* O Returns inverse prediction gain in energy domain, Q30 */ 122opus_int32 silk_LPC_inverse_pred_gain_c( /* O Returns inverse prediction gain in energy domain, Q30 */
110 const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ 123 const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
111 const opus_int order /* I Prediction order */ 124 const opus_int order /* I Prediction order */
112) 125)
113{ 126{
114 opus_int k; 127 opus_int k;
115 opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ]; 128 opus_int32 Atmp_QA[ SILK_MAX_ORDER_LPC ];
116 opus_int32 *Anew_QA;
117 opus_int32 DC_resp = 0; 129 opus_int32 DC_resp = 0;
118 130
119 Anew_QA = Atmp_QA[ order & 1 ];
120
121 /* Increase Q domain of the AR coefficients */ 131 /* Increase Q domain of the AR coefficients */
122 for( k = 0; k < order; k++ ) { 132 for( k = 0; k < order; k++ ) {
123 DC_resp += (opus_int32)A_Q12[ k ]; 133 DC_resp += (opus_int32)A_Q12[ k ];
124 Anew_QA[ k ] = silk_LSHIFT32( (opus_int32)A_Q12[ k ], QA - 12 ); 134 Atmp_QA[ k ] = silk_LSHIFT32( (opus_int32)A_Q12[ k ], QA - 12 );
125 } 135 }
126 /* If the DC is unstable, we don't even need to do the full calculations */ 136 /* If the DC is unstable, we don't even need to do the full calculations */
127 if( DC_resp >= 4096 ) { 137 if( DC_resp >= 4096 ) {
128 return 0; 138 return 0;
129 } 139 }
130 return LPC_inverse_pred_gain_QA( Atmp_QA, order ); 140 return LPC_inverse_pred_gain_QA_c( Atmp_QA, order );
131} 141}
132
133#ifdef FIXED_POINT
134
135#if 0
136/* For input in Q24 domain */
137opus_int32 silk_LPC_inverse_pred_gain_Q24( /* O Returns inverse prediction gain in energy domain, Q30 */
138 const opus_int32 *A_Q24, /* I Prediction coefficients [order] */
139 const opus_int order /* I Prediction order */
140)
141{
142 opus_int k;
143 opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ];
144 opus_int32 *Anew_QA;
145
146 Anew_QA = Atmp_QA[ order & 1 ];
147
148 /* Increase Q domain of the AR coefficients */
149 for( k = 0; k < order; k++ ) {
150 Anew_QA[ k ] = silk_RSHIFT32( A_Q24[ k ], 24 - QA );
151 }
152
153 return LPC_inverse_pred_gain_QA( Atmp_QA, order );
154}
155#endif
156#endif
diff --git a/lib/rbcodec/codecs/libopus/silk/LP_variable_cutoff.c b/lib/rbcodec/codecs/libopus/silk/LP_variable_cutoff.c
new file mode 100644
index 0000000000..79112ad354
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/LP_variable_cutoff.c
@@ -0,0 +1,135 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32/*
33 Elliptic/Cauer filters designed with 0.1 dB passband ripple,
34 80 dB minimum stopband attenuation, and
35 [0.95 : 0.15 : 0.35] normalized cut off frequencies.
36*/
37
38#include "main.h"
39
40/* Helper function, interpolates the filter taps */
41static OPUS_INLINE void silk_LP_interpolate_filter_taps(
42 opus_int32 B_Q28[ TRANSITION_NB ],
43 opus_int32 A_Q28[ TRANSITION_NA ],
44 const opus_int ind,
45 const opus_int32 fac_Q16
46)
47{
48 opus_int nb, na;
49
50 if( ind < TRANSITION_INT_NUM - 1 ) {
51 if( fac_Q16 > 0 ) {
52 if( fac_Q16 < 32768 ) { /* fac_Q16 is in range of a 16-bit int */
53 /* Piece-wise linear interpolation of B and A */
54 for( nb = 0; nb < TRANSITION_NB; nb++ ) {
55 B_Q28[ nb ] = silk_SMLAWB(
56 silk_Transition_LP_B_Q28[ ind ][ nb ],
57 silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] -
58 silk_Transition_LP_B_Q28[ ind ][ nb ],
59 fac_Q16 );
60 }
61 for( na = 0; na < TRANSITION_NA; na++ ) {
62 A_Q28[ na ] = silk_SMLAWB(
63 silk_Transition_LP_A_Q28[ ind ][ na ],
64 silk_Transition_LP_A_Q28[ ind + 1 ][ na ] -
65 silk_Transition_LP_A_Q28[ ind ][ na ],
66 fac_Q16 );
67 }
68 } else { /* ( fac_Q16 - ( 1 << 16 ) ) is in range of a 16-bit int */
69 silk_assert( fac_Q16 - ( 1 << 16 ) == silk_SAT16( fac_Q16 - ( 1 << 16 ) ) );
70 /* Piece-wise linear interpolation of B and A */
71 for( nb = 0; nb < TRANSITION_NB; nb++ ) {
72 B_Q28[ nb ] = silk_SMLAWB(
73 silk_Transition_LP_B_Q28[ ind + 1 ][ nb ],
74 silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] -
75 silk_Transition_LP_B_Q28[ ind ][ nb ],
76 fac_Q16 - ( (opus_int32)1 << 16 ) );
77 }
78 for( na = 0; na < TRANSITION_NA; na++ ) {
79 A_Q28[ na ] = silk_SMLAWB(
80 silk_Transition_LP_A_Q28[ ind + 1 ][ na ],
81 silk_Transition_LP_A_Q28[ ind + 1 ][ na ] -
82 silk_Transition_LP_A_Q28[ ind ][ na ],
83 fac_Q16 - ( (opus_int32)1 << 16 ) );
84 }
85 }
86 } else {
87 silk_memcpy( B_Q28, silk_Transition_LP_B_Q28[ ind ], TRANSITION_NB * sizeof( opus_int32 ) );
88 silk_memcpy( A_Q28, silk_Transition_LP_A_Q28[ ind ], TRANSITION_NA * sizeof( opus_int32 ) );
89 }
90 } else {
91 silk_memcpy( B_Q28, silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NB * sizeof( opus_int32 ) );
92 silk_memcpy( A_Q28, silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NA * sizeof( opus_int32 ) );
93 }
94}
95
96/* Low-pass filter with variable cutoff frequency based on */
97/* piece-wise linear interpolation between elliptic filters */
98/* Start by setting psEncC->mode <> 0; */
99/* Deactivate by setting psEncC->mode = 0; */
100void silk_LP_variable_cutoff(
101 silk_LP_state *psLP, /* I/O LP filter state */
102 opus_int16 *frame, /* I/O Low-pass filtered output signal */
103 const opus_int frame_length /* I Frame length */
104)
105{
106 opus_int32 B_Q28[ TRANSITION_NB ], A_Q28[ TRANSITION_NA ], fac_Q16 = 0;
107 opus_int ind = 0;
108
109 silk_assert( psLP->transition_frame_no >= 0 && psLP->transition_frame_no <= TRANSITION_FRAMES );
110
111 /* Run filter if needed */
112 if( psLP->mode != 0 ) {
113 /* Calculate index and interpolation factor for interpolation */
114#if( TRANSITION_INT_STEPS == 64 )
115 fac_Q16 = silk_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 - 6 );
116#else
117 fac_Q16 = silk_DIV32_16( silk_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 ), TRANSITION_FRAMES );
118#endif
119 ind = silk_RSHIFT( fac_Q16, 16 );
120 fac_Q16 -= silk_LSHIFT( ind, 16 );
121
122 silk_assert( ind >= 0 );
123 silk_assert( ind < TRANSITION_INT_NUM );
124
125 /* Interpolate filter coefficients */
126 silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 );
127
128 /* Update transition frame number for next frame */
129 psLP->transition_frame_no = silk_LIMIT( psLP->transition_frame_no + psLP->mode, 0, TRANSITION_FRAMES );
130
131 /* ARMA low-pass filtering */
132 silk_assert( TRANSITION_NB == 3 && TRANSITION_NA == 2 );
133 silk_biquad_alt_stride1( frame, B_Q28, A_Q28, psLP->In_LP_State, frame, frame_length);
134 }
135}
diff --git a/lib/rbcodec/codecs/libopus/silk/MacroCount.h b/lib/rbcodec/codecs/libopus/silk/MacroCount.h
index 834817d058..78100ffede 100644
--- a/lib/rbcodec/codecs/libopus/silk/MacroCount.h
+++ b/lib/rbcodec/codecs/libopus/silk/MacroCount.h
@@ -319,14 +319,6 @@ static OPUS_INLINE opus_int32 silk_ADD_POS_SAT32(opus_int64 a, opus_int64 b){
319 return(tmp); 319 return(tmp);
320} 320}
321 321
322#undef silk_ADD_POS_SAT64
323static OPUS_INLINE opus_int64 silk_ADD_POS_SAT64(opus_int64 a, opus_int64 b){
324 opus_int64 tmp;
325 ops_count += 1;
326 tmp = ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b)));
327 return(tmp);
328}
329
330#undef silk_LSHIFT8 322#undef silk_LSHIFT8
331static OPUS_INLINE opus_int8 silk_LSHIFT8(opus_int8 a, opus_int32 shift){ 323static OPUS_INLINE opus_int8 silk_LSHIFT8(opus_int8 a, opus_int32 shift){
332 opus_int8 ret; 324 opus_int8 ret;
@@ -699,7 +691,7 @@ return(ret);
699 691
700 692
701#undef silk_LIMIT_32 693#undef silk_LIMIT_32
702static OPUS_INLINE opus_int silk_LIMIT_32(opus_int32 a, opus_int32 limit1, opus_int32 limit2) 694static OPUS_INLINE opus_int32 silk_LIMIT_32(opus_int32 a, opus_int32 limit1, opus_int32 limit2)
703{ 695{
704 opus_int32 ret; 696 opus_int32 ret;
705 ops_count += 6; 697 ops_count += 6;
diff --git a/lib/rbcodec/codecs/libopus/silk/MacroDebug.h b/lib/rbcodec/codecs/libopus/silk/MacroDebug.h
index 35aedc5c5f..8dd4ce2ee2 100644
--- a/lib/rbcodec/codecs/libopus/silk/MacroDebug.h
+++ b/lib/rbcodec/codecs/libopus/silk/MacroDebug.h
@@ -539,8 +539,7 @@ static OPUS_INLINE opus_int32 silk_DIV32_16_(opus_int32 a32, opus_int32 b32, cha
539 no checking needed for silk_POS_SAT32 539 no checking needed for silk_POS_SAT32
540 no checking needed for silk_ADD_POS_SAT8 540 no checking needed for silk_ADD_POS_SAT8
541 no checking needed for silk_ADD_POS_SAT16 541 no checking needed for silk_ADD_POS_SAT16
542 no checking needed for silk_ADD_POS_SAT32 542 no checking needed for silk_ADD_POS_SAT32 */
543 no checking needed for silk_ADD_POS_SAT64 */
544 543
545#undef silk_LSHIFT8 544#undef silk_LSHIFT8
546#define silk_LSHIFT8(a,b) silk_LSHIFT8_((a), (b), __FILE__, __LINE__) 545#define silk_LSHIFT8(a,b) silk_LSHIFT8_((a), (b), __FILE__, __LINE__)
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF2A.c b/lib/rbcodec/codecs/libopus/silk/NLSF2A.c
index b1c559ea68..d5b7730638 100644
--- a/lib/rbcodec/codecs/libopus/silk/NLSF2A.c
+++ b/lib/rbcodec/codecs/libopus/silk/NLSF2A.c
@@ -66,7 +66,8 @@ static OPUS_INLINE void silk_NLSF2A_find_poly(
66void silk_NLSF2A( 66void silk_NLSF2A(
67 opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */ 67 opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */
68 const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */ 68 const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */
69 const opus_int d /* I filter order (should be even) */ 69 const opus_int d, /* I filter order (should be even) */
70 int arch /* I Run-time architecture */
70) 71)
71{ 72{
72 /* This ordering was found to maximize quality. It improves numerical accuracy of 73 /* This ordering was found to maximize quality. It improves numerical accuracy of
@@ -83,15 +84,14 @@ void silk_NLSF2A(
83 opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ]; 84 opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ];
84 opus_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta; 85 opus_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta;
85 opus_int32 a32_QA1[ SILK_MAX_ORDER_LPC ]; 86 opus_int32 a32_QA1[ SILK_MAX_ORDER_LPC ];
86 opus_int32 maxabs, absval, idx=0, sc_Q16;
87 87
88 silk_assert( LSF_COS_TAB_SZ_FIX == 128 ); 88 silk_assert( LSF_COS_TAB_SZ_FIX == 128 );
89 silk_assert( d==10||d==16 ); 89 celt_assert( d==10 || d==16 );
90 90
91 /* convert LSFs to 2*cos(LSF), using piecewise linear curve from table */ 91 /* convert LSFs to 2*cos(LSF), using piecewise linear curve from table */
92 ordering = d == 16 ? ordering16 : ordering10; 92 ordering = d == 16 ? ordering16 : ordering10;
93 for( k = 0; k < d; k++ ) { 93 for( k = 0; k < d; k++ ) {
94 silk_assert(NLSF[k] >= 0 ); 94 silk_assert( NLSF[k] >= 0 );
95 95
96 /* f_int on a scale 0-127 (rounded down) */ 96 /* f_int on a scale 0-127 (rounded down) */
97 f_int = silk_RSHIFT( NLSF[k], 15 - 7 ); 97 f_int = silk_RSHIFT( NLSF[k], 15 - 7 );
@@ -126,52 +126,15 @@ void silk_NLSF2A(
126 a32_QA1[ d-k-1 ] = Qtmp - Ptmp; /* QA+1 */ 126 a32_QA1[ d-k-1 ] = Qtmp - Ptmp; /* QA+1 */
127 } 127 }
128 128
129 /* Limit the maximum absolute value of the prediction coefficients, so that they'll fit in int16 */ 129 /* Convert int32 coefficients to Q12 int16 coefs */
130 for( i = 0; i < 10; i++ ) { 130 silk_LPC_fit( a_Q12, a32_QA1, 12, QA + 1, d );
131 /* Find maximum absolute value and its index */
132 maxabs = 0;
133 for( k = 0; k < d; k++ ) {
134 absval = silk_abs( a32_QA1[k] );
135 if( absval > maxabs ) {
136 maxabs = absval;
137 idx = k;
138 }
139 }
140 maxabs = silk_RSHIFT_ROUND( maxabs, QA + 1 - 12 ); /* QA+1 -> Q12 */
141
142 if( maxabs > silk_int16_MAX ) {
143 /* Reduce magnitude of prediction coefficients */
144 maxabs = silk_min( maxabs, 163838 ); /* ( silk_int32_MAX >> 14 ) + silk_int16_MAX = 163838 */
145 sc_Q16 = SILK_FIX_CONST( 0.999, 16 ) - silk_DIV32( silk_LSHIFT( maxabs - silk_int16_MAX, 14 ),
146 silk_RSHIFT32( silk_MUL( maxabs, idx + 1), 2 ) );
147 silk_bwexpander_32( a32_QA1, d, sc_Q16 );
148 } else {
149 break;
150 }
151 }
152 131
153 if( i == 10 ) { 132 for( i = 0; silk_LPC_inverse_pred_gain( a_Q12, d, arch ) == 0 && i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
154 /* Reached the last iteration, clip the coefficients */ 133 /* Prediction coefficients are (too close to) unstable; apply bandwidth expansion */
134 /* on the unscaled coefficients, convert to Q12 and measure again */
135 silk_bwexpander_32( a32_QA1, d, 65536 - silk_LSHIFT( 2, i ) );
155 for( k = 0; k < d; k++ ) { 136 for( k = 0; k < d; k++ ) {
156 a_Q12[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ) ); /* QA+1 -> Q12 */ 137 a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */
157 a32_QA1[ k ] = silk_LSHIFT( (opus_int32)a_Q12[ k ], QA + 1 - 12 );
158 }
159 } else {
160 for( k = 0; k < d; k++ ) {
161 a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */
162 }
163 }
164
165 for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
166 if( silk_LPC_inverse_pred_gain( a_Q12, d ) < SILK_FIX_CONST( 1.0 / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
167 /* Prediction coefficients are (too close to) unstable; apply bandwidth expansion */
168 /* on the unscaled coefficients, convert to Q12 and measure again */
169 silk_bwexpander_32( a32_QA1, d, 65536 - silk_LSHIFT( 2, i ) );
170 for( k = 0; k < d; k++ ) {
171 a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */
172 }
173 } else {
174 break;
175 } 138 }
176 } 139 }
177} 140}
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF_VQ.c b/lib/rbcodec/codecs/libopus/silk/NLSF_VQ.c
new file mode 100644
index 0000000000..b83182a79c
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/NLSF_VQ.c
@@ -0,0 +1,76 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33
34/* Compute quantization errors for an LPC_order element input vector for a VQ codebook */
35void silk_NLSF_VQ(
36 opus_int32 err_Q24[], /* O Quantization errors [K] */
37 const opus_int16 in_Q15[], /* I Input vectors to be quantized [LPC_order] */
38 const opus_uint8 pCB_Q8[], /* I Codebook vectors [K*LPC_order] */
39 const opus_int16 pWght_Q9[], /* I Codebook weights [K*LPC_order] */
40 const opus_int K, /* I Number of codebook vectors */
41 const opus_int LPC_order /* I Number of LPCs */
42)
43{
44 opus_int i, m;
45 opus_int32 diff_Q15, diffw_Q24, sum_error_Q24, pred_Q24;
46 const opus_int16 *w_Q9_ptr;
47 const opus_uint8 *cb_Q8_ptr;
48
49 celt_assert( ( LPC_order & 1 ) == 0 );
50
51 /* Loop over codebook */
52 cb_Q8_ptr = pCB_Q8;
53 w_Q9_ptr = pWght_Q9;
54 for( i = 0; i < K; i++ ) {
55 sum_error_Q24 = 0;
56 pred_Q24 = 0;
57 for( m = LPC_order-2; m >= 0; m -= 2 ) {
58 /* Compute weighted absolute predictive quantization error for index m + 1 */
59 diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m + 1 ], (opus_int32)cb_Q8_ptr[ m + 1 ], 7 ); /* range: [ -32767 : 32767 ]*/
60 diffw_Q24 = silk_SMULBB( diff_Q15, w_Q9_ptr[ m + 1 ] );
61 sum_error_Q24 = silk_ADD32( sum_error_Q24, silk_abs( silk_SUB_RSHIFT32( diffw_Q24, pred_Q24, 1 ) ) );
62 pred_Q24 = diffw_Q24;
63
64 /* Compute weighted absolute predictive quantization error for index m */
65 diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m ], (opus_int32)cb_Q8_ptr[ m ], 7 ); /* range: [ -32767 : 32767 ]*/
66 diffw_Q24 = silk_SMULBB( diff_Q15, w_Q9_ptr[ m ] );
67 sum_error_Q24 = silk_ADD32( sum_error_Q24, silk_abs( silk_SUB_RSHIFT32( diffw_Q24, pred_Q24, 1 ) ) );
68 pred_Q24 = diffw_Q24;
69
70 silk_assert( sum_error_Q24 >= 0 );
71 }
72 err_Q24[ i ] = sum_error_Q24;
73 cb_Q8_ptr += LPC_order;
74 w_Q9_ptr += LPC_order;
75 }
76}
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF_VQ_weights_laroia.c b/lib/rbcodec/codecs/libopus/silk/NLSF_VQ_weights_laroia.c
index 04894c59ab..9873bcde10 100644
--- a/lib/rbcodec/codecs/libopus/silk/NLSF_VQ_weights_laroia.c
+++ b/lib/rbcodec/codecs/libopus/silk/NLSF_VQ_weights_laroia.c
@@ -48,8 +48,8 @@ void silk_NLSF_VQ_weights_laroia(
48 opus_int k; 48 opus_int k;
49 opus_int32 tmp1_int, tmp2_int; 49 opus_int32 tmp1_int, tmp2_int;
50 50
51 silk_assert( D > 0 ); 51 celt_assert( D > 0 );
52 silk_assert( ( D & 1 ) == 0 ); 52 celt_assert( ( D & 1 ) == 0 );
53 53
54 /* First value */ 54 /* First value */
55 tmp1_int = silk_max_int( pNLSF_Q15[ 0 ], 1 ); 55 tmp1_int = silk_max_int( pNLSF_Q15[ 0 ], 1 );
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF_decode.c b/lib/rbcodec/codecs/libopus/silk/NLSF_decode.c
index 9f715060b8..eeb0ba8c92 100644
--- a/lib/rbcodec/codecs/libopus/silk/NLSF_decode.c
+++ b/lib/rbcodec/codecs/libopus/silk/NLSF_decode.c
@@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.
32#include "main.h" 32#include "main.h"
33 33
34/* Predictive dequantizer for NLSF residuals */ 34/* Predictive dequantizer for NLSF residuals */
35static OPUS_INLINE void silk_NLSF_residual_dequant( /* O Returns RD value in Q30 */ 35static OPUS_INLINE void silk_NLSF_residual_dequant( /* O Returns RD value in Q30 */
36 opus_int16 x_Q10[], /* O Output [ order ] */ 36 opus_int16 x_Q10[], /* O Output [ order ] */
37 const opus_int8 indices[], /* I Quantization indices [ order ] */ 37 const opus_int8 indices[], /* I Quantization indices [ order ] */
38 const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */ 38 const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */
@@ -70,15 +70,9 @@ void silk_NLSF_decode(
70 opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; 70 opus_uint8 pred_Q8[ MAX_LPC_ORDER ];
71 opus_int16 ec_ix[ MAX_LPC_ORDER ]; 71 opus_int16 ec_ix[ MAX_LPC_ORDER ];
72 opus_int16 res_Q10[ MAX_LPC_ORDER ]; 72 opus_int16 res_Q10[ MAX_LPC_ORDER ];
73 opus_int16 W_tmp_QW[ MAX_LPC_ORDER ]; 73 opus_int32 NLSF_Q15_tmp;
74 opus_int32 W_tmp_Q9, NLSF_Q15_tmp;
75 const opus_uint8 *pCB_element; 74 const opus_uint8 *pCB_element;
76 75 const opus_int16 *pCB_Wght_Q9;
77 /* Decode first stage */
78 pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ];
79 for( i = 0; i < psNLSF_CB->order; i++ ) {
80 pNLSF_Q15[ i ] = silk_LSHIFT( (opus_int16)pCB_element[ i ], 7 );
81 }
82 76
83 /* Unpack entropy table indices and predictor for current CB1 index */ 77 /* Unpack entropy table indices and predictor for current CB1 index */
84 silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, NLSFIndices[ 0 ] ); 78 silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, NLSFIndices[ 0 ] );
@@ -86,13 +80,11 @@ void silk_NLSF_decode(
86 /* Predictive residual dequantizer */ 80 /* Predictive residual dequantizer */
87 silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order ); 81 silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order );
88 82
89 /* Weights from codebook vector */ 83 /* Apply inverse square-rooted weights to first stage and add to output */
90 silk_NLSF_VQ_weights_laroia( W_tmp_QW, pNLSF_Q15, psNLSF_CB->order ); 84 pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ];
91 85 pCB_Wght_Q9 = &psNLSF_CB->CB1_Wght_Q9[ NLSFIndices[ 0 ] * psNLSF_CB->order ];
92 /* Apply inverse square-rooted weights and add to output */
93 for( i = 0; i < psNLSF_CB->order; i++ ) { 86 for( i = 0; i < psNLSF_CB->order; i++ ) {
94 W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( (opus_int32)W_tmp_QW[ i ], 18 - NLSF_W_Q ) ); 87 NLSF_Q15_tmp = silk_ADD_LSHIFT32( silk_DIV32_16( silk_LSHIFT( (opus_int32)res_Q10[ i ], 14 ), pCB_Wght_Q9[ i ] ), (opus_int16)pCB_element[ i ], 7 );
95 NLSF_Q15_tmp = silk_ADD32( pNLSF_Q15[ i ], silk_DIV32_16( silk_LSHIFT( (opus_int32)res_Q10[ i ], 14 ), W_tmp_Q9 ) );
96 pNLSF_Q15[ i ] = (opus_int16)silk_LIMIT( NLSF_Q15_tmp, 0, 32767 ); 88 pNLSF_Q15[ i ] = (opus_int16)silk_LIMIT( NLSF_Q15_tmp, 0, 32767 );
97 } 89 }
98 90
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF_del_dec_quant.c b/lib/rbcodec/codecs/libopus/silk/NLSF_del_dec_quant.c
new file mode 100644
index 0000000000..44a16acd0b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/NLSF_del_dec_quant.c
@@ -0,0 +1,215 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33
34/* Delayed-decision quantizer for NLSF residuals */
35opus_int32 silk_NLSF_del_dec_quant( /* O Returns RD value in Q25 */
36 opus_int8 indices[], /* O Quantization indices [ order ] */
37 const opus_int16 x_Q10[], /* I Input [ order ] */
38 const opus_int16 w_Q5[], /* I Weights [ order ] */
39 const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */
40 const opus_int16 ec_ix[], /* I Indices to entropy coding tables [ order ] */
41 const opus_uint8 ec_rates_Q5[], /* I Rates [] */
42 const opus_int quant_step_size_Q16, /* I Quantization step size */
43 const opus_int16 inv_quant_step_size_Q6, /* I Inverse quantization step size */
44 const opus_int32 mu_Q20, /* I R/D tradeoff */
45 const opus_int16 order /* I Number of input values */
46)
47{
48 opus_int i, j, nStates, ind_tmp, ind_min_max, ind_max_min, in_Q10, res_Q10;
49 opus_int pred_Q10, diff_Q10, rate0_Q5, rate1_Q5;
50 opus_int16 out0_Q10, out1_Q10;
51 opus_int32 RD_tmp_Q25, min_Q25, min_max_Q25, max_min_Q25;
52 opus_int ind_sort[ NLSF_QUANT_DEL_DEC_STATES ];
53 opus_int8 ind[ NLSF_QUANT_DEL_DEC_STATES ][ MAX_LPC_ORDER ];
54 opus_int16 prev_out_Q10[ 2 * NLSF_QUANT_DEL_DEC_STATES ];
55 opus_int32 RD_Q25[ 2 * NLSF_QUANT_DEL_DEC_STATES ];
56 opus_int32 RD_min_Q25[ NLSF_QUANT_DEL_DEC_STATES ];
57 opus_int32 RD_max_Q25[ NLSF_QUANT_DEL_DEC_STATES ];
58 const opus_uint8 *rates_Q5;
59
60 opus_int out0_Q10_table[2 * NLSF_QUANT_MAX_AMPLITUDE_EXT];
61 opus_int out1_Q10_table[2 * NLSF_QUANT_MAX_AMPLITUDE_EXT];
62
63 for (i = -NLSF_QUANT_MAX_AMPLITUDE_EXT; i <= NLSF_QUANT_MAX_AMPLITUDE_EXT-1; i++)
64 {
65 out0_Q10 = silk_LSHIFT( i, 10 );
66 out1_Q10 = silk_ADD16( out0_Q10, 1024 );
67 if( i > 0 ) {
68 out0_Q10 = silk_SUB16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
69 out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
70 } else if( i == 0 ) {
71 out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
72 } else if( i == -1 ) {
73 out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
74 } else {
75 out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
76 out1_Q10 = silk_ADD16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
77 }
78 out0_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_RSHIFT( silk_SMULBB( out0_Q10, quant_step_size_Q16 ), 16 );
79 out1_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_RSHIFT( silk_SMULBB( out1_Q10, quant_step_size_Q16 ), 16 );
80 }
81
82 silk_assert( (NLSF_QUANT_DEL_DEC_STATES & (NLSF_QUANT_DEL_DEC_STATES-1)) == 0 ); /* must be power of two */
83
84 nStates = 1;
85 RD_Q25[ 0 ] = 0;
86 prev_out_Q10[ 0 ] = 0;
87 for( i = order - 1; i >= 0; i-- ) {
88 rates_Q5 = &ec_rates_Q5[ ec_ix[ i ] ];
89 in_Q10 = x_Q10[ i ];
90 for( j = 0; j < nStates; j++ ) {
91 pred_Q10 = silk_RSHIFT( silk_SMULBB( (opus_int16)pred_coef_Q8[ i ], prev_out_Q10[ j ] ), 8 );
92 res_Q10 = silk_SUB16( in_Q10, pred_Q10 );
93 ind_tmp = silk_RSHIFT( silk_SMULBB( inv_quant_step_size_Q6, res_Q10 ), 16 );
94 ind_tmp = silk_LIMIT( ind_tmp, -NLSF_QUANT_MAX_AMPLITUDE_EXT, NLSF_QUANT_MAX_AMPLITUDE_EXT-1 );
95 ind[ j ][ i ] = (opus_int8)ind_tmp;
96
97 /* compute outputs for ind_tmp and ind_tmp + 1 */
98 out0_Q10 = out0_Q10_table[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT ];
99 out1_Q10 = out1_Q10_table[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE_EXT ];
100
101 out0_Q10 = silk_ADD16( out0_Q10, pred_Q10 );
102 out1_Q10 = silk_ADD16( out1_Q10, pred_Q10 );
103 prev_out_Q10[ j ] = out0_Q10;
104 prev_out_Q10[ j + nStates ] = out1_Q10;
105
106 /* compute RD for ind_tmp and ind_tmp + 1 */
107 if( ind_tmp + 1 >= NLSF_QUANT_MAX_AMPLITUDE ) {
108 if( ind_tmp + 1 == NLSF_QUANT_MAX_AMPLITUDE ) {
109 rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ];
110 rate1_Q5 = 280;
111 } else {
112 rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, 43, ind_tmp );
113 rate1_Q5 = silk_ADD16( rate0_Q5, 43 );
114 }
115 } else if( ind_tmp <= -NLSF_QUANT_MAX_AMPLITUDE ) {
116 if( ind_tmp == -NLSF_QUANT_MAX_AMPLITUDE ) {
117 rate0_Q5 = 280;
118 rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ];
119 } else {
120 rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, -43, ind_tmp );
121 rate1_Q5 = silk_SUB16( rate0_Q5, 43 );
122 }
123 } else {
124 rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ];
125 rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ];
126 }
127 RD_tmp_Q25 = RD_Q25[ j ];
128 diff_Q10 = silk_SUB16( in_Q10, out0_Q10 );
129 RD_Q25[ j ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate0_Q5 );
130 diff_Q10 = silk_SUB16( in_Q10, out1_Q10 );
131 RD_Q25[ j + nStates ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate1_Q5 );
132 }
133
134 if( nStates <= NLSF_QUANT_DEL_DEC_STATES/2 ) {
135 /* double number of states and copy */
136 for( j = 0; j < nStates; j++ ) {
137 ind[ j + nStates ][ i ] = ind[ j ][ i ] + 1;
138 }
139 nStates = silk_LSHIFT( nStates, 1 );
140 for( j = nStates; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
141 ind[ j ][ i ] = ind[ j - nStates ][ i ];
142 }
143 } else {
144 /* sort lower and upper half of RD_Q25, pairwise */
145 for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
146 if( RD_Q25[ j ] > RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] ) {
147 RD_max_Q25[ j ] = RD_Q25[ j ];
148 RD_min_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ];
149 RD_Q25[ j ] = RD_min_Q25[ j ];
150 RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] = RD_max_Q25[ j ];
151 /* swap prev_out values */
152 out0_Q10 = prev_out_Q10[ j ];
153 prev_out_Q10[ j ] = prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ];
154 prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ] = out0_Q10;
155 ind_sort[ j ] = j + NLSF_QUANT_DEL_DEC_STATES;
156 } else {
157 RD_min_Q25[ j ] = RD_Q25[ j ];
158 RD_max_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ];
159 ind_sort[ j ] = j;
160 }
161 }
162 /* compare the highest RD values of the winning half with the lowest one in the losing half, and copy if necessary */
163 /* afterwards ind_sort[] will contain the indices of the NLSF_QUANT_DEL_DEC_STATES winning RD values */
164 while( 1 ) {
165 min_max_Q25 = silk_int32_MAX;
166 max_min_Q25 = 0;
167 ind_min_max = 0;
168 ind_max_min = 0;
169 for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
170 if( min_max_Q25 > RD_max_Q25[ j ] ) {
171 min_max_Q25 = RD_max_Q25[ j ];
172 ind_min_max = j;
173 }
174 if( max_min_Q25 < RD_min_Q25[ j ] ) {
175 max_min_Q25 = RD_min_Q25[ j ];
176 ind_max_min = j;
177 }
178 }
179 if( min_max_Q25 >= max_min_Q25 ) {
180 break;
181 }
182 /* copy ind_min_max to ind_max_min */
183 ind_sort[ ind_max_min ] = ind_sort[ ind_min_max ] ^ NLSF_QUANT_DEL_DEC_STATES;
184 RD_Q25[ ind_max_min ] = RD_Q25[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ];
185 prev_out_Q10[ ind_max_min ] = prev_out_Q10[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ];
186 RD_min_Q25[ ind_max_min ] = 0;
187 RD_max_Q25[ ind_min_max ] = silk_int32_MAX;
188 silk_memcpy( ind[ ind_max_min ], ind[ ind_min_max ], MAX_LPC_ORDER * sizeof( opus_int8 ) );
189 }
190 /* increment index if it comes from the upper half */
191 for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
192 ind[ j ][ i ] += silk_RSHIFT( ind_sort[ j ], NLSF_QUANT_DEL_DEC_STATES_LOG2 );
193 }
194 }
195 }
196
197 /* last sample: find winner, copy indices and return RD value */
198 ind_tmp = 0;
199 min_Q25 = silk_int32_MAX;
200 for( j = 0; j < 2 * NLSF_QUANT_DEL_DEC_STATES; j++ ) {
201 if( min_Q25 > RD_Q25[ j ] ) {
202 min_Q25 = RD_Q25[ j ];
203 ind_tmp = j;
204 }
205 }
206 for( j = 0; j < order; j++ ) {
207 indices[ j ] = ind[ ind_tmp & ( NLSF_QUANT_DEL_DEC_STATES - 1 ) ][ j ];
208 silk_assert( indices[ j ] >= -NLSF_QUANT_MAX_AMPLITUDE_EXT );
209 silk_assert( indices[ j ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT );
210 }
211 indices[ 0 ] += silk_RSHIFT( ind_tmp, NLSF_QUANT_DEL_DEC_STATES_LOG2 );
212 silk_assert( indices[ 0 ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT );
213 silk_assert( min_Q25 >= 0 );
214 return min_Q25;
215}
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF_encode.c b/lib/rbcodec/codecs/libopus/silk/NLSF_encode.c
new file mode 100644
index 0000000000..01ac7db78c
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/NLSF_encode.c
@@ -0,0 +1,124 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33#include "stack_alloc.h"
34
35/***********************/
36/* NLSF vector encoder */
37/***********************/
38opus_int32 silk_NLSF_encode( /* O Returns RD value in Q25 */
39 opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */
40 opus_int16 *pNLSF_Q15, /* I/O (Un)quantized NLSF vector [ LPC_ORDER ] */
41 const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */
42 const opus_int16 *pW_Q2, /* I NLSF weight vector [ LPC_ORDER ] */
43 const opus_int NLSF_mu_Q20, /* I Rate weight for the RD optimization */
44 const opus_int nSurvivors, /* I Max survivors after first stage */
45 const opus_int signalType /* I Signal type: 0/1/2 */
46)
47{
48 opus_int i, s, ind1, bestIndex, prob_Q8, bits_q7;
49 opus_int32 W_tmp_Q9, ret;
50 VARDECL( opus_int32, err_Q24 );
51 VARDECL( opus_int32, RD_Q25 );
52 VARDECL( opus_int, tempIndices1 );
53 VARDECL( opus_int8, tempIndices2 );
54 opus_int16 res_Q10[ MAX_LPC_ORDER ];
55 opus_int16 NLSF_tmp_Q15[ MAX_LPC_ORDER ];
56 opus_int16 W_adj_Q5[ MAX_LPC_ORDER ];
57 opus_uint8 pred_Q8[ MAX_LPC_ORDER ];
58 opus_int16 ec_ix[ MAX_LPC_ORDER ];
59 const opus_uint8 *pCB_element, *iCDF_ptr;
60 const opus_int16 *pCB_Wght_Q9;
61 SAVE_STACK;
62
63 celt_assert( signalType >= 0 && signalType <= 2 );
64 silk_assert( NLSF_mu_Q20 <= 32767 && NLSF_mu_Q20 >= 0 );
65
66 /* NLSF stabilization */
67 silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order );
68
69 /* First stage: VQ */
70 ALLOC( err_Q24, psNLSF_CB->nVectors, opus_int32 );
71 silk_NLSF_VQ( err_Q24, pNLSF_Q15, psNLSF_CB->CB1_NLSF_Q8, psNLSF_CB->CB1_Wght_Q9, psNLSF_CB->nVectors, psNLSF_CB->order );
72
73 /* Sort the quantization errors */
74 ALLOC( tempIndices1, nSurvivors, opus_int );
75 silk_insertion_sort_increasing( err_Q24, tempIndices1, psNLSF_CB->nVectors, nSurvivors );
76
77 ALLOC( RD_Q25, nSurvivors, opus_int32 );
78 ALLOC( tempIndices2, nSurvivors * MAX_LPC_ORDER, opus_int8 );
79
80 /* Loop over survivors */
81 for( s = 0; s < nSurvivors; s++ ) {
82 ind1 = tempIndices1[ s ];
83
84 /* Residual after first stage */
85 pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ ind1 * psNLSF_CB->order ];
86 pCB_Wght_Q9 = &psNLSF_CB->CB1_Wght_Q9[ ind1 * psNLSF_CB->order ];
87 for( i = 0; i < psNLSF_CB->order; i++ ) {
88 NLSF_tmp_Q15[ i ] = silk_LSHIFT16( (opus_int16)pCB_element[ i ], 7 );
89 W_tmp_Q9 = pCB_Wght_Q9[ i ];
90 res_Q10[ i ] = (opus_int16)silk_RSHIFT( silk_SMULBB( pNLSF_Q15[ i ] - NLSF_tmp_Q15[ i ], W_tmp_Q9 ), 14 );
91 W_adj_Q5[ i ] = silk_DIV32_varQ( (opus_int32)pW_Q2[ i ], silk_SMULBB( W_tmp_Q9, W_tmp_Q9 ), 21 );
92 }
93
94 /* Unpack entropy table indices and predictor for current CB1 index */
95 silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, ind1 );
96
97 /* Trellis quantizer */
98 RD_Q25[ s ] = silk_NLSF_del_dec_quant( &tempIndices2[ s * MAX_LPC_ORDER ], res_Q10, W_adj_Q5, pred_Q8, ec_ix,
99 psNLSF_CB->ec_Rates_Q5, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->invQuantStepSize_Q6, NLSF_mu_Q20, psNLSF_CB->order );
100
101 /* Add rate for first stage */
102 iCDF_ptr = &psNLSF_CB->CB1_iCDF[ ( signalType >> 1 ) * psNLSF_CB->nVectors ];
103 if( ind1 == 0 ) {
104 prob_Q8 = 256 - iCDF_ptr[ ind1 ];
105 } else {
106 prob_Q8 = iCDF_ptr[ ind1 - 1 ] - iCDF_ptr[ ind1 ];
107 }
108 bits_q7 = ( 8 << 7 ) - silk_lin2log( prob_Q8 );
109 RD_Q25[ s ] = silk_SMLABB( RD_Q25[ s ], bits_q7, silk_RSHIFT( NLSF_mu_Q20, 2 ) );
110 }
111
112 /* Find the lowest rate-distortion error */
113 silk_insertion_sort_increasing( RD_Q25, &bestIndex, nSurvivors, 1 );
114
115 NLSFIndices[ 0 ] = (opus_int8)tempIndices1[ bestIndex ];
116 silk_memcpy( &NLSFIndices[ 1 ], &tempIndices2[ bestIndex * MAX_LPC_ORDER ], psNLSF_CB->order * sizeof( opus_int8 ) );
117
118 /* Decode */
119 silk_NLSF_decode( pNLSF_Q15, NLSFIndices, psNLSF_CB );
120
121 ret = RD_Q25[ 0 ];
122 RESTORE_STACK;
123 return ret;
124}
diff --git a/lib/rbcodec/codecs/libopus/silk/NLSF_stabilize.c b/lib/rbcodec/codecs/libopus/silk/NLSF_stabilize.c
index 1fa1ea379b..8f3426b91e 100644
--- a/lib/rbcodec/codecs/libopus/silk/NLSF_stabilize.c
+++ b/lib/rbcodec/codecs/libopus/silk/NLSF_stabilize.c
@@ -130,7 +130,7 @@ void silk_NLSF_stabilize(
130 130
131 /* Keep delta_min distance between the NLSFs */ 131 /* Keep delta_min distance between the NLSFs */
132 for( i = 1; i < L; i++ ) 132 for( i = 1; i < L; i++ )
133 NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q15[i] ); 133 NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], silk_ADD_SAT16( NLSF_Q15[i-1], NDeltaMin_Q15[i] ) );
134 134
135 /* Last NLSF should be no higher than 1 - NDeltaMin[L] */ 135 /* Last NLSF should be no higher than 1 - NDeltaMin[L] */
136 NLSF_Q15[L-1] = silk_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] ); 136 NLSF_Q15[L-1] = silk_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] );
diff --git a/lib/rbcodec/codecs/libopus/silk/NSQ.c b/lib/rbcodec/codecs/libopus/silk/NSQ.c
new file mode 100644
index 0000000000..1d64d8e257
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/NSQ.c
@@ -0,0 +1,437 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33#include "stack_alloc.h"
34#include "NSQ.h"
35
36
37static OPUS_INLINE void silk_nsq_scale_states(
38 const silk_encoder_state *psEncC, /* I Encoder State */
39 silk_nsq_state *NSQ, /* I/O NSQ state */
40 const opus_int16 x16[], /* I input */
41 opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
42 const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */
43 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
44 opus_int subfr, /* I subframe number */
45 const opus_int LTP_scale_Q14, /* I */
46 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
47 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
48 const opus_int signal_type /* I Signal type */
49);
50
51#if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
52static OPUS_INLINE void silk_noise_shape_quantizer(
53 silk_nsq_state *NSQ, /* I/O NSQ state */
54 opus_int signalType, /* I Signal type */
55 const opus_int32 x_sc_Q10[], /* I */
56 opus_int8 pulses[], /* O */
57 opus_int16 xq[], /* O */
58 opus_int32 sLTP_Q15[], /* I/O LTP state */
59 const opus_int16 a_Q12[], /* I Short term prediction coefs */
60 const opus_int16 b_Q14[], /* I Long term prediction coefs */
61 const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
62 opus_int lag, /* I Pitch lag */
63 opus_int32 HarmShapeFIRPacked_Q14, /* I */
64 opus_int Tilt_Q14, /* I Spectral tilt */
65 opus_int32 LF_shp_Q14, /* I */
66 opus_int32 Gain_Q16, /* I */
67 opus_int Lambda_Q10, /* I */
68 opus_int offset_Q10, /* I */
69 opus_int length, /* I Input length */
70 opus_int shapingLPCOrder, /* I Noise shaping AR filter order */
71 opus_int predictLPCOrder, /* I Prediction filter order */
72 int arch /* I Architecture */
73);
74#endif
75
76void silk_NSQ_c
77(
78 const silk_encoder_state *psEncC, /* I Encoder State */
79 silk_nsq_state *NSQ, /* I/O NSQ state */
80 SideInfoIndices *psIndices, /* I/O Quantization Indices */
81 const opus_int16 x16[], /* I Input */
82 opus_int8 pulses[], /* O Quantized pulse signal */
83 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
84 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
85 const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
86 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
87 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
88 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
89 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
90 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
91 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
92 const opus_int LTP_scale_Q14 /* I LTP state scaling */
93)
94{
95 opus_int k, lag, start_idx, LSF_interpolation_flag;
96 const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
97 opus_int16 *pxq;
98 VARDECL( opus_int32, sLTP_Q15 );
99 VARDECL( opus_int16, sLTP );
100 opus_int32 HarmShapeFIRPacked_Q14;
101 opus_int offset_Q10;
102 VARDECL( opus_int32, x_sc_Q10 );
103 SAVE_STACK;
104
105 NSQ->rand_seed = psIndices->Seed;
106
107 /* Set unvoiced lag to the previous one, overwrite later for voiced */
108 lag = NSQ->lagPrev;
109
110 silk_assert( NSQ->prev_gain_Q16 != 0 );
111
112 offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];
113
114 if( psIndices->NLSFInterpCoef_Q2 == 4 ) {
115 LSF_interpolation_flag = 0;
116 } else {
117 LSF_interpolation_flag = 1;
118 }
119
120 ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
121 ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
122 ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
123 /* Set up pointers to start of sub frame */
124 NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
125 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
126 pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
127 for( k = 0; k < psEncC->nb_subfr; k++ ) {
128 A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ];
129 B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
130 AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ];
131
132 /* Noise shape parameters */
133 silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
134 HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
135 HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
136
137 NSQ->rewhite_flag = 0;
138 if( psIndices->signalType == TYPE_VOICED ) {
139 /* Voiced */
140 lag = pitchL[ k ];
141
142 /* Re-whitening */
143 if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
144 /* Rewhiten with new A coefs */
145 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
146 celt_assert( start_idx > 0 );
147
148 silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
149 A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
150
151 NSQ->rewhite_flag = 1;
152 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
153 }
154 }
155
156 silk_nsq_scale_states( psEncC, NSQ, x16, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType );
157
158 silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14,
159 AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,
160 offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->arch );
161
162 x16 += psEncC->subfr_length;
163 pulses += psEncC->subfr_length;
164 pxq += psEncC->subfr_length;
165 }
166
167 /* Update lagPrev for next frame */
168 NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
169
170 /* Save quantized speech and noise shaping signals */
171 silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
172 silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
173 RESTORE_STACK;
174}
175
176/***********************************/
177/* silk_noise_shape_quantizer */
178/***********************************/
179
180#if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
181static OPUS_INLINE
182#endif
183void silk_noise_shape_quantizer(
184 silk_nsq_state *NSQ, /* I/O NSQ state */
185 opus_int signalType, /* I Signal type */
186 const opus_int32 x_sc_Q10[], /* I */
187 opus_int8 pulses[], /* O */
188 opus_int16 xq[], /* O */
189 opus_int32 sLTP_Q15[], /* I/O LTP state */
190 const opus_int16 a_Q12[], /* I Short term prediction coefs */
191 const opus_int16 b_Q14[], /* I Long term prediction coefs */
192 const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
193 opus_int lag, /* I Pitch lag */
194 opus_int32 HarmShapeFIRPacked_Q14, /* I */
195 opus_int Tilt_Q14, /* I Spectral tilt */
196 opus_int32 LF_shp_Q14, /* I */
197 opus_int32 Gain_Q16, /* I */
198 opus_int Lambda_Q10, /* I */
199 opus_int offset_Q10, /* I */
200 opus_int length, /* I Input length */
201 opus_int shapingLPCOrder, /* I Noise shaping AR filter order */
202 opus_int predictLPCOrder, /* I Prediction filter order */
203 int arch /* I Architecture */
204)
205{
206 opus_int i;
207 opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13;
208 opus_int32 n_LF_Q12, r_Q10, rr_Q10, q1_Q0, q1_Q10, q2_Q10, rd1_Q20, rd2_Q20;
209 opus_int32 exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
210 opus_int32 tmp1, tmp2, sLF_AR_shp_Q14;
211 opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr;
212#ifdef silk_short_prediction_create_arch_coef
213 opus_int32 a_Q12_arch[MAX_LPC_ORDER];
214#endif
215
216 shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
217 pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
218 Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
219
220 /* Set up short term AR state */
221 psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ];
222
223#ifdef silk_short_prediction_create_arch_coef
224 silk_short_prediction_create_arch_coef(a_Q12_arch, a_Q12, predictLPCOrder);
225#endif
226
227 for( i = 0; i < length; i++ ) {
228 /* Generate dither */
229 NSQ->rand_seed = silk_RAND( NSQ->rand_seed );
230
231 /* Short-term prediction */
232 LPC_pred_Q10 = silk_noise_shape_quantizer_short_prediction(psLPC_Q14, a_Q12, a_Q12_arch, predictLPCOrder, arch);
233
234 /* Long-term prediction */
235 if( signalType == TYPE_VOICED ) {
236 /* Unrolled loop */
237 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
238 LTP_pred_Q13 = 2;
239 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
240 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
241 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
242 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
243 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
244 pred_lag_ptr++;
245 } else {
246 LTP_pred_Q13 = 0;
247 }
248
249 /* Noise shape feedback */
250 celt_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
251 n_AR_Q12 = silk_NSQ_noise_shape_feedback_loop(&NSQ->sDiff_shp_Q14, NSQ->sAR2_Q14, AR_shp_Q13, shapingLPCOrder, arch);
252
253 n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sLF_AR_shp_Q14, Tilt_Q14 );
254
255 n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 );
256 n_LF_Q12 = silk_SMLAWT( n_LF_Q12, NSQ->sLF_AR_shp_Q14, LF_shp_Q14 );
257
258 celt_assert( lag > 0 || signalType != TYPE_VOICED );
259
260 /* Combine prediction and noise shaping signals */
261 tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 ); /* Q12 */
262 tmp1 = silk_SUB32( tmp1, n_LF_Q12 ); /* Q12 */
263 if( lag > 0 ) {
264 /* Symmetric, packed FIR coefficients */
265 n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
266 n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
267 n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 );
268 shp_lag_ptr++;
269
270 tmp2 = silk_SUB32( LTP_pred_Q13, n_LTP_Q13 ); /* Q13 */
271 tmp1 = silk_ADD_LSHIFT32( tmp2, tmp1, 1 ); /* Q13 */
272 tmp1 = silk_RSHIFT_ROUND( tmp1, 3 ); /* Q10 */
273 } else {
274 tmp1 = silk_RSHIFT_ROUND( tmp1, 2 ); /* Q10 */
275 }
276
277 r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 ); /* residual error Q10 */
278
279 /* Flip sign depending on dither */
280 if( NSQ->rand_seed < 0 ) {
281 r_Q10 = -r_Q10;
282 }
283 r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
284
285 /* Find two quantization level candidates and measure their rate-distortion */
286 q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
287 q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
288 if (Lambda_Q10 > 2048) {
289 /* For aggressive RDO, the bias becomes more than one pulse. */
290 int rdo_offset = Lambda_Q10/2 - 512;
291 if (q1_Q10 > rdo_offset) {
292 q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 );
293 } else if (q1_Q10 < -rdo_offset) {
294 q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 );
295 } else if (q1_Q10 < 0) {
296 q1_Q0 = -1;
297 } else {
298 q1_Q0 = 0;
299 }
300 }
301 if( q1_Q0 > 0 ) {
302 q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
303 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
304 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
305 rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 );
306 rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 );
307 } else if( q1_Q0 == 0 ) {
308 q1_Q10 = offset_Q10;
309 q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
310 rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 );
311 rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 );
312 } else if( q1_Q0 == -1 ) {
313 q2_Q10 = offset_Q10;
314 q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
315 rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
316 rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 );
317 } else { /* Q1_Q0 < -1 */
318 q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
319 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
320 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
321 rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
322 rd2_Q20 = silk_SMULBB( -q2_Q10, Lambda_Q10 );
323 }
324 rr_Q10 = silk_SUB32( r_Q10, q1_Q10 );
325 rd1_Q20 = silk_SMLABB( rd1_Q20, rr_Q10, rr_Q10 );
326 rr_Q10 = silk_SUB32( r_Q10, q2_Q10 );
327 rd2_Q20 = silk_SMLABB( rd2_Q20, rr_Q10, rr_Q10 );
328
329 if( rd2_Q20 < rd1_Q20 ) {
330 q1_Q10 = q2_Q10;
331 }
332
333 pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 );
334
335 /* Excitation */
336 exc_Q14 = silk_LSHIFT( q1_Q10, 4 );
337 if ( NSQ->rand_seed < 0 ) {
338 exc_Q14 = -exc_Q14;
339 }
340
341 /* Add predictions */
342 LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 );
343 xq_Q14 = silk_ADD_LSHIFT32( LPC_exc_Q14, LPC_pred_Q10, 4 );
344
345 /* Scale XQ back to normal level before saving */
346 xq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( xq_Q14, Gain_Q10 ), 8 ) );
347
348 /* Update states */
349 psLPC_Q14++;
350 *psLPC_Q14 = xq_Q14;
351 NSQ->sDiff_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_sc_Q10[ i ], 4 );
352 sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( NSQ->sDiff_shp_Q14, n_AR_Q12, 2 );
353 NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14;
354
355 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 );
356 sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 );
357 NSQ->sLTP_shp_buf_idx++;
358 NSQ->sLTP_buf_idx++;
359
360 /* Make dither dependent on quantized signal */
361 NSQ->rand_seed = silk_ADD32_ovflw( NSQ->rand_seed, pulses[ i ] );
362 }
363
364 /* Update LPC synth buffer */
365 silk_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
366}
367
368static OPUS_INLINE void silk_nsq_scale_states(
369 const silk_encoder_state *psEncC, /* I Encoder State */
370 silk_nsq_state *NSQ, /* I/O NSQ state */
371 const opus_int16 x16[], /* I input */
372 opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
373 const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */
374 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
375 opus_int subfr, /* I subframe number */
376 const opus_int LTP_scale_Q14, /* I */
377 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
378 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
379 const opus_int signal_type /* I Signal type */
380)
381{
382 opus_int i, lag;
383 opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26;
384
385 lag = pitchL[ subfr ];
386 inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
387 silk_assert( inv_gain_Q31 != 0 );
388
389 /* Scale input */
390 inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 );
391 for( i = 0; i < psEncC->subfr_length; i++ ) {
392 x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 );
393 }
394
395 /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
396 if( NSQ->rewhite_flag ) {
397 if( subfr == 0 ) {
398 /* Do LTP downscaling */
399 inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
400 }
401 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
402 silk_assert( i < MAX_FRAME_LENGTH );
403 sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );
404 }
405 }
406
407 /* Adjust for changing gain */
408 if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
409 gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
410
411 /* Scale long-term shaping state */
412 for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {
413 NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
414 }
415
416 /* Scale long-term prediction state */
417 if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
418 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
419 sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
420 }
421 }
422
423 NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 );
424 NSQ->sDiff_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sDiff_shp_Q14 );
425
426 /* Scale short-term prediction and shaping states */
427 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
428 NSQ->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] );
429 }
430 for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
431 NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] );
432 }
433
434 /* Save inverse gain */
435 NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
436 }
437}
diff --git a/lib/rbcodec/codecs/libopus/silk/NSQ.h b/lib/rbcodec/codecs/libopus/silk/NSQ.h
new file mode 100644
index 0000000000..971832f660
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/NSQ.h
@@ -0,0 +1,101 @@
1/***********************************************************************
2Copyright (c) 2014 Vidyo.
3Copyright (c) 2006-2011, Skype Limited. All rights reserved.
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions
6are met:
7- Redistributions of source code must retain the above copyright notice,
8this list of conditions and the following disclaimer.
9- Redistributions in binary form must reproduce the above copyright
10notice, this list of conditions and the following disclaimer in the
11documentation and/or other materials provided with the distribution.
12- Neither the name of Internet Society, IETF or IETF Trust, nor the
13names of specific contributors, may be used to endorse or promote
14products derived from this software without specific prior written
15permission.
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26POSSIBILITY OF SUCH DAMAGE.
27***********************************************************************/
28#ifndef SILK_NSQ_H
29#define SILK_NSQ_H
30
31#include "SigProc_FIX.h"
32
33#undef silk_short_prediction_create_arch_coef
34
35static OPUS_INLINE opus_int32 silk_noise_shape_quantizer_short_prediction_c(const opus_int32 *buf32, const opus_int16 *coef16, opus_int order)
36{
37 opus_int32 out;
38 silk_assert( order == 10 || order == 16 );
39
40 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
41 out = silk_RSHIFT( order, 1 );
42 out = silk_SMLAWB( out, buf32[ 0 ], coef16[ 0 ] );
43 out = silk_SMLAWB( out, buf32[ -1 ], coef16[ 1 ] );
44 out = silk_SMLAWB( out, buf32[ -2 ], coef16[ 2 ] );
45 out = silk_SMLAWB( out, buf32[ -3 ], coef16[ 3 ] );
46 out = silk_SMLAWB( out, buf32[ -4 ], coef16[ 4 ] );
47 out = silk_SMLAWB( out, buf32[ -5 ], coef16[ 5 ] );
48 out = silk_SMLAWB( out, buf32[ -6 ], coef16[ 6 ] );
49 out = silk_SMLAWB( out, buf32[ -7 ], coef16[ 7 ] );
50 out = silk_SMLAWB( out, buf32[ -8 ], coef16[ 8 ] );
51 out = silk_SMLAWB( out, buf32[ -9 ], coef16[ 9 ] );
52
53 if( order == 16 )
54 {
55 out = silk_SMLAWB( out, buf32[ -10 ], coef16[ 10 ] );
56 out = silk_SMLAWB( out, buf32[ -11 ], coef16[ 11 ] );
57 out = silk_SMLAWB( out, buf32[ -12 ], coef16[ 12 ] );
58 out = silk_SMLAWB( out, buf32[ -13 ], coef16[ 13 ] );
59 out = silk_SMLAWB( out, buf32[ -14 ], coef16[ 14 ] );
60 out = silk_SMLAWB( out, buf32[ -15 ], coef16[ 15 ] );
61 }
62 return out;
63}
64
65#define silk_noise_shape_quantizer_short_prediction(in, coef, coefRev, order, arch) ((void)arch,silk_noise_shape_quantizer_short_prediction_c(in, coef, order))
66
67static OPUS_INLINE opus_int32 silk_NSQ_noise_shape_feedback_loop_c(const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef, opus_int order)
68{
69 opus_int32 out;
70 opus_int32 tmp1, tmp2;
71 opus_int j;
72
73 tmp2 = data0[0];
74 tmp1 = data1[0];
75 data1[0] = tmp2;
76
77 out = silk_RSHIFT(order, 1);
78 out = silk_SMLAWB(out, tmp2, coef[0]);
79
80 for (j = 2; j < order; j += 2) {
81 tmp2 = data1[j - 1];
82 data1[j - 1] = tmp1;
83 out = silk_SMLAWB(out, tmp1, coef[j - 1]);
84 tmp1 = data1[j + 0];
85 data1[j + 0] = tmp2;
86 out = silk_SMLAWB(out, tmp2, coef[j]);
87 }
88 data1[order - 1] = tmp1;
89 out = silk_SMLAWB(out, tmp1, coef[order - 1]);
90 /* Q11 -> Q12 */
91 out = silk_LSHIFT32( out, 1 );
92 return out;
93}
94
95#define silk_NSQ_noise_shape_feedback_loop(data0, data1, coef, order, arch) ((void)arch,silk_NSQ_noise_shape_feedback_loop_c(data0, data1, coef, order))
96
97#if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
98#include "arm/NSQ_neon.h"
99#endif
100
101#endif /* SILK_NSQ_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/NSQ_del_dec.c b/lib/rbcodec/codecs/libopus/silk/NSQ_del_dec.c
new file mode 100644
index 0000000000..3fd9fa0d5b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/NSQ_del_dec.c
@@ -0,0 +1,733 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33#include "stack_alloc.h"
34#include "NSQ.h"
35
36
37typedef struct {
38 opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ];
39 opus_int32 RandState[ DECISION_DELAY ];
40 opus_int32 Q_Q10[ DECISION_DELAY ];
41 opus_int32 Xq_Q14[ DECISION_DELAY ];
42 opus_int32 Pred_Q15[ DECISION_DELAY ];
43 opus_int32 Shape_Q14[ DECISION_DELAY ];
44 opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];
45 opus_int32 LF_AR_Q14;
46 opus_int32 Diff_Q14;
47 opus_int32 Seed;
48 opus_int32 SeedInit;
49 opus_int32 RD_Q10;
50} NSQ_del_dec_struct;
51
52typedef struct {
53 opus_int32 Q_Q10;
54 opus_int32 RD_Q10;
55 opus_int32 xq_Q14;
56 opus_int32 LF_AR_Q14;
57 opus_int32 Diff_Q14;
58 opus_int32 sLTP_shp_Q14;
59 opus_int32 LPC_exc_Q14;
60} NSQ_sample_struct;
61
62typedef NSQ_sample_struct NSQ_sample_pair[ 2 ];
63
64#if defined(MIPSr1_ASM)
65#include "mips/NSQ_del_dec_mipsr1.h"
66#endif
67static OPUS_INLINE void silk_nsq_del_dec_scale_states(
68 const silk_encoder_state *psEncC, /* I Encoder State */
69 silk_nsq_state *NSQ, /* I/O NSQ state */
70 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
71 const opus_int16 x16[], /* I Input */
72 opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
73 const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
74 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
75 opus_int subfr, /* I Subframe number */
76 opus_int nStatesDelayedDecision, /* I Number of del dec states */
77 const opus_int LTP_scale_Q14, /* I LTP state scaling */
78 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
79 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
80 const opus_int signal_type, /* I Signal type */
81 const opus_int decisionDelay /* I Decision delay */
82);
83
84/******************************************/
85/* Noise shape quantizer for one subframe */
86/******************************************/
87static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
88 silk_nsq_state *NSQ, /* I/O NSQ state */
89 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
90 opus_int signalType, /* I Signal type */
91 const opus_int32 x_Q10[], /* I */
92 opus_int8 pulses[], /* O */
93 opus_int16 xq[], /* O */
94 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
95 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
96 const opus_int16 a_Q12[], /* I Short term prediction coefs */
97 const opus_int16 b_Q14[], /* I Long term prediction coefs */
98 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
99 opus_int lag, /* I Pitch lag */
100 opus_int32 HarmShapeFIRPacked_Q14, /* I */
101 opus_int Tilt_Q14, /* I Spectral tilt */
102 opus_int32 LF_shp_Q14, /* I */
103 opus_int32 Gain_Q16, /* I */
104 opus_int Lambda_Q10, /* I */
105 opus_int offset_Q10, /* I */
106 opus_int length, /* I Input length */
107 opus_int subfr, /* I Subframe number */
108 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
109 opus_int predictLPCOrder, /* I Prediction filter order */
110 opus_int warping_Q16, /* I */
111 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
112 opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
113 opus_int decisionDelay, /* I */
114 int arch /* I */
115);
116
117void silk_NSQ_del_dec_c(
118 const silk_encoder_state *psEncC, /* I Encoder State */
119 silk_nsq_state *NSQ, /* I/O NSQ state */
120 SideInfoIndices *psIndices, /* I/O Quantization Indices */
121 const opus_int16 x16[], /* I Input */
122 opus_int8 pulses[], /* O Quantized pulse signal */
123 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
124 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
125 const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
126 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
127 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
128 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
129 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
130 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
131 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
132 const opus_int LTP_scale_Q14 /* I LTP state scaling */
133)
134{
135 opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
136 opus_int last_smple_idx, smpl_buf_idx, decisionDelay;
137 const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
138 opus_int16 *pxq;
139 VARDECL( opus_int32, sLTP_Q15 );
140 VARDECL( opus_int16, sLTP );
141 opus_int32 HarmShapeFIRPacked_Q14;
142 opus_int offset_Q10;
143 opus_int32 RDmin_Q10, Gain_Q10;
144 VARDECL( opus_int32, x_sc_Q10 );
145 VARDECL( opus_int32, delayedGain_Q10 );
146 VARDECL( NSQ_del_dec_struct, psDelDec );
147 NSQ_del_dec_struct *psDD;
148 SAVE_STACK;
149
150 /* Set unvoiced lag to the previous one, overwrite later for voiced */
151 lag = NSQ->lagPrev;
152
153 silk_assert( NSQ->prev_gain_Q16 != 0 );
154
155 /* Initialize delayed decision states */
156 ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct );
157 silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) );
158 for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {
159 psDD = &psDelDec[ k ];
160 psDD->Seed = ( k + psIndices->Seed ) & 3;
161 psDD->SeedInit = psDD->Seed;
162 psDD->RD_Q10 = 0;
163 psDD->LF_AR_Q14 = NSQ->sLF_AR_shp_Q14;
164 psDD->Diff_Q14 = NSQ->sDiff_shp_Q14;
165 psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ];
166 silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
167 silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) );
168 }
169
170 offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];
171 smpl_buf_idx = 0; /* index of oldest samples */
172
173 decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length );
174
175 /* For voiced frames limit the decision delay to lower than the pitch lag */
176 if( psIndices->signalType == TYPE_VOICED ) {
177 for( k = 0; k < psEncC->nb_subfr; k++ ) {
178 decisionDelay = silk_min_int( decisionDelay, pitchL[ k ] - LTP_ORDER / 2 - 1 );
179 }
180 } else {
181 if( lag > 0 ) {
182 decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 );
183 }
184 }
185
186 if( psIndices->NLSFInterpCoef_Q2 == 4 ) {
187 LSF_interpolation_flag = 0;
188 } else {
189 LSF_interpolation_flag = 1;
190 }
191
192 ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
193 ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
194 ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
195 ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 );
196 /* Set up pointers to start of sub frame */
197 pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
198 NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
199 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
200 subfr = 0;
201 for( k = 0; k < psEncC->nb_subfr; k++ ) {
202 A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];
203 B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
204 AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ];
205
206 /* Noise shape parameters */
207 silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
208 HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
209 HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
210
211 NSQ->rewhite_flag = 0;
212 if( psIndices->signalType == TYPE_VOICED ) {
213 /* Voiced */
214 lag = pitchL[ k ];
215
216 /* Re-whitening */
217 if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
218 if( k == 2 ) {
219 /* RESET DELAYED DECISIONS */
220 /* Find winner */
221 RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
222 Winner_ind = 0;
223 for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) {
224 if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) {
225 RDmin_Q10 = psDelDec[ i ].RD_Q10;
226 Winner_ind = i;
227 }
228 }
229 for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) {
230 if( i != Winner_ind ) {
231 psDelDec[ i ].RD_Q10 += ( silk_int32_MAX >> 4 );
232 silk_assert( psDelDec[ i ].RD_Q10 >= 0 );
233 }
234 }
235
236 /* Copy final part of signals from winner state to output and long-term filter states */
237 psDD = &psDelDec[ Winner_ind ];
238 last_smple_idx = smpl_buf_idx + decisionDelay;
239 for( i = 0; i < decisionDelay; i++ ) {
240 last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY;
241 if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY;
242 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
243 pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
244 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) );
245 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];
246 }
247
248 subfr = 0;
249 }
250
251 /* Rewhiten with new A coefs */
252 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
253 celt_assert( start_idx > 0 );
254
255 silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
256 A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
257
258 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
259 NSQ->rewhite_flag = 1;
260 }
261 }
262
263 silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x16, x_sc_Q10, sLTP, sLTP_Q15, k,
264 psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );
265
266 silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,
267 delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ],
268 Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,
269 psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay, psEncC->arch );
270
271 x16 += psEncC->subfr_length;
272 pulses += psEncC->subfr_length;
273 pxq += psEncC->subfr_length;
274 }
275
276 /* Find winner */
277 RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
278 Winner_ind = 0;
279 for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) {
280 if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) {
281 RDmin_Q10 = psDelDec[ k ].RD_Q10;
282 Winner_ind = k;
283 }
284 }
285
286 /* Copy final part of signals from winner state to output and long-term filter states */
287 psDD = &psDelDec[ Winner_ind ];
288 psIndices->Seed = psDD->SeedInit;
289 last_smple_idx = smpl_buf_idx + decisionDelay;
290 Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 );
291 for( i = 0; i < decisionDelay; i++ ) {
292 last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY;
293 if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY;
294
295 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
296 pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
297 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) );
298 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];
299 }
300 silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
301 silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) );
302
303 /* Update states */
304 NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14;
305 NSQ->sDiff_shp_Q14 = psDD->Diff_Q14;
306 NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
307
308 /* Save quantized speech signal */
309 silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
310 silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
311 RESTORE_STACK;
312}
313
314/******************************************/
315/* Noise shape quantizer for one subframe */
316/******************************************/
317#ifndef OVERRIDE_silk_noise_shape_quantizer_del_dec
318static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
319 silk_nsq_state *NSQ, /* I/O NSQ state */
320 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
321 opus_int signalType, /* I Signal type */
322 const opus_int32 x_Q10[], /* I */
323 opus_int8 pulses[], /* O */
324 opus_int16 xq[], /* O */
325 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
326 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
327 const opus_int16 a_Q12[], /* I Short term prediction coefs */
328 const opus_int16 b_Q14[], /* I Long term prediction coefs */
329 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
330 opus_int lag, /* I Pitch lag */
331 opus_int32 HarmShapeFIRPacked_Q14, /* I */
332 opus_int Tilt_Q14, /* I Spectral tilt */
333 opus_int32 LF_shp_Q14, /* I */
334 opus_int32 Gain_Q16, /* I */
335 opus_int Lambda_Q10, /* I */
336 opus_int offset_Q10, /* I */
337 opus_int length, /* I Input length */
338 opus_int subfr, /* I Subframe number */
339 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
340 opus_int predictLPCOrder, /* I Prediction filter order */
341 opus_int warping_Q16, /* I */
342 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
343 opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
344 opus_int decisionDelay, /* I */
345 int arch /* I */
346)
347{
348 opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
349 opus_int32 Winner_rand_state;
350 opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14;
351 opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;
352 opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
353 opus_int32 tmp1, tmp2, sLF_AR_shp_Q14;
354 opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;
355#ifdef silk_short_prediction_create_arch_coef
356 opus_int32 a_Q12_arch[MAX_LPC_ORDER];
357#endif
358
359 VARDECL( NSQ_sample_pair, psSampleState );
360 NSQ_del_dec_struct *psDD;
361 NSQ_sample_struct *psSS;
362 SAVE_STACK;
363
364 celt_assert( nStatesDelayedDecision > 0 );
365 ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair );
366
367 shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
368 pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
369 Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
370
371#ifdef silk_short_prediction_create_arch_coef
372 silk_short_prediction_create_arch_coef(a_Q12_arch, a_Q12, predictLPCOrder);
373#endif
374
375 for( i = 0; i < length; i++ ) {
376 /* Perform common calculations used in all states */
377
378 /* Long-term prediction */
379 if( signalType == TYPE_VOICED ) {
380 /* Unrolled loop */
381 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
382 LTP_pred_Q14 = 2;
383 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
384 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
385 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
386 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
387 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
388 LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */
389 pred_lag_ptr++;
390 } else {
391 LTP_pred_Q14 = 0;
392 }
393
394 /* Long-term shaping */
395 if( lag > 0 ) {
396 /* Symmetric, packed FIR coefficients */
397 n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
398 n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
399 n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */
400 shp_lag_ptr++;
401 } else {
402 n_LTP_Q14 = 0;
403 }
404
405 for( k = 0; k < nStatesDelayedDecision; k++ ) {
406 /* Delayed decision state */
407 psDD = &psDelDec[ k ];
408
409 /* Sample state */
410 psSS = psSampleState[ k ];
411
412 /* Generate dither */
413 psDD->Seed = silk_RAND( psDD->Seed );
414
415 /* Pointer used in short term prediction and shaping */
416 psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];
417 /* Short-term prediction */
418 LPC_pred_Q14 = silk_noise_shape_quantizer_short_prediction(psLPC_Q14, a_Q12, a_Q12_arch, predictLPCOrder, arch);
419 LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */
420
421 /* Noise shape feedback */
422 celt_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
423 /* Output of lowpass section */
424 tmp2 = silk_SMLAWB( psDD->Diff_Q14, psDD->sAR2_Q14[ 0 ], warping_Q16 );
425 /* Output of allpass section */
426 tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );
427 psDD->sAR2_Q14[ 0 ] = tmp2;
428 n_AR_Q14 = silk_RSHIFT( shapingLPCOrder, 1 );
429 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ 0 ] );
430 /* Loop over allpass sections */
431 for( j = 2; j < shapingLPCOrder; j += 2 ) {
432 /* Output of allpass section */
433 tmp2 = silk_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 );
434 psDD->sAR2_Q14[ j - 1 ] = tmp1;
435 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ j - 1 ] );
436 /* Output of allpass section */
437 tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 );
438 psDD->sAR2_Q14[ j + 0 ] = tmp2;
439 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ j ] );
440 }
441 psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
442 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
443
444 n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */
445 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */
446 n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */
447
448 n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */
449 n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */
450 n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */
451
452 /* Input minus prediction plus noise feedback */
453 /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */
454 tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */
455 tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */
456 tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */
457 tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */
458
459 r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */
460
461 /* Flip sign depending on dither */
462 if ( psDD->Seed < 0 ) {
463 r_Q10 = -r_Q10;
464 }
465 r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
466
467 /* Find two quantization level candidates and measure their rate-distortion */
468 q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
469 q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
470 if (Lambda_Q10 > 2048) {
471 /* For aggressive RDO, the bias becomes more than one pulse. */
472 int rdo_offset = Lambda_Q10/2 - 512;
473 if (q1_Q10 > rdo_offset) {
474 q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 );
475 } else if (q1_Q10 < -rdo_offset) {
476 q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 );
477 } else if (q1_Q10 < 0) {
478 q1_Q0 = -1;
479 } else {
480 q1_Q0 = 0;
481 }
482 }
483 if( q1_Q0 > 0 ) {
484 q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
485 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
486 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
487 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
488 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
489 } else if( q1_Q0 == 0 ) {
490 q1_Q10 = offset_Q10;
491 q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
492 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
493 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
494 } else if( q1_Q0 == -1 ) {
495 q2_Q10 = offset_Q10;
496 q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
497 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
498 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
499 } else { /* q1_Q0 < -1 */
500 q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
501 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
502 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
503 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
504 rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 );
505 }
506 rr_Q10 = silk_SUB32( r_Q10, q1_Q10 );
507 rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 );
508 rr_Q10 = silk_SUB32( r_Q10, q2_Q10 );
509 rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 );
510
511 if( rd1_Q10 < rd2_Q10 ) {
512 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
513 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
514 psSS[ 0 ].Q_Q10 = q1_Q10;
515 psSS[ 1 ].Q_Q10 = q2_Q10;
516 } else {
517 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
518 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
519 psSS[ 0 ].Q_Q10 = q2_Q10;
520 psSS[ 1 ].Q_Q10 = q1_Q10;
521 }
522
523 /* Update states for best quantization */
524
525 /* Quantized excitation */
526 exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 );
527 if ( psDD->Seed < 0 ) {
528 exc_Q14 = -exc_Q14;
529 }
530
531 /* Add predictions */
532 LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
533 xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
534
535 /* Update states */
536 psSS[ 0 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 );
537 sLF_AR_shp_Q14 = silk_SUB32( psSS[ 0 ].Diff_Q14, n_AR_Q14 );
538 psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
539 psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14;
540 psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14;
541 psSS[ 0 ].xq_Q14 = xq_Q14;
542
543 /* Update states for second best quantization */
544
545 /* Quantized excitation */
546 exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 );
547 if ( psDD->Seed < 0 ) {
548 exc_Q14 = -exc_Q14;
549 }
550
551 /* Add predictions */
552 LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
553 xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
554
555 /* Update states */
556 psSS[ 1 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 );
557 sLF_AR_shp_Q14 = silk_SUB32( psSS[ 1 ].Diff_Q14, n_AR_Q14 );
558 psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
559 psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14;
560 psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14;
561 psSS[ 1 ].xq_Q14 = xq_Q14;
562 }
563
564 *smpl_buf_idx = ( *smpl_buf_idx - 1 ) % DECISION_DELAY;
565 if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY;
566 last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY;
567
568 /* Find winner */
569 RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
570 Winner_ind = 0;
571 for( k = 1; k < nStatesDelayedDecision; k++ ) {
572 if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) {
573 RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
574 Winner_ind = k;
575 }
576 }
577
578 /* Increase RD values of expired states */
579 Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ];
580 for( k = 0; k < nStatesDelayedDecision; k++ ) {
581 if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) {
582 psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 );
583 psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 );
584 silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 );
585 }
586 }
587
588 /* Find worst in first set and best in second set */
589 RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
590 RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10;
591 RDmax_ind = 0;
592 RDmin_ind = 0;
593 for( k = 1; k < nStatesDelayedDecision; k++ ) {
594 /* find worst in first set */
595 if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) {
596 RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
597 RDmax_ind = k;
598 }
599 /* find best in second set */
600 if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) {
601 RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10;
602 RDmin_ind = k;
603 }
604 }
605
606 /* Replace a state if best from second set outperforms worst in first set */
607 if( RDmin_Q10 < RDmax_Q10 ) {
608 silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i,
609 ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) );
610 silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) );
611 }
612
613 /* Write samples from winner to output and long-term filter states */
614 psDD = &psDelDec[ Winner_ind ];
615 if( subfr > 0 || i >= decisionDelay ) {
616 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
617 xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
618 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) );
619 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ];
620 sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ];
621 }
622 NSQ->sLTP_shp_buf_idx++;
623 NSQ->sLTP_buf_idx++;
624
625 /* Update states */
626 for( k = 0; k < nStatesDelayedDecision; k++ ) {
627 psDD = &psDelDec[ k ];
628 psSS = &psSampleState[ k ][ 0 ];
629 psDD->LF_AR_Q14 = psSS->LF_AR_Q14;
630 psDD->Diff_Q14 = psSS->Diff_Q14;
631 psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;
632 psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14;
633 psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10;
634 psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 );
635 psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14;
636 psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) );
637 psDD->RandState[ *smpl_buf_idx ] = psDD->Seed;
638 psDD->RD_Q10 = psSS->RD_Q10;
639 }
640 delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10;
641 }
642 /* Update LPC states */
643 for( k = 0; k < nStatesDelayedDecision; k++ ) {
644 psDD = &psDelDec[ k ];
645 silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
646 }
647 RESTORE_STACK;
648}
649#endif /* OVERRIDE_silk_noise_shape_quantizer_del_dec */
650
651static OPUS_INLINE void silk_nsq_del_dec_scale_states(
652 const silk_encoder_state *psEncC, /* I Encoder State */
653 silk_nsq_state *NSQ, /* I/O NSQ state */
654 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
655 const opus_int16 x16[], /* I Input */
656 opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
657 const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
658 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
659 opus_int subfr, /* I Subframe number */
660 opus_int nStatesDelayedDecision, /* I Number of del dec states */
661 const opus_int LTP_scale_Q14, /* I LTP state scaling */
662 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
663 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
664 const opus_int signal_type, /* I Signal type */
665 const opus_int decisionDelay /* I Decision delay */
666)
667{
668 opus_int i, k, lag;
669 opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26;
670 NSQ_del_dec_struct *psDD;
671
672 lag = pitchL[ subfr ];
673 inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
674 silk_assert( inv_gain_Q31 != 0 );
675
676 /* Scale input */
677 inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 );
678 for( i = 0; i < psEncC->subfr_length; i++ ) {
679 x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 );
680 }
681
682 /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
683 if( NSQ->rewhite_flag ) {
684 if( subfr == 0 ) {
685 /* Do LTP downscaling */
686 inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
687 }
688 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
689 silk_assert( i < MAX_FRAME_LENGTH );
690 sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );
691 }
692 }
693
694 /* Adjust for changing gain */
695 if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
696 gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
697
698 /* Scale long-term shaping state */
699 for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {
700 NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
701 }
702
703 /* Scale long-term prediction state */
704 if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
705 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
706 sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
707 }
708 }
709
710 for( k = 0; k < nStatesDelayedDecision; k++ ) {
711 psDD = &psDelDec[ k ];
712
713 /* Scale scalar states */
714 psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 );
715 psDD->Diff_Q14 = silk_SMULWW( gain_adj_Q16, psDD->Diff_Q14 );
716
717 /* Scale short-term prediction and shaping states */
718 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
719 psDD->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] );
720 }
721 for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
722 psDD->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] );
723 }
724 for( i = 0; i < DECISION_DELAY; i++ ) {
725 psDD->Pred_Q15[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Pred_Q15[ i ] );
726 psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] );
727 }
728 }
729
730 /* Save inverse gain */
731 NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
732 }
733}
diff --git a/lib/rbcodec/codecs/libopus/silk/PLC.c b/lib/rbcodec/codecs/libopus/silk/PLC.c
index 8b0a8fe57d..f89391651c 100644
--- a/lib/rbcodec/codecs/libopus/silk/PLC.c
+++ b/lib/rbcodec/codecs/libopus/silk/PLC.c
@@ -46,7 +46,8 @@ static OPUS_INLINE void silk_PLC_update(
46static OPUS_INLINE void silk_PLC_conceal( 46static OPUS_INLINE void silk_PLC_conceal(
47 silk_decoder_state *psDec, /* I/O Decoder state */ 47 silk_decoder_state *psDec, /* I/O Decoder state */
48 silk_decoder_control *psDecCtrl, /* I/O Decoder control */ 48 silk_decoder_control *psDecCtrl, /* I/O Decoder control */
49 opus_int16 frame[] /* O LPC residual signal */ 49 opus_int16 frame[], /* O LPC residual signal */
50 int arch /* I Run-time architecture */
50); 51);
51 52
52 53
@@ -65,7 +66,8 @@ void silk_PLC(
65 silk_decoder_state *psDec, /* I/O Decoder state */ 66 silk_decoder_state *psDec, /* I/O Decoder state */
66 silk_decoder_control *psDecCtrl, /* I/O Decoder control */ 67 silk_decoder_control *psDecCtrl, /* I/O Decoder control */
67 opus_int16 frame[], /* I/O signal */ 68 opus_int16 frame[], /* I/O signal */
68 opus_int lost /* I Loss flag */ 69 opus_int lost, /* I Loss flag */
70 int arch /* I Run-time architecture */
69) 71)
70{ 72{
71 /* PLC control function */ 73 /* PLC control function */
@@ -78,7 +80,7 @@ void silk_PLC(
78 /****************************/ 80 /****************************/
79 /* Generate Signal */ 81 /* Generate Signal */
80 /****************************/ 82 /****************************/
81 silk_PLC_conceal( psDec, psDecCtrl, frame ); 83 silk_PLC_conceal( psDec, psDecCtrl, frame, arch );
82 84
83 psDec->lossCnt++; 85 psDec->lossCnt++;
84 } else { 86 } else {
@@ -192,7 +194,8 @@ static OPUS_INLINE void silk_PLC_energy(opus_int32 *energy1, opus_int *shift1, o
192static OPUS_INLINE void silk_PLC_conceal( 194static OPUS_INLINE void silk_PLC_conceal(
193 silk_decoder_state *psDec, /* I/O Decoder state */ 195 silk_decoder_state *psDec, /* I/O Decoder state */
194 silk_decoder_control *psDecCtrl, /* I/O Decoder control */ 196 silk_decoder_control *psDecCtrl, /* I/O Decoder control */
195 opus_int16 frame[] /* O LPC residual signal */ 197 opus_int16 frame[], /* O LPC residual signal */
198 int arch /* I Run-time architecture */
196) 199)
197{ 200{
198 opus_int i, j, k; 201 opus_int i, j, k;
@@ -272,7 +275,7 @@ static OPUS_INLINE void silk_PLC_conceal(
272 /* Reduce random noise for unvoiced frames with high LPC gain */ 275 /* Reduce random noise for unvoiced frames with high LPC gain */
273 opus_int32 invGain_Q30, down_scale_Q30; 276 opus_int32 invGain_Q30, down_scale_Q30;
274 277
275 invGain_Q30 = silk_LPC_inverse_pred_gain( psPLC->prevLPC_Q12, psDec->LPC_order ); 278 invGain_Q30 = silk_LPC_inverse_pred_gain( psPLC->prevLPC_Q12, psDec->LPC_order, arch );
276 279
277 down_scale_Q30 = silk_min_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 ); 280 down_scale_Q30 = silk_min_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 );
278 down_scale_Q30 = silk_max_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 ); 281 down_scale_Q30 = silk_max_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 );
@@ -288,8 +291,8 @@ static OPUS_INLINE void silk_PLC_conceal(
288 291
289 /* Rewhiten LTP state */ 292 /* Rewhiten LTP state */
290 idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2; 293 idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2;
291 silk_assert( idx > 0 ); 294 celt_assert( idx > 0 );
292 silk_LPC_analysis_filter( &sLTP[ idx ], &psDec->outBuf[ idx ], A_Q12, psDec->ltp_mem_length - idx, psDec->LPC_order ); 295 silk_LPC_analysis_filter( &sLTP[ idx ], &psDec->outBuf[ idx ], A_Q12, psDec->ltp_mem_length - idx, psDec->LPC_order, arch );
293 /* Scale LTP state */ 296 /* Scale LTP state */
294 inv_gain_Q30 = silk_INVERSE32_varQ( psPLC->prevGain_Q16[ 1 ], 46 ); 297 inv_gain_Q30 = silk_INVERSE32_varQ( psPLC->prevGain_Q16[ 1 ], 46 );
295 inv_gain_Q30 = silk_min( inv_gain_Q30, silk_int32_MAX >> 1 ); 298 inv_gain_Q30 = silk_min( inv_gain_Q30, silk_int32_MAX >> 1 );
@@ -325,8 +328,10 @@ static OPUS_INLINE void silk_PLC_conceal(
325 for( j = 0; j < LTP_ORDER; j++ ) { 328 for( j = 0; j < LTP_ORDER; j++ ) {
326 B_Q14[ j ] = silk_RSHIFT( silk_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 ); 329 B_Q14[ j ] = silk_RSHIFT( silk_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 );
327 } 330 }
328 /* Gradually reduce excitation gain */ 331 if ( psDec->indices.signalType != TYPE_NO_VOICE_ACTIVITY ) {
329 rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 ); 332 /* Gradually reduce excitation gain */
333 rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 );
334 }
330 335
331 /* Slowly increase pitch lag */ 336 /* Slowly increase pitch lag */
332 psPLC->pitchL_Q8 = silk_SMLAWB( psPLC->pitchL_Q8, psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 ); 337 psPLC->pitchL_Q8 = silk_SMLAWB( psPLC->pitchL_Q8, psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 );
@@ -342,7 +347,7 @@ static OPUS_INLINE void silk_PLC_conceal(
342 /* Copy LPC state */ 347 /* Copy LPC state */
343 silk_memcpy( sLPC_Q14_ptr, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) ); 348 silk_memcpy( sLPC_Q14_ptr, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) );
344 349
345 silk_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */ 350 celt_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */
346 for( i = 0; i < psDec->frame_length; i++ ) { 351 for( i = 0; i < psDec->frame_length; i++ ) {
347 /* partly unrolled */ 352 /* partly unrolled */
348 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ 353 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
@@ -362,7 +367,8 @@ static OPUS_INLINE void silk_PLC_conceal(
362 } 367 }
363 368
364 /* Add prediction to LPC excitation */ 369 /* Add prediction to LPC excitation */
365 sLPC_Q14_ptr[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], LPC_pred_Q10, 4 ); 370 sLPC_Q14_ptr[ MAX_LPC_ORDER + i ] = silk_ADD_SAT32( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ],
371 silk_LSHIFT_SAT32( LPC_pred_Q10, 4 ));
366 372
367 /* Scale with Gain */ 373 /* Scale with Gain */
368 frame[ i ] = (opus_int16)silk_SAT16( silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], prevGain_Q10[ 1 ] ), 8 ) ) ); 374 frame[ i ] = (opus_int16)silk_SAT16( silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], prevGain_Q10[ 1 ] ), 8 ) ) );
diff --git a/lib/rbcodec/codecs/libopus/silk/PLC.h b/lib/rbcodec/codecs/libopus/silk/PLC.h
index f1e2eccc69..6438f51633 100644
--- a/lib/rbcodec/codecs/libopus/silk/PLC.h
+++ b/lib/rbcodec/codecs/libopus/silk/PLC.h
@@ -48,7 +48,8 @@ void silk_PLC(
48 silk_decoder_state *psDec, /* I/O Decoder state */ 48 silk_decoder_state *psDec, /* I/O Decoder state */
49 silk_decoder_control *psDecCtrl, /* I/O Decoder control */ 49 silk_decoder_control *psDecCtrl, /* I/O Decoder control */
50 opus_int16 frame[], /* I/O signal */ 50 opus_int16 frame[], /* I/O signal */
51 opus_int lost /* I Loss flag */ 51 opus_int lost, /* I Loss flag */
52 int arch /* I Run-time architecture */
52); 53);
53 54
54void silk_PLC_glue_frames( 55void silk_PLC_glue_frames(
diff --git a/lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h b/lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h
index 4be0985435..f9ae326326 100644
--- a/lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h
+++ b/lib/rbcodec/codecs/libopus/silk/SigProc_FIX.h
@@ -35,13 +35,22 @@ extern "C"
35 35
36/*#define silk_MACRO_COUNT */ /* Used to enable WMOPS counting */ 36/*#define silk_MACRO_COUNT */ /* Used to enable WMOPS counting */
37 37
38#define SILK_MAX_ORDER_LPC 16 /* max order of the LPC analysis in schur() and k2a() */ 38#define SILK_MAX_ORDER_LPC 24 /* max order of the LPC analysis in schur() and k2a() */
39 39
40#include <string.h> /* for memset(), memcpy(), memmove() */ 40#include <string.h> /* for memset(), memcpy(), memmove() */
41#include "typedef.h" 41#include "typedef.h"
42#include "resampler_structs.h" 42#include "resampler_structs.h"
43#include "macros.h" 43#include "macros.h"
44#include "cpu_support.h"
44 45
46#if defined(OPUS_X86_MAY_HAVE_SSE4_1)
47#include "x86/SigProc_FIX_sse.h"
48#endif
49
50#if (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
51#include "arm/biquad_alt_arm.h"
52#include "arm/LPC_inv_pred_gain_arm.h"
53#endif
45 54
46/********************************************************************/ 55/********************************************************************/
47/* SIGNAL PROCESSING FUNCTIONS */ 56/* SIGNAL PROCESSING FUNCTIONS */
@@ -92,14 +101,22 @@ void silk_resampler_down2_3(
92 * slower than biquad() but uses more precise coefficients 101 * slower than biquad() but uses more precise coefficients
93 * can handle (slowly) varying coefficients 102 * can handle (slowly) varying coefficients
94 */ 103 */
95void silk_biquad_alt( 104void silk_biquad_alt_stride1(
96 const opus_int16 *in, /* I input signal */ 105 const opus_int16 *in, /* I input signal */
97 const opus_int32 *B_Q28, /* I MA coefficients [3] */ 106 const opus_int32 *B_Q28, /* I MA coefficients [3] */
98 const opus_int32 *A_Q28, /* I AR coefficients [2] */ 107 const opus_int32 *A_Q28, /* I AR coefficients [2] */
99 opus_int32 *S, /* I/O State vector [2] */ 108 opus_int32 *S, /* I/O State vector [2] */
100 opus_int16 *out, /* O output signal */ 109 opus_int16 *out, /* O output signal */
101 const opus_int32 len, /* I signal length (must be even) */ 110 const opus_int32 len /* I signal length (must be even) */
102 opus_int stride /* I Operate on interleaved signal if > 1 */ 111);
112
113void silk_biquad_alt_stride2_c(
114 const opus_int16 *in, /* I input signal */
115 const opus_int32 *B_Q28, /* I MA coefficients [3] */
116 const opus_int32 *A_Q28, /* I AR coefficients [2] */
117 opus_int32 *S, /* I/O State vector [4] */
118 opus_int16 *out, /* O output signal */
119 const opus_int32 len /* I signal length (must be even) */
103); 120);
104 121
105/* Variable order MA prediction error filter. */ 122/* Variable order MA prediction error filter. */
@@ -108,7 +125,8 @@ void silk_LPC_analysis_filter(
108 const opus_int16 *in, /* I Input signal */ 125 const opus_int16 *in, /* I Input signal */
109 const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */ 126 const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */
110 const opus_int32 len, /* I Signal length */ 127 const opus_int32 len, /* I Signal length */
111 const opus_int32 d /* I Filter order */ 128 const opus_int32 d, /* I Filter order */
129 int arch /* I Run-time architecture */
112); 130);
113 131
114/* Chirp (bandwidth expand) LP AR filter */ 132/* Chirp (bandwidth expand) LP AR filter */
@@ -127,17 +145,11 @@ void silk_bwexpander_32(
127 145
128/* Compute inverse of LPC prediction gain, and */ 146/* Compute inverse of LPC prediction gain, and */
129/* test if LPC coefficients are stable (all poles within unit circle) */ 147/* test if LPC coefficients are stable (all poles within unit circle) */
130opus_int32 silk_LPC_inverse_pred_gain( /* O Returns inverse prediction gain in energy domain, Q30 */ 148opus_int32 silk_LPC_inverse_pred_gain_c( /* O Returns inverse prediction gain in energy domain, Q30 */
131 const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ 149 const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
132 const opus_int order /* I Prediction order */ 150 const opus_int order /* I Prediction order */
133); 151);
134 152
135/* For input in Q24 domain */
136opus_int32 silk_LPC_inverse_pred_gain_Q24( /* O Returns inverse prediction gain in energy domain, Q30 */
137 const opus_int32 *A_Q24, /* I Prediction coefficients [order] */
138 const opus_int order /* I Prediction order */
139);
140
141/* Split signal in two decimated bands using first-order allpass filters */ 153/* Split signal in two decimated bands using first-order allpass filters */
142void silk_ana_filt_bank_1( 154void silk_ana_filt_bank_1(
143 const opus_int16 *in, /* I Input signal [N] */ 155 const opus_int16 *in, /* I Input signal [N] */
@@ -147,6 +159,14 @@ void silk_ana_filt_bank_1(
147 const opus_int32 N /* I Number of input samples */ 159 const opus_int32 N /* I Number of input samples */
148); 160);
149 161
162#if !defined(OVERRIDE_silk_biquad_alt_stride2)
163#define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((void)(arch), silk_biquad_alt_stride2_c(in, B_Q28, A_Q28, S, out, len))
164#endif
165
166#if !defined(OVERRIDE_silk_LPC_inverse_pred_gain)
167#define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((void)(arch), silk_LPC_inverse_pred_gain_c(A_Q12, order))
168#endif
169
150/********************************************************************/ 170/********************************************************************/
151/* SCALAR FUNCTIONS */ 171/* SCALAR FUNCTIONS */
152/********************************************************************/ 172/********************************************************************/
@@ -266,7 +286,17 @@ void silk_A2NLSF(
266void silk_NLSF2A( 286void silk_NLSF2A(
267 opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */ 287 opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */
268 const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */ 288 const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */
269 const opus_int d /* I filter order (should be even) */ 289 const opus_int d, /* I filter order (should be even) */
290 int arch /* I Run-time architecture */
291);
292
293/* Convert int32 coefficients to int16 coefs and make sure there's no wrap-around */
294void silk_LPC_fit(
295 opus_int16 *a_QOUT, /* O Output signal */
296 opus_int32 *a_QIN, /* I/O Input signal */
297 const opus_int QOUT, /* I Input Q domain */
298 const opus_int QIN, /* I Input Q domain */
299 const opus_int d /* I Filter order */
270); 300);
271 301
272void silk_insertion_sort_increasing( 302void silk_insertion_sort_increasing(
@@ -303,7 +333,7 @@ void silk_NLSF_VQ_weights_laroia(
303); 333);
304 334
305/* Compute reflection coefficients from input signal */ 335/* Compute reflection coefficients from input signal */
306void silk_burg_modified( 336void silk_burg_modified_c(
307 opus_int32 *res_nrg, /* O Residual energy */ 337 opus_int32 *res_nrg, /* O Residual energy */
308 opus_int *res_nrg_Q, /* O Residual energy Q value */ 338 opus_int *res_nrg_Q, /* O Residual energy Q value */
309 opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ 339 opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
@@ -335,12 +365,15 @@ void silk_scale_vector32_Q26_lshift_18(
335/********************************************************************/ 365/********************************************************************/
336 366
337/* return sum( inVec1[i] * inVec2[i] ) */ 367/* return sum( inVec1[i] * inVec2[i] ) */
368
338opus_int32 silk_inner_prod_aligned( 369opus_int32 silk_inner_prod_aligned(
339 const opus_int16 *const inVec1, /* I input vector 1 */ 370 const opus_int16 *const inVec1, /* I input vector 1 */
340 const opus_int16 *const inVec2, /* I input vector 2 */ 371 const opus_int16 *const inVec2, /* I input vector 2 */
341 const opus_int len /* I vector lengths */ 372 const opus_int len, /* I vector lengths */
373 int arch /* I Run-time architecture */
342); 374);
343 375
376
344opus_int32 silk_inner_prod_aligned_scale( 377opus_int32 silk_inner_prod_aligned_scale(
345 const opus_int16 *const inVec1, /* I input vector 1 */ 378 const opus_int16 *const inVec1, /* I input vector 1 */
346 const opus_int16 *const inVec2, /* I input vector 2 */ 379 const opus_int16 *const inVec2, /* I input vector 2 */
@@ -348,7 +381,7 @@ opus_int32 silk_inner_prod_aligned_scale(
348 const opus_int len /* I vector lengths */ 381 const opus_int len /* I vector lengths */
349); 382);
350 383
351opus_int64 silk_inner_prod16_aligned_64( 384opus_int64 silk_inner_prod16_aligned_64_c(
352 const opus_int16 *inVec1, /* I input vector 1 */ 385 const opus_int16 *inVec1, /* I input vector 1 */
353 const opus_int16 *inVec2, /* I input vector 2 */ 386 const opus_int16 *inVec2, /* I input vector 2 */
354 const opus_int len /* I vector lengths */ 387 const opus_int len /* I vector lengths */
@@ -463,8 +496,7 @@ static OPUS_INLINE opus_int32 silk_ROR32( opus_int32 a32, opus_int rot )
463/* Add with saturation for positive input values */ 496/* Add with saturation for positive input values */
464#define silk_ADD_POS_SAT8(a, b) ((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b))) 497#define silk_ADD_POS_SAT8(a, b) ((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b)))
465#define silk_ADD_POS_SAT16(a, b) ((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b))) 498#define silk_ADD_POS_SAT16(a, b) ((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b)))
466#define silk_ADD_POS_SAT32(a, b) ((((a)+(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b))) 499#define silk_ADD_POS_SAT32(a, b) ((((opus_uint32)(a)+(opus_uint32)(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b)))
467#define silk_ADD_POS_SAT64(a, b) ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b)))
468 500
469#define silk_LSHIFT8(a, shift) ((opus_int8)((opus_uint8)(a)<<(shift))) /* shift >= 0, shift < 8 */ 501#define silk_LSHIFT8(a, shift) ((opus_int8)((opus_uint8)(a)<<(shift))) /* shift >= 0, shift < 8 */
470#define silk_LSHIFT16(a, shift) ((opus_int16)((opus_uint16)(a)<<(shift))) /* shift >= 0, shift < 16 */ 502#define silk_LSHIFT16(a, shift) ((opus_int16)((opus_uint16)(a)<<(shift))) /* shift >= 0, shift < 16 */
@@ -564,7 +596,9 @@ static OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b)
564/* Make sure to store the result as the seed for the next call (also in between */ 596/* Make sure to store the result as the seed for the next call (also in between */
565/* frames), otherwise result won't be random at all. When only using some of the */ 597/* frames), otherwise result won't be random at all. When only using some of the */
566/* bits, take the most significant bits by right-shifting. */ 598/* bits, take the most significant bits by right-shifting. */
567#define silk_RAND(seed) (silk_MLA_ovflw(907633515, (seed), 196314165)) 599#define RAND_MULTIPLIER 196314165
600#define RAND_INCREMENT 907633515
601#define silk_RAND(seed) (silk_MLA_ovflw((RAND_INCREMENT), (seed), (RAND_MULTIPLIER)))
568 602
569/* Add some multiplication functions that can be easily mapped to ARM. */ 603/* Add some multiplication functions that can be easily mapped to ARM. */
570 604
@@ -575,6 +609,14 @@ static OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b)
575/* the following seems faster on x86 */ 609/* the following seems faster on x86 */
576#define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT64(silk_SMULL((a32), (b32)), 32) 610#define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT64(silk_SMULL((a32), (b32)), 32)
577 611
612#if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
613#define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \
614 ((void)(arch), silk_burg_modified_c(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch))
615
616#define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \
617 ((void)(arch),silk_inner_prod16_aligned_64_c(inVec1, inVec2, len))
618#endif
619
578#include "Inlines.h" 620#include "Inlines.h"
579#include "MacroCount.h" 621#include "MacroCount.h"
580#include "MacroDebug.h" 622#include "MacroDebug.h"
diff --git a/lib/rbcodec/codecs/libopus/silk/VAD.c b/lib/rbcodec/codecs/libopus/silk/VAD.c
new file mode 100644
index 0000000000..d0cda52162
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/VAD.c
@@ -0,0 +1,360 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33#include "stack_alloc.h"
34
35/* Silk VAD noise level estimation */
36# if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
37static OPUS_INLINE void silk_VAD_GetNoiseLevels(
38 const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */
39 silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
40);
41#endif
42
43/**********************************/
44/* Initialization of the Silk VAD */
45/**********************************/
46opus_int silk_VAD_Init( /* O Return value, 0 if success */
47 silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
48)
49{
50 opus_int b, ret = 0;
51
52 /* reset state memory */
53 silk_memset( psSilk_VAD, 0, sizeof( silk_VAD_state ) );
54
55 /* init noise levels */
56 /* Initialize array with approx pink noise levels (psd proportional to inverse of frequency) */
57 for( b = 0; b < VAD_N_BANDS; b++ ) {
58 psSilk_VAD->NoiseLevelBias[ b ] = silk_max_32( silk_DIV32_16( VAD_NOISE_LEVELS_BIAS, b + 1 ), 1 );
59 }
60
61 /* Initialize state */
62 for( b = 0; b < VAD_N_BANDS; b++ ) {
63 psSilk_VAD->NL[ b ] = silk_MUL( 100, psSilk_VAD->NoiseLevelBias[ b ] );
64 psSilk_VAD->inv_NL[ b ] = silk_DIV32( silk_int32_MAX, psSilk_VAD->NL[ b ] );
65 }
66 psSilk_VAD->counter = 15;
67
68 /* init smoothed energy-to-noise ratio*/
69 for( b = 0; b < VAD_N_BANDS; b++ ) {
70 psSilk_VAD->NrgRatioSmth_Q8[ b ] = 100 * 256; /* 100 * 256 --> 20 dB SNR */
71 }
72
73 return( ret );
74}
75
76/* Weighting factors for tilt measure */
77static const opus_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 };
78
79/***************************************/
80/* Get the speech activity level in Q8 */
81/***************************************/
82opus_int silk_VAD_GetSA_Q8_c( /* O Return value, 0 if success */
83 silk_encoder_state *psEncC, /* I/O Encoder state */
84 const opus_int16 pIn[] /* I PCM input */
85)
86{
87 opus_int SA_Q15, pSNR_dB_Q7, input_tilt;
88 opus_int decimated_framelength1, decimated_framelength2;
89 opus_int decimated_framelength;
90 opus_int dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;
91 opus_int32 sumSquared, smooth_coef_Q16;
92 opus_int16 HPstateTmp;
93 VARDECL( opus_int16, X );
94 opus_int32 Xnrg[ VAD_N_BANDS ];
95 opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];
96 opus_int32 speech_nrg, x_tmp;
97 opus_int X_offset[ VAD_N_BANDS ];
98 opus_int ret = 0;
99 silk_VAD_state *psSilk_VAD = &psEncC->sVAD;
100 SAVE_STACK;
101
102 /* Safety checks */
103 silk_assert( VAD_N_BANDS == 4 );
104 celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
105 celt_assert( psEncC->frame_length <= 512 );
106 celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
107
108 /***********************/
109 /* Filter and Decimate */
110 /***********************/
111 decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 );
112 decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 );
113 decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 );
114 /* Decimate into 4 bands:
115 0 L 3L L 3L 5L
116 - -- - -- --
117 8 8 2 4 4
118
119 [0-1 kHz| temp. |1-2 kHz| 2-4 kHz | 4-8 kHz |
120
121 They're arranged to allow the minimal ( frame_length / 4 ) extra
122 scratch space during the downsampling process */
123 X_offset[ 0 ] = 0;
124 X_offset[ 1 ] = decimated_framelength + decimated_framelength2;
125 X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength;
126 X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2;
127 ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 );
128
129 /* 0-8 kHz to 0-4 kHz and 4-8 kHz */
130 silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[ 0 ],
131 X, &X[ X_offset[ 3 ] ], psEncC->frame_length );
132
133 /* 0-4 kHz to 0-2 kHz and 2-4 kHz */
134 silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ],
135 X, &X[ X_offset[ 2 ] ], decimated_framelength1 );
136
137 /* 0-2 kHz to 0-1 kHz and 1-2 kHz */
138 silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ],
139 X, &X[ X_offset[ 1 ] ], decimated_framelength2 );
140
141 /*********************************************/
142 /* HP filter on lowest band (differentiator) */
143 /*********************************************/
144 X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 );
145 HPstateTmp = X[ decimated_framelength - 1 ];
146 for( i = decimated_framelength - 1; i > 0; i-- ) {
147 X[ i - 1 ] = silk_RSHIFT( X[ i - 1 ], 1 );
148 X[ i ] -= X[ i - 1 ];
149 }
150 X[ 0 ] -= psSilk_VAD->HPstate;
151 psSilk_VAD->HPstate = HPstateTmp;
152
153 /*************************************/
154 /* Calculate the energy in each band */
155 /*************************************/
156 for( b = 0; b < VAD_N_BANDS; b++ ) {
157 /* Find the decimated framelength in the non-uniformly divided bands */
158 decimated_framelength = silk_RSHIFT( psEncC->frame_length, silk_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) );
159
160 /* Split length into subframe lengths */
161 dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );
162 dec_subframe_offset = 0;
163
164 /* Compute energy per sub-frame */
165 /* initialize with summed energy of last subframe */
166 Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];
167 for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {
168 sumSquared = 0;
169 for( i = 0; i < dec_subframe_length; i++ ) {
170 /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2. */
171 /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128) */
172 x_tmp = silk_RSHIFT(
173 X[ X_offset[ b ] + i + dec_subframe_offset ], 3 );
174 sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp );
175
176 /* Safety check */
177 silk_assert( sumSquared >= 0 );
178 }
179
180 /* Add/saturate summed energy of current subframe */
181 if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {
182 Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared );
183 } else {
184 /* Look-ahead subframe */
185 Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) );
186 }
187
188 dec_subframe_offset += dec_subframe_length;
189 }
190 psSilk_VAD->XnrgSubfr[ b ] = sumSquared;
191 }
192
193 /********************/
194 /* Noise estimation */
195 /********************/
196 silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD );
197
198 /***********************************************/
199 /* Signal-plus-noise to noise ratio estimation */
200 /***********************************************/
201 sumSquared = 0;
202 input_tilt = 0;
203 for( b = 0; b < VAD_N_BANDS; b++ ) {
204 speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];
205 if( speech_nrg > 0 ) {
206 /* Divide, with sufficient resolution */
207 if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) {
208 NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 );
209 } else {
210 NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 );
211 }
212
213 /* Convert to log domain */
214 SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128;
215
216 /* Sum-of-squares */
217 sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 ); /* Q14 */
218
219 /* Tilt measure */
220 if( speech_nrg < ( (opus_int32)1 << 20 ) ) {
221 /* Scale down SNR value for small subband speech energies */
222 SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );
223 }
224 input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );
225 } else {
226 NrgToNoiseRatio_Q8[ b ] = 256;
227 }
228 }
229
230 /* Mean-of-squares */
231 sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */
232
233 /* Root-mean-square approximation, scale to dBs, and write to output pointer */
234 pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */
235
236 /*********************************/
237 /* Speech Probability Estimation */
238 /*********************************/
239 SA_Q15 = silk_sigm_Q15( silk_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 );
240
241 /**************************/
242 /* Frequency Tilt Measure */
243 /**************************/
244 psEncC->input_tilt_Q15 = silk_LSHIFT( silk_sigm_Q15( input_tilt ) - 16384, 1 );
245
246 /**************************************************/
247 /* Scale the sigmoid output based on power levels */
248 /**************************************************/
249 speech_nrg = 0;
250 for( b = 0; b < VAD_N_BANDS; b++ ) {
251 /* Accumulate signal-without-noise energies, higher frequency bands have more weight */
252 speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );
253 }
254
255 if( psEncC->frame_length == 20 * psEncC->fs_kHz ) {
256 speech_nrg = silk_RSHIFT32( speech_nrg, 1 );
257 }
258 /* Power scaling */
259 if( speech_nrg <= 0 ) {
260 SA_Q15 = silk_RSHIFT( SA_Q15, 1 );
261 } else if( speech_nrg < 16384 ) {
262 speech_nrg = silk_LSHIFT32( speech_nrg, 16 );
263
264 /* square-root */
265 speech_nrg = silk_SQRT_APPROX( speech_nrg );
266 SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 );
267 }
268
269 /* Copy the resulting speech activity in Q8 */
270 psEncC->speech_activity_Q8 = silk_min_int( silk_RSHIFT( SA_Q15, 7 ), silk_uint8_MAX );
271
272 /***********************************/
273 /* Energy Level and SNR estimation */
274 /***********************************/
275 /* Smoothing coefficient */
276 smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) );
277
278 if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {
279 smooth_coef_Q16 >>= 1;
280 }
281
282 for( b = 0; b < VAD_N_BANDS; b++ ) {
283 /* compute smoothed energy-to-noise ratio per band */
284 psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ],
285 NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 );
286
287 /* signal to noise ratio in dB per band */
288 SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 );
289 /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */
290 psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) );
291 }
292
293 RESTORE_STACK;
294 return( ret );
295}
296
297/**************************/
298/* Noise level estimation */
299/**************************/
300# if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
301static OPUS_INLINE
302#endif
303void silk_VAD_GetNoiseLevels(
304 const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */
305 silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
306)
307{
308 opus_int k;
309 opus_int32 nl, nrg, inv_nrg;
310 opus_int coef, min_coef;
311
312 /* Initially faster smoothing */
313 if( psSilk_VAD->counter < 1000 ) { /* 1000 = 20 sec */
314 min_coef = silk_DIV32_16( silk_int16_MAX, silk_RSHIFT( psSilk_VAD->counter, 4 ) + 1 );
315 /* Increment frame counter */
316 psSilk_VAD->counter++;
317 } else {
318 min_coef = 0;
319 }
320
321 for( k = 0; k < VAD_N_BANDS; k++ ) {
322 /* Get old noise level estimate for current band */
323 nl = psSilk_VAD->NL[ k ];
324 silk_assert( nl >= 0 );
325
326 /* Add bias */
327 nrg = silk_ADD_POS_SAT32( pX[ k ], psSilk_VAD->NoiseLevelBias[ k ] );
328 silk_assert( nrg > 0 );
329
330 /* Invert energies */
331 inv_nrg = silk_DIV32( silk_int32_MAX, nrg );
332 silk_assert( inv_nrg >= 0 );
333
334 /* Less update when subband energy is high */
335 if( nrg > silk_LSHIFT( nl, 3 ) ) {
336 coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 >> 3;
337 } else if( nrg < nl ) {
338 coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16;
339 } else {
340 coef = silk_SMULWB( silk_SMULWW( inv_nrg, nl ), VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 << 1 );
341 }
342
343 /* Initially faster smoothing */
344 coef = silk_max_int( coef, min_coef );
345
346 /* Smooth inverse energies */
347 psSilk_VAD->inv_NL[ k ] = silk_SMLAWB( psSilk_VAD->inv_NL[ k ], inv_nrg - psSilk_VAD->inv_NL[ k ], coef );
348 silk_assert( psSilk_VAD->inv_NL[ k ] >= 0 );
349
350 /* Compute noise level by inverting again */
351 nl = silk_DIV32( silk_int32_MAX, psSilk_VAD->inv_NL[ k ] );
352 silk_assert( nl >= 0 );
353
354 /* Limit noise levels (guarantee 7 bits of head room) */
355 nl = silk_min( nl, 0x00FFFFFF );
356
357 /* Store as part of state */
358 psSilk_VAD->NL[ k ] = nl;
359 }
360}
diff --git a/lib/rbcodec/codecs/libopus/silk/VQ_WMat_EC.c b/lib/rbcodec/codecs/libopus/silk/VQ_WMat_EC.c
new file mode 100644
index 0000000000..0f3d545c4e
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/VQ_WMat_EC.c
@@ -0,0 +1,131 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33
34/* Entropy constrained matrix-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */
35void silk_VQ_WMat_EC_c(
36 opus_int8 *ind, /* O index of best codebook vector */
37 opus_int32 *res_nrg_Q15, /* O best residual energy */
38 opus_int32 *rate_dist_Q8, /* O best total bitrate */
39 opus_int *gain_Q7, /* O sum of absolute LTP coefficients */
40 const opus_int32 *XX_Q17, /* I correlation matrix */
41 const opus_int32 *xX_Q17, /* I correlation vector */
42 const opus_int8 *cb_Q7, /* I codebook */
43 const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */
44 const opus_uint8 *cl_Q5, /* I code length for each codebook vector */
45 const opus_int subfr_len, /* I number of samples per subframe */
46 const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
47 const opus_int L /* I number of vectors in codebook */
48)
49{
50 opus_int k, gain_tmp_Q7;
51 const opus_int8 *cb_row_Q7;
52 opus_int32 neg_xX_Q24[ 5 ];
53 opus_int32 sum1_Q15, sum2_Q24;
54 opus_int32 bits_res_Q8, bits_tot_Q8;
55
56 /* Negate and convert to new Q domain */
57 neg_xX_Q24[ 0 ] = -silk_LSHIFT32( xX_Q17[ 0 ], 7 );
58 neg_xX_Q24[ 1 ] = -silk_LSHIFT32( xX_Q17[ 1 ], 7 );
59 neg_xX_Q24[ 2 ] = -silk_LSHIFT32( xX_Q17[ 2 ], 7 );
60 neg_xX_Q24[ 3 ] = -silk_LSHIFT32( xX_Q17[ 3 ], 7 );
61 neg_xX_Q24[ 4 ] = -silk_LSHIFT32( xX_Q17[ 4 ], 7 );
62
63 /* Loop over codebook */
64 *rate_dist_Q8 = silk_int32_MAX;
65 *res_nrg_Q15 = silk_int32_MAX;
66 cb_row_Q7 = cb_Q7;
67 /* In things go really bad, at least *ind is set to something safe. */
68 *ind = 0;
69 for( k = 0; k < L; k++ ) {
70 opus_int32 penalty;
71 gain_tmp_Q7 = cb_gain_Q7[k];
72 /* Weighted rate */
73 /* Quantization error: 1 - 2 * xX * cb + cb' * XX * cb */
74 sum1_Q15 = SILK_FIX_CONST( 1.001, 15 );
75
76 /* Penalty for too large gain */
77 penalty = silk_LSHIFT32( silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 11 );
78
79 /* first row of XX_Q17 */
80 sum2_Q24 = silk_MLA( neg_xX_Q24[ 0 ], XX_Q17[ 1 ], cb_row_Q7[ 1 ] );
81 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 2 ], cb_row_Q7[ 2 ] );
82 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 3 ], cb_row_Q7[ 3 ] );
83 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 4 ], cb_row_Q7[ 4 ] );
84 sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 );
85 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 0 ], cb_row_Q7[ 0 ] );
86 sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 0 ] );
87
88 /* second row of XX_Q17 */
89 sum2_Q24 = silk_MLA( neg_xX_Q24[ 1 ], XX_Q17[ 7 ], cb_row_Q7[ 2 ] );
90 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 8 ], cb_row_Q7[ 3 ] );
91 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 9 ], cb_row_Q7[ 4 ] );
92 sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 );
93 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 6 ], cb_row_Q7[ 1 ] );
94 sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 1 ] );
95
96 /* third row of XX_Q17 */
97 sum2_Q24 = silk_MLA( neg_xX_Q24[ 2 ], XX_Q17[ 13 ], cb_row_Q7[ 3 ] );
98 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 14 ], cb_row_Q7[ 4 ] );
99 sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 );
100 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 12 ], cb_row_Q7[ 2 ] );
101 sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 2 ] );
102
103 /* fourth row of XX_Q17 */
104 sum2_Q24 = silk_MLA( neg_xX_Q24[ 3 ], XX_Q17[ 19 ], cb_row_Q7[ 4 ] );
105 sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 );
106 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 18 ], cb_row_Q7[ 3 ] );
107 sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 3 ] );
108
109 /* last row of XX_Q17 */
110 sum2_Q24 = silk_LSHIFT32( neg_xX_Q24[ 4 ], 1 );
111 sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 24 ], cb_row_Q7[ 4 ] );
112 sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 4 ] );
113
114 /* find best */
115 if( sum1_Q15 >= 0 ) {
116 /* Translate residual energy to bits using high-rate assumption (6 dB ==> 1 bit/sample) */
117 bits_res_Q8 = silk_SMULBB( subfr_len, silk_lin2log( sum1_Q15 + penalty) - (15 << 7) );
118 /* In the following line we reduce the codelength component by half ("-1"); seems to slghtly improve quality */
119 bits_tot_Q8 = silk_ADD_LSHIFT32( bits_res_Q8, cl_Q5[ k ], 3-1 );
120 if( bits_tot_Q8 <= *rate_dist_Q8 ) {
121 *rate_dist_Q8 = bits_tot_Q8;
122 *res_nrg_Q15 = sum1_Q15 + penalty;
123 *ind = (opus_int8)k;
124 *gain_Q7 = gain_tmp_Q7;
125 }
126 }
127
128 /* Go to next cbk vector */
129 cb_row_Q7 += LTP_ORDER;
130 }
131}
diff --git a/lib/rbcodec/codecs/libopus/silk/ana_filt_bank_1.c b/lib/rbcodec/codecs/libopus/silk/ana_filt_bank_1.c
new file mode 100644
index 0000000000..24cfb03fdb
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/ana_filt_bank_1.c
@@ -0,0 +1,74 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33
34/* Coefficients for 2-band filter bank based on first-order allpass filters */
35static opus_int16 A_fb1_20 = 5394 << 1;
36static opus_int16 A_fb1_21 = -24290; /* (opus_int16)(20623 << 1) */
37
38/* Split signal into two decimated bands using first-order allpass filters */
39void silk_ana_filt_bank_1(
40 const opus_int16 *in, /* I Input signal [N] */
41 opus_int32 *S, /* I/O State vector [2] */
42 opus_int16 *outL, /* O Low band [N/2] */
43 opus_int16 *outH, /* O High band [N/2] */
44 const opus_int32 N /* I Number of input samples */
45)
46{
47 opus_int k, N2 = silk_RSHIFT( N, 1 );
48 opus_int32 in32, X, Y, out_1, out_2;
49
50 /* Internal variables and state are in Q10 format */
51 for( k = 0; k < N2; k++ ) {
52 /* Convert to Q10 */
53 in32 = silk_LSHIFT( (opus_int32)in[ 2 * k ], 10 );
54
55 /* All-pass section for even input sample */
56 Y = silk_SUB32( in32, S[ 0 ] );
57 X = silk_SMLAWB( Y, Y, A_fb1_21 );
58 out_1 = silk_ADD32( S[ 0 ], X );
59 S[ 0 ] = silk_ADD32( in32, X );
60
61 /* Convert to Q10 */
62 in32 = silk_LSHIFT( (opus_int32)in[ 2 * k + 1 ], 10 );
63
64 /* All-pass section for odd input sample, and add to output of previous section */
65 Y = silk_SUB32( in32, S[ 1 ] );
66 X = silk_SMULWB( Y, A_fb1_20 );
67 out_2 = silk_ADD32( S[ 1 ], X );
68 S[ 1 ] = silk_ADD32( in32, X );
69
70 /* Add/subtract, convert back to int16 and store to output */
71 outL[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_ADD32( out_2, out_1 ), 11 ) );
72 outH[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SUB32( out_2, out_1 ), 11 ) );
73 }
74}
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_arm.h b/lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_arm.h
new file mode 100644
index 0000000000..9895b555c8
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_arm.h
@@ -0,0 +1,57 @@
1/***********************************************************************
2Copyright (c) 2017 Google Inc.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef SILK_LPC_INV_PRED_GAIN_ARM_H
29# define SILK_LPC_INV_PRED_GAIN_ARM_H
30
31# include "celt/arm/armcpu.h"
32
33# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
34opus_int32 silk_LPC_inverse_pred_gain_neon( /* O Returns inverse prediction gain in energy domain, Q30 */
35 const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
36 const opus_int order /* I Prediction order */
37);
38
39# if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON)
40# define OVERRIDE_silk_LPC_inverse_pred_gain (1)
41# define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((void)(arch), PRESUME_NEON(silk_LPC_inverse_pred_gain)(A_Q12, order))
42# endif
43# endif
44
45# if !defined(OVERRIDE_silk_LPC_inverse_pred_gain)
46/*Is run-time CPU detection enabled on this platform?*/
47# if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
48extern opus_int32 (*const SILK_LPC_INVERSE_PRED_GAIN_IMPL[OPUS_ARCHMASK+1])(const opus_int16 *A_Q12, const opus_int order);
49# define OVERRIDE_silk_LPC_inverse_pred_gain (1)
50# define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((*SILK_LPC_INVERSE_PRED_GAIN_IMPL[(arch)&OPUS_ARCHMASK])(A_Q12, order))
51# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
52# define OVERRIDE_silk_LPC_inverse_pred_gain (1)
53# define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((void)(arch), silk_LPC_inverse_pred_gain_neon(A_Q12, order))
54# endif
55# endif
56
57#endif /* end SILK_LPC_INV_PRED_GAIN_ARM_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_neon_intr.c b/lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_neon_intr.c
new file mode 100644
index 0000000000..ab426bcd66
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/LPC_inv_pred_gain_neon_intr.c
@@ -0,0 +1,280 @@
1/***********************************************************************
2Copyright (c) 2017 Google Inc.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <arm_neon.h>
33#include "SigProc_FIX.h"
34#include "define.h"
35
36#define QA 24
37#define A_LIMIT SILK_FIX_CONST( 0.99975, QA )
38
39#define MUL32_FRAC_Q(a32, b32, Q) ((opus_int32)(silk_RSHIFT_ROUND64(silk_SMULL(a32, b32), Q)))
40
41/* The difficulty is how to judge a 64-bit signed integer tmp64 is 32-bit overflowed,
42 * since NEON has no 64-bit min, max or comparison instructions.
43 * A failed idea is to compare the results of vmovn(tmp64) and vqmovn(tmp64) whether they are equal or not.
44 * However, this idea fails when the tmp64 is something like 0xFFFFFFF980000000.
45 * Here we know that mult2Q >= 1, so the highest bit (bit 63, sign bit) of tmp64 must equal to bit 62.
46 * tmp64 was shifted left by 1 and we got tmp64'. If high_half(tmp64') != 0 and high_half(tmp64') != -1,
47 * then we know that bit 31 to bit 63 of tmp64 can not all be the sign bit, and therefore tmp64 is 32-bit overflowed.
48 * That is, we judge if tmp64' > 0x00000000FFFFFFFF, or tmp64' <= 0xFFFFFFFF00000000.
49 * We use narrowing shift right 31 bits to tmp32' to save data bandwidth and instructions.
50 * That is, we judge if tmp32' > 0x00000000, or tmp32' <= 0xFFFFFFFF.
51 */
52
53/* Compute inverse of LPC prediction gain, and */
54/* test if LPC coefficients are stable (all poles within unit circle) */
55static OPUS_INLINE opus_int32 LPC_inverse_pred_gain_QA_neon( /* O Returns inverse prediction gain in energy domain, Q30 */
56 opus_int32 A_QA[ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */
57 const opus_int order /* I Prediction order */
58)
59{
60 opus_int k, n, mult2Q;
61 opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp1, tmp2;
62 opus_int32 max, min;
63 int32x4_t max_s32x4, min_s32x4;
64 int32x2_t max_s32x2, min_s32x2;
65
66 max_s32x4 = vdupq_n_s32( silk_int32_MIN );
67 min_s32x4 = vdupq_n_s32( silk_int32_MAX );
68 invGain_Q30 = SILK_FIX_CONST( 1, 30 );
69 for( k = order - 1; k > 0; k-- ) {
70 int32x2_t rc_Q31_s32x2, rc_mult2_s32x2;
71 int64x2_t mult2Q_s64x2;
72
73 /* Check for stability */
74 if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) {
75 return 0;
76 }
77
78 /* Set RC equal to negated AR coef */
79 rc_Q31 = -silk_LSHIFT( A_QA[ k ], 31 - QA );
80
81 /* rc_mult1_Q30 range: [ 1 : 2^30 ] */
82 rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) );
83 silk_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */
84 silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) );
85
86 /* Update inverse gain */
87 /* invGain_Q30 range: [ 0 : 2^30 ] */
88 invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
89 silk_assert( invGain_Q30 >= 0 );
90 silk_assert( invGain_Q30 <= ( 1 << 30 ) );
91 if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
92 return 0;
93 }
94
95 /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */
96 mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) );
97 rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 );
98
99 /* Update AR coefficient */
100 rc_Q31_s32x2 = vdup_n_s32( rc_Q31 );
101 mult2Q_s64x2 = vdupq_n_s64( -mult2Q );
102 rc_mult2_s32x2 = vdup_n_s32( rc_mult2 );
103
104 for( n = 0; n < ( ( k + 1 ) >> 1 ) - 3; n += 4 ) {
105 /* We always calculate extra elements of A_QA buffer when ( k % 4 ) != 0, to take the advantage of SIMD parallelization. */
106 int32x4_t tmp1_s32x4, tmp2_s32x4, t0_s32x4, t1_s32x4, s0_s32x4, s1_s32x4, t_QA0_s32x4, t_QA1_s32x4;
107 int64x2_t t0_s64x2, t1_s64x2, t2_s64x2, t3_s64x2;
108 tmp1_s32x4 = vld1q_s32( A_QA + n );
109 tmp2_s32x4 = vld1q_s32( A_QA + k - n - 4 );
110 tmp2_s32x4 = vrev64q_s32( tmp2_s32x4 );
111 tmp2_s32x4 = vcombine_s32( vget_high_s32( tmp2_s32x4 ), vget_low_s32( tmp2_s32x4 ) );
112 t0_s32x4 = vqrdmulhq_lane_s32( tmp2_s32x4, rc_Q31_s32x2, 0 );
113 t1_s32x4 = vqrdmulhq_lane_s32( tmp1_s32x4, rc_Q31_s32x2, 0 );
114 t_QA0_s32x4 = vqsubq_s32( tmp1_s32x4, t0_s32x4 );
115 t_QA1_s32x4 = vqsubq_s32( tmp2_s32x4, t1_s32x4 );
116 t0_s64x2 = vmull_s32( vget_low_s32 ( t_QA0_s32x4 ), rc_mult2_s32x2 );
117 t1_s64x2 = vmull_s32( vget_high_s32( t_QA0_s32x4 ), rc_mult2_s32x2 );
118 t2_s64x2 = vmull_s32( vget_low_s32 ( t_QA1_s32x4 ), rc_mult2_s32x2 );
119 t3_s64x2 = vmull_s32( vget_high_s32( t_QA1_s32x4 ), rc_mult2_s32x2 );
120 t0_s64x2 = vrshlq_s64( t0_s64x2, mult2Q_s64x2 );
121 t1_s64x2 = vrshlq_s64( t1_s64x2, mult2Q_s64x2 );
122 t2_s64x2 = vrshlq_s64( t2_s64x2, mult2Q_s64x2 );
123 t3_s64x2 = vrshlq_s64( t3_s64x2, mult2Q_s64x2 );
124 t0_s32x4 = vcombine_s32( vmovn_s64( t0_s64x2 ), vmovn_s64( t1_s64x2 ) );
125 t1_s32x4 = vcombine_s32( vmovn_s64( t2_s64x2 ), vmovn_s64( t3_s64x2 ) );
126 s0_s32x4 = vcombine_s32( vshrn_n_s64( t0_s64x2, 31 ), vshrn_n_s64( t1_s64x2, 31 ) );
127 s1_s32x4 = vcombine_s32( vshrn_n_s64( t2_s64x2, 31 ), vshrn_n_s64( t3_s64x2, 31 ) );
128 max_s32x4 = vmaxq_s32( max_s32x4, s0_s32x4 );
129 min_s32x4 = vminq_s32( min_s32x4, s0_s32x4 );
130 max_s32x4 = vmaxq_s32( max_s32x4, s1_s32x4 );
131 min_s32x4 = vminq_s32( min_s32x4, s1_s32x4 );
132 t1_s32x4 = vrev64q_s32( t1_s32x4 );
133 t1_s32x4 = vcombine_s32( vget_high_s32( t1_s32x4 ), vget_low_s32( t1_s32x4 ) );
134 vst1q_s32( A_QA + n, t0_s32x4 );
135 vst1q_s32( A_QA + k - n - 4, t1_s32x4 );
136 }
137 for( ; n < (k + 1) >> 1; n++ ) {
138 opus_int64 tmp64;
139 tmp1 = A_QA[ n ];
140 tmp2 = A_QA[ k - n - 1 ];
141 tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp1,
142 MUL32_FRAC_Q( tmp2, rc_Q31, 31 ) ), rc_mult2 ), mult2Q);
143 if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
144 return 0;
145 }
146 A_QA[ n ] = ( opus_int32 )tmp64;
147 tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp2,
148 MUL32_FRAC_Q( tmp1, rc_Q31, 31 ) ), rc_mult2), mult2Q);
149 if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
150 return 0;
151 }
152 A_QA[ k - n - 1 ] = ( opus_int32 )tmp64;
153 }
154 }
155
156 /* Check for stability */
157 if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) {
158 return 0;
159 }
160
161 max_s32x2 = vmax_s32( vget_low_s32( max_s32x4 ), vget_high_s32( max_s32x4 ) );
162 min_s32x2 = vmin_s32( vget_low_s32( min_s32x4 ), vget_high_s32( min_s32x4 ) );
163 max_s32x2 = vmax_s32( max_s32x2, vreinterpret_s32_s64( vshr_n_s64( vreinterpret_s64_s32( max_s32x2 ), 32 ) ) );
164 min_s32x2 = vmin_s32( min_s32x2, vreinterpret_s32_s64( vshr_n_s64( vreinterpret_s64_s32( min_s32x2 ), 32 ) ) );
165 max = vget_lane_s32( max_s32x2, 0 );
166 min = vget_lane_s32( min_s32x2, 0 );
167 if( ( max > 0 ) || ( min < -1 ) ) {
168 return 0;
169 }
170
171 /* Set RC equal to negated AR coef */
172 rc_Q31 = -silk_LSHIFT( A_QA[ 0 ], 31 - QA );
173
174 /* Range: [ 1 : 2^30 ] */
175 rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) );
176
177 /* Update inverse gain */
178 /* Range: [ 0 : 2^30 ] */
179 invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
180 silk_assert( invGain_Q30 >= 0 );
181 silk_assert( invGain_Q30 <= ( 1 << 30 ) );
182 if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
183 return 0;
184 }
185
186 return invGain_Q30;
187}
188
189/* For input in Q12 domain */
190opus_int32 silk_LPC_inverse_pred_gain_neon( /* O Returns inverse prediction gain in energy domain, Q30 */
191 const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
192 const opus_int order /* I Prediction order */
193)
194{
195#ifdef OPUS_CHECK_ASM
196 const opus_int32 invGain_Q30_c = silk_LPC_inverse_pred_gain_c( A_Q12, order );
197#endif
198
199 opus_int32 invGain_Q30;
200 if( ( SILK_MAX_ORDER_LPC != 24 ) || ( order & 1 )) {
201 invGain_Q30 = silk_LPC_inverse_pred_gain_c( A_Q12, order );
202 }
203 else {
204 opus_int32 Atmp_QA[ SILK_MAX_ORDER_LPC ];
205 opus_int32 DC_resp;
206 int16x8_t t0_s16x8, t1_s16x8, t2_s16x8;
207 int32x4_t t0_s32x4;
208 const opus_int leftover = order & 7;
209
210 /* Increase Q domain of the AR coefficients */
211 t0_s16x8 = vld1q_s16( A_Q12 + 0 );
212 t1_s16x8 = vld1q_s16( A_Q12 + 8 );
213 t2_s16x8 = vld1q_s16( A_Q12 + 16 );
214 t0_s32x4 = vpaddlq_s16( t0_s16x8 );
215
216 switch( order - leftover )
217 {
218 case 24:
219 t0_s32x4 = vpadalq_s16( t0_s32x4, t2_s16x8 );
220 /* FALLTHROUGH */
221
222 case 16:
223 t0_s32x4 = vpadalq_s16( t0_s32x4, t1_s16x8 );
224 vst1q_s32( Atmp_QA + 16, vshll_n_s16( vget_low_s16 ( t2_s16x8 ), QA - 12 ) );
225 vst1q_s32( Atmp_QA + 20, vshll_n_s16( vget_high_s16( t2_s16x8 ), QA - 12 ) );
226 /* FALLTHROUGH */
227
228 case 8:
229 {
230 const int32x2_t t_s32x2 = vpadd_s32( vget_low_s32( t0_s32x4 ), vget_high_s32( t0_s32x4 ) );
231 const int64x1_t t_s64x1 = vpaddl_s32( t_s32x2 );
232 DC_resp = vget_lane_s32( vreinterpret_s32_s64( t_s64x1 ), 0 );
233 vst1q_s32( Atmp_QA + 8, vshll_n_s16( vget_low_s16 ( t1_s16x8 ), QA - 12 ) );
234 vst1q_s32( Atmp_QA + 12, vshll_n_s16( vget_high_s16( t1_s16x8 ), QA - 12 ) );
235 }
236 break;
237
238 default:
239 DC_resp = 0;
240 break;
241 }
242 A_Q12 += order - leftover;
243
244 switch( leftover )
245 {
246 case 6:
247 DC_resp += (opus_int32)A_Q12[ 5 ];
248 DC_resp += (opus_int32)A_Q12[ 4 ];
249 /* FALLTHROUGH */
250
251 case 4:
252 DC_resp += (opus_int32)A_Q12[ 3 ];
253 DC_resp += (opus_int32)A_Q12[ 2 ];
254 /* FALLTHROUGH */
255
256 case 2:
257 DC_resp += (opus_int32)A_Q12[ 1 ];
258 DC_resp += (opus_int32)A_Q12[ 0 ];
259 /* FALLTHROUGH */
260
261 default:
262 break;
263 }
264
265 /* If the DC is unstable, we don't even need to do the full calculations */
266 if( DC_resp >= 4096 ) {
267 invGain_Q30 = 0;
268 } else {
269 vst1q_s32( Atmp_QA + 0, vshll_n_s16( vget_low_s16 ( t0_s16x8 ), QA - 12 ) );
270 vst1q_s32( Atmp_QA + 4, vshll_n_s16( vget_high_s16( t0_s16x8 ), QA - 12 ) );
271 invGain_Q30 = LPC_inverse_pred_gain_QA_neon( Atmp_QA, order );
272 }
273 }
274
275#ifdef OPUS_CHECK_ASM
276 silk_assert( invGain_Q30_c == invGain_Q30 );
277#endif
278
279 return invGain_Q30;
280}
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_arm.h b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_arm.h
new file mode 100644
index 0000000000..9e76e16927
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_arm.h
@@ -0,0 +1,100 @@
1/***********************************************************************
2Copyright (c) 2017 Google Inc.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef SILK_NSQ_DEL_DEC_ARM_H
29#define SILK_NSQ_DEL_DEC_ARM_H
30
31#include "celt/arm/armcpu.h"
32
33#if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
34void silk_NSQ_del_dec_neon(
35 const silk_encoder_state *psEncC, silk_nsq_state *NSQ,
36 SideInfoIndices *psIndices, const opus_int16 x16[], opus_int8 pulses[],
37 const opus_int16 PredCoef_Q12[2 * MAX_LPC_ORDER],
38 const opus_int16 LTPCoef_Q14[LTP_ORDER * MAX_NB_SUBFR],
39 const opus_int16 AR_Q13[MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER],
40 const opus_int HarmShapeGain_Q14[MAX_NB_SUBFR],
41 const opus_int Tilt_Q14[MAX_NB_SUBFR],
42 const opus_int32 LF_shp_Q14[MAX_NB_SUBFR],
43 const opus_int32 Gains_Q16[MAX_NB_SUBFR],
44 const opus_int pitchL[MAX_NB_SUBFR], const opus_int Lambda_Q10,
45 const opus_int LTP_scale_Q14);
46
47#if !defined(OPUS_HAVE_RTCD)
48#define OVERRIDE_silk_NSQ_del_dec (1)
49#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \
50 LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \
51 LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \
52 LTP_scale_Q14, arch) \
53 ((void)(arch), \
54 PRESUME_NEON(silk_NSQ_del_dec)( \
55 psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, \
56 AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, \
57 Lambda_Q10, LTP_scale_Q14))
58#endif
59#endif
60
61#if !defined(OVERRIDE_silk_NSQ_del_dec)
62/*Is run-time CPU detection enabled on this platform?*/
63#if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && \
64 !defined(OPUS_ARM_PRESUME_NEON_INTR))
65extern void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])(
66 const silk_encoder_state *psEncC, silk_nsq_state *NSQ,
67 SideInfoIndices *psIndices, const opus_int16 x16[], opus_int8 pulses[],
68 const opus_int16 PredCoef_Q12[2 * MAX_LPC_ORDER],
69 const opus_int16 LTPCoef_Q14[LTP_ORDER * MAX_NB_SUBFR],
70 const opus_int16 AR_Q13[MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER],
71 const opus_int HarmShapeGain_Q14[MAX_NB_SUBFR],
72 const opus_int Tilt_Q14[MAX_NB_SUBFR],
73 const opus_int32 LF_shp_Q14[MAX_NB_SUBFR],
74 const opus_int32 Gains_Q16[MAX_NB_SUBFR],
75 const opus_int pitchL[MAX_NB_SUBFR], const opus_int Lambda_Q10,
76 const opus_int LTP_scale_Q14);
77#define OVERRIDE_silk_NSQ_del_dec (1)
78#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \
79 LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \
80 LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \
81 LTP_scale_Q14, arch) \
82 ((*SILK_NSQ_DEL_DEC_IMPL[(arch)&OPUS_ARCHMASK])( \
83 psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, \
84 AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, \
85 Lambda_Q10, LTP_scale_Q14))
86#elif defined(OPUS_ARM_PRESUME_NEON_INTR)
87#define OVERRIDE_silk_NSQ_del_dec (1)
88#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \
89 LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \
90 LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \
91 LTP_scale_Q14, arch) \
92 ((void)(arch), \
93 silk_NSQ_del_dec_neon(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \
94 LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \
95 LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \
96 LTP_scale_Q14))
97#endif
98#endif
99
100#endif /* end SILK_NSQ_DEL_DEC_ARM_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_neon_intr.c b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_neon_intr.c
new file mode 100644
index 0000000000..212410f362
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_del_dec_neon_intr.c
@@ -0,0 +1,1124 @@
1/***********************************************************************
2Copyright (c) 2017 Google Inc.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <arm_neon.h>
33#ifdef OPUS_CHECK_ASM
34# include <string.h>
35#endif
36#include "main.h"
37#include "stack_alloc.h"
38
39/* NEON intrinsics optimization now can only parallelize up to 4 delay decision states. */
40/* If there are more states, C function is called, and this optimization must be expanded. */
41#define NEON_MAX_DEL_DEC_STATES 4
42
43typedef struct {
44 opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ][ NEON_MAX_DEL_DEC_STATES ];
45 opus_int32 RandState[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ];
46 opus_int32 Q_Q10[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ];
47 opus_int32 Xq_Q14[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ];
48 opus_int32 Pred_Q15[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ];
49 opus_int32 Shape_Q14[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ];
50 opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ][ NEON_MAX_DEL_DEC_STATES ];
51 opus_int32 LF_AR_Q14[ NEON_MAX_DEL_DEC_STATES ];
52 opus_int32 Diff_Q14[ NEON_MAX_DEL_DEC_STATES ];
53 opus_int32 Seed[ NEON_MAX_DEL_DEC_STATES ];
54 opus_int32 SeedInit[ NEON_MAX_DEL_DEC_STATES ];
55 opus_int32 RD_Q10[ NEON_MAX_DEL_DEC_STATES ];
56} NSQ_del_decs_struct;
57
58typedef struct {
59 opus_int32 Q_Q10[ NEON_MAX_DEL_DEC_STATES ];
60 opus_int32 RD_Q10[ NEON_MAX_DEL_DEC_STATES ];
61 opus_int32 xq_Q14[ NEON_MAX_DEL_DEC_STATES ];
62 opus_int32 LF_AR_Q14[ NEON_MAX_DEL_DEC_STATES ];
63 opus_int32 Diff_Q14[ NEON_MAX_DEL_DEC_STATES ];
64 opus_int32 sLTP_shp_Q14[ NEON_MAX_DEL_DEC_STATES ];
65 opus_int32 LPC_exc_Q14[ NEON_MAX_DEL_DEC_STATES ];
66} NSQ_samples_struct;
67
68static OPUS_INLINE void silk_nsq_del_dec_scale_states_neon(
69 const silk_encoder_state *psEncC, /* I Encoder State */
70 silk_nsq_state *NSQ, /* I/O NSQ state */
71 NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */
72 const opus_int16 x16[], /* I Input */
73 opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
74 const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
75 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
76 opus_int subfr, /* I Subframe number */
77 const opus_int LTP_scale_Q14, /* I LTP state scaling */
78 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
79 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
80 const opus_int signal_type, /* I Signal type */
81 const opus_int decisionDelay /* I Decision delay */
82);
83
84/******************************************/
85/* Noise shape quantizer for one subframe */
86/******************************************/
87static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_neon(
88 silk_nsq_state *NSQ, /* I/O NSQ state */
89 NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */
90 opus_int signalType, /* I Signal type */
91 const opus_int32 x_Q10[], /* I */
92 opus_int8 pulses[], /* O */
93 opus_int16 xq[], /* O */
94 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
95 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
96 const opus_int16 a_Q12[], /* I Short term prediction coefs */
97 const opus_int16 b_Q14[], /* I Long term prediction coefs */
98 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
99 opus_int lag, /* I Pitch lag */
100 opus_int32 HarmShapeFIRPacked_Q14, /* I */
101 opus_int Tilt_Q14, /* I Spectral tilt */
102 opus_int32 LF_shp_Q14, /* I */
103 opus_int32 Gain_Q16, /* I */
104 opus_int Lambda_Q10, /* I */
105 opus_int offset_Q10, /* I */
106 opus_int length, /* I Input length */
107 opus_int subfr, /* I Subframe number */
108 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
109 opus_int predictLPCOrder, /* I Prediction filter order */
110 opus_int warping_Q16, /* I */
111 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
112 opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
113 opus_int decisionDelay /* I */
114);
115
116static OPUS_INLINE void copy_winner_state_kernel(
117 const NSQ_del_decs_struct *psDelDec,
118 const opus_int offset,
119 const opus_int last_smple_idx,
120 const opus_int Winner_ind,
121 const int32x2_t gain_lo_s32x2,
122 const int32x2_t gain_hi_s32x2,
123 const int32x4_t shift_s32x4,
124 int32x4_t t0_s32x4,
125 int32x4_t t1_s32x4,
126 opus_int8 *const pulses,
127 opus_int16 *pxq,
128 silk_nsq_state *NSQ
129)
130{
131 int16x8_t t_s16x8;
132 int32x4_t o0_s32x4, o1_s32x4;
133
134 t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 0 ][ Winner_ind ], t0_s32x4, 0 );
135 t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 1 ][ Winner_ind ], t0_s32x4, 1 );
136 t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 2 ][ Winner_ind ], t0_s32x4, 2 );
137 t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 3 ][ Winner_ind ], t0_s32x4, 3 );
138 t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 4 ][ Winner_ind ], t1_s32x4, 0 );
139 t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 5 ][ Winner_ind ], t1_s32x4, 1 );
140 t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 6 ][ Winner_ind ], t1_s32x4, 2 );
141 t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 7 ][ Winner_ind ], t1_s32x4, 3 );
142 t_s16x8 = vcombine_s16( vrshrn_n_s32( t0_s32x4, 10 ), vrshrn_n_s32( t1_s32x4, 10 ) );
143 vst1_s8( &pulses[ offset ], vmovn_s16( t_s16x8 ) );
144
145 t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 0 ][ Winner_ind ], t0_s32x4, 0 );
146 t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 1 ][ Winner_ind ], t0_s32x4, 1 );
147 t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 2 ][ Winner_ind ], t0_s32x4, 2 );
148 t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 3 ][ Winner_ind ], t0_s32x4, 3 );
149 t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 4 ][ Winner_ind ], t1_s32x4, 0 );
150 t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 5 ][ Winner_ind ], t1_s32x4, 1 );
151 t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 6 ][ Winner_ind ], t1_s32x4, 2 );
152 t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 7 ][ Winner_ind ], t1_s32x4, 3 );
153 o0_s32x4 = vqdmulhq_lane_s32( t0_s32x4, gain_lo_s32x2, 0 );
154 o1_s32x4 = vqdmulhq_lane_s32( t1_s32x4, gain_lo_s32x2, 0 );
155 o0_s32x4 = vmlaq_lane_s32( o0_s32x4, t0_s32x4, gain_hi_s32x2, 0 );
156 o1_s32x4 = vmlaq_lane_s32( o1_s32x4, t1_s32x4, gain_hi_s32x2, 0 );
157 o0_s32x4 = vrshlq_s32( o0_s32x4, shift_s32x4 );
158 o1_s32x4 = vrshlq_s32( o1_s32x4, shift_s32x4 );
159 vst1_s16( &pxq[ offset + 0 ], vqmovn_s32( o0_s32x4 ) );
160 vst1_s16( &pxq[ offset + 4 ], vqmovn_s32( o1_s32x4 ) );
161
162 t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 0 ][ Winner_ind ], t0_s32x4, 0 );
163 t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 1 ][ Winner_ind ], t0_s32x4, 1 );
164 t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 2 ][ Winner_ind ], t0_s32x4, 2 );
165 t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 3 ][ Winner_ind ], t0_s32x4, 3 );
166 t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 4 ][ Winner_ind ], t1_s32x4, 0 );
167 t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 5 ][ Winner_ind ], t1_s32x4, 1 );
168 t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 6 ][ Winner_ind ], t1_s32x4, 2 );
169 t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 7 ][ Winner_ind ], t1_s32x4, 3 );
170 vst1q_s32( &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx + offset + 0 ], t0_s32x4 );
171 vst1q_s32( &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx + offset + 4 ], t1_s32x4 );
172}
173
174static OPUS_INLINE void copy_winner_state(
175 const NSQ_del_decs_struct *psDelDec,
176 const opus_int decisionDelay,
177 const opus_int smpl_buf_idx,
178 const opus_int Winner_ind,
179 const opus_int32 gain,
180 const opus_int32 shift,
181 opus_int8 *const pulses,
182 opus_int16 *pxq,
183 silk_nsq_state *NSQ
184)
185{
186 opus_int i, last_smple_idx;
187 const int32x2_t gain_lo_s32x2 = vdup_n_s32( silk_LSHIFT32( gain & 0x0000FFFF, 15 ) );
188 const int32x2_t gain_hi_s32x2 = vdup_n_s32( gain >> 16 );
189 const int32x4_t shift_s32x4 = vdupq_n_s32( -shift );
190 int32x4_t t0_s32x4, t1_s32x4;
191
192 t0_s32x4 = t1_s32x4 = vdupq_n_s32( 0 ); /* initialization */
193 last_smple_idx = smpl_buf_idx + decisionDelay - 1 + DECISION_DELAY;
194 if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY;
195 if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY;
196
197 for( i = 0; ( i < ( decisionDelay - 7 ) ) && ( last_smple_idx >= 7 ); i += 8, last_smple_idx -= 8 ) {
198 copy_winner_state_kernel( psDelDec, i - decisionDelay, last_smple_idx, Winner_ind, gain_lo_s32x2, gain_hi_s32x2, shift_s32x4, t0_s32x4, t1_s32x4, pulses, pxq, NSQ );
199 }
200 for( ; ( i < decisionDelay ) && ( last_smple_idx >= 0 ); i++, last_smple_idx-- ) {
201 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDelDec->Q_Q10[ last_smple_idx ][ Winner_ind ], 10 );
202 pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDelDec->Xq_Q14[ last_smple_idx ][ Winner_ind ], gain ), shift ) );
203 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDelDec->Shape_Q14[ last_smple_idx ][ Winner_ind ];
204 }
205
206 last_smple_idx += DECISION_DELAY;
207 for( ; i < ( decisionDelay - 7 ); i++, last_smple_idx-- ) {
208 copy_winner_state_kernel( psDelDec, i - decisionDelay, last_smple_idx, Winner_ind, gain_lo_s32x2, gain_hi_s32x2, shift_s32x4, t0_s32x4, t1_s32x4, pulses, pxq, NSQ );
209 }
210 for( ; i < decisionDelay; i++, last_smple_idx-- ) {
211 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDelDec->Q_Q10[ last_smple_idx ][ Winner_ind ], 10 );
212 pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDelDec->Xq_Q14[ last_smple_idx ][ Winner_ind ], gain ), shift ) );
213 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDelDec->Shape_Q14[ last_smple_idx ][ Winner_ind ];
214 }
215}
216
217void silk_NSQ_del_dec_neon(
218 const silk_encoder_state *psEncC, /* I Encoder State */
219 silk_nsq_state *NSQ, /* I/O NSQ state */
220 SideInfoIndices *psIndices, /* I/O Quantization Indices */
221 const opus_int16 x16[], /* I Input */
222 opus_int8 pulses[], /* O Quantized pulse signal */
223 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
224 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
225 const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
226 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
227 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
228 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
229 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
230 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
231 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
232 const opus_int LTP_scale_Q14 /* I LTP state scaling */
233)
234{
235#ifdef OPUS_CHECK_ASM
236 silk_nsq_state NSQ_c;
237 SideInfoIndices psIndices_c;
238 opus_int8 pulses_c[ MAX_FRAME_LENGTH ];
239 const opus_int8 *const pulses_a = pulses;
240
241 ( void )pulses_a;
242 silk_memcpy( &NSQ_c, NSQ, sizeof( NSQ_c ) );
243 silk_memcpy( &psIndices_c, psIndices, sizeof( psIndices_c ) );
244 silk_memcpy( pulses_c, pulses, sizeof( pulses_c ) );
245 silk_NSQ_del_dec_c( psEncC, &NSQ_c, &psIndices_c, x16, pulses_c, PredCoef_Q12, LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16,
246 pitchL, Lambda_Q10, LTP_scale_Q14 );
247#endif
248
249 /* The optimization parallelizes the different delay decision states. */
250 if(( psEncC->nStatesDelayedDecision > NEON_MAX_DEL_DEC_STATES ) || ( psEncC->nStatesDelayedDecision <= 2 )) {
251 /* NEON intrinsics optimization now can only parallelize up to 4 delay decision states. */
252 /* If there are more states, C function is called, and this optimization must be expanded. */
253 /* When the number of delay decision states is less than 3, there are penalties using this */
254 /* optimization, and C function is called. */
255 /* When the number of delay decision states is 2, it's better to specialize another */
256 /* structure NSQ_del_dec2_struct and optimize with shorter NEON registers. (Low priority) */
257 silk_NSQ_del_dec_c( psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14,
258 Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14 );
259 } else {
260 opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
261 opus_int smpl_buf_idx, decisionDelay;
262 const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
263 opus_int16 *pxq;
264 VARDECL( opus_int32, sLTP_Q15 );
265 VARDECL( opus_int16, sLTP );
266 opus_int32 HarmShapeFIRPacked_Q14;
267 opus_int offset_Q10;
268 opus_int32 RDmin_Q10, Gain_Q10;
269 VARDECL( opus_int32, x_sc_Q10 );
270 VARDECL( opus_int32, delayedGain_Q10 );
271 VARDECL( NSQ_del_decs_struct, psDelDec );
272 int32x4_t t_s32x4;
273 SAVE_STACK;
274
275 /* Set unvoiced lag to the previous one, overwrite later for voiced */
276 lag = NSQ->lagPrev;
277
278 silk_assert( NSQ->prev_gain_Q16 != 0 );
279
280 /* Initialize delayed decision states */
281 ALLOC( psDelDec, 1, NSQ_del_decs_struct );
282 /* Only RandState and RD_Q10 need to be initialized to 0. */
283 silk_memset( psDelDec->RandState, 0, sizeof( psDelDec->RandState ) );
284 vst1q_s32( psDelDec->RD_Q10, vdupq_n_s32( 0 ) );
285
286 for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {
287 psDelDec->SeedInit[ k ] = psDelDec->Seed[ k ] = ( k + psIndices->Seed ) & 3;
288 }
289 vst1q_s32( psDelDec->LF_AR_Q14, vld1q_dup_s32( &NSQ->sLF_AR_shp_Q14 ) );
290 vst1q_s32( psDelDec->Diff_Q14, vld1q_dup_s32( &NSQ->sDiff_shp_Q14 ) );
291 vst1q_s32( psDelDec->Shape_Q14[ 0 ], vld1q_dup_s32( &NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ] ) );
292 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
293 vst1q_s32( psDelDec->sLPC_Q14[ i ], vld1q_dup_s32( &NSQ->sLPC_Q14[ i ] ) );
294 }
295 for( i = 0; i < (opus_int)( sizeof( NSQ->sAR2_Q14 ) / sizeof( NSQ->sAR2_Q14[ 0 ] ) ); i++ ) {
296 vst1q_s32( psDelDec->sAR2_Q14[ i ], vld1q_dup_s32( &NSQ->sAR2_Q14[ i ] ) );
297 }
298
299 offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];
300 smpl_buf_idx = 0; /* index of oldest samples */
301
302 decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length );
303
304 /* For voiced frames limit the decision delay to lower than the pitch lag */
305 if( psIndices->signalType == TYPE_VOICED ) {
306 opus_int pitch_min = pitchL[ 0 ];
307 for( k = 1; k < psEncC->nb_subfr; k++ ) {
308 pitch_min = silk_min_int( pitch_min, pitchL[ k ] );
309 }
310 decisionDelay = silk_min_int( decisionDelay, pitch_min - LTP_ORDER / 2 - 1 );
311 } else {
312 if( lag > 0 ) {
313 decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 );
314 }
315 }
316
317 if( psIndices->NLSFInterpCoef_Q2 == 4 ) {
318 LSF_interpolation_flag = 0;
319 } else {
320 LSF_interpolation_flag = 1;
321 }
322
323 ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
324 ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
325 ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
326 ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 );
327 /* Set up pointers to start of sub frame */
328 pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
329 NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
330 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
331 subfr = 0;
332 for( k = 0; k < psEncC->nb_subfr; k++ ) {
333 A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];
334 B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
335 AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ];
336
337 /* Noise shape parameters */
338 silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
339 HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
340 HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
341
342 NSQ->rewhite_flag = 0;
343 if( psIndices->signalType == TYPE_VOICED ) {
344 /* Voiced */
345 lag = pitchL[ k ];
346
347 /* Re-whitening */
348 if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
349 if( k == 2 ) {
350 /* RESET DELAYED DECISIONS */
351 /* Find winner */
352 int32x4_t RD_Q10_s32x4;
353 RDmin_Q10 = psDelDec->RD_Q10[ 0 ];
354 Winner_ind = 0;
355 for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) {
356 if( psDelDec->RD_Q10[ i ] < RDmin_Q10 ) {
357 RDmin_Q10 = psDelDec->RD_Q10[ i ];
358 Winner_ind = i;
359 }
360 }
361 psDelDec->RD_Q10[ Winner_ind ] -= ( silk_int32_MAX >> 4 );
362 RD_Q10_s32x4 = vld1q_s32( psDelDec->RD_Q10 );
363 RD_Q10_s32x4 = vaddq_s32( RD_Q10_s32x4, vdupq_n_s32( silk_int32_MAX >> 4 ) );
364 vst1q_s32( psDelDec->RD_Q10, RD_Q10_s32x4 );
365
366 /* Copy final part of signals from winner state to output and long-term filter states */
367 copy_winner_state( psDelDec, decisionDelay, smpl_buf_idx, Winner_ind, Gains_Q16[ 1 ], 14, pulses, pxq, NSQ );
368
369 subfr = 0;
370 }
371
372 /* Rewhiten with new A coefs */
373 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
374 silk_assert( start_idx > 0 );
375
376 silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
377 A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
378
379 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
380 NSQ->rewhite_flag = 1;
381 }
382 }
383
384 silk_nsq_del_dec_scale_states_neon( psEncC, NSQ, psDelDec, x16, x_sc_Q10, sLTP, sLTP_Q15, k,
385 LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );
386
387 silk_noise_shape_quantizer_del_dec_neon( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,
388 delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ],
389 Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,
390 psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay );
391
392 x16 += psEncC->subfr_length;
393 pulses += psEncC->subfr_length;
394 pxq += psEncC->subfr_length;
395 }
396
397 /* Find winner */
398 RDmin_Q10 = psDelDec->RD_Q10[ 0 ];
399 Winner_ind = 0;
400 for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) {
401 if( psDelDec->RD_Q10[ k ] < RDmin_Q10 ) {
402 RDmin_Q10 = psDelDec->RD_Q10[ k ];
403 Winner_ind = k;
404 }
405 }
406
407 /* Copy final part of signals from winner state to output and long-term filter states */
408 psIndices->Seed = psDelDec->SeedInit[ Winner_ind ];
409 Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 );
410 copy_winner_state( psDelDec, decisionDelay, smpl_buf_idx, Winner_ind, Gain_Q10, 8, pulses, pxq, NSQ );
411
412 t_s32x4 = vdupq_n_s32( 0 ); /* initialization */
413 for( i = 0; i < ( NSQ_LPC_BUF_LENGTH - 3 ); i += 4 ) {
414 t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 0 ][ Winner_ind ], t_s32x4, 0 );
415 t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 1 ][ Winner_ind ], t_s32x4, 1 );
416 t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 2 ][ Winner_ind ], t_s32x4, 2 );
417 t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 3 ][ Winner_ind ], t_s32x4, 3 );
418 vst1q_s32( &NSQ->sLPC_Q14[ i ], t_s32x4 );
419 }
420
421 for( ; i < NSQ_LPC_BUF_LENGTH; i++ ) {
422 NSQ->sLPC_Q14[ i ] = psDelDec->sLPC_Q14[ i ][ Winner_ind ];
423 }
424
425 for( i = 0; i < (opus_int)( sizeof( NSQ->sAR2_Q14 ) / sizeof( NSQ->sAR2_Q14[ 0 ] ) - 3 ); i += 4 ) {
426 t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 0 ][ Winner_ind ], t_s32x4, 0 );
427 t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 1 ][ Winner_ind ], t_s32x4, 1 );
428 t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 2 ][ Winner_ind ], t_s32x4, 2 );
429 t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 3 ][ Winner_ind ], t_s32x4, 3 );
430 vst1q_s32( &NSQ->sAR2_Q14[ i ], t_s32x4 );
431 }
432
433 for( ; i < (opus_int)( sizeof( NSQ->sAR2_Q14 ) / sizeof( NSQ->sAR2_Q14[ 0 ] ) ); i++ ) {
434 NSQ->sAR2_Q14[ i ] = psDelDec->sAR2_Q14[ i ][ Winner_ind ];
435 }
436
437 /* Update states */
438 NSQ->sLF_AR_shp_Q14 = psDelDec->LF_AR_Q14[ Winner_ind ];
439 NSQ->sDiff_shp_Q14 = psDelDec->Diff_Q14[ Winner_ind ];
440 NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
441
442 /* Save quantized speech signal */
443 silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
444 silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
445 RESTORE_STACK;
446 }
447
448#ifdef OPUS_CHECK_ASM
449 silk_assert( !memcmp( &NSQ_c, NSQ, sizeof( NSQ_c ) ) );
450 silk_assert( !memcmp( &psIndices_c, psIndices, sizeof( psIndices_c ) ) );
451 silk_assert( !memcmp( pulses_c, pulses_a, sizeof( pulses_c ) ) );
452#endif
453}
454
455/******************************************/
456/* Noise shape quantizer for one subframe */
457/******************************************/
458/* Note: Function silk_short_prediction_create_arch_coef_neon() defined in NSQ_neon.h is actually a hacking C function. */
459/* Therefore here we append "_local" to the NEON function name to avoid confusion. */
460static OPUS_INLINE void silk_short_prediction_create_arch_coef_neon_local(opus_int32 *out, const opus_int16 *in, opus_int order)
461{
462 int16x8_t t_s16x8;
463 int32x4_t t0_s32x4, t1_s32x4, t2_s32x4, t3_s32x4;
464 silk_assert( order == 10 || order == 16 );
465
466 t_s16x8 = vld1q_s16( in + 0 ); /* 7 6 5 4 3 2 1 0 */
467 t_s16x8 = vrev64q_s16( t_s16x8 ); /* 4 5 6 7 0 1 2 3 */
468 t2_s32x4 = vshll_n_s16( vget_high_s16( t_s16x8 ), 15 ); /* 4 5 6 7 */
469 t3_s32x4 = vshll_n_s16( vget_low_s16( t_s16x8 ), 15 ); /* 0 1 2 3 */
470
471 if( order == 16 ) {
472 t_s16x8 = vld1q_s16( in + 8 ); /* F E D C B A 9 8 */
473 t_s16x8 = vrev64q_s16( t_s16x8 ); /* C D E F 8 9 A B */
474 t0_s32x4 = vshll_n_s16( vget_high_s16( t_s16x8 ), 15 ); /* C D E F */
475 t1_s32x4 = vshll_n_s16( vget_low_s16( t_s16x8 ), 15 ); /* 8 9 A B */
476 } else {
477 int16x4_t t_s16x4;
478
479 t0_s32x4 = vdupq_n_s32( 0 ); /* zero zero zero zero */
480 t_s16x4 = vld1_s16( in + 6 ); /* 9 8 7 6 */
481 t_s16x4 = vrev64_s16( t_s16x4 ); /* 6 7 8 9 */
482 t1_s32x4 = vshll_n_s16( t_s16x4, 15 );
483 t1_s32x4 = vcombine_s32( vget_low_s32(t0_s32x4), vget_low_s32( t1_s32x4 ) ); /* 8 9 zero zero */
484 }
485 vst1q_s32( out + 0, t0_s32x4 );
486 vst1q_s32( out + 4, t1_s32x4 );
487 vst1q_s32( out + 8, t2_s32x4 );
488 vst1q_s32( out + 12, t3_s32x4 );
489}
490
491static OPUS_INLINE int32x4_t silk_SMLAWB_lane0_neon(
492 const int32x4_t out_s32x4,
493 const int32x4_t in_s32x4,
494 const int32x2_t coef_s32x2
495)
496{
497 return vaddq_s32( out_s32x4, vqdmulhq_lane_s32( in_s32x4, coef_s32x2, 0 ) );
498}
499
500static OPUS_INLINE int32x4_t silk_SMLAWB_lane1_neon(
501 const int32x4_t out_s32x4,
502 const int32x4_t in_s32x4,
503 const int32x2_t coef_s32x2
504)
505{
506 return vaddq_s32( out_s32x4, vqdmulhq_lane_s32( in_s32x4, coef_s32x2, 1 ) );
507}
508
509/* Note: This function has different return value than silk_noise_shape_quantizer_short_prediction_neon(). */
510/* Therefore here we append "_local" to the function name to avoid confusion. */
511static OPUS_INLINE int32x4_t silk_noise_shape_quantizer_short_prediction_neon_local(const opus_int32 *buf32, const opus_int32 *a_Q12_arch, opus_int order)
512{
513 const int32x4_t a_Q12_arch0_s32x4 = vld1q_s32( a_Q12_arch + 0 );
514 const int32x4_t a_Q12_arch1_s32x4 = vld1q_s32( a_Q12_arch + 4 );
515 const int32x4_t a_Q12_arch2_s32x4 = vld1q_s32( a_Q12_arch + 8 );
516 const int32x4_t a_Q12_arch3_s32x4 = vld1q_s32( a_Q12_arch + 12 );
517 int32x4_t LPC_pred_Q14_s32x4;
518
519 silk_assert( order == 10 || order == 16 );
520 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
521 LPC_pred_Q14_s32x4 = vdupq_n_s32( silk_RSHIFT( order, 1 ) );
522 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 0 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch0_s32x4 ) );
523 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 1 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch0_s32x4 ) );
524 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 2 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch0_s32x4 ) );
525 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 3 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch0_s32x4 ) );
526 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 4 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch1_s32x4 ) );
527 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 5 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch1_s32x4 ) );
528 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 6 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch1_s32x4 ) );
529 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 7 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch1_s32x4 ) );
530 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 8 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch2_s32x4 ) );
531 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 9 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch2_s32x4 ) );
532 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 10 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch2_s32x4 ) );
533 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 11 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch2_s32x4 ) );
534 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 12 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch3_s32x4 ) );
535 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 13 * NEON_MAX_DEL_DEC_STATES ), vget_low_s32( a_Q12_arch3_s32x4 ) );
536 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane0_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 14 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch3_s32x4 ) );
537 LPC_pred_Q14_s32x4 = silk_SMLAWB_lane1_neon( LPC_pred_Q14_s32x4, vld1q_s32( buf32 + 15 * NEON_MAX_DEL_DEC_STATES ), vget_high_s32( a_Q12_arch3_s32x4 ) );
538
539 return LPC_pred_Q14_s32x4;
540}
541
542static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_neon(
543 silk_nsq_state *NSQ, /* I/O NSQ state */
544 NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */
545 opus_int signalType, /* I Signal type */
546 const opus_int32 x_Q10[], /* I */
547 opus_int8 pulses[], /* O */
548 opus_int16 xq[], /* O */
549 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
550 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
551 const opus_int16 a_Q12[], /* I Short term prediction coefs */
552 const opus_int16 b_Q14[], /* I Long term prediction coefs */
553 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
554 opus_int lag, /* I Pitch lag */
555 opus_int32 HarmShapeFIRPacked_Q14, /* I */
556 opus_int Tilt_Q14, /* I Spectral tilt */
557 opus_int32 LF_shp_Q14, /* I */
558 opus_int32 Gain_Q16, /* I */
559 opus_int Lambda_Q10, /* I */
560 opus_int offset_Q10, /* I */
561 opus_int length, /* I Input length */
562 opus_int subfr, /* I Subframe number */
563 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
564 opus_int predictLPCOrder, /* I Prediction filter order */
565 opus_int warping_Q16, /* I */
566 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
567 opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
568 opus_int decisionDelay /* I */
569)
570{
571 opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
572 opus_int32 Winner_rand_state;
573 opus_int32 LTP_pred_Q14, n_LTP_Q14;
574 opus_int32 RDmin_Q10, RDmax_Q10;
575 opus_int32 Gain_Q10;
576 opus_int32 *pred_lag_ptr, *shp_lag_ptr;
577 opus_int32 a_Q12_arch[MAX_LPC_ORDER];
578 const int32x2_t warping_Q16_s32x2 = vdup_n_s32( silk_LSHIFT32( warping_Q16, 16 ) >> 1 );
579 const opus_int32 LF_shp_Q29 = silk_LSHIFT32( LF_shp_Q14, 16 ) >> 1;
580 opus_int32 AR_shp_Q28[ MAX_SHAPE_LPC_ORDER ];
581 const uint32x4_t rand_multiplier_u32x4 = vdupq_n_u32( RAND_MULTIPLIER );
582 const uint32x4_t rand_increment_u32x4 = vdupq_n_u32( RAND_INCREMENT );
583
584 VARDECL( NSQ_samples_struct, psSampleState );
585 SAVE_STACK;
586
587 silk_assert( nStatesDelayedDecision > 0 );
588 silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
589 ALLOC( psSampleState, 2, NSQ_samples_struct );
590
591 shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
592 pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
593 Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
594
595 for( i = 0; i < ( MAX_SHAPE_LPC_ORDER - 7 ); i += 8 ) {
596 const int16x8_t t_s16x8 = vld1q_s16( AR_shp_Q13 + i );
597 vst1q_s32( AR_shp_Q28 + i + 0, vshll_n_s16( vget_low_s16( t_s16x8 ), 15 ) );
598 vst1q_s32( AR_shp_Q28 + i + 4, vshll_n_s16( vget_high_s16( t_s16x8 ), 15 ) );
599 }
600
601 for( ; i < MAX_SHAPE_LPC_ORDER; i++ ) {
602 AR_shp_Q28[i] = silk_LSHIFT32( AR_shp_Q13[i], 15 );
603 }
604
605 silk_short_prediction_create_arch_coef_neon_local( a_Q12_arch, a_Q12, predictLPCOrder );
606
607 for( i = 0; i < length; i++ ) {
608 int32x4_t Seed_s32x4, LPC_pred_Q14_s32x4;
609 int32x4_t sign_s32x4, tmp1_s32x4, tmp2_s32x4;
610 int32x4_t n_AR_Q14_s32x4, n_LF_Q14_s32x4;
611 int32x2_t AR_shp_Q28_s32x2;
612 int16x4_t r_Q10_s16x4, rr_Q10_s16x4;
613
614 /* Perform common calculations used in all states */
615
616 /* Long-term prediction */
617 if( signalType == TYPE_VOICED ) {
618 /* Unrolled loop */
619 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
620 LTP_pred_Q14 = 2;
621 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
622 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
623 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
624 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
625 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
626 LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */
627 pred_lag_ptr++;
628 } else {
629 LTP_pred_Q14 = 0;
630 }
631
632 /* Long-term shaping */
633 if( lag > 0 ) {
634 /* Symmetric, packed FIR coefficients */
635 n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
636 n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
637 n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */
638 shp_lag_ptr++;
639 } else {
640 n_LTP_Q14 = 0;
641 }
642
643 /* Generate dither */
644 Seed_s32x4 = vld1q_s32( psDelDec->Seed );
645 Seed_s32x4 = vreinterpretq_s32_u32( vmlaq_u32( rand_increment_u32x4, vreinterpretq_u32_s32( Seed_s32x4 ), rand_multiplier_u32x4 ) );
646 vst1q_s32( psDelDec->Seed, Seed_s32x4 );
647
648 /* Short-term prediction */
649 LPC_pred_Q14_s32x4 = silk_noise_shape_quantizer_short_prediction_neon_local(psDelDec->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 16 + i ], a_Q12_arch, predictLPCOrder);
650 LPC_pred_Q14_s32x4 = vshlq_n_s32( LPC_pred_Q14_s32x4, 4 ); /* Q10 -> Q14 */
651
652 /* Noise shape feedback */
653 /* Output of lowpass section */
654 tmp2_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->Diff_Q14 ), vld1q_s32( psDelDec->sAR2_Q14[ 0 ] ), warping_Q16_s32x2 );
655 /* Output of allpass section */
656 tmp1_s32x4 = vsubq_s32( vld1q_s32( psDelDec->sAR2_Q14[ 1 ] ), tmp2_s32x4 );
657 tmp1_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->sAR2_Q14[ 0 ] ), tmp1_s32x4, warping_Q16_s32x2 );
658 vst1q_s32( psDelDec->sAR2_Q14[ 0 ], tmp2_s32x4 );
659 AR_shp_Q28_s32x2 = vld1_s32( AR_shp_Q28 );
660 n_AR_Q14_s32x4 = vaddq_s32( vdupq_n_s32( silk_RSHIFT( shapingLPCOrder, 1 ) ), vqdmulhq_lane_s32( tmp2_s32x4, AR_shp_Q28_s32x2, 0 ) );
661
662 /* Loop over allpass sections */
663 for( j = 2; j < shapingLPCOrder; j += 2 ) {
664 /* Output of allpass section */
665 tmp2_s32x4 = vsubq_s32( vld1q_s32( psDelDec->sAR2_Q14[ j + 0 ] ), tmp1_s32x4 );
666 tmp2_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->sAR2_Q14[ j - 1 ] ), tmp2_s32x4, warping_Q16_s32x2 );
667 vst1q_s32( psDelDec->sAR2_Q14[ j - 1 ], tmp1_s32x4 );
668 n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_lane_s32( tmp1_s32x4, AR_shp_Q28_s32x2, 1 ) );
669 /* Output of allpass section */
670 tmp1_s32x4 = vsubq_s32( vld1q_s32( psDelDec->sAR2_Q14[ j + 1 ] ), tmp2_s32x4 );
671 tmp1_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->sAR2_Q14[ j + 0 ] ), tmp1_s32x4, warping_Q16_s32x2 );
672 vst1q_s32( psDelDec->sAR2_Q14[ j + 0 ], tmp2_s32x4 );
673 AR_shp_Q28_s32x2 = vld1_s32( &AR_shp_Q28[ j ] );
674 n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_lane_s32( tmp2_s32x4, AR_shp_Q28_s32x2, 0 ) );
675 }
676 vst1q_s32( psDelDec->sAR2_Q14[ shapingLPCOrder - 1 ], tmp1_s32x4 );
677 n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_lane_s32( tmp1_s32x4, AR_shp_Q28_s32x2, 1 ) );
678 n_AR_Q14_s32x4 = vshlq_n_s32( n_AR_Q14_s32x4, 1 ); /* Q11 -> Q12 */
679 n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_n_s32( vld1q_s32( psDelDec->LF_AR_Q14 ), silk_LSHIFT32( Tilt_Q14, 16 ) >> 1 ) ); /* Q12 */
680 n_AR_Q14_s32x4 = vshlq_n_s32( n_AR_Q14_s32x4, 2 ); /* Q12 -> Q14 */
681 n_LF_Q14_s32x4 = vqdmulhq_n_s32( vld1q_s32( psDelDec->Shape_Q14[ *smpl_buf_idx ] ), LF_shp_Q29 ); /* Q12 */
682 n_LF_Q14_s32x4 = vaddq_s32( n_LF_Q14_s32x4, vqdmulhq_n_s32( vld1q_s32( psDelDec->LF_AR_Q14 ), silk_LSHIFT32( LF_shp_Q14 >> 16 , 15 ) ) ); /* Q12 */
683 n_LF_Q14_s32x4 = vshlq_n_s32( n_LF_Q14_s32x4, 2 ); /* Q12 -> Q14 */
684
685 /* Input minus prediction plus noise feedback */
686 /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */
687 tmp1_s32x4 = vaddq_s32( n_AR_Q14_s32x4, n_LF_Q14_s32x4 ); /* Q14 */
688 tmp2_s32x4 = vaddq_s32( vdupq_n_s32( n_LTP_Q14 ), LPC_pred_Q14_s32x4 ); /* Q13 */
689 tmp1_s32x4 = vsubq_s32( tmp2_s32x4, tmp1_s32x4 ); /* Q13 */
690 tmp1_s32x4 = vrshrq_n_s32( tmp1_s32x4, 4 ); /* Q10 */
691 tmp1_s32x4 = vsubq_s32( vdupq_n_s32( x_Q10[ i ] ), tmp1_s32x4 ); /* residual error Q10 */
692
693 /* Flip sign depending on dither */
694 sign_s32x4 = vreinterpretq_s32_u32( vcltq_s32( Seed_s32x4, vdupq_n_s32( 0 ) ) );
695 tmp1_s32x4 = veorq_s32( tmp1_s32x4, sign_s32x4 );
696 tmp1_s32x4 = vsubq_s32( tmp1_s32x4, sign_s32x4 );
697 tmp1_s32x4 = vmaxq_s32( tmp1_s32x4, vdupq_n_s32( -( 31 << 10 ) ) );
698 tmp1_s32x4 = vminq_s32( tmp1_s32x4, vdupq_n_s32( 30 << 10 ) );
699 r_Q10_s16x4 = vmovn_s32( tmp1_s32x4 );
700
701 /* Find two quantization level candidates and measure their rate-distortion */
702 {
703 int16x4_t q1_Q10_s16x4 = vsub_s16( r_Q10_s16x4, vdup_n_s16( offset_Q10 ) );
704 int16x4_t q1_Q0_s16x4 = vshr_n_s16( q1_Q10_s16x4, 10 );
705 int16x4_t q2_Q10_s16x4;
706 int32x4_t rd1_Q10_s32x4, rd2_Q10_s32x4;
707 uint32x4_t t_u32x4;
708
709 if( Lambda_Q10 > 2048 ) {
710 /* For aggressive RDO, the bias becomes more than one pulse. */
711 const int rdo_offset = Lambda_Q10/2 - 512;
712 const uint16x4_t greaterThanRdo = vcgt_s16( q1_Q10_s16x4, vdup_n_s16( rdo_offset ) );
713 const uint16x4_t lessThanMinusRdo = vclt_s16( q1_Q10_s16x4, vdup_n_s16( -rdo_offset ) );
714 /* If Lambda_Q10 > 32767, then q1_Q0, q1_Q10 and q2_Q10 must change to 32-bit. */
715 silk_assert( Lambda_Q10 <= 32767 );
716
717 q1_Q0_s16x4 = vreinterpret_s16_u16( vclt_s16( q1_Q10_s16x4, vdup_n_s16( 0 ) ) );
718 q1_Q0_s16x4 = vbsl_s16( greaterThanRdo, vsub_s16( q1_Q10_s16x4, vdup_n_s16( rdo_offset ) ), q1_Q0_s16x4 );
719 q1_Q0_s16x4 = vbsl_s16( lessThanMinusRdo, vadd_s16( q1_Q10_s16x4, vdup_n_s16( rdo_offset ) ), q1_Q0_s16x4 );
720 q1_Q0_s16x4 = vshr_n_s16( q1_Q0_s16x4, 10 );
721 }
722 {
723 const uint16x4_t equal0_u16x4 = vceq_s16( q1_Q0_s16x4, vdup_n_s16( 0 ) );
724 const uint16x4_t equalMinus1_u16x4 = vceq_s16( q1_Q0_s16x4, vdup_n_s16( -1 ) );
725 const uint16x4_t lessThanMinus1_u16x4 = vclt_s16( q1_Q0_s16x4, vdup_n_s16( -1 ) );
726 int16x4_t tmp1_s16x4, tmp2_s16x4;
727
728 q1_Q10_s16x4 = vshl_n_s16( q1_Q0_s16x4, 10 );
729 tmp1_s16x4 = vadd_s16( q1_Q10_s16x4, vdup_n_s16( offset_Q10 - QUANT_LEVEL_ADJUST_Q10 ) );
730 q1_Q10_s16x4 = vadd_s16( q1_Q10_s16x4, vdup_n_s16( offset_Q10 + QUANT_LEVEL_ADJUST_Q10 ) );
731 q1_Q10_s16x4 = vbsl_s16( lessThanMinus1_u16x4, q1_Q10_s16x4, tmp1_s16x4 );
732 q1_Q10_s16x4 = vbsl_s16( equal0_u16x4, vdup_n_s16( offset_Q10 ), q1_Q10_s16x4 );
733 q1_Q10_s16x4 = vbsl_s16( equalMinus1_u16x4, vdup_n_s16( offset_Q10 - ( 1024 - QUANT_LEVEL_ADJUST_Q10 ) ), q1_Q10_s16x4 );
734 q2_Q10_s16x4 = vadd_s16( q1_Q10_s16x4, vdup_n_s16( 1024 ) );
735 q2_Q10_s16x4 = vbsl_s16( equal0_u16x4, vdup_n_s16( offset_Q10 + 1024 - QUANT_LEVEL_ADJUST_Q10 ), q2_Q10_s16x4 );
736 q2_Q10_s16x4 = vbsl_s16( equalMinus1_u16x4, vdup_n_s16( offset_Q10 ), q2_Q10_s16x4 );
737 tmp1_s16x4 = q1_Q10_s16x4;
738 tmp2_s16x4 = q2_Q10_s16x4;
739 tmp1_s16x4 = vbsl_s16( vorr_u16( equalMinus1_u16x4, lessThanMinus1_u16x4 ), vneg_s16( tmp1_s16x4 ), tmp1_s16x4 );
740 tmp2_s16x4 = vbsl_s16( lessThanMinus1_u16x4, vneg_s16( tmp2_s16x4 ), tmp2_s16x4 );
741 rd1_Q10_s32x4 = vmull_s16( tmp1_s16x4, vdup_n_s16( Lambda_Q10 ) );
742 rd2_Q10_s32x4 = vmull_s16( tmp2_s16x4, vdup_n_s16( Lambda_Q10 ) );
743 }
744
745 rr_Q10_s16x4 = vsub_s16( r_Q10_s16x4, q1_Q10_s16x4 );
746 rd1_Q10_s32x4 = vmlal_s16( rd1_Q10_s32x4, rr_Q10_s16x4, rr_Q10_s16x4 );
747 rd1_Q10_s32x4 = vshrq_n_s32( rd1_Q10_s32x4, 10 );
748
749 rr_Q10_s16x4 = vsub_s16( r_Q10_s16x4, q2_Q10_s16x4 );
750 rd2_Q10_s32x4 = vmlal_s16( rd2_Q10_s32x4, rr_Q10_s16x4, rr_Q10_s16x4 );
751 rd2_Q10_s32x4 = vshrq_n_s32( rd2_Q10_s32x4, 10 );
752
753 tmp2_s32x4 = vld1q_s32( psDelDec->RD_Q10 );
754 tmp1_s32x4 = vaddq_s32( tmp2_s32x4, vminq_s32( rd1_Q10_s32x4, rd2_Q10_s32x4 ) );
755 tmp2_s32x4 = vaddq_s32( tmp2_s32x4, vmaxq_s32( rd1_Q10_s32x4, rd2_Q10_s32x4 ) );
756 vst1q_s32( psSampleState[ 0 ].RD_Q10, tmp1_s32x4 );
757 vst1q_s32( psSampleState[ 1 ].RD_Q10, tmp2_s32x4 );
758 t_u32x4 = vcltq_s32( rd1_Q10_s32x4, rd2_Q10_s32x4 );
759 tmp1_s32x4 = vbslq_s32( t_u32x4, vmovl_s16( q1_Q10_s16x4 ), vmovl_s16( q2_Q10_s16x4 ) );
760 tmp2_s32x4 = vbslq_s32( t_u32x4, vmovl_s16( q2_Q10_s16x4 ), vmovl_s16( q1_Q10_s16x4 ) );
761 vst1q_s32( psSampleState[ 0 ].Q_Q10, tmp1_s32x4 );
762 vst1q_s32( psSampleState[ 1 ].Q_Q10, tmp2_s32x4 );
763 }
764
765 {
766 /* Update states for best quantization */
767 int32x4_t exc_Q14_s32x4, LPC_exc_Q14_s32x4, xq_Q14_s32x4, sLF_AR_shp_Q14_s32x4;
768
769 /* Quantized excitation */
770 exc_Q14_s32x4 = vshlq_n_s32( tmp1_s32x4, 4 );
771 exc_Q14_s32x4 = veorq_s32( exc_Q14_s32x4, sign_s32x4 );
772 exc_Q14_s32x4 = vsubq_s32( exc_Q14_s32x4, sign_s32x4 );
773
774 /* Add predictions */
775 LPC_exc_Q14_s32x4 = vaddq_s32( exc_Q14_s32x4, vdupq_n_s32( LTP_pred_Q14 ) );
776 xq_Q14_s32x4 = vaddq_s32( LPC_exc_Q14_s32x4, LPC_pred_Q14_s32x4 );
777
778 /* Update states */
779 tmp1_s32x4 = vsubq_s32( xq_Q14_s32x4, vshlq_n_s32( vdupq_n_s32( x_Q10[ i ] ), 4 ) );
780 vst1q_s32( psSampleState[ 0 ].Diff_Q14, tmp1_s32x4 );
781 sLF_AR_shp_Q14_s32x4 = vsubq_s32( tmp1_s32x4, n_AR_Q14_s32x4 );
782 vst1q_s32( psSampleState[ 0 ].sLTP_shp_Q14, vsubq_s32( sLF_AR_shp_Q14_s32x4, n_LF_Q14_s32x4 ) );
783 vst1q_s32( psSampleState[ 0 ].LF_AR_Q14, sLF_AR_shp_Q14_s32x4 );
784 vst1q_s32( psSampleState[ 0 ].LPC_exc_Q14, LPC_exc_Q14_s32x4 );
785 vst1q_s32( psSampleState[ 0 ].xq_Q14, xq_Q14_s32x4 );
786
787 /* Quantized excitation */
788 exc_Q14_s32x4 = vshlq_n_s32( tmp2_s32x4, 4 );
789 exc_Q14_s32x4 = veorq_s32( exc_Q14_s32x4, sign_s32x4 );
790 exc_Q14_s32x4 = vsubq_s32( exc_Q14_s32x4, sign_s32x4 );
791
792 /* Add predictions */
793 LPC_exc_Q14_s32x4 = vaddq_s32( exc_Q14_s32x4, vdupq_n_s32( LTP_pred_Q14 ) );
794 xq_Q14_s32x4 = vaddq_s32( LPC_exc_Q14_s32x4, LPC_pred_Q14_s32x4 );
795
796 /* Update states */
797 tmp1_s32x4 = vsubq_s32( xq_Q14_s32x4, vshlq_n_s32( vdupq_n_s32( x_Q10[ i ] ), 4 ) );
798 vst1q_s32( psSampleState[ 1 ].Diff_Q14, tmp1_s32x4 );
799 sLF_AR_shp_Q14_s32x4 = vsubq_s32( tmp1_s32x4, n_AR_Q14_s32x4 );
800 vst1q_s32( psSampleState[ 1 ].sLTP_shp_Q14, vsubq_s32( sLF_AR_shp_Q14_s32x4, n_LF_Q14_s32x4 ) );
801 vst1q_s32( psSampleState[ 1 ].LF_AR_Q14, sLF_AR_shp_Q14_s32x4 );
802 vst1q_s32( psSampleState[ 1 ].LPC_exc_Q14, LPC_exc_Q14_s32x4 );
803 vst1q_s32( psSampleState[ 1 ].xq_Q14, xq_Q14_s32x4 );
804 }
805
806 *smpl_buf_idx = *smpl_buf_idx ? ( *smpl_buf_idx - 1 ) : ( DECISION_DELAY - 1);
807 last_smple_idx = *smpl_buf_idx + decisionDelay + DECISION_DELAY;
808 if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY;
809 if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY;
810
811 /* Find winner */
812 RDmin_Q10 = psSampleState[ 0 ].RD_Q10[ 0 ];
813 Winner_ind = 0;
814 for( k = 1; k < nStatesDelayedDecision; k++ ) {
815 if( psSampleState[ 0 ].RD_Q10[ k ] < RDmin_Q10 ) {
816 RDmin_Q10 = psSampleState[ 0 ].RD_Q10[ k ];
817 Winner_ind = k;
818 }
819 }
820
821 /* Increase RD values of expired states */
822 {
823 uint32x4_t t_u32x4;
824 Winner_rand_state = psDelDec->RandState[ last_smple_idx ][ Winner_ind ];
825 t_u32x4 = vceqq_s32( vld1q_s32( psDelDec->RandState[ last_smple_idx ] ), vdupq_n_s32( Winner_rand_state ) );
826 t_u32x4 = vmvnq_u32( t_u32x4 );
827 t_u32x4 = vshrq_n_u32( t_u32x4, 5 );
828 tmp1_s32x4 = vld1q_s32( psSampleState[ 0 ].RD_Q10 );
829 tmp2_s32x4 = vld1q_s32( psSampleState[ 1 ].RD_Q10 );
830 tmp1_s32x4 = vaddq_s32( tmp1_s32x4, vreinterpretq_s32_u32( t_u32x4 ) );
831 tmp2_s32x4 = vaddq_s32( tmp2_s32x4, vreinterpretq_s32_u32( t_u32x4 ) );
832 vst1q_s32( psSampleState[ 0 ].RD_Q10, tmp1_s32x4 );
833 vst1q_s32( psSampleState[ 1 ].RD_Q10, tmp2_s32x4 );
834
835 /* Find worst in first set and best in second set */
836 RDmax_Q10 = psSampleState[ 0 ].RD_Q10[ 0 ];
837 RDmin_Q10 = psSampleState[ 1 ].RD_Q10[ 0 ];
838 RDmax_ind = 0;
839 RDmin_ind = 0;
840 for( k = 1; k < nStatesDelayedDecision; k++ ) {
841 /* find worst in first set */
842 if( psSampleState[ 0 ].RD_Q10[ k ] > RDmax_Q10 ) {
843 RDmax_Q10 = psSampleState[ 0 ].RD_Q10[ k ];
844 RDmax_ind = k;
845 }
846 /* find best in second set */
847 if( psSampleState[ 1 ].RD_Q10[ k ] < RDmin_Q10 ) {
848 RDmin_Q10 = psSampleState[ 1 ].RD_Q10[ k ];
849 RDmin_ind = k;
850 }
851 }
852 }
853
854 /* Replace a state if best from second set outperforms worst in first set */
855 if( RDmin_Q10 < RDmax_Q10 ) {
856 opus_int32 (*ptr)[NEON_MAX_DEL_DEC_STATES] = psDelDec->RandState;
857 const int numOthers = (int)( ( sizeof( NSQ_del_decs_struct ) - sizeof( ( (NSQ_del_decs_struct *)0 )->sLPC_Q14 ) )
858 / ( NEON_MAX_DEL_DEC_STATES * sizeof( opus_int32 ) ) );
859 /* Only ( predictLPCOrder - 1 ) of sLPC_Q14 buffer need to be updated, though the first several */
860 /* useless sLPC_Q14[] will be different comparing with C when predictLPCOrder < NSQ_LPC_BUF_LENGTH. */
861 /* Here just update constant ( NSQ_LPC_BUF_LENGTH - 1 ) for simplicity. */
862 for( j = i + 1; j < i + NSQ_LPC_BUF_LENGTH; j++ ) {
863 psDelDec->sLPC_Q14[ j ][ RDmax_ind ] = psDelDec->sLPC_Q14[ j ][ RDmin_ind ];
864 }
865 for( j = 0; j < numOthers; j++ ) {
866 ptr[ j ][ RDmax_ind ] = ptr[ j ][ RDmin_ind ];
867 }
868
869 psSampleState[ 0 ].Q_Q10[ RDmax_ind ] = psSampleState[ 1 ].Q_Q10[ RDmin_ind ];
870 psSampleState[ 0 ].RD_Q10[ RDmax_ind ] = psSampleState[ 1 ].RD_Q10[ RDmin_ind ];
871 psSampleState[ 0 ].xq_Q14[ RDmax_ind ] = psSampleState[ 1 ].xq_Q14[ RDmin_ind ];
872 psSampleState[ 0 ].LF_AR_Q14[ RDmax_ind ] = psSampleState[ 1 ].LF_AR_Q14[ RDmin_ind ];
873 psSampleState[ 0 ].Diff_Q14[ RDmax_ind ] = psSampleState[ 1 ].Diff_Q14[ RDmin_ind ];
874 psSampleState[ 0 ].sLTP_shp_Q14[ RDmax_ind ] = psSampleState[ 1 ].sLTP_shp_Q14[ RDmin_ind ];
875 psSampleState[ 0 ].LPC_exc_Q14[ RDmax_ind ] = psSampleState[ 1 ].LPC_exc_Q14[ RDmin_ind ];
876 }
877
878 /* Write samples from winner to output and long-term filter states */
879 if( subfr > 0 || i >= decisionDelay ) {
880 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDelDec->Q_Q10[ last_smple_idx ][ Winner_ind ], 10 );
881 xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
882 silk_SMULWW( psDelDec->Xq_Q14[ last_smple_idx ][ Winner_ind ], delayedGain_Q10[ last_smple_idx ] ), 8 ) );
883 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDelDec->Shape_Q14[ last_smple_idx ][ Winner_ind ];
884 sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDelDec->Pred_Q15[ last_smple_idx ][ Winner_ind ];
885 }
886 NSQ->sLTP_shp_buf_idx++;
887 NSQ->sLTP_buf_idx++;
888
889 /* Update states */
890 vst1q_s32( psDelDec->LF_AR_Q14, vld1q_s32( psSampleState[ 0 ].LF_AR_Q14 ) );
891 vst1q_s32( psDelDec->Diff_Q14, vld1q_s32( psSampleState[ 0 ].Diff_Q14 ) );
892 vst1q_s32( psDelDec->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ], vld1q_s32( psSampleState[ 0 ].xq_Q14 ) );
893 vst1q_s32( psDelDec->Xq_Q14[ *smpl_buf_idx ], vld1q_s32( psSampleState[ 0 ].xq_Q14 ) );
894 tmp1_s32x4 = vld1q_s32( psSampleState[ 0 ].Q_Q10 );
895 vst1q_s32( psDelDec->Q_Q10[ *smpl_buf_idx ], tmp1_s32x4 );
896 vst1q_s32( psDelDec->Pred_Q15[ *smpl_buf_idx ], vshlq_n_s32( vld1q_s32( psSampleState[ 0 ].LPC_exc_Q14 ), 1 ) );
897 vst1q_s32( psDelDec->Shape_Q14[ *smpl_buf_idx ], vld1q_s32( psSampleState[ 0 ].sLTP_shp_Q14 ) );
898 tmp1_s32x4 = vrshrq_n_s32( tmp1_s32x4, 10 );
899 tmp1_s32x4 = vaddq_s32( vld1q_s32( psDelDec->Seed ), tmp1_s32x4 );
900 vst1q_s32( psDelDec->Seed, tmp1_s32x4 );
901 vst1q_s32( psDelDec->RandState[ *smpl_buf_idx ], tmp1_s32x4 );
902 vst1q_s32( psDelDec->RD_Q10, vld1q_s32( psSampleState[ 0 ].RD_Q10 ) );
903 delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10;
904 }
905 /* Update LPC states */
906 silk_memcpy( psDelDec->sLPC_Q14[ 0 ], psDelDec->sLPC_Q14[ length ], NEON_MAX_DEL_DEC_STATES * NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
907
908 RESTORE_STACK;
909}
910
911static OPUS_INLINE void silk_SMULWB_8_neon(
912 const opus_int16 *a,
913 const int32x2_t b,
914 opus_int32 *o
915)
916{
917 const int16x8_t a_s16x8 = vld1q_s16( a );
918 int32x4_t o0_s32x4, o1_s32x4;
919
920 o0_s32x4 = vshll_n_s16( vget_low_s16( a_s16x8 ), 15 );
921 o1_s32x4 = vshll_n_s16( vget_high_s16( a_s16x8 ), 15 );
922 o0_s32x4 = vqdmulhq_lane_s32( o0_s32x4, b, 0 );
923 o1_s32x4 = vqdmulhq_lane_s32( o1_s32x4, b, 0 );
924 vst1q_s32( o, o0_s32x4 );
925 vst1q_s32( o + 4, o1_s32x4 );
926}
927
928/* Only works when ( b >= -65536 ) && ( b < 65536 ). */
929static OPUS_INLINE void silk_SMULWW_small_b_4_neon(
930 opus_int32 *a,
931 const int32x2_t b_s32x2)
932{
933 int32x4_t o_s32x4;
934
935 o_s32x4 = vld1q_s32( a );
936 o_s32x4 = vqdmulhq_lane_s32( o_s32x4, b_s32x2, 0 );
937 vst1q_s32( a, o_s32x4 );
938}
939
940/* Only works when ( b >= -65536 ) && ( b < 65536 ). */
941static OPUS_INLINE void silk_SMULWW_small_b_8_neon(
942 opus_int32 *a,
943 const int32x2_t b_s32x2
944)
945{
946 int32x4_t o0_s32x4, o1_s32x4;
947
948 o0_s32x4 = vld1q_s32( a );
949 o1_s32x4 = vld1q_s32( a + 4 );
950 o0_s32x4 = vqdmulhq_lane_s32( o0_s32x4, b_s32x2, 0 );
951 o1_s32x4 = vqdmulhq_lane_s32( o1_s32x4, b_s32x2, 0 );
952 vst1q_s32( a, o0_s32x4 );
953 vst1q_s32( a + 4, o1_s32x4 );
954}
955
956static OPUS_INLINE void silk_SMULWW_4_neon(
957 opus_int32 *a,
958 const int32x2_t b_s32x2)
959{
960 int32x4_t a_s32x4, o_s32x4;
961
962 a_s32x4 = vld1q_s32( a );
963 o_s32x4 = vqdmulhq_lane_s32( a_s32x4, b_s32x2, 0 );
964 o_s32x4 = vmlaq_lane_s32( o_s32x4, a_s32x4, b_s32x2, 1 );
965 vst1q_s32( a, o_s32x4 );
966}
967
968static OPUS_INLINE void silk_SMULWW_8_neon(
969 opus_int32 *a,
970 const int32x2_t b_s32x2
971)
972{
973 int32x4_t a0_s32x4, a1_s32x4, o0_s32x4, o1_s32x4;
974
975 a0_s32x4 = vld1q_s32( a );
976 a1_s32x4 = vld1q_s32( a + 4 );
977 o0_s32x4 = vqdmulhq_lane_s32( a0_s32x4, b_s32x2, 0 );
978 o1_s32x4 = vqdmulhq_lane_s32( a1_s32x4, b_s32x2, 0 );
979 o0_s32x4 = vmlaq_lane_s32( o0_s32x4, a0_s32x4, b_s32x2, 1 );
980 o1_s32x4 = vmlaq_lane_s32( o1_s32x4, a1_s32x4, b_s32x2, 1 );
981 vst1q_s32( a, o0_s32x4 );
982 vst1q_s32( a + 4, o1_s32x4 );
983}
984
985static OPUS_INLINE void silk_SMULWW_loop_neon(
986 const opus_int16 *a,
987 const opus_int32 b,
988 opus_int32 *o,
989 const opus_int loop_num
990)
991{
992 opus_int i;
993 int32x2_t b_s32x2;
994
995 b_s32x2 = vdup_n_s32( b );
996 for( i = 0; i < loop_num - 7; i += 8 ) {
997 silk_SMULWB_8_neon( a + i, b_s32x2, o + i );
998 }
999 for( ; i < loop_num; i++ ) {
1000 o[ i ] = silk_SMULWW( a[ i ], b );
1001 }
1002}
1003
1004static OPUS_INLINE void silk_nsq_del_dec_scale_states_neon(
1005 const silk_encoder_state *psEncC, /* I Encoder State */
1006 silk_nsq_state *NSQ, /* I/O NSQ state */
1007 NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */
1008 const opus_int16 x16[], /* I Input */
1009 opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
1010 const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
1011 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
1012 opus_int subfr, /* I Subframe number */
1013 const opus_int LTP_scale_Q14, /* I LTP state scaling */
1014 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
1015 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
1016 const opus_int signal_type, /* I Signal type */
1017 const opus_int decisionDelay /* I Decision delay */
1018)
1019{
1020 opus_int i, lag;
1021 opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26;
1022
1023 lag = pitchL[ subfr ];
1024 inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
1025 silk_assert( inv_gain_Q31 != 0 );
1026
1027 /* Scale input */
1028 inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 );
1029 silk_SMULWW_loop_neon( x16, inv_gain_Q26, x_sc_Q10, psEncC->subfr_length );
1030
1031 /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
1032 if( NSQ->rewhite_flag ) {
1033 if( subfr == 0 ) {
1034 /* Do LTP downscaling */
1035 inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
1036 }
1037 silk_SMULWW_loop_neon( sLTP + NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2, inv_gain_Q31, sLTP_Q15 + NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2, lag + LTP_ORDER / 2 );
1038 }
1039
1040 /* Adjust for changing gain */
1041 if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
1042 int32x2_t gain_adj_Q16_s32x2;
1043 gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
1044
1045 /* Scale long-term shaping state */
1046 if( ( gain_adj_Q16 >= -65536 ) && ( gain_adj_Q16 < 65536 ) ) {
1047 gain_adj_Q16_s32x2 = vdup_n_s32( silk_LSHIFT32( gain_adj_Q16, 15 ) );
1048 for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 7; i += 8 ) {
1049 silk_SMULWW_small_b_8_neon( NSQ->sLTP_shp_Q14 + i, gain_adj_Q16_s32x2 );
1050 }
1051 for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) {
1052 NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
1053 }
1054
1055 /* Scale long-term prediction state */
1056 if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
1057 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay - 7; i += 8 ) {
1058 silk_SMULWW_small_b_8_neon( sLTP_Q15 + i, gain_adj_Q16_s32x2 );
1059 }
1060 for( ; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
1061 sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
1062 }
1063 }
1064
1065 /* Scale scalar states */
1066 silk_SMULWW_small_b_4_neon( psDelDec->LF_AR_Q14, gain_adj_Q16_s32x2 );
1067 silk_SMULWW_small_b_4_neon( psDelDec->Diff_Q14, gain_adj_Q16_s32x2 );
1068
1069 /* Scale short-term prediction and shaping states */
1070 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
1071 silk_SMULWW_small_b_4_neon( psDelDec->sLPC_Q14[ i ], gain_adj_Q16_s32x2 );
1072 }
1073
1074 for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
1075 silk_SMULWW_small_b_4_neon( psDelDec->sAR2_Q14[ i ], gain_adj_Q16_s32x2 );
1076 }
1077
1078 for( i = 0; i < DECISION_DELAY; i++ ) {
1079 silk_SMULWW_small_b_4_neon( psDelDec->Pred_Q15[ i ], gain_adj_Q16_s32x2 );
1080 silk_SMULWW_small_b_4_neon( psDelDec->Shape_Q14[ i ], gain_adj_Q16_s32x2 );
1081 }
1082 } else {
1083 gain_adj_Q16_s32x2 = vdup_n_s32( silk_LSHIFT32( gain_adj_Q16 & 0x0000FFFF, 15 ) );
1084 gain_adj_Q16_s32x2 = vset_lane_s32( gain_adj_Q16 >> 16, gain_adj_Q16_s32x2, 1 );
1085 for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 7; i += 8 ) {
1086 silk_SMULWW_8_neon( NSQ->sLTP_shp_Q14 + i, gain_adj_Q16_s32x2 );
1087 }
1088 for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) {
1089 NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
1090 }
1091
1092 /* Scale long-term prediction state */
1093 if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
1094 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay - 7; i += 8 ) {
1095 silk_SMULWW_8_neon( sLTP_Q15 + i, gain_adj_Q16_s32x2 );
1096 }
1097 for( ; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
1098 sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
1099 }
1100 }
1101
1102 /* Scale scalar states */
1103 silk_SMULWW_4_neon( psDelDec->LF_AR_Q14, gain_adj_Q16_s32x2 );
1104 silk_SMULWW_4_neon( psDelDec->Diff_Q14, gain_adj_Q16_s32x2 );
1105
1106 /* Scale short-term prediction and shaping states */
1107 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
1108 silk_SMULWW_4_neon( psDelDec->sLPC_Q14[ i ], gain_adj_Q16_s32x2 );
1109 }
1110
1111 for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
1112 silk_SMULWW_4_neon( psDelDec->sAR2_Q14[ i ], gain_adj_Q16_s32x2 );
1113 }
1114
1115 for( i = 0; i < DECISION_DELAY; i++ ) {
1116 silk_SMULWW_4_neon( psDelDec->Pred_Q15[ i ], gain_adj_Q16_s32x2 );
1117 silk_SMULWW_4_neon( psDelDec->Shape_Q14[ i ], gain_adj_Q16_s32x2 );
1118 }
1119 }
1120
1121 /* Save inverse gain */
1122 NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
1123 }
1124}
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.c b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.c
new file mode 100644
index 0000000000..9642529973
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.c
@@ -0,0 +1,112 @@
1/***********************************************************************
2Copyright (C) 2014 Vidyo
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27#ifdef HAVE_CONFIG_H
28#include "config.h"
29#endif
30
31#include <arm_neon.h>
32#include "main.h"
33#include "stack_alloc.h"
34#include "NSQ.h"
35#include "celt/cpu_support.h"
36#include "celt/arm/armcpu.h"
37
38opus_int32 silk_noise_shape_quantizer_short_prediction_neon(const opus_int32 *buf32, const opus_int32 *coef32, opus_int order)
39{
40 int32x4_t coef0 = vld1q_s32(coef32);
41 int32x4_t coef1 = vld1q_s32(coef32 + 4);
42 int32x4_t coef2 = vld1q_s32(coef32 + 8);
43 int32x4_t coef3 = vld1q_s32(coef32 + 12);
44
45 int32x4_t a0 = vld1q_s32(buf32 - 15);
46 int32x4_t a1 = vld1q_s32(buf32 - 11);
47 int32x4_t a2 = vld1q_s32(buf32 - 7);
48 int32x4_t a3 = vld1q_s32(buf32 - 3);
49
50 int32x4_t b0 = vqdmulhq_s32(coef0, a0);
51 int32x4_t b1 = vqdmulhq_s32(coef1, a1);
52 int32x4_t b2 = vqdmulhq_s32(coef2, a2);
53 int32x4_t b3 = vqdmulhq_s32(coef3, a3);
54
55 int32x4_t c0 = vaddq_s32(b0, b1);
56 int32x4_t c1 = vaddq_s32(b2, b3);
57
58 int32x4_t d = vaddq_s32(c0, c1);
59
60 int64x2_t e = vpaddlq_s32(d);
61
62 int64x1_t f = vadd_s64(vget_low_s64(e), vget_high_s64(e));
63
64 opus_int32 out = vget_lane_s32(vreinterpret_s32_s64(f), 0);
65
66 out += silk_RSHIFT( order, 1 );
67
68 return out;
69}
70
71
72opus_int32 silk_NSQ_noise_shape_feedback_loop_neon(const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef, opus_int order)
73{
74 opus_int32 out;
75 if (order == 8)
76 {
77 int32x4_t a00 = vdupq_n_s32(data0[0]);
78 int32x4_t a01 = vld1q_s32(data1); /* data1[0] ... [3] */
79
80 int32x4_t a0 = vextq_s32 (a00, a01, 3); /* data0[0] data1[0] ...[2] */
81 int32x4_t a1 = vld1q_s32(data1 + 3); /* data1[3] ... [6] */
82
83 /*TODO: Convert these once in advance instead of once per sample, like
84 silk_noise_shape_quantizer_short_prediction_neon() does.*/
85 int16x8_t coef16 = vld1q_s16(coef);
86 int32x4_t coef0 = vmovl_s16(vget_low_s16(coef16));
87 int32x4_t coef1 = vmovl_s16(vget_high_s16(coef16));
88
89 /*This is not bit-exact with the C version, since we do not drop the
90 lower 16 bits of each multiply, but wait until the end to truncate
91 precision. This is an encoder-specific calculation (and unlike
92 silk_noise_shape_quantizer_short_prediction_neon(), is not meant to
93 simulate what the decoder will do). We still could use vqdmulhq_s32()
94 like silk_noise_shape_quantizer_short_prediction_neon() and save
95 half the multiplies, but the speed difference is not large, since we
96 then need two extra adds.*/
97 int64x2_t b0 = vmull_s32(vget_low_s32(a0), vget_low_s32(coef0));
98 int64x2_t b1 = vmlal_s32(b0, vget_high_s32(a0), vget_high_s32(coef0));
99 int64x2_t b2 = vmlal_s32(b1, vget_low_s32(a1), vget_low_s32(coef1));
100 int64x2_t b3 = vmlal_s32(b2, vget_high_s32(a1), vget_high_s32(coef1));
101
102 int64x1_t c = vadd_s64(vget_low_s64(b3), vget_high_s64(b3));
103 int64x1_t cS = vrshr_n_s64(c, 15);
104 int32x2_t d = vreinterpret_s32_s64(cS);
105
106 out = vget_lane_s32(d, 0);
107 vst1q_s32(data1, a0);
108 vst1q_s32(data1 + 4, a1);
109 return out;
110 }
111 return silk_NSQ_noise_shape_feedback_loop_c(data0, data1, coef, order);
112}
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.h b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.h
new file mode 100644
index 0000000000..b31d9442d6
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/NSQ_neon.h
@@ -0,0 +1,114 @@
1/***********************************************************************
2Copyright (C) 2014 Vidyo
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27#ifndef SILK_NSQ_NEON_H
28#define SILK_NSQ_NEON_H
29
30#include "cpu_support.h"
31#include "SigProc_FIX.h"
32
33#undef silk_short_prediction_create_arch_coef
34/* For vectorized calc, reverse a_Q12 coefs, convert to 32-bit, and shift for vqdmulhq_s32. */
35static OPUS_INLINE void silk_short_prediction_create_arch_coef_neon(opus_int32 *out, const opus_int16 *in, opus_int order)
36{
37 out[15] = silk_LSHIFT32(in[0], 15);
38 out[14] = silk_LSHIFT32(in[1], 15);
39 out[13] = silk_LSHIFT32(in[2], 15);
40 out[12] = silk_LSHIFT32(in[3], 15);
41 out[11] = silk_LSHIFT32(in[4], 15);
42 out[10] = silk_LSHIFT32(in[5], 15);
43 out[9] = silk_LSHIFT32(in[6], 15);
44 out[8] = silk_LSHIFT32(in[7], 15);
45 out[7] = silk_LSHIFT32(in[8], 15);
46 out[6] = silk_LSHIFT32(in[9], 15);
47
48 if (order == 16)
49 {
50 out[5] = silk_LSHIFT32(in[10], 15);
51 out[4] = silk_LSHIFT32(in[11], 15);
52 out[3] = silk_LSHIFT32(in[12], 15);
53 out[2] = silk_LSHIFT32(in[13], 15);
54 out[1] = silk_LSHIFT32(in[14], 15);
55 out[0] = silk_LSHIFT32(in[15], 15);
56 }
57 else
58 {
59 out[5] = 0;
60 out[4] = 0;
61 out[3] = 0;
62 out[2] = 0;
63 out[1] = 0;
64 out[0] = 0;
65 }
66}
67
68#if defined(OPUS_ARM_PRESUME_NEON_INTR)
69
70#define silk_short_prediction_create_arch_coef(out, in, order) \
71 (silk_short_prediction_create_arch_coef_neon(out, in, order))
72
73#elif defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
74
75#define silk_short_prediction_create_arch_coef(out, in, order) \
76 do { if (arch == OPUS_ARCH_ARM_NEON) { silk_short_prediction_create_arch_coef_neon(out, in, order); } } while (0)
77
78#endif
79
80opus_int32 silk_noise_shape_quantizer_short_prediction_neon(const opus_int32 *buf32, const opus_int32 *coef32, opus_int order);
81
82opus_int32 silk_NSQ_noise_shape_feedback_loop_neon(const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef, opus_int order);
83
84#if defined(OPUS_ARM_PRESUME_NEON_INTR)
85#undef silk_noise_shape_quantizer_short_prediction
86#define silk_noise_shape_quantizer_short_prediction(in, coef, coefRev, order, arch) \
87 ((void)arch,silk_noise_shape_quantizer_short_prediction_neon(in, coefRev, order))
88
89#undef silk_NSQ_noise_shape_feedback_loop
90#define silk_NSQ_noise_shape_feedback_loop(data0, data1, coef, order, arch) ((void)arch,silk_NSQ_noise_shape_feedback_loop_neon(data0, data1, coef, order))
91
92#elif defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
93
94/* silk_noise_shape_quantizer_short_prediction implementations take different parameters based on arch
95 (coef vs. coefRev) so can't use the usual IMPL table implementation */
96#undef silk_noise_shape_quantizer_short_prediction
97#define silk_noise_shape_quantizer_short_prediction(in, coef, coefRev, order, arch) \
98 (arch == OPUS_ARCH_ARM_NEON ? \
99 silk_noise_shape_quantizer_short_prediction_neon(in, coefRev, order) : \
100 silk_noise_shape_quantizer_short_prediction_c(in, coef, order))
101
102extern opus_int32
103 (*const SILK_NSQ_NOISE_SHAPE_FEEDBACK_LOOP_IMPL[OPUS_ARCHMASK+1])(
104 const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef,
105 opus_int order);
106
107#undef silk_NSQ_noise_shape_feedback_loop
108#define silk_NSQ_noise_shape_feedback_loop(data0, data1, coef, order, arch) \
109 (SILK_NSQ_NOISE_SHAPE_FEEDBACK_LOOP_IMPL[(arch)&OPUS_ARCHMASK](data0, data1, \
110 coef, order))
111
112#endif
113
114#endif /* SILK_NSQ_NEON_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/arm_silk_map.c b/lib/rbcodec/codecs/libopus/silk/arm/arm_silk_map.c
new file mode 100644
index 0000000000..0b9bfec2ca
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/arm_silk_map.c
@@ -0,0 +1,123 @@
1/***********************************************************************
2Copyright (C) 2014 Vidyo
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27#ifdef HAVE_CONFIG_H
28# include "config.h"
29#endif
30
31#include "main_FIX.h"
32#include "NSQ.h"
33#include "SigProc_FIX.h"
34
35#if defined(OPUS_HAVE_RTCD)
36
37# if (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && \
38 !defined(OPUS_ARM_PRESUME_NEON_INTR))
39
40void (*const SILK_BIQUAD_ALT_STRIDE2_IMPL[OPUS_ARCHMASK + 1])(
41 const opus_int16 *in, /* I input signal */
42 const opus_int32 *B_Q28, /* I MA coefficients [3] */
43 const opus_int32 *A_Q28, /* I AR coefficients [2] */
44 opus_int32 *S, /* I/O State vector [4] */
45 opus_int16 *out, /* O output signal */
46 const opus_int32 len /* I signal length (must be even) */
47) = {
48 silk_biquad_alt_stride2_c, /* ARMv4 */
49 silk_biquad_alt_stride2_c, /* EDSP */
50 silk_biquad_alt_stride2_c, /* Media */
51 silk_biquad_alt_stride2_neon, /* Neon */
52};
53
54opus_int32 (*const SILK_LPC_INVERSE_PRED_GAIN_IMPL[OPUS_ARCHMASK + 1])( /* O Returns inverse prediction gain in energy domain, Q30 */
55 const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
56 const opus_int order /* I Prediction order */
57) = {
58 silk_LPC_inverse_pred_gain_c, /* ARMv4 */
59 silk_LPC_inverse_pred_gain_c, /* EDSP */
60 silk_LPC_inverse_pred_gain_c, /* Media */
61 silk_LPC_inverse_pred_gain_neon, /* Neon */
62};
63
64void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])(
65 const silk_encoder_state *psEncC, /* I Encoder State */
66 silk_nsq_state *NSQ, /* I/O NSQ state */
67 SideInfoIndices *psIndices, /* I/O Quantization Indices */
68 const opus_int16 x16[], /* I Input */
69 opus_int8 pulses[], /* O Quantized pulse signal */
70 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
71 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
72 const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
73 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
74 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
75 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
76 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
77 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
78 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
79 const opus_int LTP_scale_Q14 /* I LTP state scaling */
80) = {
81 silk_NSQ_del_dec_c, /* ARMv4 */
82 silk_NSQ_del_dec_c, /* EDSP */
83 silk_NSQ_del_dec_c, /* Media */
84 silk_NSQ_del_dec_neon, /* Neon */
85};
86
87/*There is no table for silk_noise_shape_quantizer_short_prediction because the
88 NEON version takes different parameters than the C version.
89 Instead RTCD is done via if statements at the call sites.
90 See NSQ_neon.h for details.*/
91
92opus_int32
93 (*const SILK_NSQ_NOISE_SHAPE_FEEDBACK_LOOP_IMPL[OPUS_ARCHMASK+1])(
94 const opus_int32 *data0, opus_int32 *data1, const opus_int16 *coef,
95 opus_int order) = {
96 silk_NSQ_noise_shape_feedback_loop_c, /* ARMv4 */
97 silk_NSQ_noise_shape_feedback_loop_c, /* EDSP */
98 silk_NSQ_noise_shape_feedback_loop_c, /* Media */
99 silk_NSQ_noise_shape_feedback_loop_neon, /* NEON */
100};
101
102# endif
103
104# if defined(FIXED_POINT) && \
105 defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)
106
107void (*const SILK_WARPED_AUTOCORRELATION_FIX_IMPL[OPUS_ARCHMASK + 1])(
108 opus_int32 *corr, /* O Result [order + 1] */
109 opus_int *scale, /* O Scaling of the correlation vector */
110 const opus_int16 *input, /* I Input data to correlate */
111 const opus_int warping_Q16, /* I Warping coefficient */
112 const opus_int length, /* I Length of input */
113 const opus_int order /* I Correlation order (even) */
114) = {
115 silk_warped_autocorrelation_FIX_c, /* ARMv4 */
116 silk_warped_autocorrelation_FIX_c, /* EDSP */
117 silk_warped_autocorrelation_FIX_c, /* Media */
118 silk_warped_autocorrelation_FIX_neon, /* Neon */
119};
120
121# endif
122
123#endif /* OPUS_HAVE_RTCD */
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_arm.h b/lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_arm.h
new file mode 100644
index 0000000000..66ea9f43dd
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_arm.h
@@ -0,0 +1,68 @@
1/***********************************************************************
2Copyright (c) 2017 Google Inc.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef SILK_BIQUAD_ALT_ARM_H
29# define SILK_BIQUAD_ALT_ARM_H
30
31# include "celt/arm/armcpu.h"
32
33# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
34void silk_biquad_alt_stride2_neon(
35 const opus_int16 *in, /* I input signal */
36 const opus_int32 *B_Q28, /* I MA coefficients [3] */
37 const opus_int32 *A_Q28, /* I AR coefficients [2] */
38 opus_int32 *S, /* I/O State vector [4] */
39 opus_int16 *out, /* O output signal */
40 const opus_int32 len /* I signal length (must be even) */
41);
42
43# if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON)
44# define OVERRIDE_silk_biquad_alt_stride2 (1)
45# define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((void)(arch), PRESUME_NEON(silk_biquad_alt_stride2)(in, B_Q28, A_Q28, S, out, len))
46# endif
47# endif
48
49# if !defined(OVERRIDE_silk_biquad_alt_stride2)
50/*Is run-time CPU detection enabled on this platform?*/
51# if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
52extern void (*const SILK_BIQUAD_ALT_STRIDE2_IMPL[OPUS_ARCHMASK+1])(
53 const opus_int16 *in, /* I input signal */
54 const opus_int32 *B_Q28, /* I MA coefficients [3] */
55 const opus_int32 *A_Q28, /* I AR coefficients [2] */
56 opus_int32 *S, /* I/O State vector [4] */
57 opus_int16 *out, /* O output signal */
58 const opus_int32 len /* I signal length (must be even) */
59 );
60# define OVERRIDE_silk_biquad_alt_stride2 (1)
61# define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((*SILK_BIQUAD_ALT_STRIDE2_IMPL[(arch)&OPUS_ARCHMASK])(in, B_Q28, A_Q28, S, out, len))
62# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
63# define OVERRIDE_silk_biquad_alt_stride2 (1)
64# define silk_biquad_alt_stride2(in, B_Q28, A_Q28, S, out, len, arch) ((void)(arch), silk_biquad_alt_stride2_neon(in, B_Q28, A_Q28, S, out, len))
65# endif
66# endif
67
68#endif /* end SILK_BIQUAD_ALT_ARM_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_neon_intr.c b/lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_neon_intr.c
new file mode 100644
index 0000000000..9715733185
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/biquad_alt_neon_intr.c
@@ -0,0 +1,156 @@
1/***********************************************************************
2Copyright (c) 2017 Google Inc.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <arm_neon.h>
33#ifdef OPUS_CHECK_ASM
34# include <string.h>
35# include "stack_alloc.h"
36#endif
37#include "SigProc_FIX.h"
38
39static inline void silk_biquad_alt_stride2_kernel( const int32x4_t A_L_s32x4, const int32x4_t A_U_s32x4, const int32x4_t B_Q28_s32x4, const int32x2_t t_s32x2, const int32x4_t in_s32x4, int32x4_t *S_s32x4, int32x2_t *out32_Q14_s32x2 )
40{
41 int32x4_t t_s32x4, out32_Q14_s32x4;
42
43 *out32_Q14_s32x2 = vadd_s32( vget_low_s32( *S_s32x4 ), t_s32x2 ); /* silk_SMLAWB( S{0,1}, B_Q28[ 0 ], in{0,1} ) */
44 *S_s32x4 = vcombine_s32( vget_high_s32( *S_s32x4 ), vdup_n_s32( 0 ) ); /* S{0,1} = S{2,3}; S{2,3} = 0; */
45 *out32_Q14_s32x2 = vshl_n_s32( *out32_Q14_s32x2, 2 ); /* out32_Q14_{0,1} = silk_LSHIFT( silk_SMLAWB( S{0,1}, B_Q28[ 0 ], in{0,1} ), 2 ); */
46 out32_Q14_s32x4 = vcombine_s32( *out32_Q14_s32x2, *out32_Q14_s32x2 ); /* out32_Q14_{0,1,0,1} */
47 t_s32x4 = vqdmulhq_s32( out32_Q14_s32x4, A_L_s32x4 ); /* silk_SMULWB( out32_Q14_{0,1,0,1}, A{0,0,1,1}_L_Q28 ) */
48 *S_s32x4 = vrsraq_n_s32( *S_s32x4, t_s32x4, 14 ); /* S{0,1} = S{2,3} + silk_RSHIFT_ROUND(); S{2,3} = silk_RSHIFT_ROUND(); */
49 t_s32x4 = vqdmulhq_s32( out32_Q14_s32x4, A_U_s32x4 ); /* silk_SMULWB( out32_Q14_{0,1,0,1}, A{0,0,1,1}_U_Q28 ) */
50 *S_s32x4 = vaddq_s32( *S_s32x4, t_s32x4 ); /* S0 = silk_SMLAWB( S{0,1,2,3}, out32_Q14_{0,1,0,1}, A{0,0,1,1}_U_Q28 ); */
51 t_s32x4 = vqdmulhq_s32( in_s32x4, B_Q28_s32x4 ); /* silk_SMULWB( B_Q28[ {1,1,2,2} ], in{0,1,0,1} ) */
52 *S_s32x4 = vaddq_s32( *S_s32x4, t_s32x4 ); /* S0 = silk_SMLAWB( S0, B_Q28[ {1,1,2,2} ], in{0,1,0,1} ); */
53}
54
55void silk_biquad_alt_stride2_neon(
56 const opus_int16 *in, /* I input signal */
57 const opus_int32 *B_Q28, /* I MA coefficients [3] */
58 const opus_int32 *A_Q28, /* I AR coefficients [2] */
59 opus_int32 *S, /* I/O State vector [4] */
60 opus_int16 *out, /* O output signal */
61 const opus_int32 len /* I signal length (must be even) */
62)
63{
64 /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
65 opus_int k = 0;
66 const int32x2_t offset_s32x2 = vdup_n_s32( (1<<14) - 1 );
67 const int32x4_t offset_s32x4 = vcombine_s32( offset_s32x2, offset_s32x2 );
68 int16x4_t in_s16x4 = vdup_n_s16( 0 );
69 int16x4_t out_s16x4;
70 int32x2_t A_Q28_s32x2, A_L_s32x2, A_U_s32x2, B_Q28_s32x2, t_s32x2;
71 int32x4_t A_L_s32x4, A_U_s32x4, B_Q28_s32x4, S_s32x4, out32_Q14_s32x4;
72 int32x2x2_t t0_s32x2x2, t1_s32x2x2, t2_s32x2x2, S_s32x2x2;
73
74#ifdef OPUS_CHECK_ASM
75 opus_int32 S_c[ 4 ];
76 VARDECL( opus_int16, out_c );
77 SAVE_STACK;
78 ALLOC( out_c, 2 * len, opus_int16 );
79
80 silk_memcpy( &S_c, S, sizeof( S_c ) );
81 silk_biquad_alt_stride2_c( in, B_Q28, A_Q28, S_c, out_c, len );
82#endif
83
84 /* Negate A_Q28 values and split in two parts */
85 A_Q28_s32x2 = vld1_s32( A_Q28 );
86 A_Q28_s32x2 = vneg_s32( A_Q28_s32x2 );
87 A_L_s32x2 = vshl_n_s32( A_Q28_s32x2, 18 ); /* ( -A_Q28[] & 0x00003FFF ) << 18 */
88 A_L_s32x2 = vreinterpret_s32_u32( vshr_n_u32( vreinterpret_u32_s32( A_L_s32x2 ), 3 ) ); /* ( -A_Q28[] & 0x00003FFF ) << 15 */
89 A_U_s32x2 = vshr_n_s32( A_Q28_s32x2, 14 ); /* silk_RSHIFT( -A_Q28[], 14 ) */
90 A_U_s32x2 = vshl_n_s32( A_U_s32x2, 16 ); /* silk_RSHIFT( -A_Q28[], 14 ) << 16 (Clip two leading bits to conform to C function.) */
91 A_U_s32x2 = vshr_n_s32( A_U_s32x2, 1 ); /* silk_RSHIFT( -A_Q28[], 14 ) << 15 */
92
93 B_Q28_s32x2 = vld1_s32( B_Q28 );
94 t_s32x2 = vld1_s32( B_Q28 + 1 );
95 t0_s32x2x2 = vzip_s32( A_L_s32x2, A_L_s32x2 );
96 t1_s32x2x2 = vzip_s32( A_U_s32x2, A_U_s32x2 );
97 t2_s32x2x2 = vzip_s32( t_s32x2, t_s32x2 );
98 A_L_s32x4 = vcombine_s32( t0_s32x2x2.val[ 0 ], t0_s32x2x2.val[ 1 ] ); /* A{0,0,1,1}_L_Q28 */
99 A_U_s32x4 = vcombine_s32( t1_s32x2x2.val[ 0 ], t1_s32x2x2.val[ 1 ] ); /* A{0,0,1,1}_U_Q28 */
100 B_Q28_s32x4 = vcombine_s32( t2_s32x2x2.val[ 0 ], t2_s32x2x2.val[ 1 ] ); /* B_Q28[ {1,1,2,2} ] */
101 S_s32x4 = vld1q_s32( S ); /* S0 = S[ 0 ]; S3 = S[ 3 ]; */
102 S_s32x2x2 = vtrn_s32( vget_low_s32( S_s32x4 ), vget_high_s32( S_s32x4 ) ); /* S2 = S[ 1 ]; S1 = S[ 2 ]; */
103 S_s32x4 = vcombine_s32( S_s32x2x2.val[ 0 ], S_s32x2x2.val[ 1 ] );
104
105 for( ; k < len - 1; k += 2 ) {
106 int32x4_t in_s32x4[ 2 ], t_s32x4;
107 int32x2_t out32_Q14_s32x2[ 2 ];
108
109 /* S[ 2 * i + 0 ], S[ 2 * i + 1 ], S[ 2 * i + 2 ], S[ 2 * i + 3 ]: Q12 */
110 in_s16x4 = vld1_s16( &in[ 2 * k ] ); /* in{0,1,2,3} = in[ 2 * k + {0,1,2,3} ]; */
111 in_s32x4[ 0 ] = vshll_n_s16( in_s16x4, 15 ); /* in{0,1,2,3} << 15 */
112 t_s32x4 = vqdmulhq_lane_s32( in_s32x4[ 0 ], B_Q28_s32x2, 0 ); /* silk_SMULWB( B_Q28[ 0 ], in{0,1,2,3} ) */
113 in_s32x4[ 1 ] = vcombine_s32( vget_high_s32( in_s32x4[ 0 ] ), vget_high_s32( in_s32x4[ 0 ] ) ); /* in{2,3,2,3} << 15 */
114 in_s32x4[ 0 ] = vcombine_s32( vget_low_s32 ( in_s32x4[ 0 ] ), vget_low_s32 ( in_s32x4[ 0 ] ) ); /* in{0,1,0,1} << 15 */
115 silk_biquad_alt_stride2_kernel( A_L_s32x4, A_U_s32x4, B_Q28_s32x4, vget_low_s32 ( t_s32x4 ), in_s32x4[ 0 ], &S_s32x4, &out32_Q14_s32x2[ 0 ] );
116 silk_biquad_alt_stride2_kernel( A_L_s32x4, A_U_s32x4, B_Q28_s32x4, vget_high_s32( t_s32x4 ), in_s32x4[ 1 ], &S_s32x4, &out32_Q14_s32x2[ 1 ] );
117
118 /* Scale back to Q0 and saturate */
119 out32_Q14_s32x4 = vcombine_s32( out32_Q14_s32x2[ 0 ], out32_Q14_s32x2[ 1 ] ); /* out32_Q14_{0,1,2,3} */
120 out32_Q14_s32x4 = vaddq_s32( out32_Q14_s32x4, offset_s32x4 ); /* out32_Q14_{0,1,2,3} + (1<<14) - 1 */
121 out_s16x4 = vqshrn_n_s32( out32_Q14_s32x4, 14 ); /* (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_{0,1,2,3} + (1<<14) - 1, 14 ) ) */
122 vst1_s16( &out[ 2 * k ], out_s16x4 ); /* out[ 2 * k + {0,1,2,3} ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_{0,1,2,3} + (1<<14) - 1, 14 ) ); */
123 }
124
125 /* Process leftover. */
126 if( k < len ) {
127 int32x4_t in_s32x4;
128 int32x2_t out32_Q14_s32x2;
129
130 /* S[ 2 * i + 0 ], S[ 2 * i + 1 ]: Q12 */
131 in_s16x4 = vld1_lane_s16( &in[ 2 * k + 0 ], in_s16x4, 0 ); /* in{0,1} = in[ 2 * k + {0,1} ]; */
132 in_s16x4 = vld1_lane_s16( &in[ 2 * k + 1 ], in_s16x4, 1 ); /* in{0,1} = in[ 2 * k + {0,1} ]; */
133 in_s32x4 = vshll_n_s16( in_s16x4, 15 ); /* in{0,1} << 15 */
134 t_s32x2 = vqdmulh_lane_s32( vget_low_s32( in_s32x4 ), B_Q28_s32x2, 0 ); /* silk_SMULWB( B_Q28[ 0 ], in{0,1} ) */
135 in_s32x4 = vcombine_s32( vget_low_s32( in_s32x4 ), vget_low_s32( in_s32x4 ) ); /* in{0,1,0,1} << 15 */
136 silk_biquad_alt_stride2_kernel( A_L_s32x4, A_U_s32x4, B_Q28_s32x4, t_s32x2, in_s32x4, &S_s32x4, &out32_Q14_s32x2 );
137
138 /* Scale back to Q0 and saturate */
139 out32_Q14_s32x2 = vadd_s32( out32_Q14_s32x2, offset_s32x2 ); /* out32_Q14_{0,1} + (1<<14) - 1 */
140 out32_Q14_s32x4 = vcombine_s32( out32_Q14_s32x2, out32_Q14_s32x2 ); /* out32_Q14_{0,1,0,1} + (1<<14) - 1 */
141 out_s16x4 = vqshrn_n_s32( out32_Q14_s32x4, 14 ); /* (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_{0,1,0,1} + (1<<14) - 1, 14 ) ) */
142 vst1_lane_s16( &out[ 2 * k + 0 ], out_s16x4, 0 ); /* out[ 2 * k + 0 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_0 + (1<<14) - 1, 14 ) ); */
143 vst1_lane_s16( &out[ 2 * k + 1 ], out_s16x4, 1 ); /* out[ 2 * k + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14_1 + (1<<14) - 1, 14 ) ); */
144 }
145
146 vst1q_lane_s32( &S[ 0 ], S_s32x4, 0 ); /* S[ 0 ] = S0; */
147 vst1q_lane_s32( &S[ 1 ], S_s32x4, 2 ); /* S[ 1 ] = S2; */
148 vst1q_lane_s32( &S[ 2 ], S_s32x4, 1 ); /* S[ 2 ] = S1; */
149 vst1q_lane_s32( &S[ 3 ], S_s32x4, 3 ); /* S[ 3 ] = S3; */
150
151#ifdef OPUS_CHECK_ASM
152 silk_assert( !memcmp( S_c, S, sizeof( S_c ) ) );
153 silk_assert( !memcmp( out_c, out, 2 * len * sizeof( opus_int16 ) ) );
154 RESTORE_STACK;
155#endif
156}
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/macros_arm64.h b/lib/rbcodec/codecs/libopus/silk/arm/macros_arm64.h
new file mode 100644
index 0000000000..ed030413c5
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/arm/macros_arm64.h
@@ -0,0 +1,39 @@
1/***********************************************************************
2Copyright (C) 2015 Vidyo
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef SILK_MACROS_ARM64_H
29#define SILK_MACROS_ARM64_H
30
31#include <arm_neon.h>
32
33#undef silk_ADD_SAT32
34#define silk_ADD_SAT32(a, b) (vqadds_s32((a), (b)))
35
36#undef silk_SUB_SAT32
37#define silk_SUB_SAT32(a, b) (vqsubs_s32((a), (b)))
38
39#endif /* SILK_MACROS_ARM64_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/macros_armv4.h b/lib/rbcodec/codecs/libopus/silk/arm/macros_armv4.h
index 3f30e97288..877eb18dd5 100644
--- a/lib/rbcodec/codecs/libopus/silk/arm/macros_armv4.h
+++ b/lib/rbcodec/codecs/libopus/silk/arm/macros_armv4.h
@@ -28,6 +28,11 @@ POSSIBILITY OF SUCH DAMAGE.
28#ifndef SILK_MACROS_ARMv4_H 28#ifndef SILK_MACROS_ARMv4_H
29#define SILK_MACROS_ARMv4_H 29#define SILK_MACROS_ARMv4_H
30 30
31/* This macro only avoids the undefined behaviour from a left shift of
32 a negative value. It should only be used in macros that can't include
33 SigProc_FIX.h. In other cases, use silk_LSHIFT32(). */
34#define SAFE_SHL(a,b) ((opus_int32)((opus_uint32)(a) << (b)))
35
31/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ 36/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
32#undef silk_SMULWB 37#undef silk_SMULWB
33static OPUS_INLINE opus_int32 silk_SMULWB_armv4(opus_int32 a, opus_int16 b) 38static OPUS_INLINE opus_int32 silk_SMULWB_armv4(opus_int32 a, opus_int16 b)
@@ -38,7 +43,7 @@ static OPUS_INLINE opus_int32 silk_SMULWB_armv4(opus_int32 a, opus_int16 b)
38 "#silk_SMULWB\n\t" 43 "#silk_SMULWB\n\t"
39 "smull %0, %1, %2, %3\n\t" 44 "smull %0, %1, %2, %3\n\t"
40 : "=&r"(rd_lo), "=&r"(rd_hi) 45 : "=&r"(rd_lo), "=&r"(rd_hi)
41 : "%r"(a), "r"(b<<16) 46 : "%r"(a), "r"(SAFE_SHL(b,16))
42 ); 47 );
43 return rd_hi; 48 return rd_hi;
44} 49}
@@ -80,7 +85,7 @@ static OPUS_INLINE opus_int32 silk_SMULWW_armv4(opus_int32 a, opus_int32 b)
80 : "=&r"(rd_lo), "=&r"(rd_hi) 85 : "=&r"(rd_lo), "=&r"(rd_hi)
81 : "%r"(a), "r"(b) 86 : "%r"(a), "r"(b)
82 ); 87 );
83 return (rd_hi<<16)+(rd_lo>>16); 88 return SAFE_SHL(rd_hi,16)+(rd_lo>>16);
84} 89}
85#define silk_SMULWW(a, b) (silk_SMULWW_armv4(a, b)) 90#define silk_SMULWW(a, b) (silk_SMULWW_armv4(a, b))
86 91
@@ -96,8 +101,10 @@ static OPUS_INLINE opus_int32 silk_SMLAWW_armv4(opus_int32 a, opus_int32 b,
96 : "=&r"(rd_lo), "=&r"(rd_hi) 101 : "=&r"(rd_lo), "=&r"(rd_hi)
97 : "%r"(b), "r"(c) 102 : "%r"(b), "r"(c)
98 ); 103 );
99 return a+(rd_hi<<16)+(rd_lo>>16); 104 return a+SAFE_SHL(rd_hi,16)+(rd_lo>>16);
100} 105}
101#define silk_SMLAWW(a, b, c) (silk_SMLAWW_armv4(a, b, c)) 106#define silk_SMLAWW(a, b, c) (silk_SMLAWW_armv4(a, b, c))
102 107
108#undef SAFE_SHL
109
103#endif /* SILK_MACROS_ARMv4_H */ 110#endif /* SILK_MACROS_ARMv4_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/arm/macros_armv5e.h b/lib/rbcodec/codecs/libopus/silk/arm/macros_armv5e.h
index aad4117e46..b14ec65ddb 100644
--- a/lib/rbcodec/codecs/libopus/silk/arm/macros_armv5e.h
+++ b/lib/rbcodec/codecs/libopus/silk/arm/macros_armv5e.h
@@ -29,6 +29,11 @@ POSSIBILITY OF SUCH DAMAGE.
29#ifndef SILK_MACROS_ARMv5E_H 29#ifndef SILK_MACROS_ARMv5E_H
30#define SILK_MACROS_ARMv5E_H 30#define SILK_MACROS_ARMv5E_H
31 31
32/* This macro only avoids the undefined behaviour from a left shift of
33 a negative value. It should only be used in macros that can't include
34 SigProc_FIX.h. In other cases, use silk_LSHIFT32(). */
35#define SAFE_SHL(a,b) ((opus_int32)((opus_uint32)(a) << (b)))
36
32/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ 37/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
33#undef silk_SMULWB 38#undef silk_SMULWB
34static OPUS_INLINE opus_int32 silk_SMULWB_armv5e(opus_int32 a, opus_int16 b) 39static OPUS_INLINE opus_int32 silk_SMULWB_armv5e(opus_int32 a, opus_int16 b)
@@ -190,7 +195,7 @@ static OPUS_INLINE opus_int32 silk_CLZ16_armv5(opus_int16 in16)
190 "#silk_CLZ16\n\t" 195 "#silk_CLZ16\n\t"
191 "clz %0, %1;\n" 196 "clz %0, %1;\n"
192 : "=r"(res) 197 : "=r"(res)
193 : "r"(in16<<16|0x8000) 198 : "r"(SAFE_SHL(in16,16)|0x8000)
194 ); 199 );
195 return res; 200 return res;
196} 201}
@@ -210,4 +215,6 @@ static OPUS_INLINE opus_int32 silk_CLZ32_armv5(opus_int32 in32)
210} 215}
211#define silk_CLZ32(in32) (silk_CLZ32_armv5(in32)) 216#define silk_CLZ32(in32) (silk_CLZ32_armv5(in32))
212 217
218#undef SAFE_SHL
219
213#endif /* SILK_MACROS_ARMv5E_H */ 220#endif /* SILK_MACROS_ARMv5E_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/biquad_alt.c b/lib/rbcodec/codecs/libopus/silk/biquad_alt.c
new file mode 100644
index 0000000000..54566a43c0
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/biquad_alt.c
@@ -0,0 +1,121 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28/* *
29 * silk_biquad_alt.c *
30 * *
31 * Second order ARMA filter *
32 * Can handle slowly varying filter coefficients *
33 * */
34
35#ifdef HAVE_CONFIG_H
36#include "config.h"
37#endif
38
39#include "SigProc_FIX.h"
40
41/* Second order ARMA filter, alternative implementation */
42void silk_biquad_alt_stride1(
43 const opus_int16 *in, /* I input signal */
44 const opus_int32 *B_Q28, /* I MA coefficients [3] */
45 const opus_int32 *A_Q28, /* I AR coefficients [2] */
46 opus_int32 *S, /* I/O State vector [2] */
47 opus_int16 *out, /* O output signal */
48 const opus_int32 len /* I signal length (must be even) */
49)
50{
51 /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
52 opus_int k;
53 opus_int32 inval, A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14;
54
55 /* Negate A_Q28 values and split in two parts */
56 A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF; /* lower part */
57 A0_U_Q28 = silk_RSHIFT( -A_Q28[ 0 ], 14 ); /* upper part */
58 A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF; /* lower part */
59 A1_U_Q28 = silk_RSHIFT( -A_Q28[ 1 ], 14 ); /* upper part */
60
61 for( k = 0; k < len; k++ ) {
62 /* S[ 0 ], S[ 1 ]: Q12 */
63 inval = in[ k ];
64 out32_Q14 = silk_LSHIFT( silk_SMLAWB( S[ 0 ], B_Q28[ 0 ], inval ), 2 );
65
66 S[ 0 ] = S[1] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A0_L_Q28 ), 14 );
67 S[ 0 ] = silk_SMLAWB( S[ 0 ], out32_Q14, A0_U_Q28 );
68 S[ 0 ] = silk_SMLAWB( S[ 0 ], B_Q28[ 1 ], inval);
69
70 S[ 1 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A1_L_Q28 ), 14 );
71 S[ 1 ] = silk_SMLAWB( S[ 1 ], out32_Q14, A1_U_Q28 );
72 S[ 1 ] = silk_SMLAWB( S[ 1 ], B_Q28[ 2 ], inval );
73
74 /* Scale back to Q0 and saturate */
75 out[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14 + (1<<14) - 1, 14 ) );
76 }
77}
78
79void silk_biquad_alt_stride2_c(
80 const opus_int16 *in, /* I input signal */
81 const opus_int32 *B_Q28, /* I MA coefficients [3] */
82 const opus_int32 *A_Q28, /* I AR coefficients [2] */
83 opus_int32 *S, /* I/O State vector [4] */
84 opus_int16 *out, /* O output signal */
85 const opus_int32 len /* I signal length (must be even) */
86)
87{
88 /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
89 opus_int k;
90 opus_int32 A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14[ 2 ];
91
92 /* Negate A_Q28 values and split in two parts */
93 A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF; /* lower part */
94 A0_U_Q28 = silk_RSHIFT( -A_Q28[ 0 ], 14 ); /* upper part */
95 A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF; /* lower part */
96 A1_U_Q28 = silk_RSHIFT( -A_Q28[ 1 ], 14 ); /* upper part */
97
98 for( k = 0; k < len; k++ ) {
99 /* S[ 0 ], S[ 1 ], S[ 2 ], S[ 3 ]: Q12 */
100 out32_Q14[ 0 ] = silk_LSHIFT( silk_SMLAWB( S[ 0 ], B_Q28[ 0 ], in[ 2 * k + 0 ] ), 2 );
101 out32_Q14[ 1 ] = silk_LSHIFT( silk_SMLAWB( S[ 2 ], B_Q28[ 0 ], in[ 2 * k + 1 ] ), 2 );
102
103 S[ 0 ] = S[ 1 ] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 0 ], A0_L_Q28 ), 14 );
104 S[ 2 ] = S[ 3 ] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 1 ], A0_L_Q28 ), 14 );
105 S[ 0 ] = silk_SMLAWB( S[ 0 ], out32_Q14[ 0 ], A0_U_Q28 );
106 S[ 2 ] = silk_SMLAWB( S[ 2 ], out32_Q14[ 1 ], A0_U_Q28 );
107 S[ 0 ] = silk_SMLAWB( S[ 0 ], B_Q28[ 1 ], in[ 2 * k + 0 ] );
108 S[ 2 ] = silk_SMLAWB( S[ 2 ], B_Q28[ 1 ], in[ 2 * k + 1 ] );
109
110 S[ 1 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 0 ], A1_L_Q28 ), 14 );
111 S[ 3 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 1 ], A1_L_Q28 ), 14 );
112 S[ 1 ] = silk_SMLAWB( S[ 1 ], out32_Q14[ 0 ], A1_U_Q28 );
113 S[ 3 ] = silk_SMLAWB( S[ 3 ], out32_Q14[ 1 ], A1_U_Q28 );
114 S[ 1 ] = silk_SMLAWB( S[ 1 ], B_Q28[ 2 ], in[ 2 * k + 0 ] );
115 S[ 3 ] = silk_SMLAWB( S[ 3 ], B_Q28[ 2 ], in[ 2 * k + 1 ] );
116
117 /* Scale back to Q0 and saturate */
118 out[ 2 * k + 0 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14[ 0 ] + (1<<14) - 1, 14 ) );
119 out[ 2 * k + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14[ 1 ] + (1<<14) - 1, 14 ) );
120 }
121}
diff --git a/lib/rbcodec/codecs/libopus/silk/bwexpander.c b/lib/rbcodec/codecs/libopus/silk/bwexpander.c
index 2eb4456695..afa97907ec 100644
--- a/lib/rbcodec/codecs/libopus/silk/bwexpander.c
+++ b/lib/rbcodec/codecs/libopus/silk/bwexpander.c
@@ -45,7 +45,7 @@ void silk_bwexpander(
45 /* Bias in silk_SMULWB can lead to unstable filters */ 45 /* Bias in silk_SMULWB can lead to unstable filters */
46 for( i = 0; i < d - 1; i++ ) { 46 for( i = 0; i < d - 1; i++ ) {
47 ar[ i ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ i ] ), 16 ); 47 ar[ i ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ i ] ), 16 );
48 chirp_Q16 += silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 ); 48 chirp_Q16 += silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 );
49 } 49 }
50 ar[ d - 1 ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ d - 1 ] ), 16 ); 50 ar[ d - 1 ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ d - 1 ] ), 16 );
51} 51}
diff --git a/lib/rbcodec/codecs/libopus/silk/check_control_input.c b/lib/rbcodec/codecs/libopus/silk/check_control_input.c
new file mode 100644
index 0000000000..739fb01f1e
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/check_control_input.c
@@ -0,0 +1,106 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33#include "control.h"
34#include "errors.h"
35
36/* Check encoder control struct */
37opus_int check_control_input(
38 silk_EncControlStruct *encControl /* I Control structure */
39)
40{
41 celt_assert( encControl != NULL );
42
43 if( ( ( encControl->API_sampleRate != 8000 ) &&
44 ( encControl->API_sampleRate != 12000 ) &&
45 ( encControl->API_sampleRate != 16000 ) &&
46 ( encControl->API_sampleRate != 24000 ) &&
47 ( encControl->API_sampleRate != 32000 ) &&
48 ( encControl->API_sampleRate != 44100 ) &&
49 ( encControl->API_sampleRate != 48000 ) ) ||
50 ( ( encControl->desiredInternalSampleRate != 8000 ) &&
51 ( encControl->desiredInternalSampleRate != 12000 ) &&
52 ( encControl->desiredInternalSampleRate != 16000 ) ) ||
53 ( ( encControl->maxInternalSampleRate != 8000 ) &&
54 ( encControl->maxInternalSampleRate != 12000 ) &&
55 ( encControl->maxInternalSampleRate != 16000 ) ) ||
56 ( ( encControl->minInternalSampleRate != 8000 ) &&
57 ( encControl->minInternalSampleRate != 12000 ) &&
58 ( encControl->minInternalSampleRate != 16000 ) ) ||
59 ( encControl->minInternalSampleRate > encControl->desiredInternalSampleRate ) ||
60 ( encControl->maxInternalSampleRate < encControl->desiredInternalSampleRate ) ||
61 ( encControl->minInternalSampleRate > encControl->maxInternalSampleRate ) ) {
62 celt_assert( 0 );
63 return SILK_ENC_FS_NOT_SUPPORTED;
64 }
65 if( encControl->payloadSize_ms != 10 &&
66 encControl->payloadSize_ms != 20 &&
67 encControl->payloadSize_ms != 40 &&
68 encControl->payloadSize_ms != 60 ) {
69 celt_assert( 0 );
70 return SILK_ENC_PACKET_SIZE_NOT_SUPPORTED;
71 }
72 if( encControl->packetLossPercentage < 0 || encControl->packetLossPercentage > 100 ) {
73 celt_assert( 0 );
74 return SILK_ENC_INVALID_LOSS_RATE;
75 }
76 if( encControl->useDTX < 0 || encControl->useDTX > 1 ) {
77 celt_assert( 0 );
78 return SILK_ENC_INVALID_DTX_SETTING;
79 }
80 if( encControl->useCBR < 0 || encControl->useCBR > 1 ) {
81 celt_assert( 0 );
82 return SILK_ENC_INVALID_CBR_SETTING;
83 }
84 if( encControl->useInBandFEC < 0 || encControl->useInBandFEC > 1 ) {
85 celt_assert( 0 );
86 return SILK_ENC_INVALID_INBAND_FEC_SETTING;
87 }
88 if( encControl->nChannelsAPI < 1 || encControl->nChannelsAPI > ENCODER_NUM_CHANNELS ) {
89 celt_assert( 0 );
90 return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR;
91 }
92 if( encControl->nChannelsInternal < 1 || encControl->nChannelsInternal > ENCODER_NUM_CHANNELS ) {
93 celt_assert( 0 );
94 return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR;
95 }
96 if( encControl->nChannelsInternal > encControl->nChannelsAPI ) {
97 celt_assert( 0 );
98 return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR;
99 }
100 if( encControl->complexity < 0 || encControl->complexity > 10 ) {
101 celt_assert( 0 );
102 return SILK_ENC_INVALID_COMPLEXITY_SETTING;
103 }
104
105 return SILK_NO_ERROR;
106}
diff --git a/lib/rbcodec/codecs/libopus/silk/code_signs.c b/lib/rbcodec/codecs/libopus/silk/code_signs.c
index 6ac25cb389..dfd1dca9a1 100644
--- a/lib/rbcodec/codecs/libopus/silk/code_signs.c
+++ b/lib/rbcodec/codecs/libopus/silk/code_signs.c
@@ -37,7 +37,6 @@ POSSIBILITY OF SUCH DAMAGE.
37#define silk_enc_map(a) ( silk_RSHIFT( (a), 15 ) + 1 ) 37#define silk_enc_map(a) ( silk_RSHIFT( (a), 15 ) + 1 )
38#define silk_dec_map(a) ( silk_LSHIFT( (a), 1 ) - 1 ) 38#define silk_dec_map(a) ( silk_LSHIFT( (a), 1 ) - 1 )
39 39
40#if 0
41/* Encodes signs of excitation */ 40/* Encodes signs of excitation */
42void silk_encode_signs( 41void silk_encode_signs(
43 ec_enc *psRangeEnc, /* I/O Compressor data structure */ 42 ec_enc *psRangeEnc, /* I/O Compressor data structure */
@@ -71,7 +70,6 @@ void silk_encode_signs(
71 q_ptr += SHELL_CODEC_FRAME_LENGTH; 70 q_ptr += SHELL_CODEC_FRAME_LENGTH;
72 } 71 }
73} 72}
74#endif
75 73
76/* Decodes signs of excitation */ 74/* Decodes signs of excitation */
77void silk_decode_signs( 75void silk_decode_signs(
diff --git a/lib/rbcodec/codecs/libopus/silk/control.h b/lib/rbcodec/codecs/libopus/silk/control.h
index 747e5426a0..b76ec33cd6 100644
--- a/lib/rbcodec/codecs/libopus/silk/control.h
+++ b/lib/rbcodec/codecs/libopus/silk/control.h
@@ -77,6 +77,9 @@ typedef struct {
77 /* I: Flag to enable in-band Forward Error Correction (FEC); 0/1 */ 77 /* I: Flag to enable in-band Forward Error Correction (FEC); 0/1 */
78 opus_int useInBandFEC; 78 opus_int useInBandFEC;
79 79
80 /* I: Flag to actually code in-band Forward Error Correction (FEC) in the current packet; 0/1 */
81 opus_int LBRR_coded;
82
80 /* I: Flag to enable discontinuous transmission (DTX); 0/1 */ 83 /* I: Flag to enable discontinuous transmission (DTX); 0/1 */
81 opus_int useDTX; 84 opus_int useDTX;
82 85
@@ -110,6 +113,11 @@ typedef struct {
110 /* O: Tells the Opus encoder we're ready to switch */ 113 /* O: Tells the Opus encoder we're ready to switch */
111 opus_int switchReady; 114 opus_int switchReady;
112 115
116 /* O: SILK Signal type */
117 opus_int signalType;
118
119 /* O: SILK offset (dithering) */
120 opus_int offset;
113} silk_EncControlStruct; 121} silk_EncControlStruct;
114 122
115/**************************************************************************/ 123/**************************************************************************/
diff --git a/lib/rbcodec/codecs/libopus/silk/control_SNR.c b/lib/rbcodec/codecs/libopus/silk/control_SNR.c
new file mode 100644
index 0000000000..9a6db27543
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/control_SNR.c
@@ -0,0 +1,113 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33#include "tuning_parameters.h"
34
35/* These tables hold SNR values divided by 21 (so they fit in 8 bits)
36 for different target bitrates spaced at 400 bps interval. The first
37 10 values are omitted (0-4 kb/s) because they're all zeros.
38 These tables were obtained by running different SNRs through the
39 encoder and measuring the active bitrate. */
40static const unsigned char silk_TargetRate_NB_21[117 - 10] = {
41 0, 15, 39, 52, 61, 68,
42 74, 79, 84, 88, 92, 95, 99,102,105,108,111,114,117,119,122,124,
43 126,129,131,133,135,137,139,142,143,145,147,149,151,153,155,157,
44 158,160,162,163,165,167,168,170,171,173,174,176,177,179,180,182,
45 183,185,186,187,189,190,192,193,194,196,197,199,200,201,203,204,
46 205,207,208,209,211,212,213,215,216,217,219,220,221,223,224,225,
47 227,228,230,231,232,234,235,236,238,239,241,242,243,245,246,248,
48 249,250,252,253,255
49};
50
51static const unsigned char silk_TargetRate_MB_21[165 - 10] = {
52 0, 0, 28, 43, 52, 59,
53 65, 70, 74, 78, 81, 85, 87, 90, 93, 95, 98,100,102,105,107,109,
54 111,113,115,116,118,120,122,123,125,127,128,130,131,133,134,136,
55 137,138,140,141,143,144,145,147,148,149,151,152,153,154,156,157,
56 158,159,160,162,163,164,165,166,167,168,169,171,172,173,174,175,
57 176,177,178,179,180,181,182,183,184,185,186,187,188,188,189,190,
58 191,192,193,194,195,196,197,198,199,200,201,202,203,203,204,205,
59 206,207,208,209,210,211,212,213,214,214,215,216,217,218,219,220,
60 221,222,223,224,224,225,226,227,228,229,230,231,232,233,234,235,
61 236,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,
62 251,252,253,254,255
63};
64
65static const unsigned char silk_TargetRate_WB_21[201 - 10] = {
66 0, 0, 0, 8, 29, 41,
67 49, 56, 62, 66, 70, 74, 77, 80, 83, 86, 88, 91, 93, 95, 97, 99,
68 101,103,105,107,108,110,112,113,115,116,118,119,121,122,123,125,
69 126,127,129,130,131,132,134,135,136,137,138,140,141,142,143,144,
70 145,146,147,148,149,150,151,152,153,154,156,157,158,159,159,160,
71 161,162,163,164,165,166,167,168,169,170,171,171,172,173,174,175,
72 176,177,177,178,179,180,181,181,182,183,184,185,185,186,187,188,
73 189,189,190,191,192,192,193,194,195,195,196,197,198,198,199,200,
74 200,201,202,203,203,204,205,206,206,207,208,209,209,210,211,211,
75 212,213,214,214,215,216,216,217,218,219,219,220,221,221,222,223,
76 224,224,225,226,226,227,228,229,229,230,231,232,232,233,234,234,
77 235,236,237,237,238,239,240,240,241,242,243,243,244,245,246,246,
78 247,248,249,249,250,251,252,253,255
79};
80
81/* Control SNR of redidual quantizer */
82opus_int silk_control_SNR(
83 silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */
84 opus_int32 TargetRate_bps /* I Target max bitrate (bps) */
85)
86{
87 int id;
88 int bound;
89 const unsigned char *snr_table;
90
91 psEncC->TargetRate_bps = TargetRate_bps;
92 if( psEncC->nb_subfr == 2 ) {
93 TargetRate_bps -= 2000 + psEncC->fs_kHz/16;
94 }
95 if( psEncC->fs_kHz == 8 ) {
96 bound = sizeof(silk_TargetRate_NB_21);
97 snr_table = silk_TargetRate_NB_21;
98 } else if( psEncC->fs_kHz == 12 ) {
99 bound = sizeof(silk_TargetRate_MB_21);
100 snr_table = silk_TargetRate_MB_21;
101 } else {
102 bound = sizeof(silk_TargetRate_WB_21);
103 snr_table = silk_TargetRate_WB_21;
104 }
105 id = (TargetRate_bps+200)/400;
106 id = silk_min(id - 10, bound-1);
107 if( id <= 0 ) {
108 psEncC->SNR_dB_Q7 = 0;
109 } else {
110 psEncC->SNR_dB_Q7 = snr_table[id]*21;
111 }
112 return SILK_NO_ERROR;
113}
diff --git a/lib/rbcodec/codecs/libopus/silk/control_audio_bandwidth.c b/lib/rbcodec/codecs/libopus/silk/control_audio_bandwidth.c
new file mode 100644
index 0000000000..f6d22d8395
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/control_audio_bandwidth.c
@@ -0,0 +1,132 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33#include "tuning_parameters.h"
34
35/* Control internal sampling rate */
36opus_int silk_control_audio_bandwidth(
37 silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */
38 silk_EncControlStruct *encControl /* I Control structure */
39)
40{
41 opus_int fs_kHz;
42 opus_int orig_kHz;
43 opus_int32 fs_Hz;
44
45 orig_kHz = psEncC->fs_kHz;
46 /* Handle a bandwidth-switching reset where we need to be aware what the last sampling rate was. */
47 if( orig_kHz == 0 ) {
48 orig_kHz = psEncC->sLP.saved_fs_kHz;
49 }
50 fs_kHz = orig_kHz;
51 fs_Hz = silk_SMULBB( fs_kHz, 1000 );
52 if( fs_Hz == 0 ) {
53 /* Encoder has just been initialized */
54 fs_Hz = silk_min( psEncC->desiredInternal_fs_Hz, psEncC->API_fs_Hz );
55 fs_kHz = silk_DIV32_16( fs_Hz, 1000 );
56 } else if( fs_Hz > psEncC->API_fs_Hz || fs_Hz > psEncC->maxInternal_fs_Hz || fs_Hz < psEncC->minInternal_fs_Hz ) {
57 /* Make sure internal rate is not higher than external rate or maximum allowed, or lower than minimum allowed */
58 fs_Hz = psEncC->API_fs_Hz;
59 fs_Hz = silk_min( fs_Hz, psEncC->maxInternal_fs_Hz );
60 fs_Hz = silk_max( fs_Hz, psEncC->minInternal_fs_Hz );
61 fs_kHz = silk_DIV32_16( fs_Hz, 1000 );
62 } else {
63 /* State machine for the internal sampling rate switching */
64 if( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES ) {
65 /* Stop transition phase */
66 psEncC->sLP.mode = 0;
67 }
68 if( psEncC->allow_bandwidth_switch || encControl->opusCanSwitch ) {
69 /* Check if we should switch down */
70 if( silk_SMULBB( orig_kHz, 1000 ) > psEncC->desiredInternal_fs_Hz )
71 {
72 /* Switch down */
73 if( psEncC->sLP.mode == 0 ) {
74 /* New transition */
75 psEncC->sLP.transition_frame_no = TRANSITION_FRAMES;
76
77 /* Reset transition filter state */
78 silk_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) );
79 }
80 if( encControl->opusCanSwitch ) {
81 /* Stop transition phase */
82 psEncC->sLP.mode = 0;
83
84 /* Switch to a lower sample frequency */
85 fs_kHz = orig_kHz == 16 ? 12 : 8;
86 } else {
87 if( psEncC->sLP.transition_frame_no <= 0 ) {
88 encControl->switchReady = 1;
89 /* Make room for redundancy */
90 encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 );
91 } else {
92 /* Direction: down (at double speed) */
93 psEncC->sLP.mode = -2;
94 }
95 }
96 }
97 else
98 /* Check if we should switch up */
99 if( silk_SMULBB( orig_kHz, 1000 ) < psEncC->desiredInternal_fs_Hz )
100 {
101 /* Switch up */
102 if( encControl->opusCanSwitch ) {
103 /* Switch to a higher sample frequency */
104 fs_kHz = orig_kHz == 8 ? 12 : 16;
105
106 /* New transition */
107 psEncC->sLP.transition_frame_no = 0;
108
109 /* Reset transition filter state */
110 silk_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) );
111
112 /* Direction: up */
113 psEncC->sLP.mode = 1;
114 } else {
115 if( psEncC->sLP.mode == 0 ) {
116 encControl->switchReady = 1;
117 /* Make room for redundancy */
118 encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 );
119 } else {
120 /* Direction: up */
121 psEncC->sLP.mode = 1;
122 }
123 }
124 } else {
125 if (psEncC->sLP.mode<0)
126 psEncC->sLP.mode = 1;
127 }
128 }
129 }
130
131 return fs_kHz;
132}
diff --git a/lib/rbcodec/codecs/libopus/silk/control_codec.c b/lib/rbcodec/codecs/libopus/silk/control_codec.c
new file mode 100644
index 0000000000..52aa8fded3
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/control_codec.c
@@ -0,0 +1,423 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31#ifdef FIXED_POINT
32#include "main_FIX.h"
33#define silk_encoder_state_Fxx silk_encoder_state_FIX
34#else
35#include "main_FLP.h"
36#define silk_encoder_state_Fxx silk_encoder_state_FLP
37#endif
38#include "stack_alloc.h"
39#include "tuning_parameters.h"
40#include "pitch_est_defines.h"
41
42static opus_int silk_setup_resamplers(
43 silk_encoder_state_Fxx *psEnc, /* I/O */
44 opus_int fs_kHz /* I */
45);
46
47static opus_int silk_setup_fs(
48 silk_encoder_state_Fxx *psEnc, /* I/O */
49 opus_int fs_kHz, /* I */
50 opus_int PacketSize_ms /* I */
51);
52
53static opus_int silk_setup_complexity(
54 silk_encoder_state *psEncC, /* I/O */
55 opus_int Complexity /* I */
56);
57
58static OPUS_INLINE opus_int silk_setup_LBRR(
59 silk_encoder_state *psEncC, /* I/O */
60 const silk_EncControlStruct *encControl /* I */
61);
62
63
64/* Control encoder */
65opus_int silk_control_encoder(
66 silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */
67 silk_EncControlStruct *encControl, /* I Control structure */
68 const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */
69 const opus_int channelNb, /* I Channel number */
70 const opus_int force_fs_kHz
71)
72{
73 opus_int fs_kHz, ret = 0;
74
75 psEnc->sCmn.useDTX = encControl->useDTX;
76 psEnc->sCmn.useCBR = encControl->useCBR;
77 psEnc->sCmn.API_fs_Hz = encControl->API_sampleRate;
78 psEnc->sCmn.maxInternal_fs_Hz = encControl->maxInternalSampleRate;
79 psEnc->sCmn.minInternal_fs_Hz = encControl->minInternalSampleRate;
80 psEnc->sCmn.desiredInternal_fs_Hz = encControl->desiredInternalSampleRate;
81 psEnc->sCmn.useInBandFEC = encControl->useInBandFEC;
82 psEnc->sCmn.nChannelsAPI = encControl->nChannelsAPI;
83 psEnc->sCmn.nChannelsInternal = encControl->nChannelsInternal;
84 psEnc->sCmn.allow_bandwidth_switch = allow_bw_switch;
85 psEnc->sCmn.channelNb = channelNb;
86
87 if( psEnc->sCmn.controlled_since_last_payload != 0 && psEnc->sCmn.prefillFlag == 0 ) {
88 if( psEnc->sCmn.API_fs_Hz != psEnc->sCmn.prev_API_fs_Hz && psEnc->sCmn.fs_kHz > 0 ) {
89 /* Change in API sampling rate in the middle of encoding a packet */
90 ret += silk_setup_resamplers( psEnc, psEnc->sCmn.fs_kHz );
91 }
92 return ret;
93 }
94
95 /* Beyond this point we know that there are no previously coded frames in the payload buffer */
96
97 /********************************************/
98 /* Determine internal sampling rate */
99 /********************************************/
100 fs_kHz = silk_control_audio_bandwidth( &psEnc->sCmn, encControl );
101 if( force_fs_kHz ) {
102 fs_kHz = force_fs_kHz;
103 }
104 /********************************************/
105 /* Prepare resampler and buffered data */
106 /********************************************/
107 ret += silk_setup_resamplers( psEnc, fs_kHz );
108
109 /********************************************/
110 /* Set internal sampling frequency */
111 /********************************************/
112 ret += silk_setup_fs( psEnc, fs_kHz, encControl->payloadSize_ms );
113
114 /********************************************/
115 /* Set encoding complexity */
116 /********************************************/
117 ret += silk_setup_complexity( &psEnc->sCmn, encControl->complexity );
118
119 /********************************************/
120 /* Set packet loss rate measured by farend */
121 /********************************************/
122 psEnc->sCmn.PacketLoss_perc = encControl->packetLossPercentage;
123
124 /********************************************/
125 /* Set LBRR usage */
126 /********************************************/
127 ret += silk_setup_LBRR( &psEnc->sCmn, encControl );
128
129 psEnc->sCmn.controlled_since_last_payload = 1;
130
131 return ret;
132}
133
134static opus_int silk_setup_resamplers(
135 silk_encoder_state_Fxx *psEnc, /* I/O */
136 opus_int fs_kHz /* I */
137)
138{
139 opus_int ret = SILK_NO_ERROR;
140 SAVE_STACK;
141
142 if( psEnc->sCmn.fs_kHz != fs_kHz || psEnc->sCmn.prev_API_fs_Hz != psEnc->sCmn.API_fs_Hz )
143 {
144 if( psEnc->sCmn.fs_kHz == 0 ) {
145 /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
146 ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, fs_kHz * 1000, 1 );
147 } else {
148 VARDECL( opus_int16, x_buf_API_fs_Hz );
149 VARDECL( silk_resampler_state_struct, temp_resampler_state );
150#ifdef FIXED_POINT
151 opus_int16 *x_bufFIX = psEnc->x_buf;
152#else
153 VARDECL( opus_int16, x_bufFIX );
154 opus_int32 new_buf_samples;
155#endif
156 opus_int32 api_buf_samples;
157 opus_int32 old_buf_samples;
158 opus_int32 buf_length_ms;
159
160 buf_length_ms = silk_LSHIFT( psEnc->sCmn.nb_subfr * 5, 1 ) + LA_SHAPE_MS;
161 old_buf_samples = buf_length_ms * psEnc->sCmn.fs_kHz;
162
163#ifndef FIXED_POINT
164 new_buf_samples = buf_length_ms * fs_kHz;
165 ALLOC( x_bufFIX, silk_max( old_buf_samples, new_buf_samples ),
166 opus_int16 );
167 silk_float2short_array( x_bufFIX, psEnc->x_buf, old_buf_samples );
168#endif
169
170 /* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */
171 ALLOC( temp_resampler_state, 1, silk_resampler_state_struct );
172 ret += silk_resampler_init( temp_resampler_state, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ), psEnc->sCmn.API_fs_Hz, 0 );
173
174 /* Calculate number of samples to temporarily upsample */
175 api_buf_samples = buf_length_ms * silk_DIV32_16( psEnc->sCmn.API_fs_Hz, 1000 );
176
177 /* Temporary resampling of x_buf data to API_fs_Hz */
178 ALLOC( x_buf_API_fs_Hz, api_buf_samples, opus_int16 );
179 ret += silk_resampler( temp_resampler_state, x_buf_API_fs_Hz, x_bufFIX, old_buf_samples );
180
181 /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */
182 ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, silk_SMULBB( fs_kHz, 1000 ), 1 );
183
184 /* Correct resampler state by resampling buffered data from API_fs_Hz to fs_kHz */
185 ret += silk_resampler( &psEnc->sCmn.resampler_state, x_bufFIX, x_buf_API_fs_Hz, api_buf_samples );
186
187#ifndef FIXED_POINT
188 silk_short2float_array( psEnc->x_buf, x_bufFIX, new_buf_samples);
189#endif
190 }
191 }
192
193 psEnc->sCmn.prev_API_fs_Hz = psEnc->sCmn.API_fs_Hz;
194
195 RESTORE_STACK;
196 return ret;
197}
198
199static opus_int silk_setup_fs(
200 silk_encoder_state_Fxx *psEnc, /* I/O */
201 opus_int fs_kHz, /* I */
202 opus_int PacketSize_ms /* I */
203)
204{
205 opus_int ret = SILK_NO_ERROR;
206
207 /* Set packet size */
208 if( PacketSize_ms != psEnc->sCmn.PacketSize_ms ) {
209 if( ( PacketSize_ms != 10 ) &&
210 ( PacketSize_ms != 20 ) &&
211 ( PacketSize_ms != 40 ) &&
212 ( PacketSize_ms != 60 ) ) {
213 ret = SILK_ENC_PACKET_SIZE_NOT_SUPPORTED;
214 }
215 if( PacketSize_ms <= 10 ) {
216 psEnc->sCmn.nFramesPerPacket = 1;
217 psEnc->sCmn.nb_subfr = PacketSize_ms == 10 ? 2 : 1;
218 psEnc->sCmn.frame_length = silk_SMULBB( PacketSize_ms, fs_kHz );
219 psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz );
220 if( psEnc->sCmn.fs_kHz == 8 ) {
221 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF;
222 } else {
223 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF;
224 }
225 } else {
226 psEnc->sCmn.nFramesPerPacket = silk_DIV32_16( PacketSize_ms, MAX_FRAME_LENGTH_MS );
227 psEnc->sCmn.nb_subfr = MAX_NB_SUBFR;
228 psEnc->sCmn.frame_length = silk_SMULBB( 20, fs_kHz );
229 psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz );
230 if( psEnc->sCmn.fs_kHz == 8 ) {
231 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_NB_iCDF;
232 } else {
233 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_iCDF;
234 }
235 }
236 psEnc->sCmn.PacketSize_ms = PacketSize_ms;
237 psEnc->sCmn.TargetRate_bps = 0; /* trigger new SNR computation */
238 }
239
240 /* Set internal sampling frequency */
241 celt_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );
242 celt_assert( psEnc->sCmn.nb_subfr == 2 || psEnc->sCmn.nb_subfr == 4 );
243 if( psEnc->sCmn.fs_kHz != fs_kHz ) {
244 /* reset part of the state */
245 silk_memset( &psEnc->sShape, 0, sizeof( psEnc->sShape ) );
246 silk_memset( &psEnc->sCmn.sNSQ, 0, sizeof( psEnc->sCmn.sNSQ ) );
247 silk_memset( psEnc->sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );
248 silk_memset( &psEnc->sCmn.sLP.In_LP_State, 0, sizeof( psEnc->sCmn.sLP.In_LP_State ) );
249 psEnc->sCmn.inputBufIx = 0;
250 psEnc->sCmn.nFramesEncoded = 0;
251 psEnc->sCmn.TargetRate_bps = 0; /* trigger new SNR computation */
252
253 /* Initialize non-zero parameters */
254 psEnc->sCmn.prevLag = 100;
255 psEnc->sCmn.first_frame_after_reset = 1;
256 psEnc->sShape.LastGainIndex = 10;
257 psEnc->sCmn.sNSQ.lagPrev = 100;
258 psEnc->sCmn.sNSQ.prev_gain_Q16 = 65536;
259 psEnc->sCmn.prevSignalType = TYPE_NO_VOICE_ACTIVITY;
260
261 psEnc->sCmn.fs_kHz = fs_kHz;
262 if( psEnc->sCmn.fs_kHz == 8 ) {
263 if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) {
264 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_NB_iCDF;
265 } else {
266 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF;
267 }
268 } else {
269 if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) {
270 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_iCDF;
271 } else {
272 psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF;
273 }
274 }
275 if( psEnc->sCmn.fs_kHz == 8 || psEnc->sCmn.fs_kHz == 12 ) {
276 psEnc->sCmn.predictLPCOrder = MIN_LPC_ORDER;
277 psEnc->sCmn.psNLSF_CB = &silk_NLSF_CB_NB_MB;
278 } else {
279 psEnc->sCmn.predictLPCOrder = MAX_LPC_ORDER;
280 psEnc->sCmn.psNLSF_CB = &silk_NLSF_CB_WB;
281 }
282 psEnc->sCmn.subfr_length = SUB_FRAME_LENGTH_MS * fs_kHz;
283 psEnc->sCmn.frame_length = silk_SMULBB( psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr );
284 psEnc->sCmn.ltp_mem_length = silk_SMULBB( LTP_MEM_LENGTH_MS, fs_kHz );
285 psEnc->sCmn.la_pitch = silk_SMULBB( LA_PITCH_MS, fs_kHz );
286 psEnc->sCmn.max_pitch_lag = silk_SMULBB( 18, fs_kHz );
287 if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) {
288 psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz );
289 } else {
290 psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz );
291 }
292 if( psEnc->sCmn.fs_kHz == 16 ) {
293 psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform8_iCDF;
294 } else if( psEnc->sCmn.fs_kHz == 12 ) {
295 psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform6_iCDF;
296 } else {
297 psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform4_iCDF;
298 }
299 }
300
301 /* Check that settings are valid */
302 celt_assert( ( psEnc->sCmn.subfr_length * psEnc->sCmn.nb_subfr ) == psEnc->sCmn.frame_length );
303
304 return ret;
305}
306
307static opus_int silk_setup_complexity(
308 silk_encoder_state *psEncC, /* I/O */
309 opus_int Complexity /* I */
310)
311{
312 opus_int ret = 0;
313
314 /* Set encoding complexity */
315 celt_assert( Complexity >= 0 && Complexity <= 10 );
316 if( Complexity < 1 ) {
317 psEncC->pitchEstimationComplexity = SILK_PE_MIN_COMPLEX;
318 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.8, 16 );
319 psEncC->pitchEstimationLPCOrder = 6;
320 psEncC->shapingLPCOrder = 12;
321 psEncC->la_shape = 3 * psEncC->fs_kHz;
322 psEncC->nStatesDelayedDecision = 1;
323 psEncC->useInterpolatedNLSFs = 0;
324 psEncC->NLSF_MSVQ_Survivors = 2;
325 psEncC->warping_Q16 = 0;
326 } else if( Complexity < 2 ) {
327 psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
328 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.76, 16 );
329 psEncC->pitchEstimationLPCOrder = 8;
330 psEncC->shapingLPCOrder = 14;
331 psEncC->la_shape = 5 * psEncC->fs_kHz;
332 psEncC->nStatesDelayedDecision = 1;
333 psEncC->useInterpolatedNLSFs = 0;
334 psEncC->NLSF_MSVQ_Survivors = 3;
335 psEncC->warping_Q16 = 0;
336 } else if( Complexity < 3 ) {
337 psEncC->pitchEstimationComplexity = SILK_PE_MIN_COMPLEX;
338 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.8, 16 );
339 psEncC->pitchEstimationLPCOrder = 6;
340 psEncC->shapingLPCOrder = 12;
341 psEncC->la_shape = 3 * psEncC->fs_kHz;
342 psEncC->nStatesDelayedDecision = 2;
343 psEncC->useInterpolatedNLSFs = 0;
344 psEncC->NLSF_MSVQ_Survivors = 2;
345 psEncC->warping_Q16 = 0;
346 } else if( Complexity < 4 ) {
347 psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
348 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.76, 16 );
349 psEncC->pitchEstimationLPCOrder = 8;
350 psEncC->shapingLPCOrder = 14;
351 psEncC->la_shape = 5 * psEncC->fs_kHz;
352 psEncC->nStatesDelayedDecision = 2;
353 psEncC->useInterpolatedNLSFs = 0;
354 psEncC->NLSF_MSVQ_Survivors = 4;
355 psEncC->warping_Q16 = 0;
356 } else if( Complexity < 6 ) {
357 psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
358 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.74, 16 );
359 psEncC->pitchEstimationLPCOrder = 10;
360 psEncC->shapingLPCOrder = 16;
361 psEncC->la_shape = 5 * psEncC->fs_kHz;
362 psEncC->nStatesDelayedDecision = 2;
363 psEncC->useInterpolatedNLSFs = 1;
364 psEncC->NLSF_MSVQ_Survivors = 6;
365 psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
366 } else if( Complexity < 8 ) {
367 psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
368 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.72, 16 );
369 psEncC->pitchEstimationLPCOrder = 12;
370 psEncC->shapingLPCOrder = 20;
371 psEncC->la_shape = 5 * psEncC->fs_kHz;
372 psEncC->nStatesDelayedDecision = 3;
373 psEncC->useInterpolatedNLSFs = 1;
374 psEncC->NLSF_MSVQ_Survivors = 8;
375 psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
376 } else {
377 psEncC->pitchEstimationComplexity = SILK_PE_MAX_COMPLEX;
378 psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.7, 16 );
379 psEncC->pitchEstimationLPCOrder = 16;
380 psEncC->shapingLPCOrder = 24;
381 psEncC->la_shape = 5 * psEncC->fs_kHz;
382 psEncC->nStatesDelayedDecision = MAX_DEL_DEC_STATES;
383 psEncC->useInterpolatedNLSFs = 1;
384 psEncC->NLSF_MSVQ_Survivors = 16;
385 psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
386 }
387
388 /* Do not allow higher pitch estimation LPC order than predict LPC order */
389 psEncC->pitchEstimationLPCOrder = silk_min_int( psEncC->pitchEstimationLPCOrder, psEncC->predictLPCOrder );
390 psEncC->shapeWinLength = SUB_FRAME_LENGTH_MS * psEncC->fs_kHz + 2 * psEncC->la_shape;
391 psEncC->Complexity = Complexity;
392
393 celt_assert( psEncC->pitchEstimationLPCOrder <= MAX_FIND_PITCH_LPC_ORDER );
394 celt_assert( psEncC->shapingLPCOrder <= MAX_SHAPE_LPC_ORDER );
395 celt_assert( psEncC->nStatesDelayedDecision <= MAX_DEL_DEC_STATES );
396 celt_assert( psEncC->warping_Q16 <= 32767 );
397 celt_assert( psEncC->la_shape <= LA_SHAPE_MAX );
398 celt_assert( psEncC->shapeWinLength <= SHAPE_LPC_WIN_MAX );
399
400 return ret;
401}
402
403static OPUS_INLINE opus_int silk_setup_LBRR(
404 silk_encoder_state *psEncC, /* I/O */
405 const silk_EncControlStruct *encControl /* I */
406)
407{
408 opus_int LBRR_in_previous_packet, ret = SILK_NO_ERROR;
409
410 LBRR_in_previous_packet = psEncC->LBRR_enabled;
411 psEncC->LBRR_enabled = encControl->LBRR_coded;
412 if( psEncC->LBRR_enabled ) {
413 /* Set gain increase for coding LBRR excitation */
414 if( LBRR_in_previous_packet == 0 ) {
415 /* Previous packet did not have LBRR, and was therefore coded at a higher bitrate */
416 psEncC->LBRR_GainIncreases = 7;
417 } else {
418 psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( (opus_int32)psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.4, 16 ) ), 2 );
419 }
420 }
421
422 return ret;
423}
diff --git a/lib/rbcodec/codecs/libopus/silk/debug.c b/lib/rbcodec/codecs/libopus/silk/debug.c
new file mode 100644
index 0000000000..9253faf71b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/debug.c
@@ -0,0 +1,170 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "debug.h"
33#include "SigProc_FIX.h"
34
35#if SILK_TIC_TOC
36
37#ifdef _WIN32
38
39#if (defined(_WIN32) || defined(_WINCE))
40#include <windows.h> /* timer */
41#else /* Linux or Mac*/
42#include <sys/time.h>
43#endif
44
45unsigned long silk_GetHighResolutionTime(void) /* O time in usec*/
46{
47 /* Returns a time counter in microsec */
48 /* the resolution is platform dependent */
49 /* but is typically 1.62 us resolution */
50 LARGE_INTEGER lpPerformanceCount;
51 LARGE_INTEGER lpFrequency;
52 QueryPerformanceCounter(&lpPerformanceCount);
53 QueryPerformanceFrequency(&lpFrequency);
54 return (unsigned long)((1000000*(lpPerformanceCount.QuadPart)) / lpFrequency.QuadPart);
55}
56#else /* Linux or Mac*/
57unsigned long GetHighResolutionTime(void) /* O time in usec*/
58{
59 struct timeval tv;
60 gettimeofday(&tv, 0);
61 return((tv.tv_sec*1000000)+(tv.tv_usec));
62}
63#endif
64
65int silk_Timer_nTimers = 0;
66int silk_Timer_depth_ctr = 0;
67char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN];
68#ifdef WIN32
69LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX];
70#else
71unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX];
72#endif
73unsigned int silk_Timer_cnt[silk_NUM_TIMERS_MAX];
74opus_int64 silk_Timer_min[silk_NUM_TIMERS_MAX];
75opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX];
76opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX];
77opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX];
78
79#ifdef WIN32
80void silk_TimerSave(char *file_name)
81{
82 if( silk_Timer_nTimers > 0 )
83 {
84 int k;
85 FILE *fp;
86 LARGE_INTEGER lpFrequency;
87 LARGE_INTEGER lpPerformanceCount1, lpPerformanceCount2;
88 int del = 0x7FFFFFFF;
89 double avg, sum_avg;
90 /* estimate overhead of calling performance counters */
91 for( k = 0; k < 1000; k++ ) {
92 QueryPerformanceCounter(&lpPerformanceCount1);
93 QueryPerformanceCounter(&lpPerformanceCount2);
94 lpPerformanceCount2.QuadPart -= lpPerformanceCount1.QuadPart;
95 if( (int)lpPerformanceCount2.LowPart < del )
96 del = lpPerformanceCount2.LowPart;
97 }
98 QueryPerformanceFrequency(&lpFrequency);
99 /* print results to file */
100 sum_avg = 0.0f;
101 for( k = 0; k < silk_Timer_nTimers; k++ ) {
102 if (silk_Timer_depth[k] == 0) {
103 sum_avg += (1e6 * silk_Timer_sum[k] / silk_Timer_cnt[k] - del) / lpFrequency.QuadPart * silk_Timer_cnt[k];
104 }
105 }
106 fp = fopen(file_name, "w");
107 fprintf(fp, " min avg %% max count\n");
108 for( k = 0; k < silk_Timer_nTimers; k++ ) {
109 if (silk_Timer_depth[k] == 0) {
110 fprintf(fp, "%-28s", silk_Timer_tags[k]);
111 } else if (silk_Timer_depth[k] == 1) {
112 fprintf(fp, " %-27s", silk_Timer_tags[k]);
113 } else if (silk_Timer_depth[k] == 2) {
114 fprintf(fp, " %-26s", silk_Timer_tags[k]);
115 } else if (silk_Timer_depth[k] == 3) {
116 fprintf(fp, " %-25s", silk_Timer_tags[k]);
117 } else {
118 fprintf(fp, " %-24s", silk_Timer_tags[k]);
119 }
120 avg = (1e6 * silk_Timer_sum[k] / silk_Timer_cnt[k] - del) / lpFrequency.QuadPart;
121 fprintf(fp, "%8.2f", (1e6 * (silk_max_64(silk_Timer_min[k] - del, 0))) / lpFrequency.QuadPart);
122 fprintf(fp, "%12.2f %6.2f", avg, 100.0 * avg / sum_avg * silk_Timer_cnt[k]);
123 fprintf(fp, "%12.2f", (1e6 * (silk_max_64(silk_Timer_max[k] - del, 0))) / lpFrequency.QuadPart);
124 fprintf(fp, "%10d\n", silk_Timer_cnt[k]);
125 }
126 fprintf(fp, " microseconds\n");
127 fclose(fp);
128 }
129}
130#else
131void silk_TimerSave(char *file_name)
132{
133 if( silk_Timer_nTimers > 0 )
134 {
135 int k;
136 FILE *fp;
137 /* print results to file */
138 fp = fopen(file_name, "w");
139 fprintf(fp, " min avg max count\n");
140 for( k = 0; k < silk_Timer_nTimers; k++ )
141 {
142 if (silk_Timer_depth[k] == 0) {
143 fprintf(fp, "%-28s", silk_Timer_tags[k]);
144 } else if (silk_Timer_depth[k] == 1) {
145 fprintf(fp, " %-27s", silk_Timer_tags[k]);
146 } else if (silk_Timer_depth[k] == 2) {
147 fprintf(fp, " %-26s", silk_Timer_tags[k]);
148 } else if (silk_Timer_depth[k] == 3) {
149 fprintf(fp, " %-25s", silk_Timer_tags[k]);
150 } else {
151 fprintf(fp, " %-24s", silk_Timer_tags[k]);
152 }
153 fprintf(fp, "%d ", silk_Timer_min[k]);
154 fprintf(fp, "%f ", (double)silk_Timer_sum[k] / (double)silk_Timer_cnt[k]);
155 fprintf(fp, "%d ", silk_Timer_max[k]);
156 fprintf(fp, "%10d\n", silk_Timer_cnt[k]);
157 }
158 fprintf(fp, " microseconds\n");
159 fclose(fp);
160 }
161}
162#endif
163
164#endif /* SILK_TIC_TOC */
165
166#if SILK_DEBUG
167FILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ];
168int silk_debug_store_count = 0;
169#endif /* SILK_DEBUG */
170
diff --git a/lib/rbcodec/codecs/libopus/silk/debug.h b/lib/rbcodec/codecs/libopus/silk/debug.h
new file mode 100644
index 0000000000..6f68c1ca0f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/debug.h
@@ -0,0 +1,266 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef SILK_DEBUG_H
29#define SILK_DEBUG_H
30
31#include "typedef.h"
32#include <stdio.h> /* file writing */
33#include <string.h> /* strcpy, strcmp */
34
35#ifdef __cplusplus
36extern "C"
37{
38#endif
39
40unsigned long GetHighResolutionTime(void); /* O time in usec*/
41
42/* Set to 1 to enable DEBUG_STORE_DATA() macros for dumping
43 * intermediate signals from the codec.
44 */
45#define SILK_DEBUG 0
46
47/* Flag for using timers */
48#define SILK_TIC_TOC 0
49
50
51#if SILK_TIC_TOC
52
53#if (defined(_WIN32) || defined(_WINCE))
54#include <windows.h> /* timer */
55#else /* Linux or Mac*/
56#include <sys/time.h>
57#endif
58
59/*********************************/
60/* timer functions for profiling */
61/*********************************/
62/* example: */
63/* */
64/* TIC(LPC) */
65/* do_LPC(in_vec, order, acoef); // do LPC analysis */
66/* TOC(LPC) */
67/* */
68/* and call the following just before exiting (from main) */
69/* */
70/* silk_TimerSave("silk_TimingData.txt"); */
71/* */
72/* results are now in silk_TimingData.txt */
73
74void silk_TimerSave(char *file_name);
75
76/* max number of timers (in different locations) */
77#define silk_NUM_TIMERS_MAX 50
78/* max length of name tags in TIC(..), TOC(..) */
79#define silk_NUM_TIMERS_MAX_TAG_LEN 30
80
81extern int silk_Timer_nTimers;
82extern int silk_Timer_depth_ctr;
83extern char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN];
84#ifdef _WIN32
85extern LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX];
86#else
87extern unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX];
88#endif
89extern unsigned int silk_Timer_cnt[silk_NUM_TIMERS_MAX];
90extern opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX];
91extern opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX];
92extern opus_int64 silk_Timer_min[silk_NUM_TIMERS_MAX];
93extern opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX];
94
95/* WARNING: TIC()/TOC can measure only up to 0.1 seconds at a time */
96#ifdef _WIN32
97#define TIC(TAG_NAME) { \
98 static int init = 0; \
99 static int ID = -1; \
100 if( init == 0 ) \
101 { \
102 int k; \
103 init = 1; \
104 for( k = 0; k < silk_Timer_nTimers; k++ ) { \
105 if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \
106 ID = k; \
107 break; \
108 } \
109 } \
110 if (ID == -1) { \
111 ID = silk_Timer_nTimers; \
112 silk_Timer_nTimers++; \
113 silk_Timer_depth[ID] = silk_Timer_depth_ctr; \
114 strcpy(silk_Timer_tags[ID], #TAG_NAME); \
115 silk_Timer_cnt[ID] = 0; \
116 silk_Timer_sum[ID] = 0; \
117 silk_Timer_min[ID] = 0xFFFFFFFF; \
118 silk_Timer_max[ID] = 0; \
119 } \
120 } \
121 silk_Timer_depth_ctr++; \
122 QueryPerformanceCounter(&silk_Timer_start[ID]); \
123}
124#else
125#define TIC(TAG_NAME) { \
126 static int init = 0; \
127 static int ID = -1; \
128 if( init == 0 ) \
129 { \
130 int k; \
131 init = 1; \
132 for( k = 0; k < silk_Timer_nTimers; k++ ) { \
133 if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \
134 ID = k; \
135 break; \
136 } \
137 } \
138 if (ID == -1) { \
139 ID = silk_Timer_nTimers; \
140 silk_Timer_nTimers++; \
141 silk_Timer_depth[ID] = silk_Timer_depth_ctr; \
142 strcpy(silk_Timer_tags[ID], #TAG_NAME); \
143 silk_Timer_cnt[ID] = 0; \
144 silk_Timer_sum[ID] = 0; \
145 silk_Timer_min[ID] = 0xFFFFFFFF; \
146 silk_Timer_max[ID] = 0; \
147 } \
148 } \
149 silk_Timer_depth_ctr++; \
150 silk_Timer_start[ID] = GetHighResolutionTime(); \
151}
152#endif
153
154#ifdef _WIN32
155#define TOC(TAG_NAME) { \
156 LARGE_INTEGER lpPerformanceCount; \
157 static int init = 0; \
158 static int ID = 0; \
159 if( init == 0 ) \
160 { \
161 int k; \
162 init = 1; \
163 for( k = 0; k < silk_Timer_nTimers; k++ ) { \
164 if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \
165 ID = k; \
166 break; \
167 } \
168 } \
169 } \
170 QueryPerformanceCounter(&lpPerformanceCount); \
171 lpPerformanceCount.QuadPart -= silk_Timer_start[ID].QuadPart; \
172 if((lpPerformanceCount.QuadPart < 100000000) && \
173 (lpPerformanceCount.QuadPart >= 0)) { \
174 silk_Timer_cnt[ID]++; \
175 silk_Timer_sum[ID] += lpPerformanceCount.QuadPart; \
176 if( lpPerformanceCount.QuadPart > silk_Timer_max[ID] ) \
177 silk_Timer_max[ID] = lpPerformanceCount.QuadPart; \
178 if( lpPerformanceCount.QuadPart < silk_Timer_min[ID] ) \
179 silk_Timer_min[ID] = lpPerformanceCount.QuadPart; \
180 } \
181 silk_Timer_depth_ctr--; \
182}
183#else
184#define TOC(TAG_NAME) { \
185 unsigned long endTime; \
186 static int init = 0; \
187 static int ID = 0; \
188 if( init == 0 ) \
189 { \
190 int k; \
191 init = 1; \
192 for( k = 0; k < silk_Timer_nTimers; k++ ) { \
193 if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \
194 ID = k; \
195 break; \
196 } \
197 } \
198 } \
199 endTime = GetHighResolutionTime(); \
200 endTime -= silk_Timer_start[ID]; \
201 if((endTime < 100000000) && \
202 (endTime >= 0)) { \
203 silk_Timer_cnt[ID]++; \
204 silk_Timer_sum[ID] += endTime; \
205 if( endTime > silk_Timer_max[ID] ) \
206 silk_Timer_max[ID] = endTime; \
207 if( endTime < silk_Timer_min[ID] ) \
208 silk_Timer_min[ID] = endTime; \
209 } \
210 silk_Timer_depth_ctr--; \
211}
212#endif
213
214#else /* SILK_TIC_TOC */
215
216/* define macros as empty strings */
217#define TIC(TAG_NAME)
218#define TOC(TAG_NAME)
219#define silk_TimerSave(FILE_NAME)
220
221#endif /* SILK_TIC_TOC */
222
223
224#if SILK_DEBUG
225/************************************/
226/* write data to file for debugging */
227/************************************/
228/* Example: DEBUG_STORE_DATA(testfile.pcm, &RIN[0], 160*sizeof(opus_int16)); */
229
230#define silk_NUM_STORES_MAX 100
231extern FILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ];
232extern int silk_debug_store_count;
233
234/* Faster way of storing the data */
235#define DEBUG_STORE_DATA( FILE_NAME, DATA_PTR, N_BYTES ) { \
236 static opus_int init = 0, cnt = 0; \
237 static FILE **fp; \
238 if (init == 0) { \
239 init = 1; \
240 cnt = silk_debug_store_count++; \
241 silk_debug_store_fp[ cnt ] = fopen(#FILE_NAME, "wb"); \
242 } \
243 fwrite((DATA_PTR), (N_BYTES), 1, silk_debug_store_fp[ cnt ]); \
244}
245
246/* Call this at the end of main() */
247#define SILK_DEBUG_STORE_CLOSE_FILES { \
248 opus_int i; \
249 for( i = 0; i < silk_debug_store_count; i++ ) { \
250 fclose( silk_debug_store_fp[ i ] ); \
251 } \
252}
253
254#else /* SILK_DEBUG */
255
256/* define macros as empty strings */
257#define DEBUG_STORE_DATA(FILE_NAME, DATA_PTR, N_BYTES)
258#define SILK_DEBUG_STORE_CLOSE_FILES
259
260#endif /* SILK_DEBUG */
261
262#ifdef __cplusplus
263}
264#endif
265
266#endif /* SILK_DEBUG_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/dec_API.c b/lib/rbcodec/codecs/libopus/silk/dec_API.c
index 1087c6726a..7d5ca7fb9f 100644
--- a/lib/rbcodec/codecs/libopus/silk/dec_API.c
+++ b/lib/rbcodec/codecs/libopus/silk/dec_API.c
@@ -85,7 +85,8 @@ opus_int silk_Decode( /* O Returns error co
85 opus_int newPacketFlag, /* I Indicates first decoder call for this packet */ 85 opus_int newPacketFlag, /* I Indicates first decoder call for this packet */
86 ec_dec *psRangeDec, /* I/O Compressor data structure */ 86 ec_dec *psRangeDec, /* I/O Compressor data structure */
87 opus_int16 *samplesOut, /* O Decoded output speech vector */ 87 opus_int16 *samplesOut, /* O Decoded output speech vector */
88 opus_int32 *nSamplesOut /* O Number of samples decoded */ 88 opus_int32 *nSamplesOut, /* O Number of samples decoded */
89 int arch /* I Run-time architecture */
89) 90)
90{ 91{
91 opus_int i, n, decode_only_middle = 0, ret = SILK_NO_ERROR; 92 opus_int i, n, decode_only_middle = 0, ret = SILK_NO_ERROR;
@@ -103,7 +104,7 @@ opus_int silk_Decode( /* O Returns error co
103 int delay_stack_alloc; 104 int delay_stack_alloc;
104 SAVE_STACK; 105 SAVE_STACK;
105 106
106 silk_assert( decControl->nChannelsInternal == 1 || decControl->nChannelsInternal == 2 ); 107 celt_assert( decControl->nChannelsInternal == 1 || decControl->nChannelsInternal == 2 );
107 108
108 /**********************************/ 109 /**********************************/
109 /* Test if first frame in payload */ 110 /* Test if first frame in payload */
@@ -142,13 +143,13 @@ opus_int silk_Decode( /* O Returns error co
142 channel_state[ n ].nFramesPerPacket = 3; 143 channel_state[ n ].nFramesPerPacket = 3;
143 channel_state[ n ].nb_subfr = 4; 144 channel_state[ n ].nb_subfr = 4;
144 } else { 145 } else {
145 silk_assert( 0 ); 146 celt_assert( 0 );
146 RESTORE_STACK; 147 RESTORE_STACK;
147 return SILK_DEC_INVALID_FRAME_SIZE; 148 return SILK_DEC_INVALID_FRAME_SIZE;
148 } 149 }
149 fs_kHz_dec = ( decControl->internalSampleRate >> 10 ) + 1; 150 fs_kHz_dec = ( decControl->internalSampleRate >> 10 ) + 1;
150 if( fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16 ) { 151 if( fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16 ) {
151 silk_assert( 0 ); 152 celt_assert( 0 );
152 RESTORE_STACK; 153 RESTORE_STACK;
153 return SILK_DEC_INVALID_SAMPLING_FREQUENCY; 154 return SILK_DEC_INVALID_SAMPLING_FREQUENCY;
154 } 155 }
@@ -296,7 +297,7 @@ opus_int silk_Decode( /* O Returns error co
296 } else { 297 } else {
297 condCoding = CODE_CONDITIONALLY; 298 condCoding = CODE_CONDITIONALLY;
298 } 299 }
299 ret += silk_decode_frame( &channel_state[ n ], psRangeDec, &samplesOut1_tmp[ n ][ 2 ], &nSamplesOutDec, lostFlag, condCoding); 300 ret += silk_decode_frame( &channel_state[ n ], psRangeDec, &samplesOut1_tmp[ n ][ 2 ], &nSamplesOutDec, lostFlag, condCoding, arch);
300 } else { 301 } else {
301 silk_memset( &samplesOut1_tmp[ n ][ 2 ], 0, nSamplesOutDec * sizeof( opus_int16 ) ); 302 silk_memset( &samplesOut1_tmp[ n ][ 2 ], 0, nSamplesOutDec * sizeof( opus_int16 ) );
302 } 303 }
diff --git a/lib/rbcodec/codecs/libopus/silk/decode_core.c b/lib/rbcodec/codecs/libopus/silk/decode_core.c
index af68b75da9..1c352a6522 100644
--- a/lib/rbcodec/codecs/libopus/silk/decode_core.c
+++ b/lib/rbcodec/codecs/libopus/silk/decode_core.c
@@ -39,7 +39,8 @@ void silk_decode_core(
39 silk_decoder_state *psDec, /* I/O Decoder state */ 39 silk_decoder_state *psDec, /* I/O Decoder state */
40 silk_decoder_control *psDecCtrl, /* I Decoder control */ 40 silk_decoder_control *psDecCtrl, /* I Decoder control */
41 opus_int16 xq[], /* O Decoded speech */ 41 opus_int16 xq[], /* O Decoded speech */
42 const opus_int16 pulses[ MAX_FRAME_LENGTH ] /* I Pulse signal */ 42 const opus_int16 pulses[ MAX_FRAME_LENGTH ], /* I Pulse signal */
43 int arch /* I Run-time architecture */
43) 44)
44{ 45{
45 opus_int i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, signalType; 46 opus_int i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, signalType;
@@ -140,14 +141,14 @@ void silk_decode_core(
140 if( k == 0 || ( k == 2 && NLSF_interpolation_flag ) ) { 141 if( k == 0 || ( k == 2 && NLSF_interpolation_flag ) ) {
141 /* Rewhiten with new A coefs */ 142 /* Rewhiten with new A coefs */
142 start_idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2; 143 start_idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2;
143 silk_assert( start_idx > 0 ); 144 celt_assert( start_idx > 0 );
144 145
145 if( k == 2 ) { 146 if( k == 2 ) {
146 silk_memcpy( &psDec->outBuf[ psDec->ltp_mem_length ], xq, 2 * psDec->subfr_length * sizeof( opus_int16 ) ); 147 silk_memcpy( &psDec->outBuf[ psDec->ltp_mem_length ], xq, 2 * psDec->subfr_length * sizeof( opus_int16 ) );
147 } 148 }
148 149
149 silk_LPC_analysis_filter( &sLTP[ start_idx ], &psDec->outBuf[ start_idx + k * psDec->subfr_length ], 150 silk_LPC_analysis_filter( &sLTP[ start_idx ], &psDec->outBuf[ start_idx + k * psDec->subfr_length ],
150 A_Q12, psDec->ltp_mem_length - start_idx, psDec->LPC_order ); 151 A_Q12, psDec->ltp_mem_length - start_idx, psDec->LPC_order, arch );
151 152
152 /* After rewhitening the LTP state is unscaled */ 153 /* After rewhitening the LTP state is unscaled */
153 if( k == 0 ) { 154 if( k == 0 ) {
@@ -195,7 +196,7 @@ void silk_decode_core(
195 196
196 for( i = 0; i < psDec->subfr_length; i++ ) { 197 for( i = 0; i < psDec->subfr_length; i++ ) {
197 /* Short-term prediction */ 198 /* Short-term prediction */
198 silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 ); 199 celt_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
199 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ 200 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
200 LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 ); 201 LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 );
201 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] ); 202 LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] );
@@ -218,14 +219,12 @@ void silk_decode_core(
218 } 219 }
219 220
220 /* Add prediction to LPC excitation */ 221 /* Add prediction to LPC excitation */
221 sLPC_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( pres_Q14[ i ], LPC_pred_Q10, 4 ); 222 sLPC_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_SAT32( pres_Q14[ i ], silk_LSHIFT_SAT32( LPC_pred_Q10, 4 ) );
222 223
223 /* Scale with gain */ 224 /* Scale with gain */
224 pxq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14[ MAX_LPC_ORDER + i ], Gain_Q10 ), 8 ) ); 225 pxq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14[ MAX_LPC_ORDER + i ], Gain_Q10 ), 8 ) );
225 } 226 }
226 227
227 /* DEBUG_STORE_DATA( dec.pcm, pxq, psDec->subfr_length * sizeof( opus_int16 ) ) */
228
229 /* Update LPC filter state */ 228 /* Update LPC filter state */
230 silk_memcpy( sLPC_Q14, &sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); 229 silk_memcpy( sLPC_Q14, &sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );
231 pexc_Q14 += psDec->subfr_length; 230 pexc_Q14 += psDec->subfr_length;
diff --git a/lib/rbcodec/codecs/libopus/silk/decode_frame.c b/lib/rbcodec/codecs/libopus/silk/decode_frame.c
index 6a7cffbbe0..e73825b267 100644
--- a/lib/rbcodec/codecs/libopus/silk/decode_frame.c
+++ b/lib/rbcodec/codecs/libopus/silk/decode_frame.c
@@ -42,7 +42,8 @@ opus_int silk_decode_frame(
42 opus_int16 pOut[], /* O Pointer to output speech frame */ 42 opus_int16 pOut[], /* O Pointer to output speech frame */
43 opus_int32 *pN, /* O Pointer to size of output frame */ 43 opus_int32 *pN, /* O Pointer to size of output frame */
44 opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ 44 opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */
45 opus_int condCoding /* I The type of conditional coding to use */ 45 opus_int condCoding, /* I The type of conditional coding to use */
46 int arch /* I Run-time architecture */
46) 47)
47{ 48{
48 VARDECL( silk_decoder_control, psDecCtrl ); 49 VARDECL( silk_decoder_control, psDecCtrl );
@@ -54,7 +55,7 @@ opus_int silk_decode_frame(
54 psDecCtrl->LTP_scale_Q14 = 0; 55 psDecCtrl->LTP_scale_Q14 = 0;
55 56
56 /* Safety checks */ 57 /* Safety checks */
57 silk_assert( L > 0 && L <= MAX_FRAME_LENGTH ); 58 celt_assert( L > 0 && L <= MAX_FRAME_LENGTH );
58 59
59 if( lostFlag == FLAG_DECODE_NORMAL || 60 if( lostFlag == FLAG_DECODE_NORMAL ||
60 ( lostFlag == FLAG_DECODE_LBRR && psDec->LBRR_flags[ psDec->nFramesDecoded ] == 1 ) ) 61 ( lostFlag == FLAG_DECODE_LBRR && psDec->LBRR_flags[ psDec->nFramesDecoded ] == 1 ) )
@@ -81,28 +82,29 @@ opus_int silk_decode_frame(
81 /********************************************************/ 82 /********************************************************/
82 /* Run inverse NSQ */ 83 /* Run inverse NSQ */
83 /********************************************************/ 84 /********************************************************/
84 silk_decode_core( psDec, psDecCtrl, pOut, pulses ); 85 silk_decode_core( psDec, psDecCtrl, pOut, pulses, arch );
85 86
86 /********************************************************/ 87 /********************************************************/
87 /* Update PLC state */ 88 /* Update PLC state */
88 /********************************************************/ 89 /********************************************************/
89 silk_PLC( psDec, psDecCtrl, pOut, 0 ); 90 silk_PLC( psDec, psDecCtrl, pOut, 0, arch );
90 91
91 psDec->lossCnt = 0; 92 psDec->lossCnt = 0;
92 psDec->prevSignalType = psDec->indices.signalType; 93 psDec->prevSignalType = psDec->indices.signalType;
93 silk_assert( psDec->prevSignalType >= 0 && psDec->prevSignalType <= 2 ); 94 celt_assert( psDec->prevSignalType >= 0 && psDec->prevSignalType <= 2 );
94 95
95 /* A frame has been decoded without errors */ 96 /* A frame has been decoded without errors */
96 psDec->first_frame_after_reset = 0; 97 psDec->first_frame_after_reset = 0;
97 } else { 98 } else {
98 /* Handle packet loss by extrapolation */ 99 /* Handle packet loss by extrapolation */
99 silk_PLC( psDec, psDecCtrl, pOut, 1 ); 100 psDec->indices.signalType = psDec->prevSignalType;
101 silk_PLC( psDec, psDecCtrl, pOut, 1, arch );
100 } 102 }
101 103
102 /*************************/ 104 /*************************/
103 /* Update output buffer. */ 105 /* Update output buffer. */
104 /*************************/ 106 /*************************/
105 silk_assert( psDec->ltp_mem_length >= psDec->frame_length ); 107 celt_assert( psDec->ltp_mem_length >= psDec->frame_length );
106 mv_len = psDec->ltp_mem_length - psDec->frame_length; 108 mv_len = psDec->ltp_mem_length - psDec->frame_length;
107 silk_memmove( psDec->outBuf, &psDec->outBuf[ psDec->frame_length ], mv_len * sizeof(opus_int16) ); 109 silk_memmove( psDec->outBuf, &psDec->outBuf[ psDec->frame_length ], mv_len * sizeof(opus_int16) );
108 silk_memcpy( &psDec->outBuf[ mv_len ], pOut, psDec->frame_length * sizeof( opus_int16 ) ); 110 silk_memcpy( &psDec->outBuf[ mv_len ], pOut, psDec->frame_length * sizeof( opus_int16 ) );
diff --git a/lib/rbcodec/codecs/libopus/silk/decode_indices.c b/lib/rbcodec/codecs/libopus/silk/decode_indices.c
index 7afe5c26c1..0bb4a997a5 100644
--- a/lib/rbcodec/codecs/libopus/silk/decode_indices.c
+++ b/lib/rbcodec/codecs/libopus/silk/decode_indices.c
@@ -79,7 +79,7 @@ void silk_decode_indices(
79 /**********************/ 79 /**********************/
80 psDec->indices.NLSFIndices[ 0 ] = (opus_int8)ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->CB1_iCDF[ ( psDec->indices.signalType >> 1 ) * psDec->psNLSF_CB->nVectors ], 8 ); 80 psDec->indices.NLSFIndices[ 0 ] = (opus_int8)ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->CB1_iCDF[ ( psDec->indices.signalType >> 1 ) * psDec->psNLSF_CB->nVectors ], 8 );
81 silk_NLSF_unpack( ec_ix, pred_Q8, psDec->psNLSF_CB, psDec->indices.NLSFIndices[ 0 ] ); 81 silk_NLSF_unpack( ec_ix, pred_Q8, psDec->psNLSF_CB, psDec->indices.NLSFIndices[ 0 ] );
82 silk_assert( psDec->psNLSF_CB->order == psDec->LPC_order ); 82 celt_assert( psDec->psNLSF_CB->order == psDec->LPC_order );
83 for( i = 0; i < psDec->psNLSF_CB->order; i++ ) { 83 for( i = 0; i < psDec->psNLSF_CB->order; i++ ) {
84 Ix = ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); 84 Ix = ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );
85 if( Ix == 0 ) { 85 if( Ix == 0 ) {
diff --git a/lib/rbcodec/codecs/libopus/silk/decode_parameters.c b/lib/rbcodec/codecs/libopus/silk/decode_parameters.c
index e345b1dcef..a56a409858 100644
--- a/lib/rbcodec/codecs/libopus/silk/decode_parameters.c
+++ b/lib/rbcodec/codecs/libopus/silk/decode_parameters.c
@@ -52,7 +52,7 @@ void silk_decode_parameters(
52 silk_NLSF_decode( pNLSF_Q15, psDec->indices.NLSFIndices, psDec->psNLSF_CB ); 52 silk_NLSF_decode( pNLSF_Q15, psDec->indices.NLSFIndices, psDec->psNLSF_CB );
53 53
54 /* Convert NLSF parameters to AR prediction filter coefficients */ 54 /* Convert NLSF parameters to AR prediction filter coefficients */
55 silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order ); 55 silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order, psDec->arch );
56 56
57 /* If just reset, e.g., because internal Fs changed, do not allow interpolation */ 57 /* If just reset, e.g., because internal Fs changed, do not allow interpolation */
58 /* improves the case of packet loss in the first frame after a switch */ 58 /* improves the case of packet loss in the first frame after a switch */
@@ -69,7 +69,7 @@ void silk_decode_parameters(
69 } 69 }
70 70
71 /* Convert NLSF parameters to AR prediction filter coefficients */ 71 /* Convert NLSF parameters to AR prediction filter coefficients */
72 silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order ); 72 silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order, psDec->arch );
73 } else { 73 } else {
74 /* Copy LPC coefficients for first half from second half */ 74 /* Copy LPC coefficients for first half from second half */
75 silk_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) ); 75 silk_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) );
diff --git a/lib/rbcodec/codecs/libopus/silk/decode_pitch.c b/lib/rbcodec/codecs/libopus/silk/decode_pitch.c
index fedbc6a525..fd1b6bf551 100644
--- a/lib/rbcodec/codecs/libopus/silk/decode_pitch.c
+++ b/lib/rbcodec/codecs/libopus/silk/decode_pitch.c
@@ -51,7 +51,7 @@ void silk_decode_pitch(
51 Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ]; 51 Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];
52 cbk_size = PE_NB_CBKS_STAGE2_EXT; 52 cbk_size = PE_NB_CBKS_STAGE2_EXT;
53 } else { 53 } else {
54 silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 ); 54 celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 );
55 Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ]; 55 Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ];
56 cbk_size = PE_NB_CBKS_STAGE2_10MS; 56 cbk_size = PE_NB_CBKS_STAGE2_10MS;
57 } 57 }
@@ -60,7 +60,7 @@ void silk_decode_pitch(
60 Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; 60 Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
61 cbk_size = PE_NB_CBKS_STAGE3_MAX; 61 cbk_size = PE_NB_CBKS_STAGE3_MAX;
62 } else { 62 } else {
63 silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 ); 63 celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 );
64 Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; 64 Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
65 cbk_size = PE_NB_CBKS_STAGE3_10MS; 65 cbk_size = PE_NB_CBKS_STAGE3_10MS;
66 } 66 }
diff --git a/lib/rbcodec/codecs/libopus/silk/decode_pulses.c b/lib/rbcodec/codecs/libopus/silk/decode_pulses.c
index 1e14bc37b4..a56d2d3074 100644
--- a/lib/rbcodec/codecs/libopus/silk/decode_pulses.c
+++ b/lib/rbcodec/codecs/libopus/silk/decode_pulses.c
@@ -56,7 +56,7 @@ void silk_decode_pulses(
56 silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH ); 56 silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH );
57 iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH ); 57 iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH );
58 if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) { 58 if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) {
59 silk_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */ 59 celt_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */
60 iter++; 60 iter++;
61 } 61 }
62 62
@@ -69,9 +69,9 @@ void silk_decode_pulses(
69 sum_pulses[ i ] = ec_dec_icdf( psRangeDec, cdf_ptr, 8 ); 69 sum_pulses[ i ] = ec_dec_icdf( psRangeDec, cdf_ptr, 8 );
70 70
71 /* LSB indication */ 71 /* LSB indication */
72 while( sum_pulses[ i ] == MAX_PULSES + 1 ) { 72 while( sum_pulses[ i ] == SILK_MAX_PULSES + 1 ) {
73 nLshifts[ i ]++; 73 nLshifts[ i ]++;
74 /* When we've already got 10 LSBs, we shift the table to not allow (MAX_PULSES + 1) */ 74 /* When we've already got 10 LSBs, we shift the table to not allow (SILK_MAX_PULSES + 1) */
75 sum_pulses[ i ] = ec_dec_icdf( psRangeDec, 75 sum_pulses[ i ] = ec_dec_icdf( psRangeDec,
76 silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1] + ( nLshifts[ i ] == 10 ), 8 ); 76 silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1] + ( nLshifts[ i ] == 10 ), 8 );
77 } 77 }
diff --git a/lib/rbcodec/codecs/libopus/silk/decoder_set_fs.c b/lib/rbcodec/codecs/libopus/silk/decoder_set_fs.c
index eef0fd25e1..d9a13d0f0c 100644
--- a/lib/rbcodec/codecs/libopus/silk/decoder_set_fs.c
+++ b/lib/rbcodec/codecs/libopus/silk/decoder_set_fs.c
@@ -40,8 +40,8 @@ opus_int silk_decoder_set_fs(
40{ 40{
41 opus_int frame_length, ret = 0; 41 opus_int frame_length, ret = 0;
42 42
43 silk_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 ); 43 celt_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );
44 silk_assert( psDec->nb_subfr == MAX_NB_SUBFR || psDec->nb_subfr == MAX_NB_SUBFR/2 ); 44 celt_assert( psDec->nb_subfr == MAX_NB_SUBFR || psDec->nb_subfr == MAX_NB_SUBFR/2 );
45 45
46 /* New (sub)frame length */ 46 /* New (sub)frame length */
47 psDec->subfr_length = silk_SMULBB( SUB_FRAME_LENGTH_MS, fs_kHz ); 47 psDec->subfr_length = silk_SMULBB( SUB_FRAME_LENGTH_MS, fs_kHz );
@@ -86,7 +86,7 @@ opus_int silk_decoder_set_fs(
86 psDec->pitch_lag_low_bits_iCDF = silk_uniform4_iCDF; 86 psDec->pitch_lag_low_bits_iCDF = silk_uniform4_iCDF;
87 } else { 87 } else {
88 /* unsupported sampling rate */ 88 /* unsupported sampling rate */
89 silk_assert( 0 ); 89 celt_assert( 0 );
90 } 90 }
91 psDec->first_frame_after_reset = 1; 91 psDec->first_frame_after_reset = 1;
92 psDec->lagPrev = 100; 92 psDec->lagPrev = 100;
@@ -101,7 +101,7 @@ opus_int silk_decoder_set_fs(
101 } 101 }
102 102
103 /* Check that settings are valid */ 103 /* Check that settings are valid */
104 silk_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH ); 104 celt_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH );
105 105
106 return ret; 106 return ret;
107} 107}
diff --git a/lib/rbcodec/codecs/libopus/silk/define.h b/lib/rbcodec/codecs/libopus/silk/define.h
index c47aca9f58..247cb0bf71 100644
--- a/lib/rbcodec/codecs/libopus/silk/define.h
+++ b/lib/rbcodec/codecs/libopus/silk/define.h
@@ -46,7 +46,6 @@ extern "C"
46/* Limits on bitrate */ 46/* Limits on bitrate */
47#define MIN_TARGET_RATE_BPS 5000 47#define MIN_TARGET_RATE_BPS 5000
48#define MAX_TARGET_RATE_BPS 80000 48#define MAX_TARGET_RATE_BPS 80000
49#define TARGET_RATE_TAB_SZ 8
50 49
51/* LBRR thresholds */ 50/* LBRR thresholds */
52#define LBRR_NB_MIN_RATE_BPS 12000 51#define LBRR_NB_MIN_RATE_BPS 12000
@@ -56,6 +55,12 @@ extern "C"
56/* DTX settings */ 55/* DTX settings */
57#define NB_SPEECH_FRAMES_BEFORE_DTX 10 /* eq 200 ms */ 56#define NB_SPEECH_FRAMES_BEFORE_DTX 10 /* eq 200 ms */
58#define MAX_CONSECUTIVE_DTX 20 /* eq 400 ms */ 57#define MAX_CONSECUTIVE_DTX 20 /* eq 400 ms */
58#define DTX_ACTIVITY_THRESHOLD 0.1f
59
60/* VAD decision */
61#define VAD_NO_DECISION -1
62#define VAD_NO_ACTIVITY 0
63#define VAD_ACTIVITY 1
59 64
60/* Maximum sampling frequency */ 65/* Maximum sampling frequency */
61#define MAX_FS_KHZ 16 66#define MAX_FS_KHZ 16
@@ -147,7 +152,7 @@ extern "C"
147#define USE_HARM_SHAPING 1 152#define USE_HARM_SHAPING 1
148 153
149/* Max LPC order of noise shaping filters */ 154/* Max LPC order of noise shaping filters */
150#define MAX_SHAPE_LPC_ORDER 16 155#define MAX_SHAPE_LPC_ORDER 24
151 156
152#define HARM_SHAPE_FIR_TAPS 3 157#define HARM_SHAPE_FIR_TAPS 3
153 158
@@ -157,8 +162,7 @@ extern "C"
157#define LTP_BUF_LENGTH 512 162#define LTP_BUF_LENGTH 512
158#define LTP_MASK ( LTP_BUF_LENGTH - 1 ) 163#define LTP_MASK ( LTP_BUF_LENGTH - 1 )
159 164
160#define DECISION_DELAY 32 165#define DECISION_DELAY 40
161#define DECISION_DELAY_MASK ( DECISION_DELAY - 1 )
162 166
163/* Number of subframes for excitation entropy coding */ 167/* Number of subframes for excitation entropy coding */
164#define SHELL_CODEC_FRAME_LENGTH 16 168#define SHELL_CODEC_FRAME_LENGTH 16
@@ -169,15 +173,11 @@ extern "C"
169#define N_RATE_LEVELS 10 173#define N_RATE_LEVELS 10
170 174
171/* Maximum sum of pulses per shell coding frame */ 175/* Maximum sum of pulses per shell coding frame */
172#define MAX_PULSES 16 176#define SILK_MAX_PULSES 16
173 177
174#define MAX_MATRIX_SIZE MAX_LPC_ORDER /* Max of LPC Order and LTP order */ 178#define MAX_MATRIX_SIZE MAX_LPC_ORDER /* Max of LPC Order and LTP order */
175 179
176#if( MAX_LPC_ORDER > DECISION_DELAY )
177# define NSQ_LPC_BUF_LENGTH MAX_LPC_ORDER 180# define NSQ_LPC_BUF_LENGTH MAX_LPC_ORDER
178#else
179# define NSQ_LPC_BUF_LENGTH DECISION_DELAY
180#endif
181 181
182/***************************/ 182/***************************/
183/* Voice activity detector */ 183/* Voice activity detector */
@@ -205,7 +205,6 @@ extern "C"
205/******************/ 205/******************/
206#define NLSF_W_Q 2 206#define NLSF_W_Q 2
207#define NLSF_VQ_MAX_VECTORS 32 207#define NLSF_VQ_MAX_VECTORS 32
208#define NLSF_VQ_MAX_SURVIVORS 32
209#define NLSF_QUANT_MAX_AMPLITUDE 4 208#define NLSF_QUANT_MAX_AMPLITUDE 4
210#define NLSF_QUANT_MAX_AMPLITUDE_EXT 10 209#define NLSF_QUANT_MAX_AMPLITUDE_EXT 10
211#define NLSF_QUANT_LEVEL_ADJ 0.1 210#define NLSF_QUANT_LEVEL_ADJ 0.1
diff --git a/lib/rbcodec/codecs/libopus/silk/enc_API.c b/lib/rbcodec/codecs/libopus/silk/enc_API.c
new file mode 100644
index 0000000000..55a33f37e9
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/enc_API.c
@@ -0,0 +1,576 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31#include "define.h"
32#include "API.h"
33#include "control.h"
34#include "typedef.h"
35#include "stack_alloc.h"
36#include "structs.h"
37#include "tuning_parameters.h"
38#ifdef FIXED_POINT
39#include "main_FIX.h"
40#else
41#include "main_FLP.h"
42#endif
43
44/***************************************/
45/* Read control structure from encoder */
46/***************************************/
47static opus_int silk_QueryEncoder( /* O Returns error code */
48 const void *encState, /* I State */
49 silk_EncControlStruct *encStatus /* O Encoder Status */
50);
51
52/****************************************/
53/* Encoder functions */
54/****************************************/
55
56opus_int silk_Get_Encoder_Size( /* O Returns error code */
57 opus_int *encSizeBytes /* O Number of bytes in SILK encoder state */
58)
59{
60 opus_int ret = SILK_NO_ERROR;
61
62 *encSizeBytes = sizeof( silk_encoder );
63
64 return ret;
65}
66
67/*************************/
68/* Init or Reset encoder */
69/*************************/
70opus_int silk_InitEncoder( /* O Returns error code */
71 void *encState, /* I/O State */
72 int arch, /* I Run-time architecture */
73 silk_EncControlStruct *encStatus /* O Encoder Status */
74)
75{
76 silk_encoder *psEnc;
77 opus_int n, ret = SILK_NO_ERROR;
78
79 psEnc = (silk_encoder *)encState;
80
81 /* Reset encoder */
82 silk_memset( psEnc, 0, sizeof( silk_encoder ) );
83 for( n = 0; n < ENCODER_NUM_CHANNELS; n++ ) {
84 if( ret += silk_init_encoder( &psEnc->state_Fxx[ n ], arch ) ) {
85 celt_assert( 0 );
86 }
87 }
88
89 psEnc->nChannelsAPI = 1;
90 psEnc->nChannelsInternal = 1;
91
92 /* Read control structure */
93 if( ret += silk_QueryEncoder( encState, encStatus ) ) {
94 celt_assert( 0 );
95 }
96
97 return ret;
98}
99
100/***************************************/
101/* Read control structure from encoder */
102/***************************************/
103static opus_int silk_QueryEncoder( /* O Returns error code */
104 const void *encState, /* I State */
105 silk_EncControlStruct *encStatus /* O Encoder Status */
106)
107{
108 opus_int ret = SILK_NO_ERROR;
109 silk_encoder_state_Fxx *state_Fxx;
110 silk_encoder *psEnc = (silk_encoder *)encState;
111
112 state_Fxx = psEnc->state_Fxx;
113
114 encStatus->nChannelsAPI = psEnc->nChannelsAPI;
115 encStatus->nChannelsInternal = psEnc->nChannelsInternal;
116 encStatus->API_sampleRate = state_Fxx[ 0 ].sCmn.API_fs_Hz;
117 encStatus->maxInternalSampleRate = state_Fxx[ 0 ].sCmn.maxInternal_fs_Hz;
118 encStatus->minInternalSampleRate = state_Fxx[ 0 ].sCmn.minInternal_fs_Hz;
119 encStatus->desiredInternalSampleRate = state_Fxx[ 0 ].sCmn.desiredInternal_fs_Hz;
120 encStatus->payloadSize_ms = state_Fxx[ 0 ].sCmn.PacketSize_ms;
121 encStatus->bitRate = state_Fxx[ 0 ].sCmn.TargetRate_bps;
122 encStatus->packetLossPercentage = state_Fxx[ 0 ].sCmn.PacketLoss_perc;
123 encStatus->complexity = state_Fxx[ 0 ].sCmn.Complexity;
124 encStatus->useInBandFEC = state_Fxx[ 0 ].sCmn.useInBandFEC;
125 encStatus->useDTX = state_Fxx[ 0 ].sCmn.useDTX;
126 encStatus->useCBR = state_Fxx[ 0 ].sCmn.useCBR;
127 encStatus->internalSampleRate = silk_SMULBB( state_Fxx[ 0 ].sCmn.fs_kHz, 1000 );
128 encStatus->allowBandwidthSwitch = state_Fxx[ 0 ].sCmn.allow_bandwidth_switch;
129 encStatus->inWBmodeWithoutVariableLP = state_Fxx[ 0 ].sCmn.fs_kHz == 16 && state_Fxx[ 0 ].sCmn.sLP.mode == 0;
130
131 return ret;
132}
133
134
135/**************************/
136/* Encode frame with Silk */
137/**************************/
138/* Note: if prefillFlag is set, the input must contain 10 ms of audio, irrespective of what */
139/* encControl->payloadSize_ms is set to */
140opus_int silk_Encode( /* O Returns error code */
141 void *encState, /* I/O State */
142 silk_EncControlStruct *encControl, /* I Control status */
143 const opus_int16 *samplesIn, /* I Speech sample input vector */
144 opus_int nSamplesIn, /* I Number of samples in input vector */
145 ec_enc *psRangeEnc, /* I/O Compressor data structure */
146 opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */
147 const opus_int prefillFlag, /* I Flag to indicate prefilling buffers no coding */
148 opus_int activity /* I Decision of Opus voice activity detector */
149)
150{
151 opus_int n, i, nBits, flags, tmp_payloadSize_ms = 0, tmp_complexity = 0, ret = 0;
152 opus_int nSamplesToBuffer, nSamplesToBufferMax, nBlocksOf10ms;
153 opus_int nSamplesFromInput = 0, nSamplesFromInputMax;
154 opus_int speech_act_thr_for_switch_Q8;
155 opus_int32 TargetRate_bps, MStargetRates_bps[ 2 ], channelRate_bps, LBRR_symbol, sum;
156 silk_encoder *psEnc = ( silk_encoder * )encState;
157 VARDECL( opus_int16, buf );
158 opus_int transition, curr_block, tot_blocks;
159 SAVE_STACK;
160
161 if (encControl->reducedDependency)
162 {
163 psEnc->state_Fxx[0].sCmn.first_frame_after_reset = 1;
164 psEnc->state_Fxx[1].sCmn.first_frame_after_reset = 1;
165 }
166 psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded = psEnc->state_Fxx[ 1 ].sCmn.nFramesEncoded = 0;
167
168 /* Check values in encoder control structure */
169 if( ( ret = check_control_input( encControl ) ) != 0 ) {
170 celt_assert( 0 );
171 RESTORE_STACK;
172 return ret;
173 }
174
175 encControl->switchReady = 0;
176
177 if( encControl->nChannelsInternal > psEnc->nChannelsInternal ) {
178 /* Mono -> Stereo transition: init state of second channel and stereo state */
179 ret += silk_init_encoder( &psEnc->state_Fxx[ 1 ], psEnc->state_Fxx[ 0 ].sCmn.arch );
180 silk_memset( psEnc->sStereo.pred_prev_Q13, 0, sizeof( psEnc->sStereo.pred_prev_Q13 ) );
181 silk_memset( psEnc->sStereo.sSide, 0, sizeof( psEnc->sStereo.sSide ) );
182 psEnc->sStereo.mid_side_amp_Q0[ 0 ] = 0;
183 psEnc->sStereo.mid_side_amp_Q0[ 1 ] = 1;
184 psEnc->sStereo.mid_side_amp_Q0[ 2 ] = 0;
185 psEnc->sStereo.mid_side_amp_Q0[ 3 ] = 1;
186 psEnc->sStereo.width_prev_Q14 = 0;
187 psEnc->sStereo.smth_width_Q14 = SILK_FIX_CONST( 1, 14 );
188 if( psEnc->nChannelsAPI == 2 ) {
189 silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof( silk_resampler_state_struct ) );
190 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 ) );
191 }
192 }
193
194 transition = (encControl->payloadSize_ms != psEnc->state_Fxx[ 0 ].sCmn.PacketSize_ms) || (psEnc->nChannelsInternal != encControl->nChannelsInternal);
195
196 psEnc->nChannelsAPI = encControl->nChannelsAPI;
197 psEnc->nChannelsInternal = encControl->nChannelsInternal;
198
199 nBlocksOf10ms = silk_DIV32( 100 * nSamplesIn, encControl->API_sampleRate );
200 tot_blocks = ( nBlocksOf10ms > 1 ) ? nBlocksOf10ms >> 1 : 1;
201 curr_block = 0;
202 if( prefillFlag ) {
203 silk_LP_state save_LP;
204 /* Only accept input length of 10 ms */
205 if( nBlocksOf10ms != 1 ) {
206 celt_assert( 0 );
207 RESTORE_STACK;
208 return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
209 }
210 if ( prefillFlag == 2 ) {
211 save_LP = psEnc->state_Fxx[ 0 ].sCmn.sLP;
212 /* Save the sampling rate so the bandwidth switching code can keep handling transitions. */
213 save_LP.saved_fs_kHz = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz;
214 }
215 /* Reset Encoder */
216 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
217 ret = silk_init_encoder( &psEnc->state_Fxx[ n ], psEnc->state_Fxx[ n ].sCmn.arch );
218 /* Restore the variable LP state. */
219 if ( prefillFlag == 2 ) {
220 psEnc->state_Fxx[ n ].sCmn.sLP = save_LP;
221 }
222 celt_assert( !ret );
223 }
224 tmp_payloadSize_ms = encControl->payloadSize_ms;
225 encControl->payloadSize_ms = 10;
226 tmp_complexity = encControl->complexity;
227 encControl->complexity = 0;
228 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
229 psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;
230 psEnc->state_Fxx[ n ].sCmn.prefillFlag = 1;
231 }
232 } else {
233 /* Only accept input lengths that are a multiple of 10 ms */
234 if( nBlocksOf10ms * encControl->API_sampleRate != 100 * nSamplesIn || nSamplesIn < 0 ) {
235 celt_assert( 0 );
236 RESTORE_STACK;
237 return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
238 }
239 /* Make sure no more than one packet can be produced */
240 if( 1000 * (opus_int32)nSamplesIn > encControl->payloadSize_ms * encControl->API_sampleRate ) {
241 celt_assert( 0 );
242 RESTORE_STACK;
243 return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
244 }
245 }
246
247 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
248 /* Force the side channel to the same rate as the mid */
249 opus_int force_fs_kHz = (n==1) ? psEnc->state_Fxx[0].sCmn.fs_kHz : 0;
250 if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) {
251 silk_assert( 0 );
252 RESTORE_STACK;
253 return ret;
254 }
255 if( psEnc->state_Fxx[n].sCmn.first_frame_after_reset || transition ) {
256 for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) {
257 psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] = 0;
258 }
259 }
260 psEnc->state_Fxx[ n ].sCmn.inDTX = psEnc->state_Fxx[ n ].sCmn.useDTX;
261 }
262 celt_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
263
264 /* Input buffering/resampling and encoding */
265 nSamplesToBufferMax =
266 10 * nBlocksOf10ms * psEnc->state_Fxx[ 0 ].sCmn.fs_kHz;
267 nSamplesFromInputMax =
268 silk_DIV32_16( nSamplesToBufferMax *
269 psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz,
270 psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 );
271 ALLOC( buf, nSamplesFromInputMax, opus_int16 );
272 while( 1 ) {
273 nSamplesToBuffer = psEnc->state_Fxx[ 0 ].sCmn.frame_length - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx;
274 nSamplesToBuffer = silk_min( nSamplesToBuffer, nSamplesToBufferMax );
275 nSamplesFromInput = silk_DIV32_16( nSamplesToBuffer * psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 );
276 /* Resample and write to buffer */
277 if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 2 ) {
278 opus_int id = psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded;
279 for( n = 0; n < nSamplesFromInput; n++ ) {
280 buf[ n ] = samplesIn[ 2 * n ];
281 }
282 /* Making sure to start both resamplers from the same state when switching from mono to stereo */
283 if( psEnc->nPrevChannelsInternal == 1 && id==0 ) {
284 silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof(psEnc->state_Fxx[ 1 ].sCmn.resampler_state));
285 }
286
287 ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
288 &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
289 psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
290
291 nSamplesToBuffer = psEnc->state_Fxx[ 1 ].sCmn.frame_length - psEnc->state_Fxx[ 1 ].sCmn.inputBufIx;
292 nSamplesToBuffer = silk_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
293 for( n = 0; n < nSamplesFromInput; n++ ) {
294 buf[ n ] = samplesIn[ 2 * n + 1 ];
295 }
296 ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state,
297 &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
298
299 psEnc->state_Fxx[ 1 ].sCmn.inputBufIx += nSamplesToBuffer;
300 } else if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 1 ) {
301 /* Combine left and right channels before resampling */
302 for( n = 0; n < nSamplesFromInput; n++ ) {
303 sum = samplesIn[ 2 * n ] + samplesIn[ 2 * n + 1 ];
304 buf[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 );
305 }
306 ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
307 &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
308 /* On the first mono frame, average the results for the two resampler states */
309 if( psEnc->nPrevChannelsInternal == 2 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 ) {
310 ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state,
311 &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
312 for( n = 0; n < psEnc->state_Fxx[ 0 ].sCmn.frame_length; n++ ) {
313 psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ] =
314 silk_RSHIFT(psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ]
315 + psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx+n+2 ], 1);
316 }
317 }
318 psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
319 } else {
320 celt_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 );
321 silk_memcpy(buf, samplesIn, nSamplesFromInput*sizeof(opus_int16));
322 ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
323 &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
324 psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
325 }
326
327 samplesIn += nSamplesFromInput * encControl->nChannelsAPI;
328 nSamplesIn -= nSamplesFromInput;
329
330 /* Default */
331 psEnc->allowBandwidthSwitch = 0;
332
333 /* Silk encoder */
334 if( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx >= psEnc->state_Fxx[ 0 ].sCmn.frame_length ) {
335 /* Enough data in input buffer, so encode */
336 celt_assert( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx == psEnc->state_Fxx[ 0 ].sCmn.frame_length );
337 celt_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inputBufIx == psEnc->state_Fxx[ 1 ].sCmn.frame_length );
338
339 /* Deal with LBRR data */
340 if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 && !prefillFlag ) {
341 /* Create space at start of payload for VAD and FEC flags */
342 opus_uint8 iCDF[ 2 ] = { 0, 0 };
343 iCDF[ 0 ] = 256 - silk_RSHIFT( 256, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal );
344 ec_enc_icdf( psRangeEnc, 0, iCDF, 8 );
345
346 /* Encode any LBRR data from previous packet */
347 /* Encode LBRR flags */
348 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
349 LBRR_symbol = 0;
350 for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) {
351 LBRR_symbol |= silk_LSHIFT( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ], i );
352 }
353 psEnc->state_Fxx[ n ].sCmn.LBRR_flag = LBRR_symbol > 0 ? 1 : 0;
354 if( LBRR_symbol && psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket > 1 ) {
355 ec_enc_icdf( psRangeEnc, LBRR_symbol - 1, silk_LBRR_flags_iCDF_ptr[ psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket - 2 ], 8 );
356 }
357 }
358
359 /* Code LBRR indices and excitation signals */
360 for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) {
361 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
362 if( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] ) {
363 opus_int condCoding;
364
365 if( encControl->nChannelsInternal == 2 && n == 0 ) {
366 silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ i ] );
367 /* For LBRR data there's no need to code the mid-only flag if the side-channel LBRR flag is set */
368 if( psEnc->state_Fxx[ 1 ].sCmn.LBRR_flags[ i ] == 0 ) {
369 silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ i ] );
370 }
371 }
372 /* Use conditional coding if previous frame available */
373 if( i > 0 && psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i - 1 ] ) {
374 condCoding = CODE_CONDITIONALLY;
375 } else {
376 condCoding = CODE_INDEPENDENTLY;
377 }
378 silk_encode_indices( &psEnc->state_Fxx[ n ].sCmn, psRangeEnc, i, 1, condCoding );
379 silk_encode_pulses( psRangeEnc, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].signalType, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].quantOffsetType,
380 psEnc->state_Fxx[ n ].sCmn.pulses_LBRR[ i ], psEnc->state_Fxx[ n ].sCmn.frame_length );
381 }
382 }
383 }
384
385 /* Reset LBRR flags */
386 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
387 silk_memset( psEnc->state_Fxx[ n ].sCmn.LBRR_flags, 0, sizeof( psEnc->state_Fxx[ n ].sCmn.LBRR_flags ) );
388 }
389
390 psEnc->nBitsUsedLBRR = ec_tell( psRangeEnc );
391 }
392
393 silk_HP_variable_cutoff( psEnc->state_Fxx );
394
395 /* Total target bits for packet */
396 nBits = silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 );
397 /* Subtract bits used for LBRR */
398 if( !prefillFlag ) {
399 nBits -= psEnc->nBitsUsedLBRR;
400 }
401 /* Divide by number of uncoded frames left in packet */
402 nBits = silk_DIV32_16( nBits, psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket );
403 /* Convert to bits/second */
404 if( encControl->payloadSize_ms == 10 ) {
405 TargetRate_bps = silk_SMULBB( nBits, 100 );
406 } else {
407 TargetRate_bps = silk_SMULBB( nBits, 50 );
408 }
409 /* Subtract fraction of bits in excess of target in previous frames and packets */
410 TargetRate_bps -= silk_DIV32_16( silk_MUL( psEnc->nBitsExceeded, 1000 ), BITRESERVOIR_DECAY_TIME_MS );
411 if( !prefillFlag && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded > 0 ) {
412 /* Compare actual vs target bits so far in this packet */
413 opus_int32 bitsBalance = ec_tell( psRangeEnc ) - psEnc->nBitsUsedLBRR - nBits * psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded;
414 TargetRate_bps -= silk_DIV32_16( silk_MUL( bitsBalance, 1000 ), BITRESERVOIR_DECAY_TIME_MS );
415 }
416 /* Never exceed input bitrate */
417 TargetRate_bps = silk_LIMIT( TargetRate_bps, encControl->bitRate, 5000 );
418
419 /* Convert Left/Right to Mid/Side */
420 if( encControl->nChannelsInternal == 2 ) {
421 silk_stereo_LR_to_MS( &psEnc->sStereo, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ 2 ], &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ 2 ],
422 psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ], &psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ],
423 MStargetRates_bps, TargetRate_bps, psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8, encControl->toMono,
424 psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, psEnc->state_Fxx[ 0 ].sCmn.frame_length );
425 if( psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) {
426 /* Reset side channel encoder memory for first frame with side coding */
427 if( psEnc->prev_decode_only_middle == 1 ) {
428 silk_memset( &psEnc->state_Fxx[ 1 ].sShape, 0, sizeof( psEnc->state_Fxx[ 1 ].sShape ) );
429 silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sNSQ, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sNSQ ) );
430 silk_memset( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15 ) );
431 silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State ) );
432 psEnc->state_Fxx[ 1 ].sCmn.prevLag = 100;
433 psEnc->state_Fxx[ 1 ].sCmn.sNSQ.lagPrev = 100;
434 psEnc->state_Fxx[ 1 ].sShape.LastGainIndex = 10;
435 psEnc->state_Fxx[ 1 ].sCmn.prevSignalType = TYPE_NO_VOICE_ACTIVITY;
436 psEnc->state_Fxx[ 1 ].sCmn.sNSQ.prev_gain_Q16 = 65536;
437 psEnc->state_Fxx[ 1 ].sCmn.first_frame_after_reset = 1;
438 }
439 silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 1 ], activity );
440 } else {
441 psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] = 0;
442 }
443 if( !prefillFlag ) {
444 silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] );
445 if( psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) {
446 silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] );
447 }
448 }
449 } else {
450 /* Buffering */
451 silk_memcpy( psEnc->state_Fxx[ 0 ].sCmn.inputBuf, psEnc->sStereo.sMid, 2 * sizeof( opus_int16 ) );
452 silk_memcpy( psEnc->sStereo.sMid, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.frame_length ], 2 * sizeof( opus_int16 ) );
453 }
454 silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 0 ], activity );
455
456 /* Encode */
457 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
458 opus_int maxBits, useCBR;
459
460 /* Handling rate constraints */
461 maxBits = encControl->maxBits;
462 if( tot_blocks == 2 && curr_block == 0 ) {
463 maxBits = maxBits * 3 / 5;
464 } else if( tot_blocks == 3 ) {
465 if( curr_block == 0 ) {
466 maxBits = maxBits * 2 / 5;
467 } else if( curr_block == 1 ) {
468 maxBits = maxBits * 3 / 4;
469 }
470 }
471 useCBR = encControl->useCBR && curr_block == tot_blocks - 1;
472
473 if( encControl->nChannelsInternal == 1 ) {
474 channelRate_bps = TargetRate_bps;
475 } else {
476 channelRate_bps = MStargetRates_bps[ n ];
477 if( n == 0 && MStargetRates_bps[ 1 ] > 0 ) {
478 useCBR = 0;
479 /* Give mid up to 1/2 of the max bits for that frame */
480 maxBits -= encControl->maxBits / ( tot_blocks * 2 );
481 }
482 }
483
484 if( channelRate_bps > 0 ) {
485 opus_int condCoding;
486
487 silk_control_SNR( &psEnc->state_Fxx[ n ].sCmn, channelRate_bps );
488
489 /* Use independent coding if no previous frame available */
490 if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - n <= 0 ) {
491 condCoding = CODE_INDEPENDENTLY;
492 } else if( n > 0 && psEnc->prev_decode_only_middle ) {
493 /* If we skipped a side frame in this packet, we don't
494 need LTP scaling; the LTP state is well-defined. */
495 condCoding = CODE_INDEPENDENTLY_NO_LTP_SCALING;
496 } else {
497 condCoding = CODE_CONDITIONALLY;
498 }
499 if( ( ret = silk_encode_frame_Fxx( &psEnc->state_Fxx[ n ], nBytesOut, psRangeEnc, condCoding, maxBits, useCBR ) ) != 0 ) {
500 silk_assert( 0 );
501 }
502 }
503 psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;
504 psEnc->state_Fxx[ n ].sCmn.inputBufIx = 0;
505 psEnc->state_Fxx[ n ].sCmn.nFramesEncoded++;
506 }
507 psEnc->prev_decode_only_middle = psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - 1 ];
508
509 /* Insert VAD and FEC flags at beginning of bitstream */
510 if( *nBytesOut > 0 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket) {
511 flags = 0;
512 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
513 for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) {
514 flags = silk_LSHIFT( flags, 1 );
515 flags |= psEnc->state_Fxx[ n ].sCmn.VAD_flags[ i ];
516 }
517 flags = silk_LSHIFT( flags, 1 );
518 flags |= psEnc->state_Fxx[ n ].sCmn.LBRR_flag;
519 }
520 if( !prefillFlag ) {
521 ec_enc_patch_initial_bits( psRangeEnc, flags, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal );
522 }
523
524 /* Return zero bytes if all channels DTXed */
525 if( psEnc->state_Fxx[ 0 ].sCmn.inDTX && ( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inDTX ) ) {
526 *nBytesOut = 0;
527 }
528
529 psEnc->nBitsExceeded += *nBytesOut * 8;
530 psEnc->nBitsExceeded -= silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 );
531 psEnc->nBitsExceeded = silk_LIMIT( psEnc->nBitsExceeded, 0, 10000 );
532
533 /* Update flag indicating if bandwidth switching is allowed */
534 speech_act_thr_for_switch_Q8 = silk_SMLAWB( SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ),
535 SILK_FIX_CONST( ( 1 - SPEECH_ACTIVITY_DTX_THRES ) / MAX_BANDWIDTH_SWITCH_DELAY_MS, 16 + 8 ), psEnc->timeSinceSwitchAllowed_ms );
536 if( psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8 < speech_act_thr_for_switch_Q8 ) {
537 psEnc->allowBandwidthSwitch = 1;
538 psEnc->timeSinceSwitchAllowed_ms = 0;
539 } else {
540 psEnc->allowBandwidthSwitch = 0;
541 psEnc->timeSinceSwitchAllowed_ms += encControl->payloadSize_ms;
542 }
543 }
544
545 if( nSamplesIn == 0 ) {
546 break;
547 }
548 } else {
549 break;
550 }
551 curr_block++;
552 }
553
554 psEnc->nPrevChannelsInternal = encControl->nChannelsInternal;
555
556 encControl->allowBandwidthSwitch = psEnc->allowBandwidthSwitch;
557 encControl->inWBmodeWithoutVariableLP = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == 16 && psEnc->state_Fxx[ 0 ].sCmn.sLP.mode == 0;
558 encControl->internalSampleRate = silk_SMULBB( psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, 1000 );
559 encControl->stereoWidth_Q14 = encControl->toMono ? 0 : psEnc->sStereo.smth_width_Q14;
560 if( prefillFlag ) {
561 encControl->payloadSize_ms = tmp_payloadSize_ms;
562 encControl->complexity = tmp_complexity;
563 for( n = 0; n < encControl->nChannelsInternal; n++ ) {
564 psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0;
565 psEnc->state_Fxx[ n ].sCmn.prefillFlag = 0;
566 }
567 }
568
569 encControl->signalType = psEnc->state_Fxx[0].sCmn.indices.signalType;
570 encControl->offset = silk_Quantization_Offsets_Q10
571 [ psEnc->state_Fxx[0].sCmn.indices.signalType >> 1 ]
572 [ psEnc->state_Fxx[0].sCmn.indices.quantOffsetType ];
573 RESTORE_STACK;
574 return ret;
575}
576
diff --git a/lib/rbcodec/codecs/libopus/silk/encode_indices.c b/lib/rbcodec/codecs/libopus/silk/encode_indices.c
new file mode 100644
index 0000000000..4bcbc3347b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/encode_indices.c
@@ -0,0 +1,181 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33
34/* Encode side-information parameters to payload */
35void silk_encode_indices(
36 silk_encoder_state *psEncC, /* I/O Encoder state */
37 ec_enc *psRangeEnc, /* I/O Compressor data structure */
38 opus_int FrameIndex, /* I Frame number */
39 opus_int encode_LBRR, /* I Flag indicating LBRR data is being encoded */
40 opus_int condCoding /* I The type of conditional coding to use */
41)
42{
43 opus_int i, k, typeOffset;
44 opus_int encode_absolute_lagIndex, delta_lagIndex;
45 opus_int16 ec_ix[ MAX_LPC_ORDER ];
46 opus_uint8 pred_Q8[ MAX_LPC_ORDER ];
47 const SideInfoIndices *psIndices;
48
49 if( encode_LBRR ) {
50 psIndices = &psEncC->indices_LBRR[ FrameIndex ];
51 } else {
52 psIndices = &psEncC->indices;
53 }
54
55 /*******************************************/
56 /* Encode signal type and quantizer offset */
57 /*******************************************/
58 typeOffset = 2 * psIndices->signalType + psIndices->quantOffsetType;
59 celt_assert( typeOffset >= 0 && typeOffset < 6 );
60 celt_assert( encode_LBRR == 0 || typeOffset >= 2 );
61 if( encode_LBRR || typeOffset >= 2 ) {
62 ec_enc_icdf( psRangeEnc, typeOffset - 2, silk_type_offset_VAD_iCDF, 8 );
63 } else {
64 ec_enc_icdf( psRangeEnc, typeOffset, silk_type_offset_no_VAD_iCDF, 8 );
65 }
66
67 /****************/
68 /* Encode gains */
69 /****************/
70 /* first subframe */
71 if( condCoding == CODE_CONDITIONALLY ) {
72 /* conditional coding */
73 silk_assert( psIndices->GainsIndices[ 0 ] >= 0 && psIndices->GainsIndices[ 0 ] < MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 );
74 ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ 0 ], silk_delta_gain_iCDF, 8 );
75 } else {
76 /* independent coding, in two stages: MSB bits followed by 3 LSBs */
77 silk_assert( psIndices->GainsIndices[ 0 ] >= 0 && psIndices->GainsIndices[ 0 ] < N_LEVELS_QGAIN );
78 ec_enc_icdf( psRangeEnc, silk_RSHIFT( psIndices->GainsIndices[ 0 ], 3 ), silk_gain_iCDF[ psIndices->signalType ], 8 );
79 ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ 0 ] & 7, silk_uniform8_iCDF, 8 );
80 }
81
82 /* remaining subframes */
83 for( i = 1; i < psEncC->nb_subfr; i++ ) {
84 silk_assert( psIndices->GainsIndices[ i ] >= 0 && psIndices->GainsIndices[ i ] < MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 );
85 ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ i ], silk_delta_gain_iCDF, 8 );
86 }
87
88 /****************/
89 /* Encode NLSFs */
90 /****************/
91 ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ 0 ], &psEncC->psNLSF_CB->CB1_iCDF[ ( psIndices->signalType >> 1 ) * psEncC->psNLSF_CB->nVectors ], 8 );
92 silk_NLSF_unpack( ec_ix, pred_Q8, psEncC->psNLSF_CB, psIndices->NLSFIndices[ 0 ] );
93 celt_assert( psEncC->psNLSF_CB->order == psEncC->predictLPCOrder );
94 for( i = 0; i < psEncC->psNLSF_CB->order; i++ ) {
95 if( psIndices->NLSFIndices[ i+1 ] >= NLSF_QUANT_MAX_AMPLITUDE ) {
96 ec_enc_icdf( psRangeEnc, 2 * NLSF_QUANT_MAX_AMPLITUDE, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );
97 ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ i+1 ] - NLSF_QUANT_MAX_AMPLITUDE, silk_NLSF_EXT_iCDF, 8 );
98 } else if( psIndices->NLSFIndices[ i+1 ] <= -NLSF_QUANT_MAX_AMPLITUDE ) {
99 ec_enc_icdf( psRangeEnc, 0, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );
100 ec_enc_icdf( psRangeEnc, -psIndices->NLSFIndices[ i+1 ] - NLSF_QUANT_MAX_AMPLITUDE, silk_NLSF_EXT_iCDF, 8 );
101 } else {
102 ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ i+1 ] + NLSF_QUANT_MAX_AMPLITUDE, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );
103 }
104 }
105
106 /* Encode NLSF interpolation factor */
107 if( psEncC->nb_subfr == MAX_NB_SUBFR ) {
108 silk_assert( psIndices->NLSFInterpCoef_Q2 >= 0 && psIndices->NLSFInterpCoef_Q2 < 5 );
109 ec_enc_icdf( psRangeEnc, psIndices->NLSFInterpCoef_Q2, silk_NLSF_interpolation_factor_iCDF, 8 );
110 }
111
112 if( psIndices->signalType == TYPE_VOICED )
113 {
114 /*********************/
115 /* Encode pitch lags */
116 /*********************/
117 /* lag index */
118 encode_absolute_lagIndex = 1;
119 if( condCoding == CODE_CONDITIONALLY && psEncC->ec_prevSignalType == TYPE_VOICED ) {
120 /* Delta Encoding */
121 delta_lagIndex = psIndices->lagIndex - psEncC->ec_prevLagIndex;
122 if( delta_lagIndex < -8 || delta_lagIndex > 11 ) {
123 delta_lagIndex = 0;
124 } else {
125 delta_lagIndex = delta_lagIndex + 9;
126 encode_absolute_lagIndex = 0; /* Only use delta */
127 }
128 silk_assert( delta_lagIndex >= 0 && delta_lagIndex < 21 );
129 ec_enc_icdf( psRangeEnc, delta_lagIndex, silk_pitch_delta_iCDF, 8 );
130 }
131 if( encode_absolute_lagIndex ) {
132 /* Absolute encoding */
133 opus_int32 pitch_high_bits, pitch_low_bits;
134 pitch_high_bits = silk_DIV32_16( psIndices->lagIndex, silk_RSHIFT( psEncC->fs_kHz, 1 ) );
135 pitch_low_bits = psIndices->lagIndex - silk_SMULBB( pitch_high_bits, silk_RSHIFT( psEncC->fs_kHz, 1 ) );
136 silk_assert( pitch_low_bits < psEncC->fs_kHz / 2 );
137 silk_assert( pitch_high_bits < 32 );
138 ec_enc_icdf( psRangeEnc, pitch_high_bits, silk_pitch_lag_iCDF, 8 );
139 ec_enc_icdf( psRangeEnc, pitch_low_bits, psEncC->pitch_lag_low_bits_iCDF, 8 );
140 }
141 psEncC->ec_prevLagIndex = psIndices->lagIndex;
142
143 /* Countour index */
144 silk_assert( psIndices->contourIndex >= 0 );
145 silk_assert( ( psIndices->contourIndex < 34 && psEncC->fs_kHz > 8 && psEncC->nb_subfr == 4 ) ||
146 ( psIndices->contourIndex < 11 && psEncC->fs_kHz == 8 && psEncC->nb_subfr == 4 ) ||
147 ( psIndices->contourIndex < 12 && psEncC->fs_kHz > 8 && psEncC->nb_subfr == 2 ) ||
148 ( psIndices->contourIndex < 3 && psEncC->fs_kHz == 8 && psEncC->nb_subfr == 2 ) );
149 ec_enc_icdf( psRangeEnc, psIndices->contourIndex, psEncC->pitch_contour_iCDF, 8 );
150
151 /********************/
152 /* Encode LTP gains */
153 /********************/
154 /* PERIndex value */
155 silk_assert( psIndices->PERIndex >= 0 && psIndices->PERIndex < 3 );
156 ec_enc_icdf( psRangeEnc, psIndices->PERIndex, silk_LTP_per_index_iCDF, 8 );
157
158 /* Codebook Indices */
159 for( k = 0; k < psEncC->nb_subfr; k++ ) {
160 silk_assert( psIndices->LTPIndex[ k ] >= 0 && psIndices->LTPIndex[ k ] < ( 8 << psIndices->PERIndex ) );
161 ec_enc_icdf( psRangeEnc, psIndices->LTPIndex[ k ], silk_LTP_gain_iCDF_ptrs[ psIndices->PERIndex ], 8 );
162 }
163
164 /**********************/
165 /* Encode LTP scaling */
166 /**********************/
167 if( condCoding == CODE_INDEPENDENTLY ) {
168 silk_assert( psIndices->LTP_scaleIndex >= 0 && psIndices->LTP_scaleIndex < 3 );
169 ec_enc_icdf( psRangeEnc, psIndices->LTP_scaleIndex, silk_LTPscale_iCDF, 8 );
170 }
171 silk_assert( !condCoding || psIndices->LTP_scaleIndex == 0 );
172 }
173
174 psEncC->ec_prevSignalType = psIndices->signalType;
175
176 /***************/
177 /* Encode seed */
178 /***************/
179 silk_assert( psIndices->Seed >= 0 && psIndices->Seed < 4 );
180 ec_enc_icdf( psRangeEnc, psIndices->Seed, silk_uniform4_iCDF, 8 );
181}
diff --git a/lib/rbcodec/codecs/libopus/silk/encode_pulses.c b/lib/rbcodec/codecs/libopus/silk/encode_pulses.c
new file mode 100644
index 0000000000..8a1999138b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/encode_pulses.c
@@ -0,0 +1,206 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33#include "stack_alloc.h"
34
35/*********************************************/
36/* Encode quantization indices of excitation */
37/*********************************************/
38
39static OPUS_INLINE opus_int combine_and_check( /* return ok */
40 opus_int *pulses_comb, /* O */
41 const opus_int *pulses_in, /* I */
42 opus_int max_pulses, /* I max value for sum of pulses */
43 opus_int len /* I number of output values */
44)
45{
46 opus_int k, sum;
47
48 for( k = 0; k < len; k++ ) {
49 sum = pulses_in[ 2 * k ] + pulses_in[ 2 * k + 1 ];
50 if( sum > max_pulses ) {
51 return 1;
52 }
53 pulses_comb[ k ] = sum;
54 }
55
56 return 0;
57}
58
59/* Encode quantization indices of excitation */
60void silk_encode_pulses(
61 ec_enc *psRangeEnc, /* I/O compressor data structure */
62 const opus_int signalType, /* I Signal type */
63 const opus_int quantOffsetType, /* I quantOffsetType */
64 opus_int8 pulses[], /* I quantization indices */
65 const opus_int frame_length /* I Frame length */
66)
67{
68 opus_int i, k, j, iter, bit, nLS, scale_down, RateLevelIndex = 0;
69 opus_int32 abs_q, minSumBits_Q5, sumBits_Q5;
70 VARDECL( opus_int, abs_pulses );
71 VARDECL( opus_int, sum_pulses );
72 VARDECL( opus_int, nRshifts );
73 opus_int pulses_comb[ 8 ];
74 opus_int *abs_pulses_ptr;
75 const opus_int8 *pulses_ptr;
76 const opus_uint8 *cdf_ptr;
77 const opus_uint8 *nBits_ptr;
78 SAVE_STACK;
79
80 silk_memset( pulses_comb, 0, 8 * sizeof( opus_int ) ); /* Fixing Valgrind reported problem*/
81
82 /****************************/
83 /* Prepare for shell coding */
84 /****************************/
85 /* Calculate number of shell blocks */
86 silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH );
87 iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH );
88 if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) {
89 celt_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */
90 iter++;
91 silk_memset( &pulses[ frame_length ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof(opus_int8));
92 }
93
94 /* Take the absolute value of the pulses */
95 ALLOC( abs_pulses, iter * SHELL_CODEC_FRAME_LENGTH, opus_int );
96 silk_assert( !( SHELL_CODEC_FRAME_LENGTH & 3 ) );
97 for( i = 0; i < iter * SHELL_CODEC_FRAME_LENGTH; i+=4 ) {
98 abs_pulses[i+0] = ( opus_int )silk_abs( pulses[ i + 0 ] );
99 abs_pulses[i+1] = ( opus_int )silk_abs( pulses[ i + 1 ] );
100 abs_pulses[i+2] = ( opus_int )silk_abs( pulses[ i + 2 ] );
101 abs_pulses[i+3] = ( opus_int )silk_abs( pulses[ i + 3 ] );
102 }
103
104 /* Calc sum pulses per shell code frame */
105 ALLOC( sum_pulses, iter, opus_int );
106 ALLOC( nRshifts, iter, opus_int );
107 abs_pulses_ptr = abs_pulses;
108 for( i = 0; i < iter; i++ ) {
109 nRshifts[ i ] = 0;
110
111 while( 1 ) {
112 /* 1+1 -> 2 */
113 scale_down = combine_and_check( pulses_comb, abs_pulses_ptr, silk_max_pulses_table[ 0 ], 8 );
114 /* 2+2 -> 4 */
115 scale_down += combine_and_check( pulses_comb, pulses_comb, silk_max_pulses_table[ 1 ], 4 );
116 /* 4+4 -> 8 */
117 scale_down += combine_and_check( pulses_comb, pulses_comb, silk_max_pulses_table[ 2 ], 2 );
118 /* 8+8 -> 16 */
119 scale_down += combine_and_check( &sum_pulses[ i ], pulses_comb, silk_max_pulses_table[ 3 ], 1 );
120
121 if( scale_down ) {
122 /* We need to downscale the quantization signal */
123 nRshifts[ i ]++;
124 for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {
125 abs_pulses_ptr[ k ] = silk_RSHIFT( abs_pulses_ptr[ k ], 1 );
126 }
127 } else {
128 /* Jump out of while(1) loop and go to next shell coding frame */
129 break;
130 }
131 }
132 abs_pulses_ptr += SHELL_CODEC_FRAME_LENGTH;
133 }
134
135 /**************/
136 /* Rate level */
137 /**************/
138 /* find rate level that leads to fewest bits for coding of pulses per block info */
139 minSumBits_Q5 = silk_int32_MAX;
140 for( k = 0; k < N_RATE_LEVELS - 1; k++ ) {
141 nBits_ptr = silk_pulses_per_block_BITS_Q5[ k ];
142 sumBits_Q5 = silk_rate_levels_BITS_Q5[ signalType >> 1 ][ k ];
143 for( i = 0; i < iter; i++ ) {
144 if( nRshifts[ i ] > 0 ) {
145 sumBits_Q5 += nBits_ptr[ SILK_MAX_PULSES + 1 ];
146 } else {
147 sumBits_Q5 += nBits_ptr[ sum_pulses[ i ] ];
148 }
149 }
150 if( sumBits_Q5 < minSumBits_Q5 ) {
151 minSumBits_Q5 = sumBits_Q5;
152 RateLevelIndex = k;
153 }
154 }
155 ec_enc_icdf( psRangeEnc, RateLevelIndex, silk_rate_levels_iCDF[ signalType >> 1 ], 8 );
156
157 /***************************************************/
158 /* Sum-Weighted-Pulses Encoding */
159 /***************************************************/
160 cdf_ptr = silk_pulses_per_block_iCDF[ RateLevelIndex ];
161 for( i = 0; i < iter; i++ ) {
162 if( nRshifts[ i ] == 0 ) {
163 ec_enc_icdf( psRangeEnc, sum_pulses[ i ], cdf_ptr, 8 );
164 } else {
165 ec_enc_icdf( psRangeEnc, SILK_MAX_PULSES + 1, cdf_ptr, 8 );
166 for( k = 0; k < nRshifts[ i ] - 1; k++ ) {
167 ec_enc_icdf( psRangeEnc, SILK_MAX_PULSES + 1, silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1 ], 8 );
168 }
169 ec_enc_icdf( psRangeEnc, sum_pulses[ i ], silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1 ], 8 );
170 }
171 }
172
173 /******************/
174 /* Shell Encoding */
175 /******************/
176 for( i = 0; i < iter; i++ ) {
177 if( sum_pulses[ i ] > 0 ) {
178 silk_shell_encoder( psRangeEnc, &abs_pulses[ i * SHELL_CODEC_FRAME_LENGTH ] );
179 }
180 }
181
182 /****************/
183 /* LSB Encoding */
184 /****************/
185 for( i = 0; i < iter; i++ ) {
186 if( nRshifts[ i ] > 0 ) {
187 pulses_ptr = &pulses[ i * SHELL_CODEC_FRAME_LENGTH ];
188 nLS = nRshifts[ i ] - 1;
189 for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) {
190 abs_q = (opus_int8)silk_abs( pulses_ptr[ k ] );
191 for( j = nLS; j > 0; j-- ) {
192 bit = silk_RSHIFT( abs_q, j ) & 1;
193 ec_enc_icdf( psRangeEnc, bit, silk_lsb_iCDF, 8 );
194 }
195 bit = abs_q & 1;
196 ec_enc_icdf( psRangeEnc, bit, silk_lsb_iCDF, 8 );
197 }
198 }
199 }
200
201 /****************/
202 /* Encode signs */
203 /****************/
204 silk_encode_signs( psRangeEnc, pulses, frame_length, signalType, quantOffsetType, sum_pulses );
205 RESTORE_STACK;
206}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/LTP_analysis_filter_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/LTP_analysis_filter_FIX.c
new file mode 100644
index 0000000000..5574e7069f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/LTP_analysis_filter_FIX.c
@@ -0,0 +1,90 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33
34void silk_LTP_analysis_filter_FIX(
35 opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */
36 const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */
37 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */
38 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */
39 const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */
40 const opus_int subfr_length, /* I Length of each subframe */
41 const opus_int nb_subfr, /* I Number of subframes */
42 const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */
43)
44{
45 const opus_int16 *x_ptr, *x_lag_ptr;
46 opus_int16 Btmp_Q14[ LTP_ORDER ];
47 opus_int16 *LTP_res_ptr;
48 opus_int k, i;
49 opus_int32 LTP_est;
50
51 x_ptr = x;
52 LTP_res_ptr = LTP_res;
53 for( k = 0; k < nb_subfr; k++ ) {
54
55 x_lag_ptr = x_ptr - pitchL[ k ];
56
57 Btmp_Q14[ 0 ] = LTPCoef_Q14[ k * LTP_ORDER ];
58 Btmp_Q14[ 1 ] = LTPCoef_Q14[ k * LTP_ORDER + 1 ];
59 Btmp_Q14[ 2 ] = LTPCoef_Q14[ k * LTP_ORDER + 2 ];
60 Btmp_Q14[ 3 ] = LTPCoef_Q14[ k * LTP_ORDER + 3 ];
61 Btmp_Q14[ 4 ] = LTPCoef_Q14[ k * LTP_ORDER + 4 ];
62
63 /* LTP analysis FIR filter */
64 for( i = 0; i < subfr_length + pre_length; i++ ) {
65 LTP_res_ptr[ i ] = x_ptr[ i ];
66
67 /* Long-term prediction */
68 LTP_est = silk_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] );
69 LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ 1 ], Btmp_Q14[ 1 ] );
70 LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ 0 ], Btmp_Q14[ 2 ] );
71 LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ -1 ], Btmp_Q14[ 3 ] );
72 LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ -2 ], Btmp_Q14[ 4 ] );
73
74 LTP_est = silk_RSHIFT_ROUND( LTP_est, 14 ); /* round and -> Q0*/
75
76 /* Subtract long-term prediction */
77 LTP_res_ptr[ i ] = (opus_int16)silk_SAT16( (opus_int32)x_ptr[ i ] - LTP_est );
78
79 /* Scale residual */
80 LTP_res_ptr[ i ] = silk_SMULWB( invGains_Q16[ k ], LTP_res_ptr[ i ] );
81
82 x_lag_ptr++;
83 }
84
85 /* Update pointers */
86 LTP_res_ptr += subfr_length + pre_length;
87 x_ptr += subfr_length;
88 }
89}
90
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/LTP_scale_ctrl_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/LTP_scale_ctrl_FIX.c
new file mode 100644
index 0000000000..3dcedef891
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/LTP_scale_ctrl_FIX.c
@@ -0,0 +1,53 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33
34/* Calculation of LTP state scaling */
35void silk_LTP_scale_ctrl_FIX(
36 silk_encoder_state_FIX *psEnc, /* I/O encoder state */
37 silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
38 opus_int condCoding /* I The type of conditional coding to use */
39)
40{
41 opus_int round_loss;
42
43 if( condCoding == CODE_INDEPENDENTLY ) {
44 /* Only scale if first frame in packet */
45 round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket;
46 psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT(
47 silk_SMULWB( silk_SMULBB( round_loss, psEncCtrl->LTPredCodGain_Q7 ), SILK_FIX_CONST( 0.1, 9 ) ), 0, 2 );
48 } else {
49 /* Default is minimum scaling */
50 psEnc->sCmn.indices.LTP_scaleIndex = 0;
51 }
52 psEncCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ];
53}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/apply_sine_window_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/apply_sine_window_FIX.c
new file mode 100644
index 0000000000..03e088a6de
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/apply_sine_window_FIX.c
@@ -0,0 +1,101 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33
34/* Apply sine window to signal vector. */
35/* Window types: */
36/* 1 -> sine window from 0 to pi/2 */
37/* 2 -> sine window from pi/2 to pi */
38/* Every other sample is linearly interpolated, for speed. */
39/* Window length must be between 16 and 120 (incl) and a multiple of 4. */
40
41/* Matlab code for table:
42 for k=16:9*4:16+2*9*4, fprintf(' %7.d,', -round(65536*pi ./ (k:4:k+8*4))); fprintf('\n'); end
43*/
44static const opus_int16 freq_table_Q16[ 27 ] = {
45 12111, 9804, 8235, 7100, 6239, 5565, 5022, 4575, 4202,
46 3885, 3612, 3375, 3167, 2984, 2820, 2674, 2542, 2422,
47 2313, 2214, 2123, 2038, 1961, 1889, 1822, 1760, 1702,
48};
49
50void silk_apply_sine_window(
51 opus_int16 px_win[], /* O Pointer to windowed signal */
52 const opus_int16 px[], /* I Pointer to input signal */
53 const opus_int win_type, /* I Selects a window type */
54 const opus_int length /* I Window length, multiple of 4 */
55)
56{
57 opus_int k, f_Q16, c_Q16;
58 opus_int32 S0_Q16, S1_Q16;
59
60 celt_assert( win_type == 1 || win_type == 2 );
61
62 /* Length must be in a range from 16 to 120 and a multiple of 4 */
63 celt_assert( length >= 16 && length <= 120 );
64 celt_assert( ( length & 3 ) == 0 );
65
66 /* Frequency */
67 k = ( length >> 2 ) - 4;
68 celt_assert( k >= 0 && k <= 26 );
69 f_Q16 = (opus_int)freq_table_Q16[ k ];
70
71 /* Factor used for cosine approximation */
72 c_Q16 = silk_SMULWB( (opus_int32)f_Q16, -f_Q16 );
73 silk_assert( c_Q16 >= -32768 );
74
75 /* initialize state */
76 if( win_type == 1 ) {
77 /* start from 0 */
78 S0_Q16 = 0;
79 /* approximation of sin(f) */
80 S1_Q16 = f_Q16 + silk_RSHIFT( length, 3 );
81 } else {
82 /* start from 1 */
83 S0_Q16 = ( (opus_int32)1 << 16 );
84 /* approximation of cos(f) */
85 S1_Q16 = ( (opus_int32)1 << 16 ) + silk_RSHIFT( c_Q16, 1 ) + silk_RSHIFT( length, 4 );
86 }
87
88 /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */
89 /* 4 samples at a time */
90 for( k = 0; k < length; k += 4 ) {
91 px_win[ k ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k ] );
92 px_win[ k + 1 ] = (opus_int16)silk_SMULWB( S1_Q16, px[ k + 1] );
93 S0_Q16 = silk_SMULWB( S1_Q16, c_Q16 ) + silk_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1;
94 S0_Q16 = silk_min( S0_Q16, ( (opus_int32)1 << 16 ) );
95
96 px_win[ k + 2 ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k + 2] );
97 px_win[ k + 3 ] = (opus_int16)silk_SMULWB( S0_Q16, px[ k + 3 ] );
98 S1_Q16 = silk_SMULWB( S0_Q16, c_Q16 ) + silk_LSHIFT( S0_Q16, 1 ) - S1_Q16;
99 S1_Q16 = silk_min( S1_Q16, ( (opus_int32)1 << 16 ) );
100 }
101}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_arm.h b/lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_arm.h
new file mode 100644
index 0000000000..1992e43288
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_arm.h
@@ -0,0 +1,68 @@
1/***********************************************************************
2Copyright (c) 2017 Google Inc.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef SILK_WARPED_AUTOCORRELATION_FIX_ARM_H
29# define SILK_WARPED_AUTOCORRELATION_FIX_ARM_H
30
31# include "celt/arm/armcpu.h"
32
33# if defined(FIXED_POINT)
34
35# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
36void silk_warped_autocorrelation_FIX_neon(
37 opus_int32 *corr, /* O Result [order + 1] */
38 opus_int *scale, /* O Scaling of the correlation vector */
39 const opus_int16 *input, /* I Input data to correlate */
40 const opus_int warping_Q16, /* I Warping coefficient */
41 const opus_int length, /* I Length of input */
42 const opus_int order /* I Correlation order (even) */
43);
44
45# if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON)
46# define OVERRIDE_silk_warped_autocorrelation_FIX (1)
47# define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
48 ((void)(arch), PRESUME_NEON(silk_warped_autocorrelation_FIX)(corr, scale, input, warping_Q16, length, order))
49# endif
50# endif
51
52# if !defined(OVERRIDE_silk_warped_autocorrelation_FIX)
53/*Is run-time CPU detection enabled on this platform?*/
54# if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
55extern void (*const SILK_WARPED_AUTOCORRELATION_FIX_IMPL[OPUS_ARCHMASK+1])(opus_int32*, opus_int*, const opus_int16*, const opus_int, const opus_int, const opus_int);
56# define OVERRIDE_silk_warped_autocorrelation_FIX (1)
57# define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
58 ((*SILK_WARPED_AUTOCORRELATION_FIX_IMPL[(arch)&OPUS_ARCHMASK])(corr, scale, input, warping_Q16, length, order))
59# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
60# define OVERRIDE_silk_warped_autocorrelation_FIX (1)
61# define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
62 ((void)(arch), silk_warped_autocorrelation_FIX_neon(corr, scale, input, warping_Q16, length, order))
63# endif
64# endif
65
66# endif /* end FIXED_POINT */
67
68#endif /* end SILK_WARPED_AUTOCORRELATION_FIX_ARM_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c b/lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c
new file mode 100644
index 0000000000..00a70cb51f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c
@@ -0,0 +1,260 @@
1/***********************************************************************
2Copyright (c) 2017 Google Inc., Jean-Marc Valin
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <arm_neon.h>
33#ifdef OPUS_CHECK_ASM
34# include <string.h>
35#endif
36#include "stack_alloc.h"
37#include "main_FIX.h"
38
39static OPUS_INLINE void calc_corr( const opus_int32 *const input_QS, opus_int64 *const corr_QC, const opus_int offset, const int32x4_t state_QS_s32x4 )
40{
41 int64x2_t corr_QC_s64x2[ 2 ], t_s64x2[ 2 ];
42 const int32x4_t input_QS_s32x4 = vld1q_s32( input_QS + offset );
43 corr_QC_s64x2[ 0 ] = vld1q_s64( corr_QC + offset + 0 );
44 corr_QC_s64x2[ 1 ] = vld1q_s64( corr_QC + offset + 2 );
45 t_s64x2[ 0 ] = vmull_s32( vget_low_s32( state_QS_s32x4 ), vget_low_s32( input_QS_s32x4 ) );
46 t_s64x2[ 1 ] = vmull_s32( vget_high_s32( state_QS_s32x4 ), vget_high_s32( input_QS_s32x4 ) );
47 corr_QC_s64x2[ 0 ] = vsraq_n_s64( corr_QC_s64x2[ 0 ], t_s64x2[ 0 ], 2 * QS - QC );
48 corr_QC_s64x2[ 1 ] = vsraq_n_s64( corr_QC_s64x2[ 1 ], t_s64x2[ 1 ], 2 * QS - QC );
49 vst1q_s64( corr_QC + offset + 0, corr_QC_s64x2[ 0 ] );
50 vst1q_s64( corr_QC + offset + 2, corr_QC_s64x2[ 1 ] );
51}
52
53static OPUS_INLINE int32x4_t calc_state( const int32x4_t state_QS0_s32x4, const int32x4_t state_QS0_1_s32x4, const int32x4_t state_QS1_1_s32x4, const int32x4_t warping_Q16_s32x4 )
54{
55 int32x4_t t_s32x4 = vsubq_s32( state_QS0_s32x4, state_QS0_1_s32x4 );
56 t_s32x4 = vqdmulhq_s32( t_s32x4, warping_Q16_s32x4 );
57 return vaddq_s32( state_QS1_1_s32x4, t_s32x4 );
58}
59
60void silk_warped_autocorrelation_FIX_neon(
61 opus_int32 *corr, /* O Result [order + 1] */
62 opus_int *scale, /* O Scaling of the correlation vector */
63 const opus_int16 *input, /* I Input data to correlate */
64 const opus_int warping_Q16, /* I Warping coefficient */
65 const opus_int length, /* I Length of input */
66 const opus_int order /* I Correlation order (even) */
67)
68{
69 if( ( MAX_SHAPE_LPC_ORDER > 24 ) || ( order < 6 ) ) {
70 silk_warped_autocorrelation_FIX_c( corr, scale, input, warping_Q16, length, order );
71 } else {
72 opus_int n, i, lsh;
73 opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; /* In reverse order */
74 opus_int64 corr_QC_orderT;
75 int64x2_t lsh_s64x2;
76 const opus_int orderT = ( order + 3 ) & ~3;
77 opus_int64 *corr_QCT;
78 opus_int32 *input_QS;
79 VARDECL( opus_int32, input_QST );
80 VARDECL( opus_int32, state );
81 SAVE_STACK;
82
83 /* Order must be even */
84 silk_assert( ( order & 1 ) == 0 );
85 silk_assert( 2 * QS - QC >= 0 );
86
87 ALLOC( input_QST, length + 2 * MAX_SHAPE_LPC_ORDER, opus_int32 );
88
89 input_QS = input_QST;
90 /* input_QS has zero paddings in the beginning and end. */
91 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
92 input_QS += 4;
93 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
94 input_QS += 4;
95 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
96 input_QS += 4;
97 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
98 input_QS += 4;
99 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
100 input_QS += 4;
101 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
102 input_QS += 4;
103
104 /* Loop over samples */
105 for( n = 0; n < length - 7; n += 8, input_QS += 8 ) {
106 const int16x8_t t0_s16x4 = vld1q_s16( input + n );
107 vst1q_s32( input_QS + 0, vshll_n_s16( vget_low_s16( t0_s16x4 ), QS ) );
108 vst1q_s32( input_QS + 4, vshll_n_s16( vget_high_s16( t0_s16x4 ), QS ) );
109 }
110 for( ; n < length; n++, input_QS++ ) {
111 input_QS[ 0 ] = silk_LSHIFT32( (opus_int32)input[ n ], QS );
112 }
113 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
114 input_QS += 4;
115 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
116 input_QS += 4;
117 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
118 input_QS += 4;
119 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
120 input_QS += 4;
121 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
122 input_QS += 4;
123 vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
124 input_QS = input_QST + MAX_SHAPE_LPC_ORDER - orderT;
125
126 /* The following loop runs ( length + order ) times, with ( order ) extra epilogues. */
127 /* The zero paddings in input_QS guarantee corr_QC's correctness even with the extra epilogues. */
128 /* The values of state_QS will be polluted by the extra epilogues, however they are temporary values. */
129
130 /* Keep the C code here to help understand the intrinsics optimization. */
131 /*
132 {
133 opus_int32 state_QS[ 2 ][ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
134 opus_int32 *state_QST[ 3 ];
135 state_QST[ 0 ] = state_QS[ 0 ];
136 state_QST[ 1 ] = state_QS[ 1 ];
137 for( n = 0; n < length + order; n++, input_QS++ ) {
138 state_QST[ 0 ][ orderT ] = input_QS[ orderT ];
139 for( i = 0; i < orderT; i++ ) {
140 corr_QC[ i ] += silk_RSHIFT64( silk_SMULL( state_QST[ 0 ][ i ], input_QS[ i ] ), 2 * QS - QC );
141 state_QST[ 1 ][ i ] = silk_SMLAWB( state_QST[ 1 ][ i + 1 ], state_QST[ 0 ][ i ] - state_QST[ 0 ][ i + 1 ], warping_Q16 );
142 }
143 state_QST[ 2 ] = state_QST[ 0 ];
144 state_QST[ 0 ] = state_QST[ 1 ];
145 state_QST[ 1 ] = state_QST[ 2 ];
146 }
147 }
148 */
149
150 {
151 const int32x4_t warping_Q16_s32x4 = vdupq_n_s32( warping_Q16 << 15 );
152 const opus_int32 *in = input_QS + orderT;
153 opus_int o = orderT;
154 int32x4_t state_QS_s32x4[ 3 ][ 2 ];
155
156 ALLOC( state, length + orderT, opus_int32 );
157 state_QS_s32x4[ 2 ][ 1 ] = vdupq_n_s32( 0 );
158
159 /* Calculate 8 taps of all inputs in each loop. */
160 do {
161 state_QS_s32x4[ 0 ][ 0 ] = state_QS_s32x4[ 0 ][ 1 ] =
162 state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 1 ][ 1 ] = vdupq_n_s32( 0 );
163 n = 0;
164 do {
165 calc_corr( input_QS + n, corr_QC, o - 8, state_QS_s32x4[ 0 ][ 0 ] );
166 calc_corr( input_QS + n, corr_QC, o - 4, state_QS_s32x4[ 0 ][ 1 ] );
167 state_QS_s32x4[ 2 ][ 1 ] = vld1q_s32( in + n );
168 vst1q_lane_s32( state + n, state_QS_s32x4[ 0 ][ 0 ], 0 );
169 state_QS_s32x4[ 2 ][ 0 ] = vextq_s32( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 0 ][ 1 ], 1 );
170 state_QS_s32x4[ 2 ][ 1 ] = vextq_s32( state_QS_s32x4[ 0 ][ 1 ], state_QS_s32x4[ 2 ][ 1 ], 1 );
171 state_QS_s32x4[ 0 ][ 0 ] = calc_state( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 2 ][ 0 ], state_QS_s32x4[ 1 ][ 0 ], warping_Q16_s32x4 );
172 state_QS_s32x4[ 0 ][ 1 ] = calc_state( state_QS_s32x4[ 0 ][ 1 ], state_QS_s32x4[ 2 ][ 1 ], state_QS_s32x4[ 1 ][ 1 ], warping_Q16_s32x4 );
173 state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 2 ][ 0 ];
174 state_QS_s32x4[ 1 ][ 1 ] = state_QS_s32x4[ 2 ][ 1 ];
175 } while( ++n < ( length + order ) );
176 in = state;
177 o -= 8;
178 } while( o > 4 );
179
180 if( o ) {
181 /* Calculate the last 4 taps of all inputs. */
182 opus_int32 *stateT = state;
183 silk_assert( o == 4 );
184 state_QS_s32x4[ 0 ][ 0 ] = state_QS_s32x4[ 1 ][ 0 ] = vdupq_n_s32( 0 );
185 n = length + order;
186 do {
187 calc_corr( input_QS, corr_QC, 0, state_QS_s32x4[ 0 ][ 0 ] );
188 state_QS_s32x4[ 2 ][ 0 ] = vld1q_s32( stateT );
189 vst1q_lane_s32( stateT, state_QS_s32x4[ 0 ][ 0 ], 0 );
190 state_QS_s32x4[ 2 ][ 0 ] = vextq_s32( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 2 ][ 0 ], 1 );
191 state_QS_s32x4[ 0 ][ 0 ] = calc_state( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 2 ][ 0 ], state_QS_s32x4[ 1 ][ 0 ], warping_Q16_s32x4 );
192 state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 2 ][ 0 ];
193 input_QS++;
194 stateT++;
195 } while( --n );
196 }
197 }
198
199 {
200 const opus_int16 *inputT = input;
201 int32x4_t t_s32x4;
202 int64x1_t t_s64x1;
203 int64x2_t t_s64x2 = vdupq_n_s64( 0 );
204 for( n = 0; n <= length - 8; n += 8 ) {
205 int16x8_t input_s16x8 = vld1q_s16( inputT );
206 t_s32x4 = vmull_s16( vget_low_s16( input_s16x8 ), vget_low_s16( input_s16x8 ) );
207 t_s32x4 = vmlal_s16( t_s32x4, vget_high_s16( input_s16x8 ), vget_high_s16( input_s16x8 ) );
208 t_s64x2 = vaddw_s32( t_s64x2, vget_low_s32( t_s32x4 ) );
209 t_s64x2 = vaddw_s32( t_s64x2, vget_high_s32( t_s32x4 ) );
210 inputT += 8;
211 }
212 t_s64x1 = vadd_s64( vget_low_s64( t_s64x2 ), vget_high_s64( t_s64x2 ) );
213 corr_QC_orderT = vget_lane_s64( t_s64x1, 0 );
214 for( ; n < length; n++ ) {
215 corr_QC_orderT += silk_SMULL( input[ n ], input[ n ] );
216 }
217 corr_QC_orderT = silk_LSHIFT64( corr_QC_orderT, QC );
218 corr_QC[ orderT ] = corr_QC_orderT;
219 }
220
221 corr_QCT = corr_QC + orderT - order;
222 lsh = silk_CLZ64( corr_QC_orderT ) - 35;
223 lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC );
224 *scale = -( QC + lsh );
225 silk_assert( *scale >= -30 && *scale <= 12 );
226 lsh_s64x2 = vdupq_n_s64( lsh );
227 for( i = 0; i <= order - 3; i += 4 ) {
228 int32x4_t corr_s32x4;
229 int64x2_t corr_QC0_s64x2, corr_QC1_s64x2;
230 corr_QC0_s64x2 = vld1q_s64( corr_QCT + i );
231 corr_QC1_s64x2 = vld1q_s64( corr_QCT + i + 2 );
232 corr_QC0_s64x2 = vshlq_s64( corr_QC0_s64x2, lsh_s64x2 );
233 corr_QC1_s64x2 = vshlq_s64( corr_QC1_s64x2, lsh_s64x2 );
234 corr_s32x4 = vcombine_s32( vmovn_s64( corr_QC1_s64x2 ), vmovn_s64( corr_QC0_s64x2 ) );
235 corr_s32x4 = vrev64q_s32( corr_s32x4 );
236 vst1q_s32( corr + order - i - 3, corr_s32x4 );
237 }
238 if( lsh >= 0 ) {
239 for( ; i < order + 1; i++ ) {
240 corr[ order - i ] = (opus_int32)silk_CHECK_FIT32( silk_LSHIFT64( corr_QCT[ i ], lsh ) );
241 }
242 } else {
243 for( ; i < order + 1; i++ ) {
244 corr[ order - i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr_QCT[ i ], -lsh ) );
245 }
246 }
247 silk_assert( corr_QCT[ order ] >= 0 ); /* If breaking, decrease QC*/
248 RESTORE_STACK;
249 }
250
251#ifdef OPUS_CHECK_ASM
252 {
253 opus_int32 corr_c[ MAX_SHAPE_LPC_ORDER + 1 ];
254 opus_int scale_c;
255 silk_warped_autocorrelation_FIX_c( corr_c, &scale_c, input, warping_Q16, length, order );
256 silk_assert( !memcmp( corr_c, corr, sizeof( corr_c[ 0 ] ) * ( order + 1 ) ) );
257 silk_assert( scale_c == *scale );
258 }
259#endif
260}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/autocorr_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/autocorr_FIX.c
new file mode 100644
index 0000000000..de95c98693
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/autocorr_FIX.c
@@ -0,0 +1,48 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33#include "celt_lpc.h"
34
35/* Compute autocorrelation */
36void silk_autocorr(
37 opus_int32 *results, /* O Result (length correlationCount) */
38 opus_int *scale, /* O Scaling of the correlation vector */
39 const opus_int16 *inputData, /* I Input data to correlate */
40 const opus_int inputDataSize, /* I Length of input */
41 const opus_int correlationCount, /* I Number of correlation taps to compute */
42 int arch /* I Run-time architecture */
43)
44{
45 opus_int corrCount;
46 corrCount = silk_min_int( inputDataSize, correlationCount );
47 *scale = _celt_autocorr(inputData, results, NULL, 0, corrCount-1, inputDataSize, arch);
48}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/burg_modified_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/burg_modified_FIX.c
new file mode 100644
index 0000000000..274d4b28e1
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/burg_modified_FIX.c
@@ -0,0 +1,280 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33#include "define.h"
34#include "tuning_parameters.h"
35#include "pitch.h"
36
37#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */
38
39#define QA 25
40#define N_BITS_HEAD_ROOM 3
41#define MIN_RSHIFTS -16
42#define MAX_RSHIFTS (32 - QA)
43
44/* Compute reflection coefficients from input signal */
45void silk_burg_modified_c(
46 opus_int32 *res_nrg, /* O Residual energy */
47 opus_int *res_nrg_Q, /* O Residual energy Q value */
48 opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
49 const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
50 const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
51 const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */
52 const opus_int nb_subfr, /* I Number of subframes stacked in x */
53 const opus_int D, /* I Order */
54 int arch /* I Run-time architecture */
55)
56{
57 opus_int k, n, s, lz, rshifts, reached_max_gain;
58 opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2;
59 const opus_int16 *x_ptr;
60 opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ];
61 opus_int32 C_last_row[ SILK_MAX_ORDER_LPC ];
62 opus_int32 Af_QA[ SILK_MAX_ORDER_LPC ];
63 opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ];
64 opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ];
65 opus_int32 xcorr[ SILK_MAX_ORDER_LPC ];
66 opus_int64 C0_64;
67
68 celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
69
70 /* Compute autocorrelations, added over subframes */
71 C0_64 = silk_inner_prod16_aligned_64( x, x, subfr_length*nb_subfr, arch );
72 lz = silk_CLZ64(C0_64);
73 rshifts = 32 + 1 + N_BITS_HEAD_ROOM - lz;
74 if (rshifts > MAX_RSHIFTS) rshifts = MAX_RSHIFTS;
75 if (rshifts < MIN_RSHIFTS) rshifts = MIN_RSHIFTS;
76
77 if (rshifts > 0) {
78 C0 = (opus_int32)silk_RSHIFT64(C0_64, rshifts );
79 } else {
80 C0 = silk_LSHIFT32((opus_int32)C0_64, -rshifts );
81 }
82
83 CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
84 silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
85 if( rshifts > 0 ) {
86 for( s = 0; s < nb_subfr; s++ ) {
87 x_ptr = x + s * subfr_length;
88 for( n = 1; n < D + 1; n++ ) {
89 C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64(
90 silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts );
91 }
92 }
93 } else {
94 for( s = 0; s < nb_subfr; s++ ) {
95 int i;
96 opus_int32 d;
97 x_ptr = x + s * subfr_length;
98 celt_pitch_xcorr(x_ptr, x_ptr + 1, xcorr, subfr_length - D, D, arch );
99 for( n = 1; n < D + 1; n++ ) {
100 for ( i = n + subfr_length - D, d = 0; i < subfr_length; i++ )
101 d = MAC16_16( d, x_ptr[ i ], x_ptr[ i - n ] );
102 xcorr[ n - 1 ] += d;
103 }
104 for( n = 1; n < D + 1; n++ ) {
105 C_first_row[ n - 1 ] += silk_LSHIFT32( xcorr[ n - 1 ], -rshifts );
106 }
107 }
108 }
109 silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
110
111 /* Initialize */
112 CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
113
114 invGain_Q30 = (opus_int32)1 << 30;
115 reached_max_gain = 0;
116 for( n = 0; n < D; n++ ) {
117 /* Update first row of correlation matrix (without first element) */
118 /* Update last row of correlation matrix (without last element, stored in reversed order) */
119 /* Update C * Af */
120 /* Update C * flipud(Af) (stored in reversed order) */
121 if( rshifts > -2 ) {
122 for( s = 0; s < nb_subfr; s++ ) {
123 x_ptr = x + s * subfr_length;
124 x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], 16 - rshifts ); /* Q(16-rshifts) */
125 x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); /* Q(16-rshifts) */
126 tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], QA - 16 ); /* Q(QA-16) */
127 tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); /* Q(QA-16) */
128 for( k = 0; k < n; k++ ) {
129 C_first_row[ k ] = silk_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */
130 C_last_row[ k ] = silk_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */
131 Atmp_QA = Af_QA[ k ];
132 tmp1 = silk_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); /* Q(QA-16) */
133 tmp2 = silk_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); /* Q(QA-16) */
134 }
135 tmp1 = silk_LSHIFT32( -tmp1, 32 - QA - rshifts ); /* Q(16-rshifts) */
136 tmp2 = silk_LSHIFT32( -tmp2, 32 - QA - rshifts ); /* Q(16-rshifts) */
137 for( k = 0; k <= n; k++ ) {
138 CAf[ k ] = silk_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); /* Q( -rshift ) */
139 CAb[ k ] = silk_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); /* Q( -rshift ) */
140 }
141 }
142 } else {
143 for( s = 0; s < nb_subfr; s++ ) {
144 x_ptr = x + s * subfr_length;
145 x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], -rshifts ); /* Q( -rshifts ) */
146 x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); /* Q( -rshifts ) */
147 tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], 17 ); /* Q17 */
148 tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 17 ); /* Q17 */
149 for( k = 0; k < n; k++ ) {
150 C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */
151 C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */
152 Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */
153 /* We sometimes have get overflows in the multiplications (even beyond +/- 2^32),
154 but they cancel each other and the real result seems to always fit in a 32-bit
155 signed integer. This was determined experimentally, not theoretically (unfortunately). */
156 tmp1 = silk_MLA_ovflw( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */
157 tmp2 = silk_MLA_ovflw( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */
158 }
159 tmp1 = -tmp1; /* Q17 */
160 tmp2 = -tmp2; /* Q17 */
161 for( k = 0; k <= n; k++ ) {
162 CAf[ k ] = silk_SMLAWW( CAf[ k ], tmp1,
163 silk_LSHIFT32( (opus_int32)x_ptr[ n - k ], -rshifts - 1 ) ); /* Q( -rshift ) */
164 CAb[ k ] = silk_SMLAWW( CAb[ k ], tmp2,
165 silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) ); /* Q( -rshift ) */
166 }
167 }
168 }
169
170 /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */
171 tmp1 = C_first_row[ n ]; /* Q( -rshifts ) */
172 tmp2 = C_last_row[ n ]; /* Q( -rshifts ) */
173 num = 0; /* Q( -rshifts ) */
174 nrg = silk_ADD32( CAb[ 0 ], CAf[ 0 ] ); /* Q( 1-rshifts ) */
175 for( k = 0; k < n; k++ ) {
176 Atmp_QA = Af_QA[ k ];
177 lz = silk_CLZ32( silk_abs( Atmp_QA ) ) - 1;
178 lz = silk_min( 32 - QA, lz );
179 Atmp1 = silk_LSHIFT32( Atmp_QA, lz ); /* Q( QA + lz ) */
180
181 tmp1 = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
182 tmp2 = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
183 num = silk_ADD_LSHIFT32( num, silk_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
184 nrg = silk_ADD_LSHIFT32( nrg, silk_SMMUL( silk_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ),
185 Atmp1 ), 32 - QA - lz ); /* Q( 1-rshifts ) */
186 }
187 CAf[ n + 1 ] = tmp1; /* Q( -rshifts ) */
188 CAb[ n + 1 ] = tmp2; /* Q( -rshifts ) */
189 num = silk_ADD32( num, tmp2 ); /* Q( -rshifts ) */
190 num = silk_LSHIFT32( -num, 1 ); /* Q( 1-rshifts ) */
191
192 /* Calculate the next order reflection (parcor) coefficient */
193 if( silk_abs( num ) < nrg ) {
194 rc_Q31 = silk_DIV32_varQ( num, nrg, 31 );
195 } else {
196 rc_Q31 = ( num > 0 ) ? silk_int32_MAX : silk_int32_MIN;
197 }
198
199 /* Update inverse prediction gain */
200 tmp1 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );
201 tmp1 = silk_LSHIFT( silk_SMMUL( invGain_Q30, tmp1 ), 2 );
202 if( tmp1 <= minInvGain_Q30 ) {
203 /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */
204 tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */
205 rc_Q31 = silk_SQRT_APPROX( tmp2 ); /* Q15 */
206 if( rc_Q31 > 0 ) {
207 /* Newton-Raphson iteration */
208 rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */
209 rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */
210 if( num < 0 ) {
211 /* Ensure adjusted reflection coefficients has the original sign */
212 rc_Q31 = -rc_Q31;
213 }
214 }
215 invGain_Q30 = minInvGain_Q30;
216 reached_max_gain = 1;
217 } else {
218 invGain_Q30 = tmp1;
219 }
220
221 /* Update the AR coefficients */
222 for( k = 0; k < (n + 1) >> 1; k++ ) {
223 tmp1 = Af_QA[ k ]; /* QA */
224 tmp2 = Af_QA[ n - k - 1 ]; /* QA */
225 Af_QA[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* QA */
226 Af_QA[ n - k - 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* QA */
227 }
228 Af_QA[ n ] = silk_RSHIFT32( rc_Q31, 31 - QA ); /* QA */
229
230 if( reached_max_gain ) {
231 /* Reached max prediction gain; set remaining coefficients to zero and exit loop */
232 for( k = n + 1; k < D; k++ ) {
233 Af_QA[ k ] = 0;
234 }
235 break;
236 }
237
238 /* Update C * Af and C * Ab */
239 for( k = 0; k <= n + 1; k++ ) {
240 tmp1 = CAf[ k ]; /* Q( -rshifts ) */
241 tmp2 = CAb[ n - k + 1 ]; /* Q( -rshifts ) */
242 CAf[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* Q( -rshifts ) */
243 CAb[ n - k + 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* Q( -rshifts ) */
244 }
245 }
246
247 if( reached_max_gain ) {
248 for( k = 0; k < D; k++ ) {
249 /* Scale coefficients */
250 A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 );
251 }
252 /* Subtract energy of preceding samples from C0 */
253 if( rshifts > 0 ) {
254 for( s = 0; s < nb_subfr; s++ ) {
255 x_ptr = x + s * subfr_length;
256 C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D, arch ), rshifts );
257 }
258 } else {
259 for( s = 0; s < nb_subfr; s++ ) {
260 x_ptr = x + s * subfr_length;
261 C0 -= silk_LSHIFT32( silk_inner_prod_aligned( x_ptr, x_ptr, D, arch), -rshifts);
262 }
263 }
264 /* Approximate residual energy */
265 *res_nrg = silk_LSHIFT( silk_SMMUL( invGain_Q30, C0 ), 2 );
266 *res_nrg_Q = -rshifts;
267 } else {
268 /* Return residual energy */
269 nrg = CAf[ 0 ]; /* Q( -rshifts ) */
270 tmp1 = (opus_int32)1 << 16; /* Q16 */
271 for( k = 0; k < D; k++ ) {
272 Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); /* Q16 */
273 nrg = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); /* Q( -rshifts ) */
274 tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 ); /* Q16 */
275 A_Q16[ k ] = -Atmp1;
276 }
277 *res_nrg = silk_SMLAWW( nrg, silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */
278 *res_nrg_Q = -rshifts;
279 }
280}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/corrMatrix_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/corrMatrix_FIX.c
new file mode 100644
index 0000000000..1b4a29c232
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/corrMatrix_FIX.c
@@ -0,0 +1,150 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32/**********************************************************************
33 * Correlation Matrix Computations for LS estimate.
34 **********************************************************************/
35
36#include "main_FIX.h"
37
38/* Calculates correlation vector X'*t */
39void silk_corrVector_FIX(
40 const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
41 const opus_int16 *t, /* I Target vector [L] */
42 const opus_int L, /* I Length of vectors */
43 const opus_int order, /* I Max lag for correlation */
44 opus_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */
45 const opus_int rshifts, /* I Right shifts of correlations */
46 int arch /* I Run-time architecture */
47)
48{
49 opus_int lag, i;
50 const opus_int16 *ptr1, *ptr2;
51 opus_int32 inner_prod;
52
53 ptr1 = &x[ order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */
54 ptr2 = t;
55 /* Calculate X'*t */
56 if( rshifts > 0 ) {
57 /* Right shifting used */
58 for( lag = 0; lag < order; lag++ ) {
59 inner_prod = 0;
60 for( i = 0; i < L; i++ ) {
61 inner_prod = silk_ADD_RSHIFT32( inner_prod, silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts );
62 }
63 Xt[ lag ] = inner_prod; /* X[:,lag]'*t */
64 ptr1--; /* Go to next column of X */
65 }
66 } else {
67 silk_assert( rshifts == 0 );
68 for( lag = 0; lag < order; lag++ ) {
69 Xt[ lag ] = silk_inner_prod_aligned( ptr1, ptr2, L, arch ); /* X[:,lag]'*t */
70 ptr1--; /* Go to next column of X */
71 }
72 }
73}
74
75/* Calculates correlation matrix X'*X */
76void silk_corrMatrix_FIX(
77 const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
78 const opus_int L, /* I Length of vectors */
79 const opus_int order, /* I Max lag for correlation */
80 opus_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ] */
81 opus_int32 *nrg, /* O Energy of x vector */
82 opus_int *rshifts, /* O Right shifts of correlations and energy */
83 int arch /* I Run-time architecture */
84)
85{
86 opus_int i, j, lag;
87 opus_int32 energy;
88 const opus_int16 *ptr1, *ptr2;
89
90 /* Calculate energy to find shift used to fit in 32 bits */
91 silk_sum_sqr_shift( nrg, rshifts, x, L + order - 1 );
92 energy = *nrg;
93
94 /* Calculate energy of first column (0) of X: X[:,0]'*X[:,0] */
95 /* Remove contribution of first order - 1 samples */
96 for( i = 0; i < order - 1; i++ ) {
97 energy -= silk_RSHIFT32( silk_SMULBB( x[ i ], x[ i ] ), *rshifts );
98 }
99
100 /* Calculate energy of remaining columns of X: X[:,j]'*X[:,j] */
101 /* Fill out the diagonal of the correlation matrix */
102 matrix_ptr( XX, 0, 0, order ) = energy;
103 silk_assert( energy >= 0 );
104 ptr1 = &x[ order - 1 ]; /* First sample of column 0 of X */
105 for( j = 1; j < order; j++ ) {
106 energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), *rshifts ) );
107 energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr1[ -j ] ), *rshifts ) );
108 matrix_ptr( XX, j, j, order ) = energy;
109 silk_assert( energy >= 0 );
110 }
111
112 ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */
113 /* Calculate the remaining elements of the correlation matrix */
114 if( *rshifts > 0 ) {
115 /* Right shifting used */
116 for( lag = 1; lag < order; lag++ ) {
117 /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */
118 energy = 0;
119 for( i = 0; i < L; i++ ) {
120 energy += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), *rshifts );
121 }
122 /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */
123 matrix_ptr( XX, lag, 0, order ) = energy;
124 matrix_ptr( XX, 0, lag, order ) = energy;
125 for( j = 1; j < ( order - lag ); j++ ) {
126 energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), *rshifts ) );
127 energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr2[ -j ] ), *rshifts ) );
128 matrix_ptr( XX, lag + j, j, order ) = energy;
129 matrix_ptr( XX, j, lag + j, order ) = energy;
130 }
131 ptr2--; /* Update pointer to first sample of next column (lag) in X */
132 }
133 } else {
134 for( lag = 1; lag < order; lag++ ) {
135 /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */
136 energy = silk_inner_prod_aligned( ptr1, ptr2, L, arch );
137 matrix_ptr( XX, lag, 0, order ) = energy;
138 matrix_ptr( XX, 0, lag, order ) = energy;
139 /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */
140 for( j = 1; j < ( order - lag ); j++ ) {
141 energy = silk_SUB32( energy, silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ) );
142 energy = silk_SMLABB( energy, ptr1[ -j ], ptr2[ -j ] );
143 matrix_ptr( XX, lag + j, j, order ) = energy;
144 matrix_ptr( XX, j, lag + j, order ) = energy;
145 }
146 ptr2--;/* Update pointer to first sample of next column (lag) in X */
147 }
148 }
149}
150
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/encode_frame_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/encode_frame_FIX.c
new file mode 100644
index 0000000000..a02bf87dbb
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/encode_frame_FIX.c
@@ -0,0 +1,448 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <stdlib.h>
33#include "main_FIX.h"
34#include "stack_alloc.h"
35#include "tuning_parameters.h"
36
37/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */
38static OPUS_INLINE void silk_LBRR_encode_FIX(
39 silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
40 silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */
41 const opus_int16 x16[], /* I Input signal */
42 opus_int condCoding /* I The type of conditional coding used so far for this frame */
43);
44
45void silk_encode_do_VAD_FIX(
46 silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
47 opus_int activity /* I Decision of Opus voice activity detector */
48)
49{
50 const opus_int activity_threshold = SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 );
51
52 /****************************/
53 /* Voice Activity Detection */
54 /****************************/
55 silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch );
56 /* If Opus VAD is inactive and Silk VAD is active: lower Silk VAD to just under the threshold */
57 if( activity == VAD_NO_ACTIVITY && psEnc->sCmn.speech_activity_Q8 >= activity_threshold ) {
58 psEnc->sCmn.speech_activity_Q8 = activity_threshold - 1;
59 }
60
61 /**************************************************/
62 /* Convert speech activity into VAD and DTX flags */
63 /**************************************************/
64 if( psEnc->sCmn.speech_activity_Q8 < activity_threshold ) {
65 psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
66 psEnc->sCmn.noSpeechCounter++;
67 if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) {
68 psEnc->sCmn.inDTX = 0;
69 } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {
70 psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;
71 psEnc->sCmn.inDTX = 0;
72 }
73 psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0;
74 } else {
75 psEnc->sCmn.noSpeechCounter = 0;
76 psEnc->sCmn.inDTX = 0;
77 psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
78 psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
79 }
80}
81
82/****************/
83/* Encode frame */
84/****************/
85opus_int silk_encode_frame_FIX(
86 silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
87 opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */
88 ec_enc *psRangeEnc, /* I/O compressor data structure */
89 opus_int condCoding, /* I The type of conditional coding to use */
90 opus_int maxBits, /* I If > 0: maximum number of output bits */
91 opus_int useCBR /* I Flag to force constant-bitrate operation */
92)
93{
94 silk_encoder_control_FIX sEncCtrl;
95 opus_int i, iter, maxIter, found_upper, found_lower, ret = 0;
96 opus_int16 *x_frame;
97 ec_enc sRangeEnc_copy, sRangeEnc_copy2;
98 silk_nsq_state sNSQ_copy, sNSQ_copy2;
99 opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper;
100 opus_int32 gainsID, gainsID_lower, gainsID_upper;
101 opus_int16 gainMult_Q8;
102 opus_int16 ec_prevLagIndex_copy;
103 opus_int ec_prevSignalType_copy;
104 opus_int8 LastGainIndex_copy2;
105 opus_int gain_lock[ MAX_NB_SUBFR ] = {0};
106 opus_int16 best_gain_mult[ MAX_NB_SUBFR ];
107 opus_int best_sum[ MAX_NB_SUBFR ];
108 SAVE_STACK;
109
110 /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
111 LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;
112
113 psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
114
115 /**************************************************************/
116 /* Set up Input Pointers, and insert frame in input buffer */
117 /*************************************************************/
118 /* start of frame to encode */
119 x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;
120
121 /***************************************/
122 /* Ensure smooth bandwidth transitions */
123 /***************************************/
124 silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
125
126 /*******************************************/
127 /* Copy new frame to front of input buffer */
128 /*******************************************/
129 silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
130
131 if( !psEnc->sCmn.prefillFlag ) {
132 VARDECL( opus_int16, res_pitch );
133 VARDECL( opus_uint8, ec_buf_copy );
134 opus_int16 *res_pitch_frame;
135
136 ALLOC( res_pitch,
137 psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length
138 + psEnc->sCmn.ltp_mem_length, opus_int16 );
139 /* start of pitch LPC residual frame */
140 res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length;
141
142 /*****************************************/
143 /* Find pitch lags, initial LPC analysis */
144 /*****************************************/
145 silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame - psEnc->sCmn.ltp_mem_length, psEnc->sCmn.arch );
146
147 /************************/
148 /* Noise shape analysis */
149 /************************/
150 silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, psEnc->sCmn.arch );
151
152 /***************************************************/
153 /* Find linear prediction coefficients (LPC + LTP) */
154 /***************************************************/
155 silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding );
156
157 /****************************************/
158 /* Process gains */
159 /****************************************/
160 silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding );
161
162 /****************************************/
163 /* Low Bitrate Redundant Encoding */
164 /****************************************/
165 silk_LBRR_encode_FIX( psEnc, &sEncCtrl, x_frame, condCoding );
166
167 /* Loop over quantizer and entropy coding to control bitrate */
168 maxIter = 6;
169 gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
170 found_lower = 0;
171 found_upper = 0;
172 gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
173 gainsID_lower = -1;
174 gainsID_upper = -1;
175 /* Copy part of the input state */
176 silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) );
177 silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
178 seed_copy = psEnc->sCmn.indices.Seed;
179 ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex;
180 ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType;
181 ALLOC( ec_buf_copy, 1275, opus_uint8 );
182 for( iter = 0; ; iter++ ) {
183 if( gainsID == gainsID_lower ) {
184 nBits = nBits_lower;
185 } else if( gainsID == gainsID_upper ) {
186 nBits = nBits_upper;
187 } else {
188 /* Restore part of the input state */
189 if( iter > 0 ) {
190 silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) );
191 silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) );
192 psEnc->sCmn.indices.Seed = seed_copy;
193 psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
194 psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
195 }
196
197 /*****************************************/
198 /* Noise shaping quantization */
199 /*****************************************/
200 if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
201 silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
202 sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14,
203 sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
204 psEnc->sCmn.arch );
205 } else {
206 silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
207 sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14,
208 sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
209 psEnc->sCmn.arch);
210 }
211
212 if ( iter == maxIter && !found_lower ) {
213 silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
214 }
215
216 /****************************************/
217 /* Encode Parameters */
218 /****************************************/
219 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
220
221 /****************************************/
222 /* Encode Excitation Signal */
223 /****************************************/
224 silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
225 psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
226
227 nBits = ec_tell( psRangeEnc );
228
229 /* If we still bust after the last iteration, do some damage control. */
230 if ( iter == maxIter && !found_lower && nBits > maxBits ) {
231 silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
232
233 /* Keep gains the same as the last frame. */
234 psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
235 for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
236 psEnc->sCmn.indices.GainsIndices[ i ] = 4;
237 }
238 if (condCoding != CODE_CONDITIONALLY) {
239 psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev;
240 }
241 psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
242 psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
243 /* Clear all pulses. */
244 for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
245 psEnc->sCmn.pulses[ i ] = 0;
246 }
247
248 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
249
250 silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
251 psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
252
253 nBits = ec_tell( psRangeEnc );
254 }
255
256 if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
257 break;
258 }
259 }
260
261 if( iter == maxIter ) {
262 if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {
263 /* Restore output state from earlier iteration that did meet the bitrate budget */
264 silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
265 celt_assert( sRangeEnc_copy2.offs <= 1275 );
266 silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );
267 silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );
268 psEnc->sShape.LastGainIndex = LastGainIndex_copy2;
269 }
270 break;
271 }
272
273 if( nBits > maxBits ) {
274 if( found_lower == 0 && iter >= 2 ) {
275 /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
276 sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 );
277 found_upper = 0;
278 gainsID_upper = -1;
279 } else {
280 found_upper = 1;
281 nBits_upper = nBits;
282 gainMult_upper = gainMult_Q8;
283 gainsID_upper = gainsID;
284 }
285 } else if( nBits < maxBits - 5 ) {
286 found_lower = 1;
287 nBits_lower = nBits;
288 gainMult_lower = gainMult_Q8;
289 if( gainsID != gainsID_lower ) {
290 gainsID_lower = gainsID;
291 /* Copy part of the output state */
292 silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
293 celt_assert( psRangeEnc->offs <= 1275 );
294 silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
295 silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
296 LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;
297 }
298 } else {
299 /* Within 5 bits of budget: close enough */
300 break;
301 }
302
303 if ( !found_lower && nBits > maxBits ) {
304 int j;
305 for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
306 int sum=0;
307 for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) {
308 sum += abs( psEnc->sCmn.pulses[j] );
309 }
310 if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) {
311 best_sum[i] = sum;
312 best_gain_mult[i] = gainMult_Q8;
313 } else {
314 gain_lock[i] = 1;
315 }
316 }
317 }
318 if( ( found_lower & found_upper ) == 0 ) {
319 /* Adjust gain according to high-rate rate/distortion curve */
320 if( nBits > maxBits ) {
321 if (gainMult_Q8 < 16384) {
322 gainMult_Q8 *= 2;
323 } else {
324 gainMult_Q8 = 32767;
325 }
326 } else {
327 opus_int32 gain_factor_Q16;
328 gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
329 gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
330 }
331
332 } else {
333 /* Adjust gain by interpolating */
334 gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower );
335 /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */
336 if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) {
337 gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 );
338 } else
339 if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) {
340 gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 );
341 }
342 }
343
344 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
345 opus_int16 tmp;
346 if ( gain_lock[i] ) {
347 tmp = best_gain_mult[i];
348 } else {
349 tmp = gainMult_Q8;
350 }
351 sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 );
352 }
353
354 /* Quantize gains */
355 psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
356 silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16,
357 &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
358
359 /* Unique identifier of gains vector */
360 gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
361 }
362 }
363
364 /* Update input buffer */
365 silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
366 ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) );
367
368 /* Exit without entropy coding */
369 if( psEnc->sCmn.prefillFlag ) {
370 /* No payload */
371 *pnBytesOut = 0;
372 RESTORE_STACK;
373 return ret;
374 }
375
376 /* Parameters needed for next frame */
377 psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];
378 psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;
379
380 /****************************************/
381 /* Finalize payload */
382 /****************************************/
383 psEnc->sCmn.first_frame_after_reset = 0;
384 /* Payload size */
385 *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );
386
387 RESTORE_STACK;
388 return ret;
389}
390
391/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */
392static OPUS_INLINE void silk_LBRR_encode_FIX(
393 silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
394 silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */
395 const opus_int16 x16[], /* I Input signal */
396 opus_int condCoding /* I The type of conditional coding used so far for this frame */
397)
398{
399 opus_int32 TempGains_Q16[ MAX_NB_SUBFR ];
400 SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];
401 silk_nsq_state sNSQ_LBRR;
402
403 /*******************************************/
404 /* Control use of inband LBRR */
405 /*******************************************/
406 if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {
407 psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
408
409 /* Copy noise shaping quantizer state and quantization indices from regular encoding */
410 silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
411 silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );
412
413 /* Save original gains */
414 silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
415
416 if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {
417 /* First frame in packet or previous frame not LBRR coded */
418 psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
419
420 /* Increase Gains to get target LBRR rate */
421 psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;
422 psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );
423 }
424
425 /* Decode to get gains in sync with decoder */
426 /* Overwrite unquantized gains with quantized gains */
427 silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices,
428 &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
429
430 /*****************************************/
431 /* Noise shaping quantization */
432 /*****************************************/
433 if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
434 silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16,
435 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
436 psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
437 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
438 } else {
439 silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16,
440 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
441 psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
442 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
443 }
444
445 /* Restore original gains */
446 silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
447 }
448}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/find_LPC_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/find_LPC_FIX.c
new file mode 100644
index 0000000000..c762a0f2a2
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/find_LPC_FIX.c
@@ -0,0 +1,151 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33#include "stack_alloc.h"
34#include "tuning_parameters.h"
35
36/* Finds LPC vector from correlations, and converts to NLSF */
37void silk_find_LPC_FIX(
38 silk_encoder_state *psEncC, /* I/O Encoder state */
39 opus_int16 NLSF_Q15[], /* O NLSFs */
40 const opus_int16 x[], /* I Input signal */
41 const opus_int32 minInvGain_Q30 /* I Inverse of max prediction gain */
42)
43{
44 opus_int k, subfr_length;
45 opus_int32 a_Q16[ MAX_LPC_ORDER ];
46 opus_int isInterpLower, shift;
47 opus_int32 res_nrg0, res_nrg1;
48 opus_int rshift0, rshift1;
49
50 /* Used only for LSF interpolation */
51 opus_int32 a_tmp_Q16[ MAX_LPC_ORDER ], res_nrg_interp, res_nrg, res_tmp_nrg;
52 opus_int res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q;
53 opus_int16 a_tmp_Q12[ MAX_LPC_ORDER ];
54 opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ];
55 SAVE_STACK;
56
57 subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder;
58
59 /* Default: no interpolation */
60 psEncC->indices.NLSFInterpCoef_Q2 = 4;
61
62 /* Burg AR analysis for the full frame */
63 silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, minInvGain_Q30, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder, psEncC->arch );
64
65 if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) {
66 VARDECL( opus_int16, LPC_res );
67
68 /* Optimal solution for last 10 ms */
69 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 );
70
71 /* subtract residual energy here, as that's easier than adding it to the */
72 /* residual energy of the first 10 ms in each iteration of the search below */
73 shift = res_tmp_nrg_Q - res_nrg_Q;
74 if( shift >= 0 ) {
75 if( shift < 32 ) {
76 res_nrg = res_nrg - silk_RSHIFT( res_tmp_nrg, shift );
77 }
78 } else {
79 silk_assert( shift > -32 );
80 res_nrg = silk_RSHIFT( res_nrg, -shift ) - res_tmp_nrg;
81 res_nrg_Q = res_tmp_nrg_Q;
82 }
83
84 /* Convert to NLSFs */
85 silk_A2NLSF( NLSF_Q15, a_tmp_Q16, psEncC->predictLPCOrder );
86
87 ALLOC( LPC_res, 2 * subfr_length, opus_int16 );
88
89 /* Search over interpolation indices to find the one with lowest residual energy */
90 for( k = 3; k >= 0; k-- ) {
91 /* Interpolate NLSFs for first half */
92 silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder );
93
94 /* Convert to LPC for residual energy evaluation */
95 silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, psEncC->predictLPCOrder, psEncC->arch );
96
97 /* Calculate residual energy with NLSF interpolation */
98 silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, psEncC->predictLPCOrder, psEncC->arch );
99
100 silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + psEncC->predictLPCOrder, subfr_length - psEncC->predictLPCOrder );
101 silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder );
102
103 /* Add subframe energies from first half frame */
104 shift = rshift0 - rshift1;
105 if( shift >= 0 ) {
106 res_nrg1 = silk_RSHIFT( res_nrg1, shift );
107 res_nrg_interp_Q = -rshift0;
108 } else {
109 res_nrg0 = silk_RSHIFT( res_nrg0, -shift );
110 res_nrg_interp_Q = -rshift1;
111 }
112 res_nrg_interp = silk_ADD32( res_nrg0, res_nrg1 );
113
114 /* Compare with first half energy without NLSF interpolation, or best interpolated value so far */
115 shift = res_nrg_interp_Q - res_nrg_Q;
116 if( shift >= 0 ) {
117 if( silk_RSHIFT( res_nrg_interp, shift ) < res_nrg ) {
118 isInterpLower = silk_TRUE;
119 } else {
120 isInterpLower = silk_FALSE;
121 }
122 } else {
123 if( -shift < 32 ) {
124 if( res_nrg_interp < silk_RSHIFT( res_nrg, -shift ) ) {
125 isInterpLower = silk_TRUE;
126 } else {
127 isInterpLower = silk_FALSE;
128 }
129 } else {
130 isInterpLower = silk_FALSE;
131 }
132 }
133
134 /* Determine whether current interpolated NLSFs are best so far */
135 if( isInterpLower == silk_TRUE ) {
136 /* Interpolation has lower residual energy */
137 res_nrg = res_nrg_interp;
138 res_nrg_Q = res_nrg_interp_Q;
139 psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k;
140 }
141 }
142 }
143
144 if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) {
145 /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */
146 silk_A2NLSF( NLSF_Q15, a_Q16, psEncC->predictLPCOrder );
147 }
148
149 celt_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );
150 RESTORE_STACK;
151}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/find_LTP_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/find_LTP_FIX.c
new file mode 100644
index 0000000000..62d4afb250
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/find_LTP_FIX.c
@@ -0,0 +1,99 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33#include "tuning_parameters.h"
34
35void silk_find_LTP_FIX(
36 opus_int32 XXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Correlation matrix */
37 opus_int32 xXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER ], /* O Correlation vector */
38 const opus_int16 r_ptr[], /* I Residual signal after LPC */
39 const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
40 const opus_int subfr_length, /* I Subframe length */
41 const opus_int nb_subfr, /* I Number of subframes */
42 int arch /* I Run-time architecture */
43)
44{
45 opus_int i, k, extra_shifts;
46 opus_int xx_shifts, xX_shifts, XX_shifts;
47 const opus_int16 *lag_ptr;
48 opus_int32 *XXLTP_Q17_ptr, *xXLTP_Q17_ptr;
49 opus_int32 xx, nrg, temp;
50
51 xXLTP_Q17_ptr = xXLTP_Q17;
52 XXLTP_Q17_ptr = XXLTP_Q17;
53 for( k = 0; k < nb_subfr; k++ ) {
54 lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 );
55
56 silk_sum_sqr_shift( &xx, &xx_shifts, r_ptr, subfr_length + LTP_ORDER ); /* xx in Q( -xx_shifts ) */
57 silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, XXLTP_Q17_ptr, &nrg, &XX_shifts, arch ); /* XXLTP_Q17_ptr and nrg in Q( -XX_shifts ) */
58 extra_shifts = xx_shifts - XX_shifts;
59 if( extra_shifts > 0 ) {
60 /* Shift XX */
61 xX_shifts = xx_shifts;
62 for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
63 XXLTP_Q17_ptr[ i ] = silk_RSHIFT32( XXLTP_Q17_ptr[ i ], extra_shifts ); /* Q( -xX_shifts ) */
64 }
65 nrg = silk_RSHIFT32( nrg, extra_shifts ); /* Q( -xX_shifts ) */
66 } else if( extra_shifts < 0 ) {
67 /* Shift xx */
68 xX_shifts = XX_shifts;
69 xx = silk_RSHIFT32( xx, -extra_shifts ); /* Q( -xX_shifts ) */
70 } else {
71 xX_shifts = xx_shifts;
72 }
73 silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, xXLTP_Q17_ptr, xX_shifts, arch ); /* xXLTP_Q17_ptr in Q( -xX_shifts ) */
74
75 /* At this point all correlations are in Q(-xX_shifts) */
76 temp = silk_SMLAWB( 1, nrg, SILK_FIX_CONST( LTP_CORR_INV_MAX, 16 ) );
77 temp = silk_max( temp, xx );
78TIC(div)
79#if 0
80 for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
81 XXLTP_Q17_ptr[ i ] = silk_DIV32_varQ( XXLTP_Q17_ptr[ i ], temp, 17 );
82 }
83 for( i = 0; i < LTP_ORDER; i++ ) {
84 xXLTP_Q17_ptr[ i ] = silk_DIV32_varQ( xXLTP_Q17_ptr[ i ], temp, 17 );
85 }
86#else
87 for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
88 XXLTP_Q17_ptr[ i ] = (opus_int32)( silk_LSHIFT64( (opus_int64)XXLTP_Q17_ptr[ i ], 17 ) / temp );
89 }
90 for( i = 0; i < LTP_ORDER; i++ ) {
91 xXLTP_Q17_ptr[ i ] = (opus_int32)( silk_LSHIFT64( (opus_int64)xXLTP_Q17_ptr[ i ], 17 ) / temp );
92 }
93#endif
94TOC(div)
95 r_ptr += subfr_length;
96 XXLTP_Q17_ptr += LTP_ORDER * LTP_ORDER;
97 xXLTP_Q17_ptr += LTP_ORDER;
98 }
99}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/find_pitch_lags_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/find_pitch_lags_FIX.c
new file mode 100644
index 0000000000..6c3379f2bb
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/find_pitch_lags_FIX.c
@@ -0,0 +1,143 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33#include "stack_alloc.h"
34#include "tuning_parameters.h"
35
36/* Find pitch lags */
37void silk_find_pitch_lags_FIX(
38 silk_encoder_state_FIX *psEnc, /* I/O encoder state */
39 silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
40 opus_int16 res[], /* O residual */
41 const opus_int16 x[], /* I Speech signal */
42 int arch /* I Run-time architecture */
43)
44{
45 opus_int buf_len, i, scale;
46 opus_int32 thrhld_Q13, res_nrg;
47 const opus_int16 *x_ptr;
48 VARDECL( opus_int16, Wsig );
49 opus_int16 *Wsig_ptr;
50 opus_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ];
51 opus_int16 rc_Q15[ MAX_FIND_PITCH_LPC_ORDER ];
52 opus_int32 A_Q24[ MAX_FIND_PITCH_LPC_ORDER ];
53 opus_int16 A_Q12[ MAX_FIND_PITCH_LPC_ORDER ];
54 SAVE_STACK;
55
56 /******************************************/
57 /* Set up buffer lengths etc based on Fs */
58 /******************************************/
59 buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
60
61 /* Safety check */
62 celt_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
63
64 /*************************************/
65 /* Estimate LPC AR coefficients */
66 /*************************************/
67
68 /* Calculate windowed signal */
69
70 ALLOC( Wsig, psEnc->sCmn.pitch_LPC_win_length, opus_int16 );
71
72 /* First LA_LTP samples */
73 x_ptr = x + buf_len - psEnc->sCmn.pitch_LPC_win_length;
74 Wsig_ptr = Wsig;
75 silk_apply_sine_window( Wsig_ptr, x_ptr, 1, psEnc->sCmn.la_pitch );
76
77 /* Middle un - windowed samples */
78 Wsig_ptr += psEnc->sCmn.la_pitch;
79 x_ptr += psEnc->sCmn.la_pitch;
80 silk_memcpy( Wsig_ptr, x_ptr, ( psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( opus_int16 ) );
81
82 /* Last LA_LTP samples */
83 Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 );
84 x_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 );
85 silk_apply_sine_window( Wsig_ptr, x_ptr, 2, psEnc->sCmn.la_pitch );
86
87 /* Calculate autocorrelation sequence */
88 silk_autocorr( auto_corr, &scale, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1, arch );
89
90 /* Add white noise, as fraction of energy */
91 auto_corr[ 0 ] = silk_SMLAWB( auto_corr[ 0 ], auto_corr[ 0 ], SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ) + 1;
92
93 /* Calculate the reflection coefficients using schur */
94 res_nrg = silk_schur( rc_Q15, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder );
95
96 /* Prediction gain */
97 psEncCtrl->predGain_Q16 = silk_DIV32_varQ( auto_corr[ 0 ], silk_max_int( res_nrg, 1 ), 16 );
98
99 /* Convert reflection coefficients to prediction coefficients */
100 silk_k2a( A_Q24, rc_Q15, psEnc->sCmn.pitchEstimationLPCOrder );
101
102 /* Convert From 32 bit Q24 to 16 bit Q12 coefs */
103 for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) {
104 A_Q12[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT( A_Q24[ i ], 12 ) );
105 }
106
107 /* Do BWE */
108 silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWIDTH_EXPANSION, 16 ) );
109
110 /*****************************************/
111 /* LPC analysis filtering */
112 /*****************************************/
113 silk_LPC_analysis_filter( res, x, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder, psEnc->sCmn.arch );
114
115 if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) {
116 /* Threshold for pitch estimator */
117 thrhld_Q13 = SILK_FIX_CONST( 0.6, 13 );
118 thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.004, 13 ), psEnc->sCmn.pitchEstimationLPCOrder );
119 thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 21 ), psEnc->sCmn.speech_activity_Q8 );
120 thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.15, 13 ), silk_RSHIFT( psEnc->sCmn.prevSignalType, 1 ) );
121 thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 14 ), psEnc->sCmn.input_tilt_Q15 );
122 thrhld_Q13 = silk_SAT16( thrhld_Q13 );
123
124 /*****************************************/
125 /* Call pitch estimator */
126 /*****************************************/
127 if( silk_pitch_analysis_core( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex,
128 &psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16,
129 (opus_int)thrhld_Q13, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr,
130 psEnc->sCmn.arch) == 0 )
131 {
132 psEnc->sCmn.indices.signalType = TYPE_VOICED;
133 } else {
134 psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
135 }
136 } else {
137 silk_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) );
138 psEnc->sCmn.indices.lagIndex = 0;
139 psEnc->sCmn.indices.contourIndex = 0;
140 psEnc->LTPCorr_Q15 = 0;
141 }
142 RESTORE_STACK;
143}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/find_pred_coefs_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/find_pred_coefs_FIX.c
new file mode 100644
index 0000000000..606d863347
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/find_pred_coefs_FIX.c
@@ -0,0 +1,145 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33#include "stack_alloc.h"
34
35void silk_find_pred_coefs_FIX(
36 silk_encoder_state_FIX *psEnc, /* I/O encoder state */
37 silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
38 const opus_int16 res_pitch[], /* I Residual from pitch analysis */
39 const opus_int16 x[], /* I Speech signal */
40 opus_int condCoding /* I The type of conditional coding to use */
41)
42{
43 opus_int i;
44 opus_int32 invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ];
45 opus_int16 NLSF_Q15[ MAX_LPC_ORDER ];
46 const opus_int16 *x_ptr;
47 opus_int16 *x_pre_ptr;
48 VARDECL( opus_int16, LPC_in_pre );
49 opus_int32 min_gain_Q16, minInvGain_Q30;
50 SAVE_STACK;
51
52 /* weighting for weighted least squares */
53 min_gain_Q16 = silk_int32_MAX >> 6;
54 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
55 min_gain_Q16 = silk_min( min_gain_Q16, psEncCtrl->Gains_Q16[ i ] );
56 }
57 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
58 /* Divide to Q16 */
59 silk_assert( psEncCtrl->Gains_Q16[ i ] > 0 );
60 /* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */
61 invGains_Q16[ i ] = silk_DIV32_varQ( min_gain_Q16, psEncCtrl->Gains_Q16[ i ], 16 - 2 );
62
63 /* Limit inverse */
64 invGains_Q16[ i ] = silk_max( invGains_Q16[ i ], 100 );
65
66 /* Square the inverted gains */
67 silk_assert( invGains_Q16[ i ] == silk_SAT16( invGains_Q16[ i ] ) );
68
69 /* Invert the inverted and normalized gains */
70 local_gains[ i ] = silk_DIV32( ( (opus_int32)1 << 16 ), invGains_Q16[ i ] );
71 }
72
73 ALLOC( LPC_in_pre,
74 psEnc->sCmn.nb_subfr * psEnc->sCmn.predictLPCOrder
75 + psEnc->sCmn.frame_length, opus_int16 );
76 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
77 VARDECL( opus_int32, xXLTP_Q17 );
78 VARDECL( opus_int32, XXLTP_Q17 );
79
80 /**********/
81 /* VOICED */
82 /**********/
83 celt_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
84
85 ALLOC( xXLTP_Q17, psEnc->sCmn.nb_subfr * LTP_ORDER, opus_int32 );
86 ALLOC( XXLTP_Q17, psEnc->sCmn.nb_subfr * LTP_ORDER * LTP_ORDER, opus_int32 );
87
88 /* LTP analysis */
89 silk_find_LTP_FIX( XXLTP_Q17, xXLTP_Q17, res_pitch,
90 psEncCtrl->pitchL, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch );
91
92 /* Quantize LTP gain parameters */
93 silk_quant_LTP_gains( psEncCtrl->LTPCoef_Q14, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex,
94 &psEnc->sCmn.sum_log_gain_Q7, &psEncCtrl->LTPredCodGain_Q7, XXLTP_Q17, xXLTP_Q17, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch );
95
96 /* Control LTP scaling */
97 silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl, condCoding );
98
99 /* Create LTP residual */
100 silk_LTP_analysis_filter_FIX( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef_Q14,
101 psEncCtrl->pitchL, invGains_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder );
102
103 } else {
104 /************/
105 /* UNVOICED */
106 /************/
107 /* Create signal with prepended subframes, scaled by inverse gains */
108 x_ptr = x - psEnc->sCmn.predictLPCOrder;
109 x_pre_ptr = LPC_in_pre;
110 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
111 silk_scale_copy_vector16( x_pre_ptr, x_ptr, invGains_Q16[ i ],
112 psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder );
113 x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder;
114 x_ptr += psEnc->sCmn.subfr_length;
115 }
116
117 silk_memset( psEncCtrl->LTPCoef_Q14, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( opus_int16 ) );
118 psEncCtrl->LTPredCodGain_Q7 = 0;
119 psEnc->sCmn.sum_log_gain_Q7 = 0;
120 }
121
122 /* Limit on total predictive coding gain */
123 if( psEnc->sCmn.first_frame_after_reset ) {
124 minInvGain_Q30 = SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET, 30 );
125 } else {
126 minInvGain_Q30 = silk_log2lin( silk_SMLAWB( 16 << 7, (opus_int32)psEncCtrl->LTPredCodGain_Q7, SILK_FIX_CONST( 1.0 / 3, 16 ) ) ); /* Q16 */
127 minInvGain_Q30 = silk_DIV32_varQ( minInvGain_Q30,
128 silk_SMULWW( SILK_FIX_CONST( MAX_PREDICTION_POWER_GAIN, 0 ),
129 silk_SMLAWB( SILK_FIX_CONST( 0.25, 18 ), SILK_FIX_CONST( 0.75, 18 ), psEncCtrl->coding_quality_Q14 ) ), 14 );
130 }
131
132 /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */
133 silk_find_LPC_FIX( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain_Q30 );
134
135 /* Quantize LSFs */
136 silk_process_NLSFs( &psEnc->sCmn, psEncCtrl->PredCoef_Q12, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 );
137
138 /* Calculate residual energy using quantized LPC coefficients */
139 silk_residual_energy_FIX( psEncCtrl->ResNrg, psEncCtrl->ResNrgQ, LPC_in_pre, psEncCtrl->PredCoef_Q12, local_gains,
140 psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder, psEnc->sCmn.arch );
141
142 /* Copy to prediction struct for use in next frame for interpolation */
143 silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );
144 RESTORE_STACK;
145}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/k2a_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/k2a_FIX.c
new file mode 100644
index 0000000000..549f6eadaa
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/k2a_FIX.c
@@ -0,0 +1,54 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33
34/* Step up function, converts reflection coefficients to prediction coefficients */
35void silk_k2a(
36 opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */
37 const opus_int16 *rc_Q15, /* I Reflection coefficients [order] Q15 */
38 const opus_int32 order /* I Prediction order */
39)
40{
41 opus_int k, n;
42 opus_int32 rc, tmp1, tmp2;
43
44 for( k = 0; k < order; k++ ) {
45 rc = rc_Q15[ k ];
46 for( n = 0; n < (k + 1) >> 1; n++ ) {
47 tmp1 = A_Q24[ n ];
48 tmp2 = A_Q24[ k - n - 1 ];
49 A_Q24[ n ] = silk_SMLAWB( tmp1, silk_LSHIFT( tmp2, 1 ), rc );
50 A_Q24[ k - n - 1 ] = silk_SMLAWB( tmp2, silk_LSHIFT( tmp1, 1 ), rc );
51 }
52 A_Q24[ k ] = -silk_LSHIFT( (opus_int32)rc_Q15[ k ], 9 );
53 }
54}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/k2a_Q16_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/k2a_Q16_FIX.c
new file mode 100644
index 0000000000..1595aa6212
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/k2a_Q16_FIX.c
@@ -0,0 +1,54 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33
34/* Step up function, converts reflection coefficients to prediction coefficients */
35void silk_k2a_Q16(
36 opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */
37 const opus_int32 *rc_Q16, /* I Reflection coefficients [order] Q16 */
38 const opus_int32 order /* I Prediction order */
39)
40{
41 opus_int k, n;
42 opus_int32 rc, tmp1, tmp2;
43
44 for( k = 0; k < order; k++ ) {
45 rc = rc_Q16[ k ];
46 for( n = 0; n < (k + 1) >> 1; n++ ) {
47 tmp1 = A_Q24[ n ];
48 tmp2 = A_Q24[ k - n - 1 ];
49 A_Q24[ n ] = silk_SMLAWW( tmp1, tmp2, rc );
50 A_Q24[ k - n - 1 ] = silk_SMLAWW( tmp2, tmp1, rc );
51 }
52 A_Q24[ k ] = -silk_LSHIFT( rc, 8 );
53 }
54}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/main_FIX.h b/lib/rbcodec/codecs/libopus/silk/fixed/main_FIX.h
new file mode 100644
index 0000000000..6d2112e511
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/main_FIX.h
@@ -0,0 +1,244 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef SILK_MAIN_FIX_H
29#define SILK_MAIN_FIX_H
30
31#include "SigProc_FIX.h"
32#include "structs_FIX.h"
33#include "control.h"
34#include "main.h"
35#include "PLC.h"
36#include "debug.h"
37#include "entenc.h"
38
39#if ((defined(OPUS_ARM_ASM) && defined(FIXED_POINT)) \
40 || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
41#include "fixed/arm/warped_autocorrelation_FIX_arm.h"
42#endif
43
44#ifndef FORCE_CPP_BUILD
45#ifdef __cplusplus
46extern "C"
47{
48#endif
49#endif
50
51#define silk_encoder_state_Fxx silk_encoder_state_FIX
52#define silk_encode_do_VAD_Fxx silk_encode_do_VAD_FIX
53#define silk_encode_frame_Fxx silk_encode_frame_FIX
54
55#define QC 10
56#define QS 13
57
58/*********************/
59/* Encoder Functions */
60/*********************/
61
62/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */
63void silk_HP_variable_cutoff(
64 silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */
65);
66
67/* Encoder main function */
68void silk_encode_do_VAD_FIX(
69 silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
70 opus_int activity /* I Decision of Opus voice activity detector */
71);
72
73/* Encoder main function */
74opus_int silk_encode_frame_FIX(
75 silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
76 opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */
77 ec_enc *psRangeEnc, /* I/O compressor data structure */
78 opus_int condCoding, /* I The type of conditional coding to use */
79 opus_int maxBits, /* I If > 0: maximum number of output bits */
80 opus_int useCBR /* I Flag to force constant-bitrate operation */
81);
82
83/* Initializes the Silk encoder state */
84opus_int silk_init_encoder(
85 silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk FIX encoder state */
86 int arch /* I Run-time architecture */
87);
88
89/* Control the Silk encoder */
90opus_int silk_control_encoder(
91 silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */
92 silk_EncControlStruct *encControl, /* I Control structure */
93 const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */
94 const opus_int channelNb, /* I Channel number */
95 const opus_int force_fs_kHz
96);
97
98/**************************/
99/* Noise shaping analysis */
100/**************************/
101/* Compute noise shaping coefficients and initial gain values */
102void silk_noise_shape_analysis_FIX(
103 silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
104 silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */
105 const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */
106 const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */
107 int arch /* I Run-time architecture */
108);
109
110/* Autocorrelations for a warped frequency axis */
111void silk_warped_autocorrelation_FIX_c(
112 opus_int32 *corr, /* O Result [order + 1] */
113 opus_int *scale, /* O Scaling of the correlation vector */
114 const opus_int16 *input, /* I Input data to correlate */
115 const opus_int warping_Q16, /* I Warping coefficient */
116 const opus_int length, /* I Length of input */
117 const opus_int order /* I Correlation order (even) */
118);
119
120#if !defined(OVERRIDE_silk_warped_autocorrelation_FIX)
121#define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
122 ((void)(arch), silk_warped_autocorrelation_FIX_c(corr, scale, input, warping_Q16, length, order))
123#endif
124
125/* Calculation of LTP state scaling */
126void silk_LTP_scale_ctrl_FIX(
127 silk_encoder_state_FIX *psEnc, /* I/O encoder state */
128 silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
129 opus_int condCoding /* I The type of conditional coding to use */
130);
131
132/**********************************************/
133/* Prediction Analysis */
134/**********************************************/
135/* Find pitch lags */
136void silk_find_pitch_lags_FIX(
137 silk_encoder_state_FIX *psEnc, /* I/O encoder state */
138 silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
139 opus_int16 res[], /* O residual */
140 const opus_int16 x[], /* I Speech signal */
141 int arch /* I Run-time architecture */
142);
143
144/* Find LPC and LTP coefficients */
145void silk_find_pred_coefs_FIX(
146 silk_encoder_state_FIX *psEnc, /* I/O encoder state */
147 silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */
148 const opus_int16 res_pitch[], /* I Residual from pitch analysis */
149 const opus_int16 x[], /* I Speech signal */
150 opus_int condCoding /* I The type of conditional coding to use */
151);
152
153/* LPC analysis */
154void silk_find_LPC_FIX(
155 silk_encoder_state *psEncC, /* I/O Encoder state */
156 opus_int16 NLSF_Q15[], /* O NLSFs */
157 const opus_int16 x[], /* I Input signal */
158 const opus_int32 minInvGain_Q30 /* I Inverse of max prediction gain */
159);
160
161/* LTP analysis */
162void silk_find_LTP_FIX(
163 opus_int32 XXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Correlation matrix */
164 opus_int32 xXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER ], /* O Correlation vector */
165 const opus_int16 r_lpc[], /* I Residual signal after LPC */
166 const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
167 const opus_int subfr_length, /* I Subframe length */
168 const opus_int nb_subfr, /* I Number of subframes */
169 int arch /* I Run-time architecture */
170);
171
172void silk_LTP_analysis_filter_FIX(
173 opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */
174 const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */
175 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */
176 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */
177 const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */
178 const opus_int subfr_length, /* I Length of each subframe */
179 const opus_int nb_subfr, /* I Number of subframes */
180 const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */
181);
182
183/* Calculates residual energies of input subframes where all subframes have LPC_order */
184/* of preceding samples */
185void silk_residual_energy_FIX(
186 opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */
187 opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */
188 const opus_int16 x[], /* I Input signal */
189 opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */
190 const opus_int32 gains[ MAX_NB_SUBFR ], /* I Quantization gains */
191 const opus_int subfr_length, /* I Subframe length */
192 const opus_int nb_subfr, /* I Number of subframes */
193 const opus_int LPC_order, /* I LPC order */
194 int arch /* I Run-time architecture */
195);
196
197/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */
198opus_int32 silk_residual_energy16_covar_FIX(
199 const opus_int16 *c, /* I Prediction vector */
200 const opus_int32 *wXX, /* I Correlation matrix */
201 const opus_int32 *wXx, /* I Correlation vector */
202 opus_int32 wxx, /* I Signal energy */
203 opus_int D, /* I Dimension */
204 opus_int cQ /* I Q value for c vector 0 - 15 */
205);
206
207/* Processing of gains */
208void silk_process_gains_FIX(
209 silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
210 silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control */
211 opus_int condCoding /* I The type of conditional coding to use */
212);
213
214/******************/
215/* Linear Algebra */
216/******************/
217/* Calculates correlation matrix X'*X */
218void silk_corrMatrix_FIX(
219 const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
220 const opus_int L, /* I Length of vectors */
221 const opus_int order, /* I Max lag for correlation */
222 opus_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ] */
223 opus_int32 *nrg, /* O Energy of x vector */
224 opus_int *rshifts, /* O Right shifts of correlations */
225 int arch /* I Run-time architecture */
226);
227
228/* Calculates correlation vector X'*t */
229void silk_corrVector_FIX(
230 const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
231 const opus_int16 *t, /* I Target vector [L] */
232 const opus_int L, /* I Length of vectors */
233 const opus_int order, /* I Max lag for correlation */
234 opus_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */
235 const opus_int rshifts, /* I Right shifts of correlations */
236 int arch /* I Run-time architecture */
237);
238
239#ifndef FORCE_CPP_BUILD
240#ifdef __cplusplus
241}
242#endif /* __cplusplus */
243#endif /* FORCE_CPP_BUILD */
244#endif /* SILK_MAIN_FIX_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h b/lib/rbcodec/codecs/libopus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h
new file mode 100644
index 0000000000..3999b5bd09
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h
@@ -0,0 +1,336 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28
29/**************************************************************/
30/* Compute noise shaping coefficients and initial gain values */
31/**************************************************************/
32#define OVERRIDE_silk_noise_shape_analysis_FIX
33
34void silk_noise_shape_analysis_FIX(
35 silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
36 silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */
37 const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */
38 const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */
39 int arch /* I Run-time architecture */
40)
41{
42 silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
43 opus_int k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0;
44 opus_int32 SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32;
45 opus_int32 nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
46 opus_int32 delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;
47 opus_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ];
48 opus_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];
49 opus_int32 AR1_Q24[ MAX_SHAPE_LPC_ORDER ];
50 opus_int32 AR2_Q24[ MAX_SHAPE_LPC_ORDER ];
51 VARDECL( opus_int16, x_windowed );
52 const opus_int16 *x_ptr, *pitch_res_ptr;
53 SAVE_STACK;
54
55 /* Point to start of first LPC analysis block */
56 x_ptr = x - psEnc->sCmn.la_shape;
57
58 /****************/
59 /* GAIN CONTROL */
60 /****************/
61 SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7;
62
63 /* Input quality is the average of the quality in the lowest two VAD bands */
64 psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ]
65 + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 );
66
67 /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */
68 psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 -
69 SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 );
70
71 /* Reduce coding SNR during low speech activity */
72 if( psEnc->sCmn.useCBR == 0 ) {
73 b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8;
74 b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 );
75 SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
76 silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), /* Q11*/
77 silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); /* Q12*/
78 }
79
80 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
81 /* Reduce gains for periodic signals */
82 SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 );
83 } else {
84 /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */
85 SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
86 silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ),
87 SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 );
88 }
89
90 /*************************/
91 /* SPARSENESS PROCESSING */
92 /*************************/
93 /* Set quantizer offset */
94 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
95 /* Initially set to 0; may be overruled in process_gains(..) */
96 psEnc->sCmn.indices.quantOffsetType = 0;
97 psEncCtrl->sparseness_Q8 = 0;
98 } else {
99 /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
100 nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 );
101 energy_variation_Q7 = 0;
102 log_energy_prev_Q7 = 0;
103 pitch_res_ptr = pitch_res;
104 for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) {
105 silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );
106 nrg += silk_RSHIFT( nSamples, scale ); /* Q(-scale)*/
107
108 log_energy_Q7 = silk_lin2log( nrg );
109 if( k > 0 ) {
110 energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 );
111 }
112 log_energy_prev_Q7 = log_energy_Q7;
113 pitch_res_ptr += nSamples;
114 }
115
116 psEncCtrl->sparseness_Q8 = silk_RSHIFT( silk_sigm_Q15( silk_SMULWB( energy_variation_Q7 -
117 SILK_FIX_CONST( 5.0, 7 ), SILK_FIX_CONST( 0.1, 16 ) ) ), 7 );
118
119 /* Set quantization offset depending on sparseness measure */
120 if( psEncCtrl->sparseness_Q8 > SILK_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) {
121 psEnc->sCmn.indices.quantOffsetType = 0;
122 } else {
123 psEnc->sCmn.indices.quantOffsetType = 1;
124 }
125
126 /* Increase coding SNR for sparse signals */
127 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 ) );
128 }
129
130 /*******************************/
131 /* Control bandwidth expansion */
132 /*******************************/
133 /* More BWE for signals with high prediction gain */
134 strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );
135 BWExp1_Q16 = BWExp2_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ),
136 silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 );
137 delta_Q16 = silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - silk_SMULBB( 3, psEncCtrl->coding_quality_Q14 ),
138 SILK_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) );
139 BWExp1_Q16 = silk_SUB32( BWExp1_Q16, delta_Q16 );
140 BWExp2_Q16 = silk_ADD32( BWExp2_Q16, delta_Q16 );
141 /* BWExp1 will be applied after BWExp2, so make it relative */
142 BWExp1_Q16 = silk_DIV32_16( silk_LSHIFT( BWExp1_Q16, 14 ), silk_RSHIFT( BWExp2_Q16, 2 ) );
143
144 if( psEnc->sCmn.warping_Q16 > 0 ) {
145 /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
146 warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) );
147 } else {
148 warping_Q16 = 0;
149 }
150
151 /********************************************/
152 /* Compute noise shaping AR coefs and gains */
153 /********************************************/
154 ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 );
155 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
156 /* Apply window: sine slope followed by flat part followed by cosine slope */
157 opus_int shift, slope_part, flat_part;
158 flat_part = psEnc->sCmn.fs_kHz * 3;
159 slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 );
160
161 silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part );
162 shift = slope_part;
163 silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) );
164 shift += flat_part;
165 silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part );
166
167 /* Update pointer: next LPC analysis block */
168 x_ptr += psEnc->sCmn.subfr_length;
169
170 if( psEnc->sCmn.warping_Q16 > 0 ) {
171 /* Calculate warped auto correlation */
172 silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch );
173 } else {
174 /* Calculate regular auto correlation */
175 silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch );
176 }
177
178 /* Add white noise, as a fraction of energy */
179 auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ),
180 SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) );
181
182 /* Calculate the reflection coefficients using schur */
183 nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder );
184 silk_assert( nrg >= 0 );
185
186 /* Convert reflection coefficients to prediction coefficients */
187 silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );
188
189 Qnrg = -scale; /* range: -12...30*/
190 silk_assert( Qnrg >= -12 );
191 silk_assert( Qnrg <= 30 );
192
193 /* Make sure that Qnrg is an even number */
194 if( Qnrg & 1 ) {
195 Qnrg -= 1;
196 nrg >>= 1;
197 }
198
199 tmp32 = silk_SQRT_APPROX( nrg );
200 Qnrg >>= 1; /* range: -6...15*/
201
202 psEncCtrl->Gains_Q16[ k ] = (silk_LSHIFT32( silk_LIMIT( (tmp32), silk_RSHIFT32( silk_int32_MIN, (16 - Qnrg) ), \
203 silk_RSHIFT32( silk_int32_MAX, (16 - Qnrg) ) ), (16 - Qnrg) ));
204
205 if( psEnc->sCmn.warping_Q16 > 0 ) {
206 /* Adjust gain for warping */
207 gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );
208 silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
209 if ( silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 ) >= ( silk_int32_MAX >> 1 ) ) {
210 psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX;
211 } else {
212 psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
213 }
214 }
215
216 /* Bandwidth expansion for synthesis filter shaping */
217 silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 );
218
219 /* Compute noise shaping filter coefficients */
220 silk_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( opus_int32 ) );
221
222 /* Bandwidth expansion for analysis filter shaping */
223 silk_assert( BWExp1_Q16 <= SILK_FIX_CONST( 1.0, 16 ) );
224 silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 );
225
226 /* Ratio of prediction gains, in energy domain */
227 pre_nrg_Q30 = silk_LPC_inverse_pred_gain_Q24( AR2_Q24, psEnc->sCmn.shapingLPCOrder, arch );
228 nrg = silk_LPC_inverse_pred_gain_Q24( AR1_Q24, psEnc->sCmn.shapingLPCOrder, arch );
229
230 /*psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;*/
231 pre_nrg_Q30 = silk_LSHIFT32( silk_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 );
232 psEncCtrl->GainsPre_Q14[ k ] = ( opus_int ) SILK_FIX_CONST( 0.3, 14 ) + silk_DIV32_varQ( pre_nrg_Q30, nrg, 14 );
233
234 /* Convert to monic warped prediction coefficients and limit absolute values */
235 limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );
236
237 /* Convert from Q24 to Q13 and store in int16 */
238 for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {
239 psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) );
240 psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) );
241 }
242 }
243
244 /*****************/
245 /* Gain tweaking */
246 /*****************/
247 /* Increase gains during low speech activity and put lower limit on gains */
248 gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) );
249 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 ) ) );
250 silk_assert( gain_mult_Q16 > 0 );
251 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
252 psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
253 silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
254 psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 );
255 }
256
257 gain_mult_Q16 = SILK_FIX_CONST( 1.0, 16 ) + silk_RSHIFT_ROUND( silk_MLA( SILK_FIX_CONST( INPUT_TILT, 26 ),
258 psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 );
259 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
260 psEncCtrl->GainsPre_Q14[ k ] = silk_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] );
261 }
262
263 /************************************************/
264 /* Control low-frequency shaping and noise tilt */
265 /************************************************/
266 /* Less low frequency shaping for noisy inputs */
267 strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ),
268 SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) );
269 strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 );
270 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
271 /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */
272 /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/
273 opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz );
274 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
275 b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] );
276 /* Pack two coefficients in one int32 */
277 psEncCtrl->LF_shp_Q14[ k ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 );
278 psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
279 }
280 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*/
281 Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) -
282 silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ),
283 silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) );
284 } else {
285 b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/
286 /* Pack two coefficients in one int32 */
287 psEncCtrl->LF_shp_Q14[ 0 ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 -
288 silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 );
289 psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
290 for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) {
291 psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ];
292 }
293 Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 );
294 }
295
296 /****************************/
297 /* HARMONIC SHAPING CONTROL */
298 /****************************/
299 /* Control boosting of harmonic frequencies */
300 HarmBoost_Q16 = silk_SMULWB( silk_SMULWB( SILK_FIX_CONST( 1.0, 17 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ),
301 psEnc->LTPCorr_Q15 ), SILK_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) );
302
303 /* More harmonic boost for noisy input signals */
304 HarmBoost_Q16 = silk_SMLAWB( HarmBoost_Q16,
305 SILK_FIX_CONST( 1.0, 16 ) - silk_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SILK_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) );
306
307 if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
308 /* More harmonic noise shaping for high bitrates or noisy input */
309 HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ),
310 SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ),
311 psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) );
312
313 /* Less harmonic noise shaping for less periodic signals */
314 HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ),
315 silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) );
316 } else {
317 HarmShapeGain_Q16 = 0;
318 }
319
320 /*************************/
321 /* Smooth over subframes */
322 /*************************/
323 for( k = 0; k < MAX_NB_SUBFR; k++ ) {
324 psShapeSt->HarmBoost_smth_Q16 =
325 silk_SMLAWB( psShapeSt->HarmBoost_smth_Q16, HarmBoost_Q16 - psShapeSt->HarmBoost_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
326 psShapeSt->HarmShapeGain_smth_Q16 =
327 silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
328 psShapeSt->Tilt_smth_Q16 =
329 silk_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
330
331 psEncCtrl->HarmBoost_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16, 2 );
332 psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );
333 psEncCtrl->Tilt_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 );
334 }
335 RESTORE_STACK;
336}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/mips/prefilter_FIX_mipsr1.h b/lib/rbcodec/codecs/libopus/silk/fixed/mips/prefilter_FIX_mipsr1.h
new file mode 100644
index 0000000000..21b256885f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/mips/prefilter_FIX_mipsr1.h
@@ -0,0 +1,184 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27#ifndef __PREFILTER_FIX_MIPSR1_H__
28#define __PREFILTER_FIX_MIPSR1_H__
29
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
34#include "main_FIX.h"
35#include "stack_alloc.h"
36#include "tuning_parameters.h"
37
38#define OVERRIDE_silk_warped_LPC_analysis_filter_FIX
39void silk_warped_LPC_analysis_filter_FIX(
40 opus_int32 state[], /* I/O State [order + 1] */
41 opus_int32 res_Q2[], /* O Residual signal [length] */
42 const opus_int16 coef_Q13[], /* I Coefficients [order] */
43 const opus_int16 input[], /* I Input signal [length] */
44 const opus_int16 lambda_Q16, /* I Warping factor */
45 const opus_int length, /* I Length of input signal */
46 const opus_int order, /* I Filter order (even) */
47 int arch
48)
49{
50 opus_int n, i;
51 opus_int32 acc_Q11, acc_Q22, tmp1, tmp2, tmp3, tmp4;
52 opus_int32 state_cur, state_next;
53
54 (void)arch;
55
56 /* Order must be even */
57 /* Length must be even */
58
59 silk_assert( ( order & 1 ) == 0 );
60 silk_assert( ( length & 1 ) == 0 );
61
62 for( n = 0; n < length; n+=2 ) {
63 /* Output of lowpass section */
64 tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 );
65 state_cur = silk_LSHIFT( input[ n ], 14 );
66 /* Output of allpass section */
67 tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 );
68 state_next = tmp2;
69 acc_Q11 = silk_RSHIFT( order, 1 );
70 acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] );
71
72
73 /* Output of lowpass section */
74 tmp4 = silk_SMLAWB( state_cur, state_next, lambda_Q16 );
75 state[ 0 ] = silk_LSHIFT( input[ n+1 ], 14 );
76 /* Output of allpass section */
77 tmp3 = silk_SMLAWB( state_next, tmp1 - tmp4, lambda_Q16 );
78 state[ 1 ] = tmp4;
79 acc_Q22 = silk_RSHIFT( order, 1 );
80 acc_Q22 = silk_SMLAWB( acc_Q22, tmp4, coef_Q13[ 0 ] );
81
82 /* Loop over allpass sections */
83 for( i = 2; i < order; i += 2 ) {
84 /* Output of allpass section */
85 tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 );
86 state_cur = tmp1;
87 acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] );
88 /* Output of allpass section */
89 tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 );
90 state_next = tmp2;
91 acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] );
92
93
94 /* Output of allpass section */
95 tmp4 = silk_SMLAWB( state_cur, state_next - tmp3, lambda_Q16 );
96 state[ i ] = tmp3;
97 acc_Q22 = silk_SMLAWB( acc_Q22, tmp3, coef_Q13[ i - 1 ] );
98 /* Output of allpass section */
99 tmp3 = silk_SMLAWB( state_next, tmp1 - tmp4, lambda_Q16 );
100 state[ i + 1 ] = tmp4;
101 acc_Q22 = silk_SMLAWB( acc_Q22, tmp4, coef_Q13[ i ] );
102 }
103 acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );
104 res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 );
105
106 state[ order ] = tmp3;
107 acc_Q22 = silk_SMLAWB( acc_Q22, tmp3, coef_Q13[ order - 1 ] );
108 res_Q2[ n+1 ] = silk_LSHIFT( (opus_int32)input[ n+1 ], 2 ) - silk_RSHIFT_ROUND( acc_Q22, 9 );
109 }
110}
111
112
113
114/* Prefilter for finding Quantizer input signal */
115#define OVERRIDE_silk_prefilt_FIX
116static inline void silk_prefilt_FIX(
117 silk_prefilter_state_FIX *P, /* I/O state */
118 opus_int32 st_res_Q12[], /* I short term residual signal */
119 opus_int32 xw_Q3[], /* O prefiltered signal */
120 opus_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */
121 opus_int Tilt_Q14, /* I Tilt shaping coeficient */
122 opus_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients */
123 opus_int lag, /* I Lag for harmonic shaping */
124 opus_int length /* I Length of signals */
125)
126{
127 opus_int i, idx, LTP_shp_buf_idx;
128 opus_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10;
129 opus_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12;
130 opus_int16 *LTP_shp_buf;
131
132 /* To speed up use temp variables instead of using the struct */
133 LTP_shp_buf = P->sLTP_shp;
134 LTP_shp_buf_idx = P->sLTP_shp_buf_idx;
135 sLF_AR_shp_Q12 = P->sLF_AR_shp_Q12;
136 sLF_MA_shp_Q12 = P->sLF_MA_shp_Q12;
137
138 if( lag > 0 ) {
139 for( i = 0; i < length; i++ ) {
140 /* unrolled loop */
141 silk_assert( HARM_SHAPE_FIR_TAPS == 3 );
142 idx = lag + LTP_shp_buf_idx;
143 n_LTP_Q12 = silk_SMULBB( LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
144 n_LTP_Q12 = silk_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
145 n_LTP_Q12 = silk_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
146
147 n_Tilt_Q10 = silk_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );
148 n_LF_Q10 = silk_SMLAWB( silk_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );
149
150 sLF_AR_shp_Q12 = silk_SUB32( st_res_Q12[ i ], silk_LSHIFT( n_Tilt_Q10, 2 ) );
151 sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12, silk_LSHIFT( n_LF_Q10, 2 ) );
152
153 LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
154 LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );
155
156 xw_Q3[i] = silk_RSHIFT_ROUND( silk_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 9 );
157 }
158 }
159 else
160 {
161 for( i = 0; i < length; i++ ) {
162
163 n_LTP_Q12 = 0;
164
165 n_Tilt_Q10 = silk_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );
166 n_LF_Q10 = silk_SMLAWB( silk_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );
167
168 sLF_AR_shp_Q12 = silk_SUB32( st_res_Q12[ i ], silk_LSHIFT( n_Tilt_Q10, 2 ) );
169 sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12, silk_LSHIFT( n_LF_Q10, 2 ) );
170
171 LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
172 LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );
173
174 xw_Q3[i] = silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 9 );
175 }
176 }
177
178 /* Copy temp variable back to state */
179 P->sLF_AR_shp_Q12 = sLF_AR_shp_Q12;
180 P->sLF_MA_shp_Q12 = sLF_MA_shp_Q12;
181 P->sLTP_shp_buf_idx = LTP_shp_buf_idx;
182}
183
184#endif /* __PREFILTER_FIX_MIPSR1_H__ */
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h b/lib/rbcodec/codecs/libopus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h
new file mode 100644
index 0000000000..fcbd96c88d
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h
@@ -0,0 +1,166 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__
29#define __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35#include "main_FIX.h"
36
37#undef QC
38#define QC 10
39
40#undef QS
41#define QS 14
42
43/* Autocorrelations for a warped frequency axis */
44#define OVERRIDE_silk_warped_autocorrelation_FIX
45void silk_warped_autocorrelation_FIX(
46 opus_int32 *corr, /* O Result [order + 1] */
47 opus_int *scale, /* O Scaling of the correlation vector */
48 const opus_int16 *input, /* I Input data to correlate */
49 const opus_int warping_Q16, /* I Warping coefficient */
50 const opus_int length, /* I Length of input */
51 const opus_int order, /* I Correlation order (even) */
52 int arch /* I Run-time architecture */
53)
54{
55 opus_int n, i, lsh;
56 opus_int32 tmp1_QS=0, tmp2_QS=0, tmp3_QS=0, tmp4_QS=0, tmp5_QS=0, tmp6_QS=0, tmp7_QS=0, tmp8_QS=0, start_1=0, start_2=0, start_3=0;
57 opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
58 opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
59 opus_int64 temp64;
60
61 opus_int32 val;
62 val = 2 * QS - QC;
63
64 /* Order must be even */
65 silk_assert( ( order & 1 ) == 0 );
66 silk_assert( 2 * QS - QC >= 0 );
67
68 /* Loop over samples */
69 for( n = 0; n < length; n=n+4 ) {
70
71 tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS );
72 start_1 = tmp1_QS;
73 tmp3_QS = silk_LSHIFT32( (opus_int32)input[ n+1], QS );
74 start_2 = tmp3_QS;
75 tmp5_QS = silk_LSHIFT32( (opus_int32)input[ n+2], QS );
76 start_3 = tmp5_QS;
77 tmp7_QS = silk_LSHIFT32( (opus_int32)input[ n+3], QS );
78
79 /* Loop over allpass sections */
80 for( i = 0; i < order; i += 2 ) {
81 /* Output of allpass section */
82 tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 );
83 corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp1_QS, start_1);
84
85 tmp4_QS = silk_SMLAWB( tmp1_QS, tmp2_QS - tmp3_QS, warping_Q16 );
86 corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp3_QS, start_2);
87
88 tmp6_QS = silk_SMLAWB( tmp3_QS, tmp4_QS - tmp5_QS, warping_Q16 );
89 corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp5_QS, start_3);
90
91 tmp8_QS = silk_SMLAWB( tmp5_QS, tmp6_QS - tmp7_QS, warping_Q16 );
92 state_QS[ i ] = tmp7_QS;
93 corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp7_QS, state_QS[0]);
94
95 /* Output of allpass section */
96 tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 );
97 corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp2_QS, start_1);
98
99 tmp3_QS = silk_SMLAWB( tmp2_QS, tmp1_QS - tmp4_QS, warping_Q16 );
100 corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp4_QS, start_2);
101
102 tmp5_QS = silk_SMLAWB( tmp4_QS, tmp3_QS - tmp6_QS, warping_Q16 );
103 corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp6_QS, start_3);
104
105 tmp7_QS = silk_SMLAWB( tmp6_QS, tmp5_QS - tmp8_QS, warping_Q16 );
106 state_QS[ i + 1 ] = tmp8_QS;
107 corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp8_QS, state_QS[ 0 ]);
108
109 }
110 state_QS[ order ] = tmp7_QS;
111
112 corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp1_QS, start_1);
113 corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp3_QS, start_2);
114 corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp5_QS, start_3);
115 corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp7_QS, state_QS[ 0 ]);
116 }
117
118 for(;n< length; n++ ) {
119
120 tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS );
121
122 /* Loop over allpass sections */
123 for( i = 0; i < order; i += 2 ) {
124
125 /* Output of allpass section */
126 tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 );
127 state_QS[ i ] = tmp1_QS;
128 corr_QC[ i ] = __builtin_mips_madd( corr_QC[ i ], tmp1_QS, state_QS[ 0 ]);
129
130 /* Output of allpass section */
131 tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 );
132 state_QS[ i + 1 ] = tmp2_QS;
133 corr_QC[ i+1 ] = __builtin_mips_madd( corr_QC[ i+1 ], tmp2_QS, state_QS[ 0 ]);
134 }
135 state_QS[ order ] = tmp1_QS;
136 corr_QC[ order ] = __builtin_mips_madd( corr_QC[ order ], tmp1_QS, state_QS[ 0 ]);
137 }
138
139 temp64 = corr_QC[ 0 ];
140 temp64 = __builtin_mips_shilo(temp64, val);
141
142 lsh = silk_CLZ64( temp64 ) - 35;
143 lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC );
144 *scale = -( QC + lsh );
145 silk_assert( *scale >= -30 && *scale <= 12 );
146 if( lsh >= 0 ) {
147 for( i = 0; i < order + 1; i++ ) {
148 temp64 = corr_QC[ i ];
149 //temp64 = __builtin_mips_shilo(temp64, val);
150 temp64 = (val >= 0) ? (temp64 >> val) : (temp64 << -val);
151 corr[ i ] = (opus_int32)silk_CHECK_FIT32( __builtin_mips_shilo( temp64, -lsh ) );
152 }
153 } else {
154 for( i = 0; i < order + 1; i++ ) {
155 temp64 = corr_QC[ i ];
156 //temp64 = __builtin_mips_shilo(temp64, val);
157 temp64 = (val >= 0) ? (temp64 >> val) : (temp64 << -val);
158 corr[ i ] = (opus_int32)silk_CHECK_FIT32( __builtin_mips_shilo( temp64, -lsh ) );
159 }
160 }
161
162 corr_QC[ 0 ] = __builtin_mips_shilo(corr_QC[ 0 ], val);
163
164 silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/
165}
166#endif /* __WARPED_AUTOCORRELATION_FIX_MIPSR1_H__ */
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/noise_shape_analysis_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/noise_shape_analysis_FIX.c
new file mode 100644
index 0000000000..85fea0bf09
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/noise_shape_analysis_FIX.c
@@ -0,0 +1,407 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33#include "stack_alloc.h"
34#include "tuning_parameters.h"
35
36/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */
37/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */
38/* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */
39/* coefficient in an array of coefficients, for monic filters. */
40static OPUS_INLINE opus_int32 warped_gain( /* gain in Q16*/
41 const opus_int32 *coefs_Q24,
42 opus_int lambda_Q16,
43 opus_int order
44) {
45 opus_int i;
46 opus_int32 gain_Q24;
47
48 lambda_Q16 = -lambda_Q16;
49 gain_Q24 = coefs_Q24[ order - 1 ];
50 for( i = order - 2; i >= 0; i-- ) {
51 gain_Q24 = silk_SMLAWB( coefs_Q24[ i ], gain_Q24, lambda_Q16 );
52 }
53 gain_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), gain_Q24, -lambda_Q16 );
54 return silk_INVERSE32_varQ( gain_Q24, 40 );
55}
56
57/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */
58/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */
59static OPUS_INLINE void limit_warped_coefs(
60 opus_int32 *coefs_Q24,
61 opus_int lambda_Q16,
62 opus_int32 limit_Q24,
63 opus_int order
64) {
65 opus_int i, iter, ind = 0;
66 opus_int32 tmp, maxabs_Q24, chirp_Q16, gain_Q16;
67 opus_int32 nom_Q16, den_Q24;
68 opus_int32 limit_Q20, maxabs_Q20;
69
70 /* Convert to monic coefficients */
71 lambda_Q16 = -lambda_Q16;
72 for( i = order - 1; i > 0; i-- ) {
73 coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
74 }
75 lambda_Q16 = -lambda_Q16;
76 nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 );
77 den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 );
78 gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
79 for( i = 0; i < order; i++ ) {
80 coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
81 }
82 limit_Q20 = silk_RSHIFT(limit_Q24, 4);
83 for( iter = 0; iter < 10; iter++ ) {
84 /* Find maximum absolute value */
85 maxabs_Q24 = -1;
86 for( i = 0; i < order; i++ ) {
87 tmp = silk_abs_int32( coefs_Q24[ i ] );
88 if( tmp > maxabs_Q24 ) {
89 maxabs_Q24 = tmp;
90 ind = i;
91 }
92 }
93 /* Use Q20 to avoid any overflow when multiplying by (ind + 1) later. */
94 maxabs_Q20 = silk_RSHIFT(maxabs_Q24, 4);
95 if( maxabs_Q20 <= limit_Q20 ) {
96 /* Coefficients are within range - done */
97 return;
98 }
99
100 /* Convert back to true warped coefficients */
101 for( i = 1; i < order; i++ ) {
102 coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
103 }
104 gain_Q16 = silk_INVERSE32_varQ( gain_Q16, 32 );
105 for( i = 0; i < order; i++ ) {
106 coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
107 }
108
109 /* Apply bandwidth expansion */
110 chirp_Q16 = SILK_FIX_CONST( 0.99, 16 ) - silk_DIV32_varQ(
111 silk_SMULWB( maxabs_Q20 - limit_Q20, silk_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ),
112 silk_MUL( maxabs_Q20, ind + 1 ), 22 );
113 silk_bwexpander_32( coefs_Q24, order, chirp_Q16 );
114
115 /* Convert to monic warped coefficients */
116 lambda_Q16 = -lambda_Q16;
117 for( i = order - 1; i > 0; i-- ) {
118 coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
119 }
120 lambda_Q16 = -lambda_Q16;
121 nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 );
122 den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 );
123 gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
124 for( i = 0; i < order; i++ ) {
125 coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
126 }
127 }
128 silk_assert( 0 );
129}
130
131/* Disable MIPS version until it's updated. */
132#if 0 && defined(MIPSr1_ASM)
133#include "mips/noise_shape_analysis_FIX_mipsr1.h"
134#endif
135
136/**************************************************************/
137/* Compute noise shaping coefficients and initial gain values */
138/**************************************************************/
139#ifndef OVERRIDE_silk_noise_shape_analysis_FIX
140void silk_noise_shape_analysis_FIX(
141 silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */
142 silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */
143 const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */
144 const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */
145 int arch /* I Run-time architecture */
146)
147{
148 silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
149 opus_int k, i, nSamples, nSegs, Qnrg, b_Q14, warping_Q16, scale = 0;
150 opus_int32 SNR_adj_dB_Q7, HarmShapeGain_Q16, Tilt_Q16, tmp32;
151 opus_int32 nrg, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
152 opus_int32 BWExp_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;
153 opus_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ];
154 opus_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];
155 opus_int32 AR_Q24[ MAX_SHAPE_LPC_ORDER ];
156 VARDECL( opus_int16, x_windowed );
157 const opus_int16 *x_ptr, *pitch_res_ptr;
158 SAVE_STACK;
159
160 /* Point to start of first LPC analysis block */
161 x_ptr = x - psEnc->sCmn.la_shape;
162
163 /****************/
164 /* GAIN CONTROL */
165 /****************/
166 SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7;
167
168 /* Input quality is the average of the quality in the lowest two VAD bands */
169 psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ]
170 + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 );
171
172 /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */
173 psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 -
174 SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 );
175
176 /* Reduce coding SNR during low speech activity */
177 if( psEnc->sCmn.useCBR == 0 ) {
178 b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8;
179 b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 );
180 SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
181 silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), /* Q11*/
182 silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); /* Q12*/
183 }
184
185 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
186 /* Reduce gains for periodic signals */
187 SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 );
188 } else {
189 /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */
190 SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
191 silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ),
192 SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 );
193 }
194
195 /*************************/
196 /* SPARSENESS PROCESSING */
197 /*************************/
198 /* Set quantizer offset */
199 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
200 /* Initially set to 0; may be overruled in process_gains(..) */
201 psEnc->sCmn.indices.quantOffsetType = 0;
202 } else {
203 /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
204 nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 );
205 energy_variation_Q7 = 0;
206 log_energy_prev_Q7 = 0;
207 pitch_res_ptr = pitch_res;
208 nSegs = silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2;
209 for( k = 0; k < nSegs; k++ ) {
210 silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );
211 nrg += silk_RSHIFT( nSamples, scale ); /* Q(-scale)*/
212
213 log_energy_Q7 = silk_lin2log( nrg );
214 if( k > 0 ) {
215 energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 );
216 }
217 log_energy_prev_Q7 = log_energy_Q7;
218 pitch_res_ptr += nSamples;
219 }
220
221 /* Set quantization offset depending on sparseness measure */
222 if( energy_variation_Q7 > SILK_FIX_CONST( ENERGY_VARIATION_THRESHOLD_QNT_OFFSET, 7 ) * (nSegs-1) ) {
223 psEnc->sCmn.indices.quantOffsetType = 0;
224 } else {
225 psEnc->sCmn.indices.quantOffsetType = 1;
226 }
227 }
228
229 /*******************************/
230 /* Control bandwidth expansion */
231 /*******************************/
232 /* More BWE for signals with high prediction gain */
233 strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );
234 BWExp_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ),
235 silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 );
236
237 if( psEnc->sCmn.warping_Q16 > 0 ) {
238 /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
239 warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) );
240 } else {
241 warping_Q16 = 0;
242 }
243
244 /********************************************/
245 /* Compute noise shaping AR coefs and gains */
246 /********************************************/
247 ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 );
248 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
249 /* Apply window: sine slope followed by flat part followed by cosine slope */
250 opus_int shift, slope_part, flat_part;
251 flat_part = psEnc->sCmn.fs_kHz * 3;
252 slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 );
253
254 silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part );
255 shift = slope_part;
256 silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) );
257 shift += flat_part;
258 silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part );
259
260 /* Update pointer: next LPC analysis block */
261 x_ptr += psEnc->sCmn.subfr_length;
262
263 if( psEnc->sCmn.warping_Q16 > 0 ) {
264 /* Calculate warped auto correlation */
265 silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch );
266 } else {
267 /* Calculate regular auto correlation */
268 silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch );
269 }
270
271 /* Add white noise, as a fraction of energy */
272 auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ),
273 SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) );
274
275 /* Calculate the reflection coefficients using schur */
276 nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder );
277 silk_assert( nrg >= 0 );
278
279 /* Convert reflection coefficients to prediction coefficients */
280 silk_k2a_Q16( AR_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );
281
282 Qnrg = -scale; /* range: -12...30*/
283 silk_assert( Qnrg >= -12 );
284 silk_assert( Qnrg <= 30 );
285
286 /* Make sure that Qnrg is an even number */
287 if( Qnrg & 1 ) {
288 Qnrg -= 1;
289 nrg >>= 1;
290 }
291
292 tmp32 = silk_SQRT_APPROX( nrg );
293 Qnrg >>= 1; /* range: -6...15*/
294
295 psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( tmp32, 16 - Qnrg );
296
297 if( psEnc->sCmn.warping_Q16 > 0 ) {
298 /* Adjust gain for warping */
299 gain_mult_Q16 = warped_gain( AR_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );
300 silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 );
301 if( psEncCtrl->Gains_Q16[ k ] < SILK_FIX_CONST( 0.25, 16 ) ) {
302 psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
303 } else {
304 psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 );
305 if ( psEncCtrl->Gains_Q16[ k ] >= ( silk_int32_MAX >> 1 ) ) {
306 psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX;
307 } else {
308 psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT32( psEncCtrl->Gains_Q16[ k ], 1 );
309 }
310 }
311 silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 );
312 }
313
314 /* Bandwidth expansion */
315 silk_bwexpander_32( AR_Q24, psEnc->sCmn.shapingLPCOrder, BWExp_Q16 );
316
317 if( psEnc->sCmn.warping_Q16 > 0 ) {
318 /* Convert to monic warped prediction coefficients and limit absolute values */
319 limit_warped_coefs( AR_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );
320
321 /* Convert from Q24 to Q13 and store in int16 */
322 for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {
323 psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR_Q24[ i ], 11 ) );
324 }
325 } else {
326 silk_LPC_fit( &psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER ], AR_Q24, 13, 24, psEnc->sCmn.shapingLPCOrder );
327 }
328 }
329
330 /*****************/
331 /* Gain tweaking */
332 /*****************/
333 /* Increase gains during low speech activity and put lower limit on gains */
334 gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) );
335 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 ) ) );
336 silk_assert( gain_mult_Q16 > 0 );
337 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
338 psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
339 silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
340 psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 );
341 }
342
343
344 /************************************************/
345 /* Control low-frequency shaping and noise tilt */
346 /************************************************/
347 /* Less low frequency shaping for noisy inputs */
348 strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ),
349 SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) );
350 strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 );
351 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
352 /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */
353 /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/
354 opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz );
355 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
356 b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] );
357 /* Pack two coefficients in one int32 */
358 psEncCtrl->LF_shp_Q14[ k ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 );
359 psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
360 }
361 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*/
362 Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) -
363 silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ),
364 silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) );
365 } else {
366 b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/
367 /* Pack two coefficients in one int32 */
368 psEncCtrl->LF_shp_Q14[ 0 ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 -
369 silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 );
370 psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
371 for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) {
372 psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ];
373 }
374 Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 );
375 }
376
377 /****************************/
378 /* HARMONIC SHAPING CONTROL */
379 /****************************/
380 if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
381 /* More harmonic noise shaping for high bitrates or noisy input */
382 HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ),
383 SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ),
384 psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) );
385
386 /* Less harmonic noise shaping for less periodic signals */
387 HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ),
388 silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) );
389 } else {
390 HarmShapeGain_Q16 = 0;
391 }
392
393 /*************************/
394 /* Smooth over subframes */
395 /*************************/
396 for( k = 0; k < MAX_NB_SUBFR; k++ ) {
397 psShapeSt->HarmShapeGain_smth_Q16 =
398 silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
399 psShapeSt->Tilt_smth_Q16 =
400 silk_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
401
402 psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );
403 psEncCtrl->Tilt_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 );
404 }
405 RESTORE_STACK;
406}
407#endif /* OVERRIDE_silk_noise_shape_analysis_FIX */
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/pitch_analysis_core_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/pitch_analysis_core_FIX.c
new file mode 100644
index 0000000000..14729046d2
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/pitch_analysis_core_FIX.c
@@ -0,0 +1,721 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32/***********************************************************
33* Pitch analyser function
34********************************************************** */
35#include "SigProc_FIX.h"
36#include "pitch_est_defines.h"
37#include "stack_alloc.h"
38#include "debug.h"
39#include "pitch.h"
40
41#define SCRATCH_SIZE 22
42#define SF_LENGTH_4KHZ ( PE_SUBFR_LENGTH_MS * 4 )
43#define SF_LENGTH_8KHZ ( PE_SUBFR_LENGTH_MS * 8 )
44#define MIN_LAG_4KHZ ( PE_MIN_LAG_MS * 4 )
45#define MIN_LAG_8KHZ ( PE_MIN_LAG_MS * 8 )
46#define MAX_LAG_4KHZ ( PE_MAX_LAG_MS * 4 )
47#define MAX_LAG_8KHZ ( PE_MAX_LAG_MS * 8 - 1 )
48#define CSTRIDE_4KHZ ( MAX_LAG_4KHZ + 1 - MIN_LAG_4KHZ )
49#define CSTRIDE_8KHZ ( MAX_LAG_8KHZ + 3 - ( MIN_LAG_8KHZ - 2 ) )
50#define D_COMP_MIN ( MIN_LAG_8KHZ - 3 )
51#define D_COMP_MAX ( MAX_LAG_8KHZ + 4 )
52#define D_COMP_STRIDE ( D_COMP_MAX - D_COMP_MIN )
53
54typedef opus_int32 silk_pe_stage3_vals[ PE_NB_STAGE3_LAGS ];
55
56/************************************************************/
57/* Internally used functions */
58/************************************************************/
59static void silk_P_Ana_calc_corr_st3(
60 silk_pe_stage3_vals cross_corr_st3[], /* O 3 DIM correlation array */
61 const opus_int16 frame[], /* I vector to correlate */
62 opus_int start_lag, /* I lag offset to search around */
63 opus_int sf_length, /* I length of a 5 ms subframe */
64 opus_int nb_subfr, /* I number of subframes */
65 opus_int complexity, /* I Complexity setting */
66 int arch /* I Run-time architecture */
67);
68
69static void silk_P_Ana_calc_energy_st3(
70 silk_pe_stage3_vals energies_st3[], /* O 3 DIM energy array */
71 const opus_int16 frame[], /* I vector to calc energy in */
72 opus_int start_lag, /* I lag offset to search around */
73 opus_int sf_length, /* I length of one 5 ms subframe */
74 opus_int nb_subfr, /* I number of subframes */
75 opus_int complexity, /* I Complexity setting */
76 int arch /* I Run-time architecture */
77);
78
79/*************************************************************/
80/* FIXED POINT CORE PITCH ANALYSIS FUNCTION */
81/*************************************************************/
82opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */
83 const opus_int16 *frame_unscaled, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */
84 opus_int *pitch_out, /* O 4 pitch lag values */
85 opus_int16 *lagIndex, /* O Lag Index */
86 opus_int8 *contourIndex, /* O Pitch contour Index */
87 opus_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */
88 opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */
89 const opus_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */
90 const opus_int search_thres2_Q13, /* I Final threshold for lag candidates 0 - 1 */
91 const opus_int Fs_kHz, /* I Sample frequency (kHz) */
92 const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */
93 const opus_int nb_subfr, /* I number of 5 ms subframes */
94 int arch /* I Run-time architecture */
95)
96{
97 VARDECL( opus_int16, frame_8kHz_buf );
98 VARDECL( opus_int16, frame_4kHz );
99 VARDECL( opus_int16, frame_scaled );
100 opus_int32 filt_state[ 6 ];
101 const opus_int16 *frame, *frame_8kHz;
102 opus_int i, k, d, j;
103 VARDECL( opus_int16, C );
104 VARDECL( opus_int32, xcorr32 );
105 const opus_int16 *target_ptr, *basis_ptr;
106 opus_int32 cross_corr, normalizer, energy, energy_basis, energy_target;
107 opus_int d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp, shift;
108 VARDECL( opus_int16, d_comp );
109 opus_int32 sum, threshold, lag_counter;
110 opus_int CBimax, CBimax_new, CBimax_old, lag, start_lag, end_lag, lag_new;
111 opus_int32 CC[ PE_NB_CBKS_STAGE2_EXT ], CCmax, CCmax_b, CCmax_new_b, CCmax_new;
112 VARDECL( silk_pe_stage3_vals, energies_st3 );
113 VARDECL( silk_pe_stage3_vals, cross_corr_st3 );
114 opus_int frame_length, frame_length_8kHz, frame_length_4kHz;
115 opus_int sf_length;
116 opus_int min_lag;
117 opus_int max_lag;
118 opus_int32 contour_bias_Q15, diff;
119 opus_int nb_cbk_search, cbk_size;
120 opus_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q13;
121 const opus_int8 *Lag_CB_ptr;
122 SAVE_STACK;
123
124 /* Check for valid sampling frequency */
125 celt_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
126
127 /* Check for valid complexity setting */
128 celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
129 celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
130
131 silk_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) );
132 silk_assert( search_thres2_Q13 >= 0 && search_thres2_Q13 <= (1<<13) );
133
134 /* Set up frame lengths max / min lag for the sampling frequency */
135 frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz;
136 frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4;
137 frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8;
138 sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz;
139 min_lag = PE_MIN_LAG_MS * Fs_kHz;
140 max_lag = PE_MAX_LAG_MS * Fs_kHz - 1;
141
142 /* Downscale input if necessary */
143 silk_sum_sqr_shift( &energy, &shift, frame_unscaled, frame_length );
144 shift += 3 - silk_CLZ32( energy ); /* at least two bits headroom */
145 ALLOC( frame_scaled, frame_length, opus_int16 );
146 if( shift > 0 ) {
147 shift = silk_RSHIFT( shift + 1, 1 );
148 for( i = 0; i < frame_length; i++ ) {
149 frame_scaled[ i ] = silk_RSHIFT( frame_unscaled[ i ], shift );
150 }
151 frame = frame_scaled;
152 } else {
153 frame = frame_unscaled;
154 }
155
156 ALLOC( frame_8kHz_buf, ( Fs_kHz == 8 ) ? 1 : frame_length_8kHz, opus_int16 );
157 /* Resample from input sampled at Fs_kHz to 8 kHz */
158 if( Fs_kHz == 16 ) {
159 silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );
160 silk_resampler_down2( filt_state, frame_8kHz_buf, frame, frame_length );
161 frame_8kHz = frame_8kHz_buf;
162 } else if( Fs_kHz == 12 ) {
163 silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) );
164 silk_resampler_down2_3( filt_state, frame_8kHz_buf, frame, frame_length );
165 frame_8kHz = frame_8kHz_buf;
166 } else {
167 celt_assert( Fs_kHz == 8 );
168 frame_8kHz = frame;
169 }
170
171 /* Decimate again to 4 kHz */
172 silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );/* Set state to zero */
173 ALLOC( frame_4kHz, frame_length_4kHz, opus_int16 );
174 silk_resampler_down2( filt_state, frame_4kHz, frame_8kHz, frame_length_8kHz );
175
176 /* Low-pass filter */
177 for( i = frame_length_4kHz - 1; i > 0; i-- ) {
178 frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] );
179 }
180
181
182 /******************************************************************************
183 * FIRST STAGE, operating in 4 khz
184 ******************************************************************************/
185 ALLOC( C, nb_subfr * CSTRIDE_8KHZ, opus_int16 );
186 ALLOC( xcorr32, MAX_LAG_4KHZ-MIN_LAG_4KHZ+1, opus_int32 );
187 silk_memset( C, 0, (nb_subfr >> 1) * CSTRIDE_4KHZ * sizeof( opus_int16 ) );
188 target_ptr = &frame_4kHz[ silk_LSHIFT( SF_LENGTH_4KHZ, 2 ) ];
189 for( k = 0; k < nb_subfr >> 1; k++ ) {
190 /* Check that we are within range of the array */
191 celt_assert( target_ptr >= frame_4kHz );
192 celt_assert( target_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
193
194 basis_ptr = target_ptr - MIN_LAG_4KHZ;
195
196 /* Check that we are within range of the array */
197 celt_assert( basis_ptr >= frame_4kHz );
198 celt_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
199
200 celt_pitch_xcorr( target_ptr, target_ptr - MAX_LAG_4KHZ, xcorr32, SF_LENGTH_8KHZ, MAX_LAG_4KHZ - MIN_LAG_4KHZ + 1, arch );
201
202 /* Calculate first vector products before loop */
203 cross_corr = xcorr32[ MAX_LAG_4KHZ - MIN_LAG_4KHZ ];
204 normalizer = silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ, arch );
205 normalizer = silk_ADD32( normalizer, silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ, arch ) );
206 normalizer = silk_ADD32( normalizer, silk_SMULBB( SF_LENGTH_8KHZ, 4000 ) );
207
208 matrix_ptr( C, k, 0, CSTRIDE_4KHZ ) =
209 (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */
210
211 /* From now on normalizer is computed recursively */
212 for( d = MIN_LAG_4KHZ + 1; d <= MAX_LAG_4KHZ; d++ ) {
213 basis_ptr--;
214
215 /* Check that we are within range of the array */
216 silk_assert( basis_ptr >= frame_4kHz );
217 silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
218
219 cross_corr = xcorr32[ MAX_LAG_4KHZ - d ];
220
221 /* Add contribution of new sample and remove contribution from oldest sample */
222 normalizer = silk_ADD32( normalizer,
223 silk_SMULBB( basis_ptr[ 0 ], basis_ptr[ 0 ] ) -
224 silk_SMULBB( basis_ptr[ SF_LENGTH_8KHZ ], basis_ptr[ SF_LENGTH_8KHZ ] ) );
225
226 matrix_ptr( C, k, d - MIN_LAG_4KHZ, CSTRIDE_4KHZ) =
227 (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */
228 }
229 /* Update target pointer */
230 target_ptr += SF_LENGTH_8KHZ;
231 }
232
233 /* Combine two subframes into single correlation measure and apply short-lag bias */
234 if( nb_subfr == PE_MAX_NB_SUBFR ) {
235 for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) {
236 sum = (opus_int32)matrix_ptr( C, 0, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ )
237 + (opus_int32)matrix_ptr( C, 1, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ ); /* Q14 */
238 sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q14 */
239 C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum; /* Q14 */
240 }
241 } else {
242 /* Only short-lag bias */
243 for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) {
244 sum = silk_LSHIFT( (opus_int32)C[ i - MIN_LAG_4KHZ ], 1 ); /* Q14 */
245 sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q14 */
246 C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum; /* Q14 */
247 }
248 }
249
250 /* Sort */
251 length_d_srch = silk_ADD_LSHIFT32( 4, complexity, 1 );
252 celt_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
253 silk_insertion_sort_decreasing_int16( C, d_srch, CSTRIDE_4KHZ,
254 length_d_srch );
255
256 /* Escape if correlation is very low already here */
257 Cmax = (opus_int)C[ 0 ]; /* Q14 */
258 if( Cmax < SILK_FIX_CONST( 0.2, 14 ) ) {
259 silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );
260 *LTPCorr_Q15 = 0;
261 *lagIndex = 0;
262 *contourIndex = 0;
263 RESTORE_STACK;
264 return 1;
265 }
266
267 threshold = silk_SMULWB( search_thres1_Q16, Cmax );
268 for( i = 0; i < length_d_srch; i++ ) {
269 /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */
270 if( C[ i ] > threshold ) {
271 d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + MIN_LAG_4KHZ, 1 );
272 } else {
273 length_d_srch = i;
274 break;
275 }
276 }
277 celt_assert( length_d_srch > 0 );
278
279 ALLOC( d_comp, D_COMP_STRIDE, opus_int16 );
280 for( i = D_COMP_MIN; i < D_COMP_MAX; i++ ) {
281 d_comp[ i - D_COMP_MIN ] = 0;
282 }
283 for( i = 0; i < length_d_srch; i++ ) {
284 d_comp[ d_srch[ i ] - D_COMP_MIN ] = 1;
285 }
286
287 /* Convolution */
288 for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) {
289 d_comp[ i - D_COMP_MIN ] +=
290 d_comp[ i - 1 - D_COMP_MIN ] + d_comp[ i - 2 - D_COMP_MIN ];
291 }
292
293 length_d_srch = 0;
294 for( i = MIN_LAG_8KHZ; i < MAX_LAG_8KHZ + 1; i++ ) {
295 if( d_comp[ i + 1 - D_COMP_MIN ] > 0 ) {
296 d_srch[ length_d_srch ] = i;
297 length_d_srch++;
298 }
299 }
300
301 /* Convolution */
302 for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) {
303 d_comp[ i - D_COMP_MIN ] += d_comp[ i - 1 - D_COMP_MIN ]
304 + d_comp[ i - 2 - D_COMP_MIN ] + d_comp[ i - 3 - D_COMP_MIN ];
305 }
306
307 length_d_comp = 0;
308 for( i = MIN_LAG_8KHZ; i < D_COMP_MAX; i++ ) {
309 if( d_comp[ i - D_COMP_MIN ] > 0 ) {
310 d_comp[ length_d_comp ] = i - 2;
311 length_d_comp++;
312 }
313 }
314
315 /**********************************************************************************
316 ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation
317 *************************************************************************************/
318
319 /*********************************************************************************
320 * Find energy of each subframe projected onto its history, for a range of delays
321 *********************************************************************************/
322 silk_memset( C, 0, nb_subfr * CSTRIDE_8KHZ * sizeof( opus_int16 ) );
323
324 target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ];
325 for( k = 0; k < nb_subfr; k++ ) {
326
327 /* Check that we are within range of the array */
328 celt_assert( target_ptr >= frame_8kHz );
329 celt_assert( target_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz );
330
331 energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ, arch ), 1 );
332 for( j = 0; j < length_d_comp; j++ ) {
333 d = d_comp[ j ];
334 basis_ptr = target_ptr - d;
335
336 /* Check that we are within range of the array */
337 silk_assert( basis_ptr >= frame_8kHz );
338 silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz );
339
340 cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, SF_LENGTH_8KHZ, arch );
341 if( cross_corr > 0 ) {
342 energy_basis = silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ, arch );
343 matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) =
344 (opus_int16)silk_DIV32_varQ( cross_corr,
345 silk_ADD32( energy_target,
346 energy_basis ),
347 13 + 1 ); /* Q13 */
348 } else {
349 matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) = 0;
350 }
351 }
352 target_ptr += SF_LENGTH_8KHZ;
353 }
354
355 /* search over lag range and lags codebook */
356 /* scale factor for lag codebook, as a function of center lag */
357
358 CCmax = silk_int32_MIN;
359 CCmax_b = silk_int32_MIN;
360
361 CBimax = 0; /* To avoid returning undefined lag values */
362 lag = -1; /* To check if lag with strong enough correlation has been found */
363
364 if( prevLag > 0 ) {
365 if( Fs_kHz == 12 ) {
366 prevLag = silk_DIV32_16( silk_LSHIFT( prevLag, 1 ), 3 );
367 } else if( Fs_kHz == 16 ) {
368 prevLag = silk_RSHIFT( prevLag, 1 );
369 }
370 prevLag_log2_Q7 = silk_lin2log( (opus_int32)prevLag );
371 } else {
372 prevLag_log2_Q7 = 0;
373 }
374 silk_assert( search_thres2_Q13 == silk_SAT16( search_thres2_Q13 ) );
375 /* Set up stage 2 codebook based on number of subframes */
376 if( nb_subfr == PE_MAX_NB_SUBFR ) {
377 cbk_size = PE_NB_CBKS_STAGE2_EXT;
378 Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];
379 if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) {
380 /* If input is 8 khz use a larger codebook here because it is last stage */
381 nb_cbk_search = PE_NB_CBKS_STAGE2_EXT;
382 } else {
383 nb_cbk_search = PE_NB_CBKS_STAGE2;
384 }
385 } else {
386 cbk_size = PE_NB_CBKS_STAGE2_10MS;
387 Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ];
388 nb_cbk_search = PE_NB_CBKS_STAGE2_10MS;
389 }
390
391 for( k = 0; k < length_d_srch; k++ ) {
392 d = d_srch[ k ];
393 for( j = 0; j < nb_cbk_search; j++ ) {
394 CC[ j ] = 0;
395 for( i = 0; i < nb_subfr; i++ ) {
396 opus_int d_subfr;
397 /* Try all codebooks */
398 d_subfr = d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size );
399 CC[ j ] = CC[ j ]
400 + (opus_int32)matrix_ptr( C, i,
401 d_subfr - ( MIN_LAG_8KHZ - 2 ),
402 CSTRIDE_8KHZ );
403 }
404 }
405 /* Find best codebook */
406 CCmax_new = silk_int32_MIN;
407 CBimax_new = 0;
408 for( i = 0; i < nb_cbk_search; i++ ) {
409 if( CC[ i ] > CCmax_new ) {
410 CCmax_new = CC[ i ];
411 CBimax_new = i;
412 }
413 }
414
415 /* Bias towards shorter lags */
416 lag_log2_Q7 = silk_lin2log( d ); /* Q7 */
417 silk_assert( lag_log2_Q7 == silk_SAT16( lag_log2_Q7 ) );
418 silk_assert( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) ) );
419 CCmax_new_b = CCmax_new - silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ), lag_log2_Q7 ), 7 ); /* Q13 */
420
421 /* Bias towards previous lag */
422 silk_assert( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) ) );
423 if( prevLag > 0 ) {
424 delta_lag_log2_sqr_Q7 = lag_log2_Q7 - prevLag_log2_Q7;
425 silk_assert( delta_lag_log2_sqr_Q7 == silk_SAT16( delta_lag_log2_sqr_Q7 ) );
426 delta_lag_log2_sqr_Q7 = silk_RSHIFT( silk_SMULBB( delta_lag_log2_sqr_Q7, delta_lag_log2_sqr_Q7 ), 7 );
427 prev_lag_bias_Q13 = silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ), *LTPCorr_Q15 ), 15 ); /* Q13 */
428 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 ) );
429 CCmax_new_b -= prev_lag_bias_Q13; /* Q13 */
430 }
431
432 if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */
433 CCmax_new > silk_SMULBB( nb_subfr, search_thres2_Q13 ) && /* Correlation needs to be high enough to be voiced */
434 silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= MIN_LAG_8KHZ /* Lag must be in range */
435 ) {
436 CCmax_b = CCmax_new_b;
437 CCmax = CCmax_new;
438 lag = d;
439 CBimax = CBimax_new;
440 }
441 }
442
443 if( lag == -1 ) {
444 /* No suitable candidate found */
445 silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );
446 *LTPCorr_Q15 = 0;
447 *lagIndex = 0;
448 *contourIndex = 0;
449 RESTORE_STACK;
450 return 1;
451 }
452
453 /* Output normalized correlation */
454 *LTPCorr_Q15 = (opus_int)silk_LSHIFT( silk_DIV32_16( CCmax, nb_subfr ), 2 );
455 silk_assert( *LTPCorr_Q15 >= 0 );
456
457 if( Fs_kHz > 8 ) {
458 /* Search in original signal */
459
460 CBimax_old = CBimax;
461 /* Compensate for decimation */
462 silk_assert( lag == silk_SAT16( lag ) );
463 if( Fs_kHz == 12 ) {
464 lag = silk_RSHIFT( silk_SMULBB( lag, 3 ), 1 );
465 } else if( Fs_kHz == 16 ) {
466 lag = silk_LSHIFT( lag, 1 );
467 } else {
468 lag = silk_SMULBB( lag, 3 );
469 }
470
471 lag = silk_LIMIT_int( lag, min_lag, max_lag );
472 start_lag = silk_max_int( lag - 2, min_lag );
473 end_lag = silk_min_int( lag + 2, max_lag );
474 lag_new = lag; /* to avoid undefined lag */
475 CBimax = 0; /* to avoid undefined lag */
476
477 CCmax = silk_int32_MIN;
478 /* pitch lags according to second stage */
479 for( k = 0; k < nb_subfr; k++ ) {
480 pitch_out[ k ] = lag + 2 * silk_CB_lags_stage2[ k ][ CBimax_old ];
481 }
482
483 /* Set up codebook parameters according to complexity setting and frame length */
484 if( nb_subfr == PE_MAX_NB_SUBFR ) {
485 nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];
486 cbk_size = PE_NB_CBKS_STAGE3_MAX;
487 Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
488 } else {
489 nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
490 cbk_size = PE_NB_CBKS_STAGE3_10MS;
491 Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
492 }
493
494 /* Calculate the correlations and energies needed in stage 3 */
495 ALLOC( energies_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals );
496 ALLOC( cross_corr_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals );
497 silk_P_Ana_calc_corr_st3( cross_corr_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch );
498 silk_P_Ana_calc_energy_st3( energies_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch );
499
500 lag_counter = 0;
501 silk_assert( lag == silk_SAT16( lag ) );
502 contour_bias_Q15 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 15 ), lag );
503
504 target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ];
505 energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, nb_subfr * sf_length, arch ), 1 );
506 for( d = start_lag; d <= end_lag; d++ ) {
507 for( j = 0; j < nb_cbk_search; j++ ) {
508 cross_corr = 0;
509 energy = energy_target;
510 for( k = 0; k < nb_subfr; k++ ) {
511 cross_corr = silk_ADD32( cross_corr,
512 matrix_ptr( cross_corr_st3, k, j,
513 nb_cbk_search )[ lag_counter ] );
514 energy = silk_ADD32( energy,
515 matrix_ptr( energies_st3, k, j,
516 nb_cbk_search )[ lag_counter ] );
517 silk_assert( energy >= 0 );
518 }
519 if( cross_corr > 0 ) {
520 CCmax_new = silk_DIV32_varQ( cross_corr, energy, 13 + 1 ); /* Q13 */
521 /* Reduce depending on flatness of contour */
522 diff = silk_int16_MAX - silk_MUL( contour_bias_Q15, j ); /* Q15 */
523 silk_assert( diff == silk_SAT16( diff ) );
524 CCmax_new = silk_SMULWB( CCmax_new, diff ); /* Q14 */
525 } else {
526 CCmax_new = 0;
527 }
528
529 if( CCmax_new > CCmax && ( d + silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) {
530 CCmax = CCmax_new;
531 lag_new = d;
532 CBimax = j;
533 }
534 }
535 lag_counter++;
536 }
537
538 for( k = 0; k < nb_subfr; k++ ) {
539 pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
540 pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz );
541 }
542 *lagIndex = (opus_int16)( lag_new - min_lag);
543 *contourIndex = (opus_int8)CBimax;
544 } else { /* Fs_kHz == 8 */
545 /* Save Lags */
546 for( k = 0; k < nb_subfr; k++ ) {
547 pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
548 pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], MIN_LAG_8KHZ, PE_MAX_LAG_MS * 8 );
549 }
550 *lagIndex = (opus_int16)( lag - MIN_LAG_8KHZ );
551 *contourIndex = (opus_int8)CBimax;
552 }
553 celt_assert( *lagIndex >= 0 );
554 /* return as voiced */
555 RESTORE_STACK;
556 return 0;
557}
558
559/***********************************************************************
560 * Calculates the correlations used in stage 3 search. In order to cover
561 * the whole lag codebook for all the searched offset lags (lag +- 2),
562 * the following correlations are needed in each sub frame:
563 *
564 * sf1: lag range [-8,...,7] total 16 correlations
565 * sf2: lag range [-4,...,4] total 9 correlations
566 * sf3: lag range [-3,....4] total 8 correltions
567 * sf4: lag range [-6,....8] total 15 correlations
568 *
569 * In total 48 correlations. The direct implementation computed in worst
570 * case 4*12*5 = 240 correlations, but more likely around 120.
571 ***********************************************************************/
572static void silk_P_Ana_calc_corr_st3(
573 silk_pe_stage3_vals cross_corr_st3[], /* O 3 DIM correlation array */
574 const opus_int16 frame[], /* I vector to correlate */
575 opus_int start_lag, /* I lag offset to search around */
576 opus_int sf_length, /* I length of a 5 ms subframe */
577 opus_int nb_subfr, /* I number of subframes */
578 opus_int complexity, /* I Complexity setting */
579 int arch /* I Run-time architecture */
580)
581{
582 const opus_int16 *target_ptr;
583 opus_int i, j, k, lag_counter, lag_low, lag_high;
584 opus_int nb_cbk_search, delta, idx, cbk_size;
585 VARDECL( opus_int32, scratch_mem );
586 VARDECL( opus_int32, xcorr32 );
587 const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
588 SAVE_STACK;
589
590 celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
591 celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
592
593 if( nb_subfr == PE_MAX_NB_SUBFR ) {
594 Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
595 Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
596 nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
597 cbk_size = PE_NB_CBKS_STAGE3_MAX;
598 } else {
599 celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
600 Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
601 Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
602 nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
603 cbk_size = PE_NB_CBKS_STAGE3_10MS;
604 }
605 ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 );
606 ALLOC( xcorr32, SCRATCH_SIZE, opus_int32 );
607
608 target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */
609 for( k = 0; k < nb_subfr; k++ ) {
610 lag_counter = 0;
611
612 /* Calculate the correlations for each subframe */
613 lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 );
614 lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 );
615 celt_assert(lag_high-lag_low+1 <= SCRATCH_SIZE);
616 celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr32, sf_length, lag_high - lag_low + 1, arch );
617 for( j = lag_low; j <= lag_high; j++ ) {
618 silk_assert( lag_counter < SCRATCH_SIZE );
619 scratch_mem[ lag_counter ] = xcorr32[ lag_high - j ];
620 lag_counter++;
621 }
622
623 delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );
624 for( i = 0; i < nb_cbk_search; i++ ) {
625 /* Fill out the 3 dim array that stores the correlations for */
626 /* each code_book vector for each start lag */
627 idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;
628 for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
629 silk_assert( idx + j < SCRATCH_SIZE );
630 silk_assert( idx + j < lag_counter );
631 matrix_ptr( cross_corr_st3, k, i, nb_cbk_search )[ j ] =
632 scratch_mem[ idx + j ];
633 }
634 }
635 target_ptr += sf_length;
636 }
637 RESTORE_STACK;
638}
639
640/********************************************************************/
641/* Calculate the energies for first two subframes. The energies are */
642/* calculated recursively. */
643/********************************************************************/
644static void silk_P_Ana_calc_energy_st3(
645 silk_pe_stage3_vals energies_st3[], /* O 3 DIM energy array */
646 const opus_int16 frame[], /* I vector to calc energy in */
647 opus_int start_lag, /* I lag offset to search around */
648 opus_int sf_length, /* I length of one 5 ms subframe */
649 opus_int nb_subfr, /* I number of subframes */
650 opus_int complexity, /* I Complexity setting */
651 int arch /* I Run-time architecture */
652)
653{
654 const opus_int16 *target_ptr, *basis_ptr;
655 opus_int32 energy;
656 opus_int k, i, j, lag_counter;
657 opus_int nb_cbk_search, delta, idx, cbk_size, lag_diff;
658 VARDECL( opus_int32, scratch_mem );
659 const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
660 SAVE_STACK;
661
662 celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
663 celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
664
665 if( nb_subfr == PE_MAX_NB_SUBFR ) {
666 Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
667 Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
668 nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
669 cbk_size = PE_NB_CBKS_STAGE3_MAX;
670 } else {
671 celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
672 Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
673 Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
674 nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
675 cbk_size = PE_NB_CBKS_STAGE3_10MS;
676 }
677 ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 );
678
679 target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ];
680 for( k = 0; k < nb_subfr; k++ ) {
681 lag_counter = 0;
682
683 /* Calculate the energy for first lag */
684 basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) );
685 energy = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length, arch );
686 silk_assert( energy >= 0 );
687 scratch_mem[ lag_counter ] = energy;
688 lag_counter++;
689
690 lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) - matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 );
691 for( i = 1; i < lag_diff; i++ ) {
692 /* remove part outside new window */
693 energy -= silk_SMULBB( basis_ptr[ sf_length - i ], basis_ptr[ sf_length - i ] );
694 silk_assert( energy >= 0 );
695
696 /* add part that comes into window */
697 energy = silk_ADD_SAT32( energy, silk_SMULBB( basis_ptr[ -i ], basis_ptr[ -i ] ) );
698 silk_assert( energy >= 0 );
699 silk_assert( lag_counter < SCRATCH_SIZE );
700 scratch_mem[ lag_counter ] = energy;
701 lag_counter++;
702 }
703
704 delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );
705 for( i = 0; i < nb_cbk_search; i++ ) {
706 /* Fill out the 3 dim array that stores the correlations for */
707 /* each code_book vector for each start lag */
708 idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;
709 for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
710 silk_assert( idx + j < SCRATCH_SIZE );
711 silk_assert( idx + j < lag_counter );
712 matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] =
713 scratch_mem[ idx + j ];
714 silk_assert(
715 matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] >= 0 );
716 }
717 }
718 target_ptr += sf_length;
719 }
720 RESTORE_STACK;
721}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/process_gains_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/process_gains_FIX.c
new file mode 100644
index 0000000000..05aba31788
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/process_gains_FIX.c
@@ -0,0 +1,117 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33#include "tuning_parameters.h"
34
35/* Processing of gains */
36void silk_process_gains_FIX(
37 silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
38 silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control */
39 opus_int condCoding /* I The type of conditional coding to use */
40)
41{
42 silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
43 opus_int k;
44 opus_int32 s_Q16, InvMaxSqrVal_Q16, gain, gain_squared, ResNrg, ResNrgPart, quant_offset_Q10;
45
46 /* Gain reduction when LTP coding gain is high */
47 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
48 /*s = -0.5f * silk_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); */
49 s_Q16 = -silk_sigm_Q15( silk_RSHIFT_ROUND( psEncCtrl->LTPredCodGain_Q7 - SILK_FIX_CONST( 12.0, 7 ), 4 ) );
50 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
51 psEncCtrl->Gains_Q16[ k ] = silk_SMLAWB( psEncCtrl->Gains_Q16[ k ], psEncCtrl->Gains_Q16[ k ], s_Q16 );
52 }
53 }
54
55 /* Limit the quantized signal */
56 /* InvMaxSqrVal = pow( 2.0f, 0.33f * ( 21.0f - SNR_dB ) ) / subfr_length; */
57 InvMaxSqrVal_Q16 = silk_DIV32_16( silk_log2lin(
58 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 );
59
60 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
61 /* Soft limit on ratio residual energy and squared gains */
62 ResNrg = psEncCtrl->ResNrg[ k ];
63 ResNrgPart = silk_SMULWW( ResNrg, InvMaxSqrVal_Q16 );
64 if( psEncCtrl->ResNrgQ[ k ] > 0 ) {
65 ResNrgPart = silk_RSHIFT_ROUND( ResNrgPart, psEncCtrl->ResNrgQ[ k ] );
66 } else {
67 if( ResNrgPart >= silk_RSHIFT( silk_int32_MAX, -psEncCtrl->ResNrgQ[ k ] ) ) {
68 ResNrgPart = silk_int32_MAX;
69 } else {
70 ResNrgPart = silk_LSHIFT( ResNrgPart, -psEncCtrl->ResNrgQ[ k ] );
71 }
72 }
73 gain = psEncCtrl->Gains_Q16[ k ];
74 gain_squared = silk_ADD_SAT32( ResNrgPart, silk_SMMUL( gain, gain ) );
75 if( gain_squared < silk_int16_MAX ) {
76 /* recalculate with higher precision */
77 gain_squared = silk_SMLAWW( silk_LSHIFT( ResNrgPart, 16 ), gain, gain );
78 silk_assert( gain_squared > 0 );
79 gain = silk_SQRT_APPROX( gain_squared ); /* Q8 */
80 gain = silk_min( gain, silk_int32_MAX >> 8 );
81 psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( gain, 8 ); /* Q16 */
82 } else {
83 gain = silk_SQRT_APPROX( gain_squared ); /* Q0 */
84 gain = silk_min( gain, silk_int32_MAX >> 16 );
85 psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( gain, 16 ); /* Q16 */
86 }
87 }
88
89 /* Save unquantized gains and gain Index */
90 silk_memcpy( psEncCtrl->GainsUnq_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
91 psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex;
92
93 /* Quantize gains */
94 silk_gains_quant( psEnc->sCmn.indices.GainsIndices, psEncCtrl->Gains_Q16,
95 &psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
96
97 /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */
98 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
99 if( psEncCtrl->LTPredCodGain_Q7 + silk_RSHIFT( psEnc->sCmn.input_tilt_Q15, 8 ) > SILK_FIX_CONST( 1.0, 7 ) ) {
100 psEnc->sCmn.indices.quantOffsetType = 0;
101 } else {
102 psEnc->sCmn.indices.quantOffsetType = 1;
103 }
104 }
105
106 /* Quantizer boundary adjustment */
107 quant_offset_Q10 = silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ];
108 psEncCtrl->Lambda_Q10 = SILK_FIX_CONST( LAMBDA_OFFSET, 10 )
109 + silk_SMULBB( SILK_FIX_CONST( LAMBDA_DELAYED_DECISIONS, 10 ), psEnc->sCmn.nStatesDelayedDecision )
110 + silk_SMULWB( SILK_FIX_CONST( LAMBDA_SPEECH_ACT, 18 ), psEnc->sCmn.speech_activity_Q8 )
111 + silk_SMULWB( SILK_FIX_CONST( LAMBDA_INPUT_QUALITY, 12 ), psEncCtrl->input_quality_Q14 )
112 + silk_SMULWB( SILK_FIX_CONST( LAMBDA_CODING_QUALITY, 12 ), psEncCtrl->coding_quality_Q14 )
113 + silk_SMULWB( SILK_FIX_CONST( LAMBDA_QUANT_OFFSET, 16 ), quant_offset_Q10 );
114
115 silk_assert( psEncCtrl->Lambda_Q10 > 0 );
116 silk_assert( psEncCtrl->Lambda_Q10 < SILK_FIX_CONST( 2, 10 ) );
117}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/regularize_correlations_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/regularize_correlations_FIX.c
new file mode 100644
index 0000000000..a2836b05f4
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/regularize_correlations_FIX.c
@@ -0,0 +1,47 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33
34/* Add noise to matrix diagonal */
35void silk_regularize_correlations_FIX(
36 opus_int32 *XX, /* I/O Correlation matrices */
37 opus_int32 *xx, /* I/O Correlation values */
38 opus_int32 noise, /* I Noise to add */
39 opus_int D /* I Dimension of XX */
40)
41{
42 opus_int i;
43 for( i = 0; i < D; i++ ) {
44 matrix_ptr( &XX[ 0 ], i, i, D ) = silk_ADD32( matrix_ptr( &XX[ 0 ], i, i, D ), noise );
45 }
46 xx[ 0 ] += noise;
47}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/residual_energy16_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/residual_energy16_FIX.c
new file mode 100644
index 0000000000..7f130f3d3d
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/residual_energy16_FIX.c
@@ -0,0 +1,103 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33
34/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */
35opus_int32 silk_residual_energy16_covar_FIX(
36 const opus_int16 *c, /* I Prediction vector */
37 const opus_int32 *wXX, /* I Correlation matrix */
38 const opus_int32 *wXx, /* I Correlation vector */
39 opus_int32 wxx, /* I Signal energy */
40 opus_int D, /* I Dimension */
41 opus_int cQ /* I Q value for c vector 0 - 15 */
42)
43{
44 opus_int i, j, lshifts, Qxtra;
45 opus_int32 c_max, w_max, tmp, tmp2, nrg;
46 opus_int cn[ MAX_MATRIX_SIZE ];
47 const opus_int32 *pRow;
48
49 /* Safety checks */
50 celt_assert( D >= 0 );
51 celt_assert( D <= 16 );
52 celt_assert( cQ > 0 );
53 celt_assert( cQ < 16 );
54
55 lshifts = 16 - cQ;
56 Qxtra = lshifts;
57
58 c_max = 0;
59 for( i = 0; i < D; i++ ) {
60 c_max = silk_max_32( c_max, silk_abs( (opus_int32)c[ i ] ) );
61 }
62 Qxtra = silk_min_int( Qxtra, silk_CLZ32( c_max ) - 17 );
63
64 w_max = silk_max_32( wXX[ 0 ], wXX[ D * D - 1 ] );
65 Qxtra = silk_min_int( Qxtra, silk_CLZ32( silk_MUL( D, silk_RSHIFT( silk_SMULWB( w_max, c_max ), 4 ) ) ) - 5 );
66 Qxtra = silk_max_int( Qxtra, 0 );
67 for( i = 0; i < D; i++ ) {
68 cn[ i ] = silk_LSHIFT( ( opus_int )c[ i ], Qxtra );
69 silk_assert( silk_abs(cn[i]) <= ( silk_int16_MAX + 1 ) ); /* Check that silk_SMLAWB can be used */
70 }
71 lshifts -= Qxtra;
72
73 /* Compute wxx - 2 * wXx * c */
74 tmp = 0;
75 for( i = 0; i < D; i++ ) {
76 tmp = silk_SMLAWB( tmp, wXx[ i ], cn[ i ] );
77 }
78 nrg = silk_RSHIFT( wxx, 1 + lshifts ) - tmp; /* Q: -lshifts - 1 */
79
80 /* Add c' * wXX * c, assuming wXX is symmetric */
81 tmp2 = 0;
82 for( i = 0; i < D; i++ ) {
83 tmp = 0;
84 pRow = &wXX[ i * D ];
85 for( j = i + 1; j < D; j++ ) {
86 tmp = silk_SMLAWB( tmp, pRow[ j ], cn[ j ] );
87 }
88 tmp = silk_SMLAWB( tmp, silk_RSHIFT( pRow[ i ], 1 ), cn[ i ] );
89 tmp2 = silk_SMLAWB( tmp2, tmp, cn[ i ] );
90 }
91 nrg = silk_ADD_LSHIFT32( nrg, tmp2, lshifts ); /* Q: -lshifts - 1 */
92
93 /* Keep one bit free always, because we add them for LSF interpolation */
94 if( nrg < 1 ) {
95 nrg = 1;
96 } else if( nrg > silk_RSHIFT( silk_int32_MAX, lshifts + 2 ) ) {
97 nrg = silk_int32_MAX >> 1;
98 } else {
99 nrg = silk_LSHIFT( nrg, lshifts + 1 ); /* Q0 */
100 }
101 return nrg;
102
103}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/residual_energy_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/residual_energy_FIX.c
new file mode 100644
index 0000000000..6c7cade9a0
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/residual_energy_FIX.c
@@ -0,0 +1,98 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33#include "stack_alloc.h"
34
35/* Calculates residual energies of input subframes where all subframes have LPC_order */
36/* of preceding samples */
37void silk_residual_energy_FIX(
38 opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */
39 opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */
40 const opus_int16 x[], /* I Input signal */
41 opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */
42 const opus_int32 gains[ MAX_NB_SUBFR ], /* I Quantization gains */
43 const opus_int subfr_length, /* I Subframe length */
44 const opus_int nb_subfr, /* I Number of subframes */
45 const opus_int LPC_order, /* I LPC order */
46 int arch /* I Run-time architecture */
47)
48{
49 opus_int offset, i, j, rshift, lz1, lz2;
50 opus_int16 *LPC_res_ptr;
51 VARDECL( opus_int16, LPC_res );
52 const opus_int16 *x_ptr;
53 opus_int32 tmp32;
54 SAVE_STACK;
55
56 x_ptr = x;
57 offset = LPC_order + subfr_length;
58
59 /* Filter input to create the LPC residual for each frame half, and measure subframe energies */
60 ALLOC( LPC_res, ( MAX_NB_SUBFR >> 1 ) * offset, opus_int16 );
61 celt_assert( ( nb_subfr >> 1 ) * ( MAX_NB_SUBFR >> 1 ) == nb_subfr );
62 for( i = 0; i < nb_subfr >> 1; i++ ) {
63 /* Calculate half frame LPC residual signal including preceding samples */
64 silk_LPC_analysis_filter( LPC_res, x_ptr, a_Q12[ i ], ( MAX_NB_SUBFR >> 1 ) * offset, LPC_order, arch );
65
66 /* Point to first subframe of the just calculated LPC residual signal */
67 LPC_res_ptr = LPC_res + LPC_order;
68 for( j = 0; j < ( MAX_NB_SUBFR >> 1 ); j++ ) {
69 /* Measure subframe energy */
70 silk_sum_sqr_shift( &nrgs[ i * ( MAX_NB_SUBFR >> 1 ) + j ], &rshift, LPC_res_ptr, subfr_length );
71
72 /* Set Q values for the measured energy */
73 nrgsQ[ i * ( MAX_NB_SUBFR >> 1 ) + j ] = -rshift;
74
75 /* Move to next subframe */
76 LPC_res_ptr += offset;
77 }
78 /* Move to next frame half */
79 x_ptr += ( MAX_NB_SUBFR >> 1 ) * offset;
80 }
81
82 /* Apply the squared subframe gains */
83 for( i = 0; i < nb_subfr; i++ ) {
84 /* Fully upscale gains and energies */
85 lz1 = silk_CLZ32( nrgs[ i ] ) - 1;
86 lz2 = silk_CLZ32( gains[ i ] ) - 1;
87
88 tmp32 = silk_LSHIFT32( gains[ i ], lz2 );
89
90 /* Find squared gains */
91 tmp32 = silk_SMMUL( tmp32, tmp32 ); /* Q( 2 * lz2 - 32 )*/
92
93 /* Scale energies */
94 nrgs[ i ] = silk_SMMUL( tmp32, silk_LSHIFT32( nrgs[ i ], lz1 ) ); /* Q( nrgsQ[ i ] + lz1 + 2 * lz2 - 32 - 32 )*/
95 nrgsQ[ i ] += lz1 + 2 * lz2 - 32 - 32;
96 }
97 RESTORE_STACK;
98}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/schur64_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/schur64_FIX.c
new file mode 100644
index 0000000000..4b7e19ea59
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/schur64_FIX.c
@@ -0,0 +1,93 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33
34/* Slower than schur(), but more accurate. */
35/* Uses SMULL(), available on armv4 */
36opus_int32 silk_schur64( /* O returns residual energy */
37 opus_int32 rc_Q16[], /* O Reflection coefficients [order] Q16 */
38 const opus_int32 c[], /* I Correlations [order+1] */
39 opus_int32 order /* I Prediction order */
40)
41{
42 opus_int k, n;
43 opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
44 opus_int32 Ctmp1_Q30, Ctmp2_Q30, rc_tmp_Q31;
45
46 celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
47
48 /* Check for invalid input */
49 if( c[ 0 ] <= 0 ) {
50 silk_memset( rc_Q16, 0, order * sizeof( opus_int32 ) );
51 return 0;
52 }
53
54 k = 0;
55 do {
56 C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
57 } while( ++k <= order );
58
59 for( k = 0; k < order; k++ ) {
60 /* Check that we won't be getting an unstable rc, otherwise stop here. */
61 if (silk_abs_int32(C[ k + 1 ][ 0 ]) >= C[ 0 ][ 1 ]) {
62 if ( C[ k + 1 ][ 0 ] > 0 ) {
63 rc_Q16[ k ] = -SILK_FIX_CONST( .99f, 16 );
64 } else {
65 rc_Q16[ k ] = SILK_FIX_CONST( .99f, 16 );
66 }
67 k++;
68 break;
69 }
70
71 /* Get reflection coefficient: divide two Q30 values and get result in Q31 */
72 rc_tmp_Q31 = silk_DIV32_varQ( -C[ k + 1 ][ 0 ], C[ 0 ][ 1 ], 31 );
73
74 /* Save the output */
75 rc_Q16[ k ] = silk_RSHIFT_ROUND( rc_tmp_Q31, 15 );
76
77 /* Update correlations */
78 for( n = 0; n < order - k; n++ ) {
79 Ctmp1_Q30 = C[ n + k + 1 ][ 0 ];
80 Ctmp2_Q30 = C[ n ][ 1 ];
81
82 /* Multiply and add the highest int32 */
83 C[ n + k + 1 ][ 0 ] = Ctmp1_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp2_Q30, 1 ), rc_tmp_Q31 );
84 C[ n ][ 1 ] = Ctmp2_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp1_Q30, 1 ), rc_tmp_Q31 );
85 }
86 }
87
88 for(; k < order; k++ ) {
89 rc_Q16[ k ] = 0;
90 }
91
92 return silk_max_32( 1, C[ 0 ][ 1 ] );
93}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/schur_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/schur_FIX.c
new file mode 100644
index 0000000000..2840f6b1aa
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/schur_FIX.c
@@ -0,0 +1,107 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33
34/* Faster than schur64(), but much less accurate. */
35/* uses SMLAWB(), requiring armv5E and higher. */
36opus_int32 silk_schur( /* O Returns residual energy */
37 opus_int16 *rc_Q15, /* O reflection coefficients [order] Q15 */
38 const opus_int32 *c, /* I correlations [order+1] */
39 const opus_int32 order /* I prediction order */
40)
41{
42 opus_int k, n, lz;
43 opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
44 opus_int32 Ctmp1, Ctmp2, rc_tmp_Q15;
45
46 celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
47
48 /* Get number of leading zeros */
49 lz = silk_CLZ32( c[ 0 ] );
50
51 /* Copy correlations and adjust level to Q30 */
52 k = 0;
53 if( lz < 2 ) {
54 /* lz must be 1, so shift one to the right */
55 do {
56 C[ k ][ 0 ] = C[ k ][ 1 ] = silk_RSHIFT( c[ k ], 1 );
57 } while( ++k <= order );
58 } else if( lz > 2 ) {
59 /* Shift to the left */
60 lz -= 2;
61 do {
62 C[ k ][ 0 ] = C[ k ][ 1 ] = silk_LSHIFT( c[ k ], lz );
63 } while( ++k <= order );
64 } else {
65 /* No need to shift */
66 do {
67 C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
68 } while( ++k <= order );
69 }
70
71 for( k = 0; k < order; k++ ) {
72 /* Check that we won't be getting an unstable rc, otherwise stop here. */
73 if (silk_abs_int32(C[ k + 1 ][ 0 ]) >= C[ 0 ][ 1 ]) {
74 if ( C[ k + 1 ][ 0 ] > 0 ) {
75 rc_Q15[ k ] = -SILK_FIX_CONST( .99f, 15 );
76 } else {
77 rc_Q15[ k ] = SILK_FIX_CONST( .99f, 15 );
78 }
79 k++;
80 break;
81 }
82
83 /* Get reflection coefficient */
84 rc_tmp_Q15 = -silk_DIV32_16( C[ k + 1 ][ 0 ], silk_max_32( silk_RSHIFT( C[ 0 ][ 1 ], 15 ), 1 ) );
85
86 /* Clip (shouldn't happen for properly conditioned inputs) */
87 rc_tmp_Q15 = silk_SAT16( rc_tmp_Q15 );
88
89 /* Store */
90 rc_Q15[ k ] = (opus_int16)rc_tmp_Q15;
91
92 /* Update correlations */
93 for( n = 0; n < order - k; n++ ) {
94 Ctmp1 = C[ n + k + 1 ][ 0 ];
95 Ctmp2 = C[ n ][ 1 ];
96 C[ n + k + 1 ][ 0 ] = silk_SMLAWB( Ctmp1, silk_LSHIFT( Ctmp2, 1 ), rc_tmp_Q15 );
97 C[ n ][ 1 ] = silk_SMLAWB( Ctmp2, silk_LSHIFT( Ctmp1, 1 ), rc_tmp_Q15 );
98 }
99 }
100
101 for(; k < order; k++ ) {
102 rc_Q15[ k ] = 0;
103 }
104
105 /* return residual energy */
106 return silk_max_32( 1, C[ 0 ][ 1 ] );
107}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/structs_FIX.h b/lib/rbcodec/codecs/libopus/silk/fixed/structs_FIX.h
new file mode 100644
index 0000000000..2774a97b24
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/structs_FIX.h
@@ -0,0 +1,116 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef SILK_STRUCTS_FIX_H
29#define SILK_STRUCTS_FIX_H
30
31#include "typedef.h"
32#include "main.h"
33#include "structs.h"
34
35#ifdef __cplusplus
36extern "C"
37{
38#endif
39
40/********************************/
41/* Noise shaping analysis state */
42/********************************/
43typedef struct {
44 opus_int8 LastGainIndex;
45 opus_int32 HarmBoost_smth_Q16;
46 opus_int32 HarmShapeGain_smth_Q16;
47 opus_int32 Tilt_smth_Q16;
48} silk_shape_state_FIX;
49
50/********************************/
51/* Encoder state FIX */
52/********************************/
53typedef struct {
54 silk_encoder_state sCmn; /* Common struct, shared with floating-point code */
55 silk_shape_state_FIX sShape; /* Shape state */
56
57 /* Buffer for find pitch and noise shape analysis */
58 silk_DWORD_ALIGN opus_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */
59 opus_int LTPCorr_Q15; /* Normalized correlation from pitch lag estimator */
60 opus_int32 resNrgSmth;
61} silk_encoder_state_FIX;
62
63/************************/
64/* Encoder control FIX */
65/************************/
66typedef struct {
67 /* Prediction and coding parameters */
68 opus_int32 Gains_Q16[ MAX_NB_SUBFR ];
69 silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];
70 opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ];
71 opus_int LTP_scale_Q14;
72 opus_int pitchL[ MAX_NB_SUBFR ];
73
74 /* Noise shaping parameters */
75 /* Testing */
76 silk_DWORD_ALIGN opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
77 opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */
78 opus_int Tilt_Q14[ MAX_NB_SUBFR ];
79 opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ];
80 opus_int Lambda_Q10;
81 opus_int input_quality_Q14;
82 opus_int coding_quality_Q14;
83
84 /* measures */
85 opus_int32 predGain_Q16;
86 opus_int LTPredCodGain_Q7;
87 opus_int32 ResNrg[ MAX_NB_SUBFR ]; /* Residual energy per subframe */
88 opus_int ResNrgQ[ MAX_NB_SUBFR ]; /* Q domain for the residual energy > 0 */
89
90 /* Parameters for CBR mode */
91 opus_int32 GainsUnq_Q16[ MAX_NB_SUBFR ];
92 opus_int8 lastGainIndexPrev;
93} silk_encoder_control_FIX;
94
95/************************/
96/* Encoder Super Struct */
97/************************/
98typedef struct {
99 silk_encoder_state_FIX state_Fxx[ ENCODER_NUM_CHANNELS ];
100 stereo_enc_state sStereo;
101 opus_int32 nBitsUsedLBRR;
102 opus_int32 nBitsExceeded;
103 opus_int nChannelsAPI;
104 opus_int nChannelsInternal;
105 opus_int nPrevChannelsInternal;
106 opus_int timeSinceSwitchAllowed_ms;
107 opus_int allowBandwidthSwitch;
108 opus_int prev_decode_only_middle;
109} silk_encoder;
110
111
112#ifdef __cplusplus
113}
114#endif
115
116#endif
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/vector_ops_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/vector_ops_FIX.c
new file mode 100644
index 0000000000..d94980014f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/vector_ops_FIX.c
@@ -0,0 +1,102 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33#include "pitch.h"
34
35/* Copy and multiply a vector by a constant */
36void silk_scale_copy_vector16(
37 opus_int16 *data_out,
38 const opus_int16 *data_in,
39 opus_int32 gain_Q16, /* I Gain in Q16 */
40 const opus_int dataSize /* I Length */
41)
42{
43 opus_int i;
44 opus_int32 tmp32;
45
46 for( i = 0; i < dataSize; i++ ) {
47 tmp32 = silk_SMULWB( gain_Q16, data_in[ i ] );
48 data_out[ i ] = (opus_int16)silk_CHECK_FIT16( tmp32 );
49 }
50}
51
52/* Multiply a vector by a constant */
53void silk_scale_vector32_Q26_lshift_18(
54 opus_int32 *data1, /* I/O Q0/Q18 */
55 opus_int32 gain_Q26, /* I Q26 */
56 opus_int dataSize /* I length */
57)
58{
59 opus_int i;
60
61 for( i = 0; i < dataSize; i++ ) {
62 data1[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( silk_SMULL( data1[ i ], gain_Q26 ), 8 ) ); /* OUTPUT: Q18 */
63 }
64}
65
66/* sum = for(i=0;i<len;i++)inVec1[i]*inVec2[i]; --- inner product */
67/* Note for ARM asm: */
68/* * inVec1 and inVec2 should be at least 2 byte aligned. */
69/* * len should be positive 16bit integer. */
70/* * only when len>6, memory access can be reduced by half. */
71opus_int32 silk_inner_prod_aligned(
72 const opus_int16 *const inVec1, /* I input vector 1 */
73 const opus_int16 *const inVec2, /* I input vector 2 */
74 const opus_int len, /* I vector lengths */
75 int arch /* I Run-time architecture */
76)
77{
78#ifdef FIXED_POINT
79 return celt_inner_prod(inVec1, inVec2, len, arch);
80#else
81 opus_int i;
82 opus_int32 sum = 0;
83 for( i = 0; i < len; i++ ) {
84 sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] );
85 }
86 return sum;
87#endif
88}
89
90opus_int64 silk_inner_prod16_aligned_64_c(
91 const opus_int16 *inVec1, /* I input vector 1 */
92 const opus_int16 *inVec2, /* I input vector 2 */
93 const opus_int len /* I vector lengths */
94)
95{
96 opus_int i;
97 opus_int64 sum = 0;
98 for( i = 0; i < len; i++ ) {
99 sum = silk_SMLALBB( sum, inVec1[ i ], inVec2[ i ] );
100 }
101 return sum;
102}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/warped_autocorrelation_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/warped_autocorrelation_FIX.c
new file mode 100644
index 0000000000..52002a1118
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/warped_autocorrelation_FIX.c
@@ -0,0 +1,90 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FIX.h"
33
34#if defined(MIPSr1_ASM)
35#include "mips/warped_autocorrelation_FIX_mipsr1.h"
36#endif
37
38
39/* Autocorrelations for a warped frequency axis */
40void silk_warped_autocorrelation_FIX_c(
41 opus_int32 *corr, /* O Result [order + 1] */
42 opus_int *scale, /* O Scaling of the correlation vector */
43 const opus_int16 *input, /* I Input data to correlate */
44 const opus_int warping_Q16, /* I Warping coefficient */
45 const opus_int length, /* I Length of input */
46 const opus_int order /* I Correlation order (even) */
47)
48{
49 opus_int n, i, lsh;
50 opus_int32 tmp1_QS, tmp2_QS;
51 opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
52 opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
53
54 /* Order must be even */
55 celt_assert( ( order & 1 ) == 0 );
56 silk_assert( 2 * QS - QC >= 0 );
57
58 /* Loop over samples */
59 for( n = 0; n < length; n++ ) {
60 tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS );
61 /* Loop over allpass sections */
62 for( i = 0; i < order; i += 2 ) {
63 /* Output of allpass section */
64 tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 );
65 state_QS[ i ] = tmp1_QS;
66 corr_QC[ i ] += silk_RSHIFT64( silk_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC );
67 /* Output of allpass section */
68 tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 );
69 state_QS[ i + 1 ] = tmp2_QS;
70 corr_QC[ i + 1 ] += silk_RSHIFT64( silk_SMULL( tmp2_QS, state_QS[ 0 ] ), 2 * QS - QC );
71 }
72 state_QS[ order ] = tmp1_QS;
73 corr_QC[ order ] += silk_RSHIFT64( silk_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC );
74 }
75
76 lsh = silk_CLZ64( corr_QC[ 0 ] ) - 35;
77 lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC );
78 *scale = -( QC + lsh );
79 silk_assert( *scale >= -30 && *scale <= 12 );
80 if( lsh >= 0 ) {
81 for( i = 0; i < order + 1; i++ ) {
82 corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_LSHIFT64( corr_QC[ i ], lsh ) );
83 }
84 } else {
85 for( i = 0; i < order + 1; i++ ) {
86 corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr_QC[ i ], -lsh ) );
87 }
88 }
89 silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/
90}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/x86/burg_modified_FIX_sse4_1.c b/lib/rbcodec/codecs/libopus/silk/fixed/x86/burg_modified_FIX_sse4_1.c
new file mode 100644
index 0000000000..bbb1ce0fcc
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/x86/burg_modified_FIX_sse4_1.c
@@ -0,0 +1,377 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <xmmintrin.h>
33#include <emmintrin.h>
34#include <smmintrin.h>
35
36#include "SigProc_FIX.h"
37#include "define.h"
38#include "tuning_parameters.h"
39#include "pitch.h"
40#include "celt/x86/x86cpu.h"
41
42#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */
43
44#define QA 25
45#define N_BITS_HEAD_ROOM 2
46#define MIN_RSHIFTS -16
47#define MAX_RSHIFTS (32 - QA)
48
49/* Compute reflection coefficients from input signal */
50void silk_burg_modified_sse4_1(
51 opus_int32 *res_nrg, /* O Residual energy */
52 opus_int *res_nrg_Q, /* O Residual energy Q value */
53 opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
54 const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
55 const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
56 const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */
57 const opus_int nb_subfr, /* I Number of subframes stacked in x */
58 const opus_int D, /* I Order */
59 int arch /* I Run-time architecture */
60)
61{
62 opus_int k, n, s, lz, rshifts, rshifts_extra, reached_max_gain;
63 opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2;
64 const opus_int16 *x_ptr;
65 opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ];
66 opus_int32 C_last_row[ SILK_MAX_ORDER_LPC ];
67 opus_int32 Af_QA[ SILK_MAX_ORDER_LPC ];
68 opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ];
69 opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ];
70 opus_int32 xcorr[ SILK_MAX_ORDER_LPC ];
71
72 __m128i FIRST_3210, LAST_3210, ATMP_3210, TMP1_3210, TMP2_3210, T1_3210, T2_3210, PTR_3210, SUBFR_3210, X1_3210, X2_3210;
73 __m128i CONST1 = _mm_set1_epi32(1);
74
75 celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
76
77 /* Compute autocorrelations, added over subframes */
78 silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length );
79 if( rshifts > MAX_RSHIFTS ) {
80 C0 = silk_LSHIFT32( C0, rshifts - MAX_RSHIFTS );
81 silk_assert( C0 > 0 );
82 rshifts = MAX_RSHIFTS;
83 } else {
84 lz = silk_CLZ32( C0 ) - 1;
85 rshifts_extra = N_BITS_HEAD_ROOM - lz;
86 if( rshifts_extra > 0 ) {
87 rshifts_extra = silk_min( rshifts_extra, MAX_RSHIFTS - rshifts );
88 C0 = silk_RSHIFT32( C0, rshifts_extra );
89 } else {
90 rshifts_extra = silk_max( rshifts_extra, MIN_RSHIFTS - rshifts );
91 C0 = silk_LSHIFT32( C0, -rshifts_extra );
92 }
93 rshifts += rshifts_extra;
94 }
95 CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
96 silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
97 if( rshifts > 0 ) {
98 for( s = 0; s < nb_subfr; s++ ) {
99 x_ptr = x + s * subfr_length;
100 for( n = 1; n < D + 1; n++ ) {
101 C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64(
102 silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n, arch ), rshifts );
103 }
104 }
105 } else {
106 for( s = 0; s < nb_subfr; s++ ) {
107 int i;
108 opus_int32 d;
109 x_ptr = x + s * subfr_length;
110 celt_pitch_xcorr(x_ptr, x_ptr + 1, xcorr, subfr_length - D, D, arch );
111 for( n = 1; n < D + 1; n++ ) {
112 for ( i = n + subfr_length - D, d = 0; i < subfr_length; i++ )
113 d = MAC16_16( d, x_ptr[ i ], x_ptr[ i - n ] );
114 xcorr[ n - 1 ] += d;
115 }
116 for( n = 1; n < D + 1; n++ ) {
117 C_first_row[ n - 1 ] += silk_LSHIFT32( xcorr[ n - 1 ], -rshifts );
118 }
119 }
120 }
121 silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) );
122
123 /* Initialize */
124 CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */
125
126 invGain_Q30 = (opus_int32)1 << 30;
127 reached_max_gain = 0;
128 for( n = 0; n < D; n++ ) {
129 /* Update first row of correlation matrix (without first element) */
130 /* Update last row of correlation matrix (without last element, stored in reversed order) */
131 /* Update C * Af */
132 /* Update C * flipud(Af) (stored in reversed order) */
133 if( rshifts > -2 ) {
134 for( s = 0; s < nb_subfr; s++ ) {
135 x_ptr = x + s * subfr_length;
136 x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], 16 - rshifts ); /* Q(16-rshifts) */
137 x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); /* Q(16-rshifts) */
138 tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], QA - 16 ); /* Q(QA-16) */
139 tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); /* Q(QA-16) */
140 for( k = 0; k < n; k++ ) {
141 C_first_row[ k ] = silk_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */
142 C_last_row[ k ] = silk_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */
143 Atmp_QA = Af_QA[ k ];
144 tmp1 = silk_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); /* Q(QA-16) */
145 tmp2 = silk_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); /* Q(QA-16) */
146 }
147 tmp1 = silk_LSHIFT32( -tmp1, 32 - QA - rshifts ); /* Q(16-rshifts) */
148 tmp2 = silk_LSHIFT32( -tmp2, 32 - QA - rshifts ); /* Q(16-rshifts) */
149 for( k = 0; k <= n; k++ ) {
150 CAf[ k ] = silk_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); /* Q( -rshift ) */
151 CAb[ k ] = silk_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); /* Q( -rshift ) */
152 }
153 }
154 } else {
155 for( s = 0; s < nb_subfr; s++ ) {
156 x_ptr = x + s * subfr_length;
157 x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], -rshifts ); /* Q( -rshifts ) */
158 x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); /* Q( -rshifts ) */
159 tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], 17 ); /* Q17 */
160 tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 17 ); /* Q17 */
161
162 X1_3210 = _mm_set1_epi32( x1 );
163 X2_3210 = _mm_set1_epi32( x2 );
164 TMP1_3210 = _mm_setzero_si128();
165 TMP2_3210 = _mm_setzero_si128();
166 for( k = 0; k < n - 3; k += 4 ) {
167 PTR_3210 = OP_CVTEPI16_EPI32_M64( &x_ptr[ n - k - 1 - 3 ] );
168 SUBFR_3210 = OP_CVTEPI16_EPI32_M64( &x_ptr[ subfr_length - n + k ] );
169 FIRST_3210 = _mm_loadu_si128( (__m128i *)&C_first_row[ k ] );
170 PTR_3210 = _mm_shuffle_epi32( PTR_3210, _MM_SHUFFLE( 0, 1, 2, 3 ) );
171 LAST_3210 = _mm_loadu_si128( (__m128i *)&C_last_row[ k ] );
172 ATMP_3210 = _mm_loadu_si128( (__m128i *)&Af_QA[ k ] );
173
174 T1_3210 = _mm_mullo_epi32( PTR_3210, X1_3210 );
175 T2_3210 = _mm_mullo_epi32( SUBFR_3210, X2_3210 );
176
177 ATMP_3210 = _mm_srai_epi32( ATMP_3210, 7 );
178 ATMP_3210 = _mm_add_epi32( ATMP_3210, CONST1 );
179 ATMP_3210 = _mm_srai_epi32( ATMP_3210, 1 );
180
181 FIRST_3210 = _mm_add_epi32( FIRST_3210, T1_3210 );
182 LAST_3210 = _mm_add_epi32( LAST_3210, T2_3210 );
183
184 PTR_3210 = _mm_mullo_epi32( ATMP_3210, PTR_3210 );
185 SUBFR_3210 = _mm_mullo_epi32( ATMP_3210, SUBFR_3210 );
186
187 _mm_storeu_si128( (__m128i *)&C_first_row[ k ], FIRST_3210 );
188 _mm_storeu_si128( (__m128i *)&C_last_row[ k ], LAST_3210 );
189
190 TMP1_3210 = _mm_add_epi32( TMP1_3210, PTR_3210 );
191 TMP2_3210 = _mm_add_epi32( TMP2_3210, SUBFR_3210 );
192 }
193
194 TMP1_3210 = _mm_add_epi32( TMP1_3210, _mm_unpackhi_epi64(TMP1_3210, TMP1_3210 ) );
195 TMP2_3210 = _mm_add_epi32( TMP2_3210, _mm_unpackhi_epi64(TMP2_3210, TMP2_3210 ) );
196 TMP1_3210 = _mm_add_epi32( TMP1_3210, _mm_shufflelo_epi16(TMP1_3210, 0x0E ) );
197 TMP2_3210 = _mm_add_epi32( TMP2_3210, _mm_shufflelo_epi16(TMP2_3210, 0x0E ) );
198
199 tmp1 += _mm_cvtsi128_si32( TMP1_3210 );
200 tmp2 += _mm_cvtsi128_si32( TMP2_3210 );
201
202 for( ; k < n; k++ ) {
203 C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */
204 C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */
205 Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */
206 tmp1 = silk_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */
207 tmp2 = silk_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */
208 }
209
210 tmp1 = -tmp1; /* Q17 */
211 tmp2 = -tmp2; /* Q17 */
212
213 {
214 __m128i xmm_tmp1, xmm_tmp2;
215 __m128i xmm_x_ptr_n_k_x2x0, xmm_x_ptr_n_k_x3x1;
216 __m128i xmm_x_ptr_sub_x2x0, xmm_x_ptr_sub_x3x1;
217
218 xmm_tmp1 = _mm_set1_epi32( tmp1 );
219 xmm_tmp2 = _mm_set1_epi32( tmp2 );
220
221 for( k = 0; k <= n - 3; k += 4 ) {
222 xmm_x_ptr_n_k_x2x0 = OP_CVTEPI16_EPI32_M64( &x_ptr[ n - k - 3 ] );
223 xmm_x_ptr_sub_x2x0 = OP_CVTEPI16_EPI32_M64( &x_ptr[ subfr_length - n + k - 1 ] );
224
225 xmm_x_ptr_n_k_x2x0 = _mm_shuffle_epi32( xmm_x_ptr_n_k_x2x0, _MM_SHUFFLE( 0, 1, 2, 3 ) );
226
227 xmm_x_ptr_n_k_x2x0 = _mm_slli_epi32( xmm_x_ptr_n_k_x2x0, -rshifts - 1 );
228 xmm_x_ptr_sub_x2x0 = _mm_slli_epi32( xmm_x_ptr_sub_x2x0, -rshifts - 1 );
229
230 /* equal shift right 4 bytes, xmm_x_ptr_n_k_x3x1 = _mm_srli_si128(xmm_x_ptr_n_k_x2x0, 4)*/
231 xmm_x_ptr_n_k_x3x1 = _mm_shuffle_epi32( xmm_x_ptr_n_k_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );
232 xmm_x_ptr_sub_x3x1 = _mm_shuffle_epi32( xmm_x_ptr_sub_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );
233
234 xmm_x_ptr_n_k_x2x0 = _mm_mul_epi32( xmm_x_ptr_n_k_x2x0, xmm_tmp1 );
235 xmm_x_ptr_n_k_x3x1 = _mm_mul_epi32( xmm_x_ptr_n_k_x3x1, xmm_tmp1 );
236 xmm_x_ptr_sub_x2x0 = _mm_mul_epi32( xmm_x_ptr_sub_x2x0, xmm_tmp2 );
237 xmm_x_ptr_sub_x3x1 = _mm_mul_epi32( xmm_x_ptr_sub_x3x1, xmm_tmp2 );
238
239 xmm_x_ptr_n_k_x2x0 = _mm_srli_epi64( xmm_x_ptr_n_k_x2x0, 16 );
240 xmm_x_ptr_n_k_x3x1 = _mm_slli_epi64( xmm_x_ptr_n_k_x3x1, 16 );
241 xmm_x_ptr_sub_x2x0 = _mm_srli_epi64( xmm_x_ptr_sub_x2x0, 16 );
242 xmm_x_ptr_sub_x3x1 = _mm_slli_epi64( xmm_x_ptr_sub_x3x1, 16 );
243
244 xmm_x_ptr_n_k_x2x0 = _mm_blend_epi16( xmm_x_ptr_n_k_x2x0, xmm_x_ptr_n_k_x3x1, 0xCC );
245 xmm_x_ptr_sub_x2x0 = _mm_blend_epi16( xmm_x_ptr_sub_x2x0, xmm_x_ptr_sub_x3x1, 0xCC );
246
247 X1_3210 = _mm_loadu_si128( (__m128i *)&CAf[ k ] );
248 PTR_3210 = _mm_loadu_si128( (__m128i *)&CAb[ k ] );
249
250 X1_3210 = _mm_add_epi32( X1_3210, xmm_x_ptr_n_k_x2x0 );
251 PTR_3210 = _mm_add_epi32( PTR_3210, xmm_x_ptr_sub_x2x0 );
252
253 _mm_storeu_si128( (__m128i *)&CAf[ k ], X1_3210 );
254 _mm_storeu_si128( (__m128i *)&CAb[ k ], PTR_3210 );
255 }
256
257 for( ; k <= n; k++ ) {
258 CAf[ k ] = silk_SMLAWW( CAf[ k ], tmp1,
259 silk_LSHIFT32( (opus_int32)x_ptr[ n - k ], -rshifts - 1 ) ); /* Q( -rshift ) */
260 CAb[ k ] = silk_SMLAWW( CAb[ k ], tmp2,
261 silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) ); /* Q( -rshift ) */
262 }
263 }
264 }
265 }
266
267 /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */
268 tmp1 = C_first_row[ n ]; /* Q( -rshifts ) */
269 tmp2 = C_last_row[ n ]; /* Q( -rshifts ) */
270 num = 0; /* Q( -rshifts ) */
271 nrg = silk_ADD32( CAb[ 0 ], CAf[ 0 ] ); /* Q( 1-rshifts ) */
272 for( k = 0; k < n; k++ ) {
273 Atmp_QA = Af_QA[ k ];
274 lz = silk_CLZ32( silk_abs( Atmp_QA ) ) - 1;
275 lz = silk_min( 32 - QA, lz );
276 Atmp1 = silk_LSHIFT32( Atmp_QA, lz ); /* Q( QA + lz ) */
277
278 tmp1 = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
279 tmp2 = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
280 num = silk_ADD_LSHIFT32( num, silk_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */
281 nrg = silk_ADD_LSHIFT32( nrg, silk_SMMUL( silk_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ),
282 Atmp1 ), 32 - QA - lz ); /* Q( 1-rshifts ) */
283 }
284 CAf[ n + 1 ] = tmp1; /* Q( -rshifts ) */
285 CAb[ n + 1 ] = tmp2; /* Q( -rshifts ) */
286 num = silk_ADD32( num, tmp2 ); /* Q( -rshifts ) */
287 num = silk_LSHIFT32( -num, 1 ); /* Q( 1-rshifts ) */
288
289 /* Calculate the next order reflection (parcor) coefficient */
290 if( silk_abs( num ) < nrg ) {
291 rc_Q31 = silk_DIV32_varQ( num, nrg, 31 );
292 } else {
293 rc_Q31 = ( num > 0 ) ? silk_int32_MAX : silk_int32_MIN;
294 }
295
296 /* Update inverse prediction gain */
297 tmp1 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );
298 tmp1 = silk_LSHIFT( silk_SMMUL( invGain_Q30, tmp1 ), 2 );
299 if( tmp1 <= minInvGain_Q30 ) {
300 /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */
301 tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */
302 rc_Q31 = silk_SQRT_APPROX( tmp2 ); /* Q15 */
303 if( rc_Q31 > 0 ) {
304 /* Newton-Raphson iteration */
305 rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */
306 rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */
307 if( num < 0 ) {
308 /* Ensure adjusted reflection coefficients has the original sign */
309 rc_Q31 = -rc_Q31;
310 }
311 }
312 invGain_Q30 = minInvGain_Q30;
313 reached_max_gain = 1;
314 } else {
315 invGain_Q30 = tmp1;
316 }
317
318 /* Update the AR coefficients */
319 for( k = 0; k < (n + 1) >> 1; k++ ) {
320 tmp1 = Af_QA[ k ]; /* QA */
321 tmp2 = Af_QA[ n - k - 1 ]; /* QA */
322 Af_QA[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* QA */
323 Af_QA[ n - k - 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* QA */
324 }
325 Af_QA[ n ] = silk_RSHIFT32( rc_Q31, 31 - QA ); /* QA */
326
327 if( reached_max_gain ) {
328 /* Reached max prediction gain; set remaining coefficients to zero and exit loop */
329 for( k = n + 1; k < D; k++ ) {
330 Af_QA[ k ] = 0;
331 }
332 break;
333 }
334
335 /* Update C * Af and C * Ab */
336 for( k = 0; k <= n + 1; k++ ) {
337 tmp1 = CAf[ k ]; /* Q( -rshifts ) */
338 tmp2 = CAb[ n - k + 1 ]; /* Q( -rshifts ) */
339 CAf[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* Q( -rshifts ) */
340 CAb[ n - k + 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* Q( -rshifts ) */
341 }
342 }
343
344 if( reached_max_gain ) {
345 for( k = 0; k < D; k++ ) {
346 /* Scale coefficients */
347 A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 );
348 }
349 /* Subtract energy of preceding samples from C0 */
350 if( rshifts > 0 ) {
351 for( s = 0; s < nb_subfr; s++ ) {
352 x_ptr = x + s * subfr_length;
353 C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D, arch ), rshifts );
354 }
355 } else {
356 for( s = 0; s < nb_subfr; s++ ) {
357 x_ptr = x + s * subfr_length;
358 C0 -= silk_LSHIFT32( silk_inner_prod_aligned( x_ptr, x_ptr, D, arch ), -rshifts );
359 }
360 }
361 /* Approximate residual energy */
362 *res_nrg = silk_LSHIFT( silk_SMMUL( invGain_Q30, C0 ), 2 );
363 *res_nrg_Q = -rshifts;
364 } else {
365 /* Return residual energy */
366 nrg = CAf[ 0 ]; /* Q( -rshifts ) */
367 tmp1 = (opus_int32)1 << 16; /* Q16 */
368 for( k = 0; k < D; k++ ) {
369 Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); /* Q16 */
370 nrg = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); /* Q( -rshifts ) */
371 tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 ); /* Q16 */
372 A_Q16[ k ] = -Atmp1;
373 }
374 *res_nrg = silk_SMLAWW( nrg, silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */
375 *res_nrg_Q = -rshifts;
376 }
377}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/x86/prefilter_FIX_sse.c b/lib/rbcodec/codecs/libopus/silk/fixed/x86/prefilter_FIX_sse.c
new file mode 100644
index 0000000000..555432cd96
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/x86/prefilter_FIX_sse.c
@@ -0,0 +1,160 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <xmmintrin.h>
33#include <emmintrin.h>
34#include <smmintrin.h>
35#include "main.h"
36#include "celt/x86/x86cpu.h"
37
38void silk_warped_LPC_analysis_filter_FIX_sse4_1(
39 opus_int32 state[], /* I/O State [order + 1] */
40 opus_int32 res_Q2[], /* O Residual signal [length] */
41 const opus_int16 coef_Q13[], /* I Coefficients [order] */
42 const opus_int16 input[], /* I Input signal [length] */
43 const opus_int16 lambda_Q16, /* I Warping factor */
44 const opus_int length, /* I Length of input signal */
45 const opus_int order /* I Filter order (even) */
46)
47{
48 opus_int n, i;
49 opus_int32 acc_Q11, tmp1, tmp2;
50
51 /* Order must be even */
52 celt_assert( ( order & 1 ) == 0 );
53
54 if (order == 10)
55 {
56 if (0 == lambda_Q16)
57 {
58 __m128i coef_Q13_3210, coef_Q13_7654;
59 __m128i coef_Q13_0123, coef_Q13_4567;
60 __m128i state_0123, state_4567;
61 __m128i xmm_product1, xmm_product2;
62 __m128i xmm_tempa, xmm_tempb;
63
64 register opus_int32 sum;
65 register opus_int32 state_8, state_9, state_a;
66 register opus_int64 coef_Q13_8, coef_Q13_9;
67
68 celt_assert( length > 0 );
69
70 coef_Q13_3210 = OP_CVTEPI16_EPI32_M64( &coef_Q13[ 0 ] );
71 coef_Q13_7654 = OP_CVTEPI16_EPI32_M64( &coef_Q13[ 4 ] );
72
73 coef_Q13_0123 = _mm_shuffle_epi32( coef_Q13_3210, _MM_SHUFFLE( 0, 1, 2, 3 ) );
74 coef_Q13_4567 = _mm_shuffle_epi32( coef_Q13_7654, _MM_SHUFFLE( 0, 1, 2, 3 ) );
75
76 coef_Q13_8 = (opus_int64) coef_Q13[ 8 ];
77 coef_Q13_9 = (opus_int64) coef_Q13[ 9 ];
78
79 state_0123 = _mm_loadu_si128( (__m128i *)(&state[ 0 ] ) );
80 state_4567 = _mm_loadu_si128( (__m128i *)(&state[ 4 ] ) );
81
82 state_0123 = _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) );
83 state_4567 = _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) );
84
85 state_8 = state[ 8 ];
86 state_9 = state[ 9 ];
87 state_a = 0;
88
89 for( n = 0; n < length; n++ )
90 {
91 xmm_product1 = _mm_mul_epi32( coef_Q13_0123, state_0123 ); /* 64-bit multiply, only 2 pairs */
92 xmm_product2 = _mm_mul_epi32( coef_Q13_4567, state_4567 );
93
94 xmm_tempa = _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) );
95 xmm_tempb = _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) );
96
97 xmm_product1 = _mm_srli_epi64( xmm_product1, 16 ); /* >> 16, zero extending works */
98 xmm_product2 = _mm_srli_epi64( xmm_product2, 16 );
99
100 xmm_tempa = _mm_mul_epi32( coef_Q13_3210, xmm_tempa );
101 xmm_tempb = _mm_mul_epi32( coef_Q13_7654, xmm_tempb );
102
103 xmm_tempa = _mm_srli_epi64( xmm_tempa, 16 );
104 xmm_tempb = _mm_srli_epi64( xmm_tempb, 16 );
105
106 xmm_tempa = _mm_add_epi32( xmm_tempa, xmm_product1 );
107 xmm_tempb = _mm_add_epi32( xmm_tempb, xmm_product2 );
108 xmm_tempa = _mm_add_epi32( xmm_tempa, xmm_tempb );
109
110 sum = (opus_int32)((coef_Q13_8 * state_8) >> 16);
111 sum += (opus_int32)((coef_Q13_9 * state_9) >> 16);
112
113 xmm_tempa = _mm_add_epi32( xmm_tempa, _mm_shuffle_epi32( xmm_tempa, _MM_SHUFFLE( 0, 0, 0, 2 ) ) );
114 sum += _mm_cvtsi128_si32( xmm_tempa);
115 res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( ( 5 + sum ), 9);
116
117 /* move right */
118 state_a = state_9;
119 state_9 = state_8;
120 state_8 = _mm_cvtsi128_si32( state_4567 );
121 state_4567 = _mm_alignr_epi8( state_0123, state_4567, 4 );
122
123 state_0123 = _mm_alignr_epi8( _mm_cvtsi32_si128( silk_LSHIFT( input[ n ], 14 ) ), state_0123, 4 );
124 }
125
126 _mm_storeu_si128( (__m128i *)( &state[ 0 ] ), _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) ) );
127 _mm_storeu_si128( (__m128i *)( &state[ 4 ] ), _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) ) );
128 state[ 8 ] = state_8;
129 state[ 9 ] = state_9;
130 state[ 10 ] = state_a;
131
132 return;
133 }
134 }
135
136 for( n = 0; n < length; n++ ) {
137 /* Output of lowpass section */
138 tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 );
139 state[ 0 ] = silk_LSHIFT( input[ n ], 14 );
140 /* Output of allpass section */
141 tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 );
142 state[ 1 ] = tmp2;
143 acc_Q11 = silk_RSHIFT( order, 1 );
144 acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] );
145 /* Loop over allpass sections */
146 for( i = 2; i < order; i += 2 ) {
147 /* Output of allpass section */
148 tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 );
149 state[ i ] = tmp1;
150 acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] );
151 /* Output of allpass section */
152 tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 );
153 state[ i + 1 ] = tmp2;
154 acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] );
155 }
156 state[ order ] = tmp1;
157 acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );
158 res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 );
159 }
160}
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/x86/vector_ops_FIX_sse4_1.c b/lib/rbcodec/codecs/libopus/silk/fixed/x86/vector_ops_FIX_sse4_1.c
new file mode 100644
index 0000000000..c1e90564d0
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/x86/vector_ops_FIX_sse4_1.c
@@ -0,0 +1,88 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <xmmintrin.h>
33#include <emmintrin.h>
34#include <smmintrin.h>
35#include "main.h"
36
37#include "SigProc_FIX.h"
38#include "pitch.h"
39
40opus_int64 silk_inner_prod16_aligned_64_sse4_1(
41 const opus_int16 *inVec1, /* I input vector 1 */
42 const opus_int16 *inVec2, /* I input vector 2 */
43 const opus_int len /* I vector lengths */
44)
45{
46 opus_int i, dataSize8;
47 opus_int64 sum;
48
49 __m128i xmm_tempa;
50 __m128i inVec1_76543210, acc1;
51 __m128i inVec2_76543210, acc2;
52
53 sum = 0;
54 dataSize8 = len & ~7;
55
56 acc1 = _mm_setzero_si128();
57 acc2 = _mm_setzero_si128();
58
59 for( i = 0; i < dataSize8; i += 8 ) {
60 inVec1_76543210 = _mm_loadu_si128( (__m128i *)(&inVec1[i + 0] ) );
61 inVec2_76543210 = _mm_loadu_si128( (__m128i *)(&inVec2[i + 0] ) );
62
63 /* only when all 4 operands are -32768 (0x8000), this results in wrap around */
64 inVec1_76543210 = _mm_madd_epi16( inVec1_76543210, inVec2_76543210 );
65
66 xmm_tempa = _mm_cvtepi32_epi64( inVec1_76543210 );
67 /* equal shift right 8 bytes */
68 inVec1_76543210 = _mm_shuffle_epi32( inVec1_76543210, _MM_SHUFFLE( 0, 0, 3, 2 ) );
69 inVec1_76543210 = _mm_cvtepi32_epi64( inVec1_76543210 );
70
71 acc1 = _mm_add_epi64( acc1, xmm_tempa );
72 acc2 = _mm_add_epi64( acc2, inVec1_76543210 );
73 }
74
75 acc1 = _mm_add_epi64( acc1, acc2 );
76
77 /* equal shift right 8 bytes */
78 acc2 = _mm_shuffle_epi32( acc1, _MM_SHUFFLE( 0, 0, 3, 2 ) );
79 acc1 = _mm_add_epi64( acc1, acc2 );
80
81 _mm_storel_epi64( (__m128i *)&sum, acc1 );
82
83 for( ; i < len; i++ ) {
84 sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] );
85 }
86
87 return sum;
88}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/LPC_analysis_filter_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/LPC_analysis_filter_FLP.c
new file mode 100644
index 0000000000..0e1a1fed0f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/LPC_analysis_filter_FLP.c
@@ -0,0 +1,249 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <stdlib.h>
33#include "main_FLP.h"
34
35/************************************************/
36/* LPC analysis filter */
37/* NB! State is kept internally and the */
38/* filter always starts with zero state */
39/* first Order output samples are set to zero */
40/************************************************/
41
42/* 16th order LPC analysis filter, does not write first 16 samples */
43static OPUS_INLINE void silk_LPC_analysis_filter16_FLP(
44 silk_float r_LPC[], /* O LPC residual signal */
45 const silk_float PredCoef[], /* I LPC coefficients */
46 const silk_float s[], /* I Input signal */
47 const opus_int length /* I Length of input signal */
48)
49{
50 opus_int ix;
51 silk_float LPC_pred;
52 const silk_float *s_ptr;
53
54 for( ix = 16; ix < length; ix++ ) {
55 s_ptr = &s[ix - 1];
56
57 /* short-term prediction */
58 LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
59 s_ptr[ -1 ] * PredCoef[ 1 ] +
60 s_ptr[ -2 ] * PredCoef[ 2 ] +
61 s_ptr[ -3 ] * PredCoef[ 3 ] +
62 s_ptr[ -4 ] * PredCoef[ 4 ] +
63 s_ptr[ -5 ] * PredCoef[ 5 ] +
64 s_ptr[ -6 ] * PredCoef[ 6 ] +
65 s_ptr[ -7 ] * PredCoef[ 7 ] +
66 s_ptr[ -8 ] * PredCoef[ 8 ] +
67 s_ptr[ -9 ] * PredCoef[ 9 ] +
68 s_ptr[ -10 ] * PredCoef[ 10 ] +
69 s_ptr[ -11 ] * PredCoef[ 11 ] +
70 s_ptr[ -12 ] * PredCoef[ 12 ] +
71 s_ptr[ -13 ] * PredCoef[ 13 ] +
72 s_ptr[ -14 ] * PredCoef[ 14 ] +
73 s_ptr[ -15 ] * PredCoef[ 15 ];
74
75 /* prediction error */
76 r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
77 }
78}
79
80/* 12th order LPC analysis filter, does not write first 12 samples */
81static OPUS_INLINE void silk_LPC_analysis_filter12_FLP(
82 silk_float r_LPC[], /* O LPC residual signal */
83 const silk_float PredCoef[], /* I LPC coefficients */
84 const silk_float s[], /* I Input signal */
85 const opus_int length /* I Length of input signal */
86)
87{
88 opus_int ix;
89 silk_float LPC_pred;
90 const silk_float *s_ptr;
91
92 for( ix = 12; ix < length; ix++ ) {
93 s_ptr = &s[ix - 1];
94
95 /* short-term prediction */
96 LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
97 s_ptr[ -1 ] * PredCoef[ 1 ] +
98 s_ptr[ -2 ] * PredCoef[ 2 ] +
99 s_ptr[ -3 ] * PredCoef[ 3 ] +
100 s_ptr[ -4 ] * PredCoef[ 4 ] +
101 s_ptr[ -5 ] * PredCoef[ 5 ] +
102 s_ptr[ -6 ] * PredCoef[ 6 ] +
103 s_ptr[ -7 ] * PredCoef[ 7 ] +
104 s_ptr[ -8 ] * PredCoef[ 8 ] +
105 s_ptr[ -9 ] * PredCoef[ 9 ] +
106 s_ptr[ -10 ] * PredCoef[ 10 ] +
107 s_ptr[ -11 ] * PredCoef[ 11 ];
108
109 /* prediction error */
110 r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
111 }
112}
113
114/* 10th order LPC analysis filter, does not write first 10 samples */
115static OPUS_INLINE void silk_LPC_analysis_filter10_FLP(
116 silk_float r_LPC[], /* O LPC residual signal */
117 const silk_float PredCoef[], /* I LPC coefficients */
118 const silk_float s[], /* I Input signal */
119 const opus_int length /* I Length of input signal */
120)
121{
122 opus_int ix;
123 silk_float LPC_pred;
124 const silk_float *s_ptr;
125
126 for( ix = 10; ix < length; ix++ ) {
127 s_ptr = &s[ix - 1];
128
129 /* short-term prediction */
130 LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
131 s_ptr[ -1 ] * PredCoef[ 1 ] +
132 s_ptr[ -2 ] * PredCoef[ 2 ] +
133 s_ptr[ -3 ] * PredCoef[ 3 ] +
134 s_ptr[ -4 ] * PredCoef[ 4 ] +
135 s_ptr[ -5 ] * PredCoef[ 5 ] +
136 s_ptr[ -6 ] * PredCoef[ 6 ] +
137 s_ptr[ -7 ] * PredCoef[ 7 ] +
138 s_ptr[ -8 ] * PredCoef[ 8 ] +
139 s_ptr[ -9 ] * PredCoef[ 9 ];
140
141 /* prediction error */
142 r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
143 }
144}
145
146/* 8th order LPC analysis filter, does not write first 8 samples */
147static OPUS_INLINE void silk_LPC_analysis_filter8_FLP(
148 silk_float r_LPC[], /* O LPC residual signal */
149 const silk_float PredCoef[], /* I LPC coefficients */
150 const silk_float s[], /* I Input signal */
151 const opus_int length /* I Length of input signal */
152)
153{
154 opus_int ix;
155 silk_float LPC_pred;
156 const silk_float *s_ptr;
157
158 for( ix = 8; ix < length; ix++ ) {
159 s_ptr = &s[ix - 1];
160
161 /* short-term prediction */
162 LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
163 s_ptr[ -1 ] * PredCoef[ 1 ] +
164 s_ptr[ -2 ] * PredCoef[ 2 ] +
165 s_ptr[ -3 ] * PredCoef[ 3 ] +
166 s_ptr[ -4 ] * PredCoef[ 4 ] +
167 s_ptr[ -5 ] * PredCoef[ 5 ] +
168 s_ptr[ -6 ] * PredCoef[ 6 ] +
169 s_ptr[ -7 ] * PredCoef[ 7 ];
170
171 /* prediction error */
172 r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
173 }
174}
175
176/* 6th order LPC analysis filter, does not write first 6 samples */
177static OPUS_INLINE void silk_LPC_analysis_filter6_FLP(
178 silk_float r_LPC[], /* O LPC residual signal */
179 const silk_float PredCoef[], /* I LPC coefficients */
180 const silk_float s[], /* I Input signal */
181 const opus_int length /* I Length of input signal */
182)
183{
184 opus_int ix;
185 silk_float LPC_pred;
186 const silk_float *s_ptr;
187
188 for( ix = 6; ix < length; ix++ ) {
189 s_ptr = &s[ix - 1];
190
191 /* short-term prediction */
192 LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] +
193 s_ptr[ -1 ] * PredCoef[ 1 ] +
194 s_ptr[ -2 ] * PredCoef[ 2 ] +
195 s_ptr[ -3 ] * PredCoef[ 3 ] +
196 s_ptr[ -4 ] * PredCoef[ 4 ] +
197 s_ptr[ -5 ] * PredCoef[ 5 ];
198
199 /* prediction error */
200 r_LPC[ix] = s_ptr[ 1 ] - LPC_pred;
201 }
202}
203
204/************************************************/
205/* LPC analysis filter */
206/* NB! State is kept internally and the */
207/* filter always starts with zero state */
208/* first Order output samples are set to zero */
209/************************************************/
210void silk_LPC_analysis_filter_FLP(
211 silk_float r_LPC[], /* O LPC residual signal */
212 const silk_float PredCoef[], /* I LPC coefficients */
213 const silk_float s[], /* I Input signal */
214 const opus_int length, /* I Length of input signal */
215 const opus_int Order /* I LPC order */
216)
217{
218 celt_assert( Order <= length );
219
220 switch( Order ) {
221 case 6:
222 silk_LPC_analysis_filter6_FLP( r_LPC, PredCoef, s, length );
223 break;
224
225 case 8:
226 silk_LPC_analysis_filter8_FLP( r_LPC, PredCoef, s, length );
227 break;
228
229 case 10:
230 silk_LPC_analysis_filter10_FLP( r_LPC, PredCoef, s, length );
231 break;
232
233 case 12:
234 silk_LPC_analysis_filter12_FLP( r_LPC, PredCoef, s, length );
235 break;
236
237 case 16:
238 silk_LPC_analysis_filter16_FLP( r_LPC, PredCoef, s, length );
239 break;
240
241 default:
242 celt_assert( 0 );
243 break;
244 }
245
246 /* Set first Order output samples to zero */
247 silk_memset( r_LPC, 0, Order * sizeof( silk_float ) );
248}
249
diff --git a/lib/rbcodec/codecs/libopus/silk/float/LPC_inv_pred_gain_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/LPC_inv_pred_gain_FLP.c
new file mode 100644
index 0000000000..2be2122d61
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/LPC_inv_pred_gain_FLP.c
@@ -0,0 +1,73 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33#include "SigProc_FLP.h"
34#include "define.h"
35
36/* compute inverse of LPC prediction gain, and */
37/* test if LPC coefficients are stable (all poles within unit circle) */
38/* this code is based on silk_a2k_FLP() */
39silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction gain, energy domain */
40 const silk_float *A, /* I prediction coefficients [order] */
41 opus_int32 order /* I prediction order */
42)
43{
44 opus_int k, n;
45 double invGain, rc, rc_mult1, rc_mult2, tmp1, tmp2;
46 silk_float Atmp[ SILK_MAX_ORDER_LPC ];
47
48 silk_memcpy( Atmp, A, order * sizeof(silk_float) );
49
50 invGain = 1.0;
51 for( k = order - 1; k > 0; k-- ) {
52 rc = -Atmp[ k ];
53 rc_mult1 = 1.0f - rc * rc;
54 invGain *= rc_mult1;
55 if( invGain * MAX_PREDICTION_POWER_GAIN < 1.0f ) {
56 return 0.0f;
57 }
58 rc_mult2 = 1.0f / rc_mult1;
59 for( n = 0; n < (k + 1) >> 1; n++ ) {
60 tmp1 = Atmp[ n ];
61 tmp2 = Atmp[ k - n - 1 ];
62 Atmp[ n ] = (silk_float)( ( tmp1 - tmp2 * rc ) * rc_mult2 );
63 Atmp[ k - n - 1 ] = (silk_float)( ( tmp2 - tmp1 * rc ) * rc_mult2 );
64 }
65 }
66 rc = -Atmp[ 0 ];
67 rc_mult1 = 1.0f - rc * rc;
68 invGain *= rc_mult1;
69 if( invGain * MAX_PREDICTION_POWER_GAIN < 1.0f ) {
70 return 0.0f;
71 }
72 return (silk_float)invGain;
73}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/LTP_analysis_filter_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/LTP_analysis_filter_FLP.c
new file mode 100644
index 0000000000..849b7c1c52
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/LTP_analysis_filter_FLP.c
@@ -0,0 +1,75 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FLP.h"
33
34void silk_LTP_analysis_filter_FLP(
35 silk_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */
36 const silk_float *x, /* I Input signal, with preceding samples */
37 const silk_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */
38 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
39 const silk_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */
40 const opus_int subfr_length, /* I Length of each subframe */
41 const opus_int nb_subfr, /* I number of subframes */
42 const opus_int pre_length /* I Preceding samples for each subframe */
43)
44{
45 const silk_float *x_ptr, *x_lag_ptr;
46 silk_float Btmp[ LTP_ORDER ];
47 silk_float *LTP_res_ptr;
48 silk_float inv_gain;
49 opus_int k, i, j;
50
51 x_ptr = x;
52 LTP_res_ptr = LTP_res;
53 for( k = 0; k < nb_subfr; k++ ) {
54 x_lag_ptr = x_ptr - pitchL[ k ];
55 inv_gain = invGains[ k ];
56 for( i = 0; i < LTP_ORDER; i++ ) {
57 Btmp[ i ] = B[ k * LTP_ORDER + i ];
58 }
59
60 /* LTP analysis FIR filter */
61 for( i = 0; i < subfr_length + pre_length; i++ ) {
62 LTP_res_ptr[ i ] = x_ptr[ i ];
63 /* Subtract long-term prediction */
64 for( j = 0; j < LTP_ORDER; j++ ) {
65 LTP_res_ptr[ i ] -= Btmp[ j ] * x_lag_ptr[ LTP_ORDER / 2 - j ];
66 }
67 LTP_res_ptr[ i ] *= inv_gain;
68 x_lag_ptr++;
69 }
70
71 /* Update pointers */
72 LTP_res_ptr += subfr_length + pre_length;
73 x_ptr += subfr_length;
74 }
75}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/LTP_scale_ctrl_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/LTP_scale_ctrl_FLP.c
new file mode 100644
index 0000000000..8dbe29d0fa
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/LTP_scale_ctrl_FLP.c
@@ -0,0 +1,52 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FLP.h"
33
34void silk_LTP_scale_ctrl_FLP(
35 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
36 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
37 opus_int condCoding /* I The type of conditional coding to use */
38)
39{
40 opus_int round_loss;
41
42 if( condCoding == CODE_INDEPENDENTLY ) {
43 /* Only scale if first frame in packet */
44 round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket;
45 psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT( round_loss * psEncCtrl->LTPredCodGain * 0.1f, 0.0f, 2.0f );
46 } else {
47 /* Default is minimum scaling */
48 psEnc->sCmn.indices.LTP_scaleIndex = 0;
49 }
50
51 psEncCtrl->LTP_scale = (silk_float)silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ] / 16384.0f;
52}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/SigProc_FLP.h b/lib/rbcodec/codecs/libopus/silk/float/SigProc_FLP.h
new file mode 100644
index 0000000000..953de8b09e
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/SigProc_FLP.h
@@ -0,0 +1,197 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef SILK_SIGPROC_FLP_H
29#define SILK_SIGPROC_FLP_H
30
31#include "SigProc_FIX.h"
32#include "float_cast.h"
33#include <math.h>
34
35#ifdef __cplusplus
36extern "C"
37{
38#endif
39
40/********************************************************************/
41/* SIGNAL PROCESSING FUNCTIONS */
42/********************************************************************/
43
44/* Chirp (bw expand) LP AR filter */
45void silk_bwexpander_FLP(
46 silk_float *ar, /* I/O AR filter to be expanded (without leading 1) */
47 const opus_int d, /* I length of ar */
48 const silk_float chirp /* I chirp factor (typically in range (0..1) ) */
49);
50
51/* compute inverse of LPC prediction gain, and */
52/* test if LPC coefficients are stable (all poles within unit circle) */
53/* this code is based on silk_FLP_a2k() */
54silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction gain, energy domain */
55 const silk_float *A, /* I prediction coefficients [order] */
56 opus_int32 order /* I prediction order */
57);
58
59silk_float silk_schur_FLP( /* O returns residual energy */
60 silk_float refl_coef[], /* O reflection coefficients (length order) */
61 const silk_float auto_corr[], /* I autocorrelation sequence (length order+1) */
62 opus_int order /* I order */
63);
64
65void silk_k2a_FLP(
66 silk_float *A, /* O prediction coefficients [order] */
67 const silk_float *rc, /* I reflection coefficients [order] */
68 opus_int32 order /* I prediction order */
69);
70
71/* compute autocorrelation */
72void silk_autocorrelation_FLP(
73 silk_float *results, /* O result (length correlationCount) */
74 const silk_float *inputData, /* I input data to correlate */
75 opus_int inputDataSize, /* I length of input */
76 opus_int correlationCount /* I number of correlation taps to compute */
77);
78
79opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, 1 unvoiced */
80 const silk_float *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */
81 opus_int *pitch_out, /* O Pitch lag values [nb_subfr] */
82 opus_int16 *lagIndex, /* O Lag Index */
83 opus_int8 *contourIndex, /* O Pitch contour Index */
84 silk_float *LTPCorr, /* I/O Normalized correlation; input: value from previous frame */
85 opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */
86 const silk_float search_thres1, /* I First stage threshold for lag candidates 0 - 1 */
87 const silk_float search_thres2, /* I Final threshold for lag candidates 0 - 1 */
88 const opus_int Fs_kHz, /* I sample frequency (kHz) */
89 const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */
90 const opus_int nb_subfr, /* I Number of 5 ms subframes */
91 int arch /* I Run-time architecture */
92);
93
94void silk_insertion_sort_decreasing_FLP(
95 silk_float *a, /* I/O Unsorted / Sorted vector */
96 opus_int *idx, /* O Index vector for the sorted elements */
97 const opus_int L, /* I Vector length */
98 const opus_int K /* I Number of correctly sorted positions */
99);
100
101/* Compute reflection coefficients from input signal */
102silk_float silk_burg_modified_FLP( /* O returns residual energy */
103 silk_float A[], /* O prediction coefficients (length order) */
104 const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */
105 const silk_float minInvGain, /* I minimum inverse prediction gain */
106 const opus_int subfr_length, /* I input signal subframe length (incl. D preceding samples) */
107 const opus_int nb_subfr, /* I number of subframes stacked in x */
108 const opus_int D /* I order */
109);
110
111/* multiply a vector by a constant */
112void silk_scale_vector_FLP(
113 silk_float *data1,
114 silk_float gain,
115 opus_int dataSize
116);
117
118/* copy and multiply a vector by a constant */
119void silk_scale_copy_vector_FLP(
120 silk_float *data_out,
121 const silk_float *data_in,
122 silk_float gain,
123 opus_int dataSize
124);
125
126/* inner product of two silk_float arrays, with result as double */
127double silk_inner_product_FLP(
128 const silk_float *data1,
129 const silk_float *data2,
130 opus_int dataSize
131);
132
133/* sum of squares of a silk_float array, with result as double */
134double silk_energy_FLP(
135 const silk_float *data,
136 opus_int dataSize
137);
138
139/********************************************************************/
140/* MACROS */
141/********************************************************************/
142
143#define PI (3.1415926536f)
144
145#define silk_min_float( a, b ) (((a) < (b)) ? (a) : (b))
146#define silk_max_float( a, b ) (((a) > (b)) ? (a) : (b))
147#define silk_abs_float( a ) ((silk_float)fabs(a))
148
149/* sigmoid function */
150static OPUS_INLINE silk_float silk_sigmoid( silk_float x )
151{
152 return (silk_float)(1.0 / (1.0 + exp(-x)));
153}
154
155/* floating-point to integer conversion (rounding) */
156static OPUS_INLINE opus_int32 silk_float2int( silk_float x )
157{
158 return (opus_int32)float2int( x );
159}
160
161/* floating-point to integer conversion (rounding) */
162static OPUS_INLINE void silk_float2short_array(
163 opus_int16 *out,
164 const silk_float *in,
165 opus_int32 length
166)
167{
168 opus_int32 k;
169 for( k = length - 1; k >= 0; k-- ) {
170 out[k] = silk_SAT16( (opus_int32)float2int( in[k] ) );
171 }
172}
173
174/* integer to floating-point conversion */
175static OPUS_INLINE void silk_short2float_array(
176 silk_float *out,
177 const opus_int16 *in,
178 opus_int32 length
179)
180{
181 opus_int32 k;
182 for( k = length - 1; k >= 0; k-- ) {
183 out[k] = (silk_float)in[k];
184 }
185}
186
187/* using log2() helps the fixed-point conversion */
188static OPUS_INLINE silk_float silk_log2( double x )
189{
190 return ( silk_float )( 3.32192809488736 * log10( x ) );
191}
192
193#ifdef __cplusplus
194}
195#endif
196
197#endif /* SILK_SIGPROC_FLP_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/float/apply_sine_window_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/apply_sine_window_FLP.c
new file mode 100644
index 0000000000..e49e717991
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/apply_sine_window_FLP.c
@@ -0,0 +1,81 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FLP.h"
33
34/* Apply sine window to signal vector */
35/* Window types: */
36/* 1 -> sine window from 0 to pi/2 */
37/* 2 -> sine window from pi/2 to pi */
38void silk_apply_sine_window_FLP(
39 silk_float px_win[], /* O Pointer to windowed signal */
40 const silk_float px[], /* I Pointer to input signal */
41 const opus_int win_type, /* I Selects a window type */
42 const opus_int length /* I Window length, multiple of 4 */
43)
44{
45 opus_int k;
46 silk_float freq, c, S0, S1;
47
48 celt_assert( win_type == 1 || win_type == 2 );
49
50 /* Length must be multiple of 4 */
51 celt_assert( ( length & 3 ) == 0 );
52
53 freq = PI / ( length + 1 );
54
55 /* Approximation of 2 * cos(f) */
56 c = 2.0f - freq * freq;
57
58 /* Initialize state */
59 if( win_type < 2 ) {
60 /* Start from 0 */
61 S0 = 0.0f;
62 /* Approximation of sin(f) */
63 S1 = freq;
64 } else {
65 /* Start from 1 */
66 S0 = 1.0f;
67 /* Approximation of cos(f) */
68 S1 = 0.5f * c;
69 }
70
71 /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */
72 /* 4 samples at a time */
73 for( k = 0; k < length; k += 4 ) {
74 px_win[ k + 0 ] = px[ k + 0 ] * 0.5f * ( S0 + S1 );
75 px_win[ k + 1 ] = px[ k + 1 ] * S1;
76 S0 = c * S1 - S0;
77 px_win[ k + 2 ] = px[ k + 2 ] * 0.5f * ( S1 + S0 );
78 px_win[ k + 3 ] = px[ k + 3 ] * S0;
79 S1 = c * S0 - S1;
80 }
81}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/autocorrelation_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/autocorrelation_FLP.c
new file mode 100644
index 0000000000..8b8a9e659a
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/autocorrelation_FLP.c
@@ -0,0 +1,52 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "typedef.h"
33#include "SigProc_FLP.h"
34
35/* compute autocorrelation */
36void silk_autocorrelation_FLP(
37 silk_float *results, /* O result (length correlationCount) */
38 const silk_float *inputData, /* I input data to correlate */
39 opus_int inputDataSize, /* I length of input */
40 opus_int correlationCount /* I number of correlation taps to compute */
41)
42{
43 opus_int i;
44
45 if( correlationCount > inputDataSize ) {
46 correlationCount = inputDataSize;
47 }
48
49 for( i = 0; i < correlationCount; i++ ) {
50 results[ i ] = (silk_float)silk_inner_product_FLP( inputData, inputData + i, inputDataSize - i );
51 }
52}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/burg_modified_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/burg_modified_FLP.c
new file mode 100644
index 0000000000..756b76a35b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/burg_modified_FLP.c
@@ -0,0 +1,186 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FLP.h"
33#include "tuning_parameters.h"
34#include "define.h"
35
36#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384*/
37
38/* Compute reflection coefficients from input signal */
39silk_float silk_burg_modified_FLP( /* O returns residual energy */
40 silk_float A[], /* O prediction coefficients (length order) */
41 const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */
42 const silk_float minInvGain, /* I minimum inverse prediction gain */
43 const opus_int subfr_length, /* I input signal subframe length (incl. D preceding samples) */
44 const opus_int nb_subfr, /* I number of subframes stacked in x */
45 const opus_int D /* I order */
46)
47{
48 opus_int k, n, s, reached_max_gain;
49 double C0, invGain, num, nrg_f, nrg_b, rc, Atmp, tmp1, tmp2;
50 const silk_float *x_ptr;
51 double C_first_row[ SILK_MAX_ORDER_LPC ], C_last_row[ SILK_MAX_ORDER_LPC ];
52 double CAf[ SILK_MAX_ORDER_LPC + 1 ], CAb[ SILK_MAX_ORDER_LPC + 1 ];
53 double Af[ SILK_MAX_ORDER_LPC ];
54
55 celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
56
57 /* Compute autocorrelations, added over subframes */
58 C0 = silk_energy_FLP( x, nb_subfr * subfr_length );
59 silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( double ) );
60 for( s = 0; s < nb_subfr; s++ ) {
61 x_ptr = x + s * subfr_length;
62 for( n = 1; n < D + 1; n++ ) {
63 C_first_row[ n - 1 ] += silk_inner_product_FLP( x_ptr, x_ptr + n, subfr_length - n );
64 }
65 }
66 silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( double ) );
67
68 /* Initialize */
69 CAb[ 0 ] = CAf[ 0 ] = C0 + FIND_LPC_COND_FAC * C0 + 1e-9f;
70 invGain = 1.0f;
71 reached_max_gain = 0;
72 for( n = 0; n < D; n++ ) {
73 /* Update first row of correlation matrix (without first element) */
74 /* Update last row of correlation matrix (without last element, stored in reversed order) */
75 /* Update C * Af */
76 /* Update C * flipud(Af) (stored in reversed order) */
77 for( s = 0; s < nb_subfr; s++ ) {
78 x_ptr = x + s * subfr_length;
79 tmp1 = x_ptr[ n ];
80 tmp2 = x_ptr[ subfr_length - n - 1 ];
81 for( k = 0; k < n; k++ ) {
82 C_first_row[ k ] -= x_ptr[ n ] * x_ptr[ n - k - 1 ];
83 C_last_row[ k ] -= x_ptr[ subfr_length - n - 1 ] * x_ptr[ subfr_length - n + k ];
84 Atmp = Af[ k ];
85 tmp1 += x_ptr[ n - k - 1 ] * Atmp;
86 tmp2 += x_ptr[ subfr_length - n + k ] * Atmp;
87 }
88 for( k = 0; k <= n; k++ ) {
89 CAf[ k ] -= tmp1 * x_ptr[ n - k ];
90 CAb[ k ] -= tmp2 * x_ptr[ subfr_length - n + k - 1 ];
91 }
92 }
93 tmp1 = C_first_row[ n ];
94 tmp2 = C_last_row[ n ];
95 for( k = 0; k < n; k++ ) {
96 Atmp = Af[ k ];
97 tmp1 += C_last_row[ n - k - 1 ] * Atmp;
98 tmp2 += C_first_row[ n - k - 1 ] * Atmp;
99 }
100 CAf[ n + 1 ] = tmp1;
101 CAb[ n + 1 ] = tmp2;
102
103 /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */
104 num = CAb[ n + 1 ];
105 nrg_b = CAb[ 0 ];
106 nrg_f = CAf[ 0 ];
107 for( k = 0; k < n; k++ ) {
108 Atmp = Af[ k ];
109 num += CAb[ n - k ] * Atmp;
110 nrg_b += CAb[ k + 1 ] * Atmp;
111 nrg_f += CAf[ k + 1 ] * Atmp;
112 }
113 silk_assert( nrg_f > 0.0 );
114 silk_assert( nrg_b > 0.0 );
115
116 /* Calculate the next order reflection (parcor) coefficient */
117 rc = -2.0 * num / ( nrg_f + nrg_b );
118 silk_assert( rc > -1.0 && rc < 1.0 );
119
120 /* Update inverse prediction gain */
121 tmp1 = invGain * ( 1.0 - rc * rc );
122 if( tmp1 <= minInvGain ) {
123 /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */
124 rc = sqrt( 1.0 - minInvGain / invGain );
125 if( num > 0 ) {
126 /* Ensure adjusted reflection coefficients has the original sign */
127 rc = -rc;
128 }
129 invGain = minInvGain;
130 reached_max_gain = 1;
131 } else {
132 invGain = tmp1;
133 }
134
135 /* Update the AR coefficients */
136 for( k = 0; k < (n + 1) >> 1; k++ ) {
137 tmp1 = Af[ k ];
138 tmp2 = Af[ n - k - 1 ];
139 Af[ k ] = tmp1 + rc * tmp2;
140 Af[ n - k - 1 ] = tmp2 + rc * tmp1;
141 }
142 Af[ n ] = rc;
143
144 if( reached_max_gain ) {
145 /* Reached max prediction gain; set remaining coefficients to zero and exit loop */
146 for( k = n + 1; k < D; k++ ) {
147 Af[ k ] = 0.0;
148 }
149 break;
150 }
151
152 /* Update C * Af and C * Ab */
153 for( k = 0; k <= n + 1; k++ ) {
154 tmp1 = CAf[ k ];
155 CAf[ k ] += rc * CAb[ n - k + 1 ];
156 CAb[ n - k + 1 ] += rc * tmp1;
157 }
158 }
159
160 if( reached_max_gain ) {
161 /* Convert to silk_float */
162 for( k = 0; k < D; k++ ) {
163 A[ k ] = (silk_float)( -Af[ k ] );
164 }
165 /* Subtract energy of preceding samples from C0 */
166 for( s = 0; s < nb_subfr; s++ ) {
167 C0 -= silk_energy_FLP( x + s * subfr_length, D );
168 }
169 /* Approximate residual energy */
170 nrg_f = C0 * invGain;
171 } else {
172 /* Compute residual energy and store coefficients as silk_float */
173 nrg_f = CAf[ 0 ];
174 tmp1 = 1.0;
175 for( k = 0; k < D; k++ ) {
176 Atmp = Af[ k ];
177 nrg_f += CAf[ k + 1 ] * Atmp;
178 tmp1 += Atmp * Atmp;
179 A[ k ] = (silk_float)(-Atmp);
180 }
181 nrg_f -= FIND_LPC_COND_FAC * C0 * tmp1;
182 }
183
184 /* Return residual energy */
185 return (silk_float)nrg_f;
186}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/bwexpander_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/bwexpander_FLP.c
new file mode 100644
index 0000000000..d55a4d79ab
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/bwexpander_FLP.c
@@ -0,0 +1,49 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FLP.h"
33
34/* Chirp (bw expand) LP AR filter */
35void silk_bwexpander_FLP(
36 silk_float *ar, /* I/O AR filter to be expanded (without leading 1) */
37 const opus_int d, /* I length of ar */
38 const silk_float chirp /* I chirp factor (typically in range (0..1) ) */
39)
40{
41 opus_int i;
42 silk_float cfac = chirp;
43
44 for( i = 0; i < d - 1; i++ ) {
45 ar[ i ] *= cfac;
46 cfac *= chirp;
47 }
48 ar[ d - 1 ] *= cfac;
49}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/corrMatrix_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/corrMatrix_FLP.c
new file mode 100644
index 0000000000..eae6a1cfca
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/corrMatrix_FLP.c
@@ -0,0 +1,93 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32/**********************************************************************
33 * Correlation matrix computations for LS estimate.
34 **********************************************************************/
35
36#include "main_FLP.h"
37
38/* Calculates correlation vector X'*t */
39void silk_corrVector_FLP(
40 const silk_float *x, /* I x vector [L+order-1] used to create X */
41 const silk_float *t, /* I Target vector [L] */
42 const opus_int L, /* I Length of vecors */
43 const opus_int Order, /* I Max lag for correlation */
44 silk_float *Xt /* O X'*t correlation vector [order] */
45)
46{
47 opus_int lag;
48 const silk_float *ptr1;
49
50 ptr1 = &x[ Order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */
51 for( lag = 0; lag < Order; lag++ ) {
52 /* Calculate X[:,lag]'*t */
53 Xt[ lag ] = (silk_float)silk_inner_product_FLP( ptr1, t, L );
54 ptr1--; /* Next column of X */
55 }
56}
57
58/* Calculates correlation matrix X'*X */
59void silk_corrMatrix_FLP(
60 const silk_float *x, /* I x vector [ L+order-1 ] used to create X */
61 const opus_int L, /* I Length of vectors */
62 const opus_int Order, /* I Max lag for correlation */
63 silk_float *XX /* O X'*X correlation matrix [order x order] */
64)
65{
66 opus_int j, lag;
67 double energy;
68 const silk_float *ptr1, *ptr2;
69
70 ptr1 = &x[ Order - 1 ]; /* First sample of column 0 of X */
71 energy = silk_energy_FLP( ptr1, L ); /* X[:,0]'*X[:,0] */
72 matrix_ptr( XX, 0, 0, Order ) = ( silk_float )energy;
73 for( j = 1; j < Order; j++ ) {
74 /* Calculate X[:,j]'*X[:,j] */
75 energy += ptr1[ -j ] * ptr1[ -j ] - ptr1[ L - j ] * ptr1[ L - j ];
76 matrix_ptr( XX, j, j, Order ) = ( silk_float )energy;
77 }
78
79 ptr2 = &x[ Order - 2 ]; /* First sample of column 1 of X */
80 for( lag = 1; lag < Order; lag++ ) {
81 /* Calculate X[:,0]'*X[:,lag] */
82 energy = silk_inner_product_FLP( ptr1, ptr2, L );
83 matrix_ptr( XX, lag, 0, Order ) = ( silk_float )energy;
84 matrix_ptr( XX, 0, lag, Order ) = ( silk_float )energy;
85 /* Calculate X[:,j]'*X[:,j + lag] */
86 for( j = 1; j < ( Order - lag ); j++ ) {
87 energy += ptr1[ -j ] * ptr2[ -j ] - ptr1[ L - j ] * ptr2[ L - j ];
88 matrix_ptr( XX, lag + j, j, Order ) = ( silk_float )energy;
89 matrix_ptr( XX, j, lag + j, Order ) = ( silk_float )energy;
90 }
91 ptr2--; /* Next column of X */
92 }
93}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/encode_frame_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/encode_frame_FLP.c
new file mode 100644
index 0000000000..b029c3f5ca
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/encode_frame_FLP.c
@@ -0,0 +1,435 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <stdlib.h>
33#include "main_FLP.h"
34#include "tuning_parameters.h"
35
36/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */
37static OPUS_INLINE void silk_LBRR_encode_FLP(
38 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
39 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
40 const silk_float xfw[], /* I Input signal */
41 opus_int condCoding /* I The type of conditional coding used so far for this frame */
42);
43
44void silk_encode_do_VAD_FLP(
45 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
46 opus_int activity /* I Decision of Opus voice activity detector */
47)
48{
49 const opus_int activity_threshold = SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 );
50
51 /****************************/
52 /* Voice Activity Detection */
53 /****************************/
54 silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch );
55 /* If Opus VAD is inactive and Silk VAD is active: lower Silk VAD to just under the threshold */
56 if( activity == VAD_NO_ACTIVITY && psEnc->sCmn.speech_activity_Q8 >= activity_threshold ) {
57 psEnc->sCmn.speech_activity_Q8 = activity_threshold - 1;
58 }
59
60 /**************************************************/
61 /* Convert speech activity into VAD and DTX flags */
62 /**************************************************/
63 if( psEnc->sCmn.speech_activity_Q8 < activity_threshold ) {
64 psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
65 psEnc->sCmn.noSpeechCounter++;
66 if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) {
67 psEnc->sCmn.inDTX = 0;
68 } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {
69 psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;
70 psEnc->sCmn.inDTX = 0;
71 }
72 psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0;
73 } else {
74 psEnc->sCmn.noSpeechCounter = 0;
75 psEnc->sCmn.inDTX = 0;
76 psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
77 psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
78 }
79}
80
81/****************/
82/* Encode frame */
83/****************/
84opus_int silk_encode_frame_FLP(
85 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
86 opus_int32 *pnBytesOut, /* O Number of payload bytes; */
87 ec_enc *psRangeEnc, /* I/O compressor data structure */
88 opus_int condCoding, /* I The type of conditional coding to use */
89 opus_int maxBits, /* I If > 0: maximum number of output bits */
90 opus_int useCBR /* I Flag to force constant-bitrate operation */
91)
92{
93 silk_encoder_control_FLP sEncCtrl;
94 opus_int i, iter, maxIter, found_upper, found_lower, ret = 0;
95 silk_float *x_frame, *res_pitch_frame;
96 silk_float res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
97 ec_enc sRangeEnc_copy, sRangeEnc_copy2;
98 silk_nsq_state sNSQ_copy, sNSQ_copy2;
99 opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper;
100 opus_int32 gainsID, gainsID_lower, gainsID_upper;
101 opus_int16 gainMult_Q8;
102 opus_int16 ec_prevLagIndex_copy;
103 opus_int ec_prevSignalType_copy;
104 opus_int8 LastGainIndex_copy2;
105 opus_int32 pGains_Q16[ MAX_NB_SUBFR ];
106 opus_uint8 ec_buf_copy[ 1275 ];
107 opus_int gain_lock[ MAX_NB_SUBFR ] = {0};
108 opus_int16 best_gain_mult[ MAX_NB_SUBFR ];
109 opus_int best_sum[ MAX_NB_SUBFR ];
110
111 /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
112 LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;
113
114 psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
115
116 /**************************************************************/
117 /* Set up Input Pointers, and insert frame in input buffer */
118 /**************************************************************/
119 /* pointers aligned with start of frame to encode */
120 x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */
121 res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; /* start of pitch LPC residual frame */
122
123 /***************************************/
124 /* Ensure smooth bandwidth transitions */
125 /***************************************/
126 silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
127
128 /*******************************************/
129 /* Copy new frame to front of input buffer */
130 /*******************************************/
131 silk_short2float_array( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
132
133 /* Add tiny signal to avoid high CPU load from denormalized floating point numbers */
134 for( i = 0; i < 8; i++ ) {
135 x_frame[ LA_SHAPE_MS * psEnc->sCmn.fs_kHz + i * ( psEnc->sCmn.frame_length >> 3 ) ] += ( 1 - ( i & 2 ) ) * 1e-6f;
136 }
137
138 if( !psEnc->sCmn.prefillFlag ) {
139 /*****************************************/
140 /* Find pitch lags, initial LPC analysis */
141 /*****************************************/
142 silk_find_pitch_lags_FLP( psEnc, &sEncCtrl, res_pitch, x_frame, psEnc->sCmn.arch );
143
144 /************************/
145 /* Noise shape analysis */
146 /************************/
147 silk_noise_shape_analysis_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame );
148
149 /***************************************************/
150 /* Find linear prediction coefficients (LPC + LTP) */
151 /***************************************************/
152 silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding );
153
154 /****************************************/
155 /* Process gains */
156 /****************************************/
157 silk_process_gains_FLP( psEnc, &sEncCtrl, condCoding );
158
159 /****************************************/
160 /* Low Bitrate Redundant Encoding */
161 /****************************************/
162 silk_LBRR_encode_FLP( psEnc, &sEncCtrl, x_frame, condCoding );
163
164 /* Loop over quantizer and entroy coding to control bitrate */
165 maxIter = 6;
166 gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
167 found_lower = 0;
168 found_upper = 0;
169 gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
170 gainsID_lower = -1;
171 gainsID_upper = -1;
172 /* Copy part of the input state */
173 silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) );
174 silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
175 seed_copy = psEnc->sCmn.indices.Seed;
176 ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex;
177 ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType;
178 for( iter = 0; ; iter++ ) {
179 if( gainsID == gainsID_lower ) {
180 nBits = nBits_lower;
181 } else if( gainsID == gainsID_upper ) {
182 nBits = nBits_upper;
183 } else {
184 /* Restore part of the input state */
185 if( iter > 0 ) {
186 silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) );
187 silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) );
188 psEnc->sCmn.indices.Seed = seed_copy;
189 psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
190 psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
191 }
192
193 /*****************************************/
194 /* Noise shaping quantization */
195 /*****************************************/
196 silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, x_frame );
197
198 if ( iter == maxIter && !found_lower ) {
199 silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
200 }
201
202 /****************************************/
203 /* Encode Parameters */
204 /****************************************/
205 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
206
207 /****************************************/
208 /* Encode Excitation Signal */
209 /****************************************/
210 silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
211 psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
212
213 nBits = ec_tell( psRangeEnc );
214
215 /* If we still bust after the last iteration, do some damage control. */
216 if ( iter == maxIter && !found_lower && nBits > maxBits ) {
217 silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
218
219 /* Keep gains the same as the last frame. */
220 psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
221 for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
222 psEnc->sCmn.indices.GainsIndices[ i ] = 4;
223 }
224 if (condCoding != CODE_CONDITIONALLY) {
225 psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev;
226 }
227 psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
228 psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
229 /* Clear all pulses. */
230 for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
231 psEnc->sCmn.pulses[ i ] = 0;
232 }
233
234 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
235
236 silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
237 psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
238
239 nBits = ec_tell( psRangeEnc );
240 }
241
242 if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
243 break;
244 }
245 }
246
247 if( iter == maxIter ) {
248 if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {
249 /* Restore output state from earlier iteration that did meet the bitrate budget */
250 silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
251 celt_assert( sRangeEnc_copy2.offs <= 1275 );
252 silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );
253 silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );
254 psEnc->sShape.LastGainIndex = LastGainIndex_copy2;
255 }
256 break;
257 }
258
259 if( nBits > maxBits ) {
260 if( found_lower == 0 && iter >= 2 ) {
261 /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
262 sEncCtrl.Lambda = silk_max_float(sEncCtrl.Lambda*1.5f, 1.5f);
263 /* Reducing dithering can help us hit the target. */
264 psEnc->sCmn.indices.quantOffsetType = 0;
265 found_upper = 0;
266 gainsID_upper = -1;
267 } else {
268 found_upper = 1;
269 nBits_upper = nBits;
270 gainMult_upper = gainMult_Q8;
271 gainsID_upper = gainsID;
272 }
273 } else if( nBits < maxBits - 5 ) {
274 found_lower = 1;
275 nBits_lower = nBits;
276 gainMult_lower = gainMult_Q8;
277 if( gainsID != gainsID_lower ) {
278 gainsID_lower = gainsID;
279 /* Copy part of the output state */
280 silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
281 celt_assert( psRangeEnc->offs <= 1275 );
282 silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
283 silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
284 LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;
285 }
286 } else {
287 /* Within 5 bits of budget: close enough */
288 break;
289 }
290
291 if ( !found_lower && nBits > maxBits ) {
292 int j;
293 for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
294 int sum=0;
295 for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) {
296 sum += abs( psEnc->sCmn.pulses[j] );
297 }
298 if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) {
299 best_sum[i] = sum;
300 best_gain_mult[i] = gainMult_Q8;
301 } else {
302 gain_lock[i] = 1;
303 }
304 }
305 }
306 if( ( found_lower & found_upper ) == 0 ) {
307 /* Adjust gain according to high-rate rate/distortion curve */
308 if( nBits > maxBits ) {
309 if (gainMult_Q8 < 16384) {
310 gainMult_Q8 *= 2;
311 } else {
312 gainMult_Q8 = 32767;
313 }
314 } else {
315 opus_int32 gain_factor_Q16;
316 gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
317 gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
318 }
319 } else {
320 /* Adjust gain by interpolating */
321 gainMult_Q8 = gainMult_lower + ( ( gainMult_upper - gainMult_lower ) * ( maxBits - nBits_lower ) ) / ( nBits_upper - nBits_lower );
322 /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */
323 if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) {
324 gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 );
325 } else
326 if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) {
327 gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 );
328 }
329 }
330
331 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
332 opus_int16 tmp;
333 if ( gain_lock[i] ) {
334 tmp = best_gain_mult[i];
335 } else {
336 tmp = gainMult_Q8;
337 }
338 pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 );
339 }
340
341 /* Quantize gains */
342 psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
343 silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16,
344 &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
345
346 /* Unique identifier of gains vector */
347 gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
348
349 /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */
350 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
351 sEncCtrl.Gains[ i ] = pGains_Q16[ i ] / 65536.0f;
352 }
353 }
354 }
355
356 /* Update input buffer */
357 silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
358 ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( silk_float ) );
359
360 /* Exit without entropy coding */
361 if( psEnc->sCmn.prefillFlag ) {
362 /* No payload */
363 *pnBytesOut = 0;
364 return ret;
365 }
366
367 /* Parameters needed for next frame */
368 psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];
369 psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;
370
371 /****************************************/
372 /* Finalize payload */
373 /****************************************/
374 psEnc->sCmn.first_frame_after_reset = 0;
375 /* Payload size */
376 *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );
377
378 return ret;
379}
380
381/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */
382static OPUS_INLINE void silk_LBRR_encode_FLP(
383 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
384 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
385 const silk_float xfw[], /* I Input signal */
386 opus_int condCoding /* I The type of conditional coding used so far for this frame */
387)
388{
389 opus_int k;
390 opus_int32 Gains_Q16[ MAX_NB_SUBFR ];
391 silk_float TempGains[ MAX_NB_SUBFR ];
392 SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];
393 silk_nsq_state sNSQ_LBRR;
394
395 /*******************************************/
396 /* Control use of inband LBRR */
397 /*******************************************/
398 if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {
399 psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
400
401 /* Copy noise shaping quantizer state and quantization indices from regular encoding */
402 silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
403 silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );
404
405 /* Save original gains */
406 silk_memcpy( TempGains, psEncCtrl->Gains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) );
407
408 if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {
409 /* First frame in packet or previous frame not LBRR coded */
410 psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
411
412 /* Increase Gains to get target LBRR rate */
413 psIndices_LBRR->GainsIndices[ 0 ] += psEnc->sCmn.LBRR_GainIncreases;
414 psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );
415 }
416
417 /* Decode to get gains in sync with decoder */
418 silk_gains_dequant( Gains_Q16, psIndices_LBRR->GainsIndices,
419 &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
420
421 /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */
422 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
423 psEncCtrl->Gains[ k ] = Gains_Q16[ k ] * ( 1.0f / 65536.0f );
424 }
425
426 /*****************************************/
427 /* Noise shaping quantization */
428 /*****************************************/
429 silk_NSQ_wrapper_FLP( psEnc, psEncCtrl, psIndices_LBRR, &sNSQ_LBRR,
430 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], xfw );
431
432 /* Restore original gains */
433 silk_memcpy( psEncCtrl->Gains, TempGains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) );
434 }
435}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/energy_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/energy_FLP.c
new file mode 100644
index 0000000000..7bc7173c9c
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/energy_FLP.c
@@ -0,0 +1,59 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FLP.h"
33
34/* sum of squares of a silk_float array, with result as double */
35double silk_energy_FLP(
36 const silk_float *data,
37 opus_int dataSize
38)
39{
40 opus_int i;
41 double result;
42
43 /* 4x unrolled loop */
44 result = 0.0;
45 for( i = 0; i < dataSize - 3; i += 4 ) {
46 result += data[ i + 0 ] * (double)data[ i + 0 ] +
47 data[ i + 1 ] * (double)data[ i + 1 ] +
48 data[ i + 2 ] * (double)data[ i + 2 ] +
49 data[ i + 3 ] * (double)data[ i + 3 ];
50 }
51
52 /* add any remaining products */
53 for( ; i < dataSize; i++ ) {
54 result += data[ i ] * (double)data[ i ];
55 }
56
57 silk_assert( result >= 0.0 );
58 return result;
59}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/find_LPC_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/find_LPC_FLP.c
new file mode 100644
index 0000000000..fa3ffe7f8b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/find_LPC_FLP.c
@@ -0,0 +1,104 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "define.h"
33#include "main_FLP.h"
34#include "tuning_parameters.h"
35
36/* LPC analysis */
37void silk_find_LPC_FLP(
38 silk_encoder_state *psEncC, /* I/O Encoder state */
39 opus_int16 NLSF_Q15[], /* O NLSFs */
40 const silk_float x[], /* I Input signal */
41 const silk_float minInvGain /* I Inverse of max prediction gain */
42)
43{
44 opus_int k, subfr_length;
45 silk_float a[ MAX_LPC_ORDER ];
46
47 /* Used only for NLSF interpolation */
48 silk_float res_nrg, res_nrg_2nd, res_nrg_interp;
49 opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ];
50 silk_float a_tmp[ MAX_LPC_ORDER ];
51 silk_float LPC_res[ MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ];
52
53 subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder;
54
55 /* Default: No interpolation */
56 psEncC->indices.NLSFInterpCoef_Q2 = 4;
57
58 /* Burg AR analysis for the full frame */
59 res_nrg = silk_burg_modified_FLP( a, x, minInvGain, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder );
60
61 if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) {
62 /* Optimal solution for last 10 ms; subtract residual energy here, as that's easier than */
63 /* adding it to the residual energy of the first 10 ms in each iteration of the search below */
64 res_nrg -= silk_burg_modified_FLP( a_tmp, x + ( MAX_NB_SUBFR / 2 ) * subfr_length, minInvGain, subfr_length, MAX_NB_SUBFR / 2, psEncC->predictLPCOrder );
65
66 /* Convert to NLSFs */
67 silk_A2NLSF_FLP( NLSF_Q15, a_tmp, psEncC->predictLPCOrder );
68
69 /* Search over interpolation indices to find the one with lowest residual energy */
70 res_nrg_2nd = silk_float_MAX;
71 for( k = 3; k >= 0; k-- ) {
72 /* Interpolate NLSFs for first half */
73 silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder );
74
75 /* Convert to LPC for residual energy evaluation */
76 silk_NLSF2A_FLP( a_tmp, NLSF0_Q15, psEncC->predictLPCOrder, psEncC->arch );
77
78 /* Calculate residual energy with LSF interpolation */
79 silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, psEncC->predictLPCOrder );
80 res_nrg_interp = (silk_float)(
81 silk_energy_FLP( LPC_res + psEncC->predictLPCOrder, subfr_length - psEncC->predictLPCOrder ) +
82 silk_energy_FLP( LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder ) );
83
84 /* Determine whether current interpolated NLSFs are best so far */
85 if( res_nrg_interp < res_nrg ) {
86 /* Interpolation has lower residual energy */
87 res_nrg = res_nrg_interp;
88 psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k;
89 } else if( res_nrg_interp > res_nrg_2nd ) {
90 /* No reason to continue iterating - residual energies will continue to climb */
91 break;
92 }
93 res_nrg_2nd = res_nrg_interp;
94 }
95 }
96
97 if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) {
98 /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */
99 silk_A2NLSF_FLP( NLSF_Q15, a, psEncC->predictLPCOrder );
100 }
101
102 celt_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 ||
103 ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );
104}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/find_LTP_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/find_LTP_FLP.c
new file mode 100644
index 0000000000..f97064930e
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/find_LTP_FLP.c
@@ -0,0 +1,64 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FLP.h"
33#include "tuning_parameters.h"
34
35void silk_find_LTP_FLP(
36 silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
37 silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* O Weight for LTP quantization */
38 const silk_float r_ptr[], /* I LPC residual */
39 const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
40 const opus_int subfr_length, /* I Subframe length */
41 const opus_int nb_subfr /* I number of subframes */
42)
43{
44 opus_int k;
45 silk_float *xX_ptr, *XX_ptr;
46 const silk_float *lag_ptr;
47 silk_float xx, temp;
48
49 xX_ptr = xX;
50 XX_ptr = XX;
51 for( k = 0; k < nb_subfr; k++ ) {
52 lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 );
53 silk_corrMatrix_FLP( lag_ptr, subfr_length, LTP_ORDER, XX_ptr );
54 silk_corrVector_FLP( lag_ptr, r_ptr, subfr_length, LTP_ORDER, xX_ptr );
55 xx = ( silk_float )silk_energy_FLP( r_ptr, subfr_length + LTP_ORDER );
56 temp = 1.0f / silk_max( xx, LTP_CORR_INV_MAX * 0.5f * ( XX_ptr[ 0 ] + XX_ptr[ 24 ] ) + 1.0f );
57 silk_scale_vector_FLP( XX_ptr, temp, LTP_ORDER * LTP_ORDER );
58 silk_scale_vector_FLP( xX_ptr, temp, LTP_ORDER );
59
60 r_ptr += subfr_length;
61 XX_ptr += LTP_ORDER * LTP_ORDER;
62 xX_ptr += LTP_ORDER;
63 }
64}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/find_pitch_lags_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/find_pitch_lags_FLP.c
new file mode 100644
index 0000000000..dedbcd2836
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/find_pitch_lags_FLP.c
@@ -0,0 +1,132 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <stdlib.h>
33#include "main_FLP.h"
34#include "tuning_parameters.h"
35
36void silk_find_pitch_lags_FLP(
37 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
38 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
39 silk_float res[], /* O Residual */
40 const silk_float x[], /* I Speech signal */
41 int arch /* I Run-time architecture */
42)
43{
44 opus_int buf_len;
45 silk_float thrhld, res_nrg;
46 const silk_float *x_buf_ptr, *x_buf;
47 silk_float auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ];
48 silk_float A[ MAX_FIND_PITCH_LPC_ORDER ];
49 silk_float refl_coef[ MAX_FIND_PITCH_LPC_ORDER ];
50 silk_float Wsig[ FIND_PITCH_LPC_WIN_MAX ];
51 silk_float *Wsig_ptr;
52
53 /******************************************/
54 /* Set up buffer lengths etc based on Fs */
55 /******************************************/
56 buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
57
58 /* Safety check */
59 celt_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
60
61 x_buf = x - psEnc->sCmn.ltp_mem_length;
62
63 /******************************************/
64 /* Estimate LPC AR coeficients */
65 /******************************************/
66
67 /* Calculate windowed signal */
68
69 /* First LA_LTP samples */
70 x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length;
71 Wsig_ptr = Wsig;
72 silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch );
73
74 /* Middle non-windowed samples */
75 Wsig_ptr += psEnc->sCmn.la_pitch;
76 x_buf_ptr += psEnc->sCmn.la_pitch;
77 silk_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ) ) * sizeof( silk_float ) );
78
79 /* Last LA_LTP samples */
80 Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 );
81 x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 );
82 silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch );
83
84 /* Calculate autocorrelation sequence */
85 silk_autocorrelation_FLP( auto_corr, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 );
86
87 /* Add white noise, as a fraction of the energy */
88 auto_corr[ 0 ] += auto_corr[ 0 ] * FIND_PITCH_WHITE_NOISE_FRACTION + 1;
89
90 /* Calculate the reflection coefficients using Schur */
91 res_nrg = silk_schur_FLP( refl_coef, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder );
92
93 /* Prediction gain */
94 psEncCtrl->predGain = auto_corr[ 0 ] / silk_max_float( res_nrg, 1.0f );
95
96 /* Convert reflection coefficients to prediction coefficients */
97 silk_k2a_FLP( A, refl_coef, psEnc->sCmn.pitchEstimationLPCOrder );
98
99 /* Bandwidth expansion */
100 silk_bwexpander_FLP( A, psEnc->sCmn.pitchEstimationLPCOrder, FIND_PITCH_BANDWIDTH_EXPANSION );
101
102 /*****************************************/
103 /* LPC analysis filtering */
104 /*****************************************/
105 silk_LPC_analysis_filter_FLP( res, A, x_buf, buf_len, psEnc->sCmn.pitchEstimationLPCOrder );
106
107 if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) {
108 /* Threshold for pitch estimator */
109 thrhld = 0.6f;
110 thrhld -= 0.004f * psEnc->sCmn.pitchEstimationLPCOrder;
111 thrhld -= 0.1f * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f );
112 thrhld -= 0.15f * (psEnc->sCmn.prevSignalType >> 1);
113 thrhld -= 0.1f * psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f );
114
115 /*****************************************/
116 /* Call Pitch estimator */
117 /*****************************************/
118 if( silk_pitch_analysis_core_FLP( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex,
119 &psEnc->sCmn.indices.contourIndex, &psEnc->LTPCorr, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16 / 65536.0f,
120 thrhld, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr, arch ) == 0 )
121 {
122 psEnc->sCmn.indices.signalType = TYPE_VOICED;
123 } else {
124 psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
125 }
126 } else {
127 silk_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) );
128 psEnc->sCmn.indices.lagIndex = 0;
129 psEnc->sCmn.indices.contourIndex = 0;
130 psEnc->LTPCorr = 0;
131 }
132}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/find_pred_coefs_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/find_pred_coefs_FLP.c
new file mode 100644
index 0000000000..dcf7c5202d
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/find_pred_coefs_FLP.c
@@ -0,0 +1,116 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FLP.h"
33
34/* Find LPC and LTP coefficients */
35void silk_find_pred_coefs_FLP(
36 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
37 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
38 const silk_float res_pitch[], /* I Residual from pitch analysis */
39 const silk_float x[], /* I Speech signal */
40 opus_int condCoding /* I The type of conditional coding to use */
41)
42{
43 opus_int i;
44 silk_float XXLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ];
45 silk_float xXLTP[ MAX_NB_SUBFR * LTP_ORDER ];
46 silk_float invGains[ MAX_NB_SUBFR ];
47 opus_int16 NLSF_Q15[ MAX_LPC_ORDER ];
48 const silk_float *x_ptr;
49 silk_float *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ];
50 silk_float minInvGain;
51
52 /* Weighting for weighted least squares */
53 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
54 silk_assert( psEncCtrl->Gains[ i ] > 0.0f );
55 invGains[ i ] = 1.0f / psEncCtrl->Gains[ i ];
56 }
57
58 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
59 /**********/
60 /* VOICED */
61 /**********/
62 celt_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
63
64 /* LTP analysis */
65 silk_find_LTP_FLP( XXLTP, xXLTP, res_pitch, psEncCtrl->pitchL, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr );
66
67 /* Quantize LTP gain parameters */
68 silk_quant_LTP_gains_FLP( psEncCtrl->LTPCoef, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex,
69 &psEnc->sCmn.sum_log_gain_Q7, &psEncCtrl->LTPredCodGain, XXLTP, xXLTP, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch );
70
71 /* Control LTP scaling */
72 silk_LTP_scale_ctrl_FLP( psEnc, psEncCtrl, condCoding );
73
74 /* Create LTP residual */
75 silk_LTP_analysis_filter_FLP( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef,
76 psEncCtrl->pitchL, invGains, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder );
77 } else {
78 /************/
79 /* UNVOICED */
80 /************/
81 /* Create signal with prepended subframes, scaled by inverse gains */
82 x_ptr = x - psEnc->sCmn.predictLPCOrder;
83 x_pre_ptr = LPC_in_pre;
84 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
85 silk_scale_copy_vector_FLP( x_pre_ptr, x_ptr, invGains[ i ],
86 psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder );
87 x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder;
88 x_ptr += psEnc->sCmn.subfr_length;
89 }
90 silk_memset( psEncCtrl->LTPCoef, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( silk_float ) );
91 psEncCtrl->LTPredCodGain = 0.0f;
92 psEnc->sCmn.sum_log_gain_Q7 = 0;
93 }
94
95 /* Limit on total predictive coding gain */
96 if( psEnc->sCmn.first_frame_after_reset ) {
97 minInvGain = 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET;
98 } else {
99 minInvGain = (silk_float)pow( 2, psEncCtrl->LTPredCodGain / 3 ) / MAX_PREDICTION_POWER_GAIN;
100 minInvGain /= 0.25f + 0.75f * psEncCtrl->coding_quality;
101 }
102
103 /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */
104 silk_find_LPC_FLP( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain );
105
106 /* Quantize LSFs */
107 silk_process_NLSFs_FLP( &psEnc->sCmn, psEncCtrl->PredCoef, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 );
108
109 /* Calculate residual energy using quantized LPC coefficients */
110 silk_residual_energy_FLP( psEncCtrl->ResNrg, LPC_in_pre, psEncCtrl->PredCoef, psEncCtrl->Gains,
111 psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder );
112
113 /* Copy to prediction struct for use in next frame for interpolation */
114 silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );
115}
116
diff --git a/lib/rbcodec/codecs/libopus/silk/float/inner_product_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/inner_product_FLP.c
new file mode 100644
index 0000000000..cdd39d24ce
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/inner_product_FLP.c
@@ -0,0 +1,59 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FLP.h"
33
34/* inner product of two silk_float arrays, with result as double */
35double silk_inner_product_FLP(
36 const silk_float *data1,
37 const silk_float *data2,
38 opus_int dataSize
39)
40{
41 opus_int i;
42 double result;
43
44 /* 4x unrolled loop */
45 result = 0.0;
46 for( i = 0; i < dataSize - 3; i += 4 ) {
47 result += data1[ i + 0 ] * (double)data2[ i + 0 ] +
48 data1[ i + 1 ] * (double)data2[ i + 1 ] +
49 data1[ i + 2 ] * (double)data2[ i + 2 ] +
50 data1[ i + 3 ] * (double)data2[ i + 3 ];
51 }
52
53 /* add any remaining products */
54 for( ; i < dataSize; i++ ) {
55 result += data1[ i ] * (double)data2[ i ];
56 }
57
58 return result;
59}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/k2a_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/k2a_FLP.c
new file mode 100644
index 0000000000..1448008dbb
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/k2a_FLP.c
@@ -0,0 +1,54 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FLP.h"
33
34/* step up function, converts reflection coefficients to prediction coefficients */
35void silk_k2a_FLP(
36 silk_float *A, /* O prediction coefficients [order] */
37 const silk_float *rc, /* I reflection coefficients [order] */
38 opus_int32 order /* I prediction order */
39)
40{
41 opus_int k, n;
42 silk_float rck, tmp1, tmp2;
43
44 for( k = 0; k < order; k++ ) {
45 rck = rc[ k ];
46 for( n = 0; n < (k + 1) >> 1; n++ ) {
47 tmp1 = A[ n ];
48 tmp2 = A[ k - n - 1 ];
49 A[ n ] = tmp1 + tmp2 * rck;
50 A[ k - n - 1 ] = tmp2 + tmp1 * rck;
51 }
52 A[ k ] = -rck;
53 }
54}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/main_FLP.h b/lib/rbcodec/codecs/libopus/silk/float/main_FLP.h
new file mode 100644
index 0000000000..5dc0ccf4a4
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/main_FLP.h
@@ -0,0 +1,286 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef SILK_MAIN_FLP_H
29#define SILK_MAIN_FLP_H
30
31#include "SigProc_FLP.h"
32#include "SigProc_FIX.h"
33#include "structs_FLP.h"
34#include "main.h"
35#include "define.h"
36#include "debug.h"
37#include "entenc.h"
38
39#ifdef __cplusplus
40extern "C"
41{
42#endif
43
44#define silk_encoder_state_Fxx silk_encoder_state_FLP
45#define silk_encode_do_VAD_Fxx silk_encode_do_VAD_FLP
46#define silk_encode_frame_Fxx silk_encode_frame_FLP
47
48/*********************/
49/* Encoder Functions */
50/*********************/
51
52/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */
53void silk_HP_variable_cutoff(
54 silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */
55);
56
57/* Encoder main function */
58void silk_encode_do_VAD_FLP(
59 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
60 opus_int activity /* I Decision of Opus voice activity detector */
61);
62
63/* Encoder main function */
64opus_int silk_encode_frame_FLP(
65 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
66 opus_int32 *pnBytesOut, /* O Number of payload bytes; */
67 ec_enc *psRangeEnc, /* I/O compressor data structure */
68 opus_int condCoding, /* I The type of conditional coding to use */
69 opus_int maxBits, /* I If > 0: maximum number of output bits */
70 opus_int useCBR /* I Flag to force constant-bitrate operation */
71);
72
73/* Initializes the Silk encoder state */
74opus_int silk_init_encoder(
75 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
76 int arch /* I Run-tim architecture */
77);
78
79/* Control the Silk encoder */
80opus_int silk_control_encoder(
81 silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */
82 silk_EncControlStruct *encControl, /* I Control structure */
83 const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */
84 const opus_int channelNb, /* I Channel number */
85 const opus_int force_fs_kHz
86);
87
88/**************************/
89/* Noise shaping analysis */
90/**************************/
91/* Compute noise shaping coefficients and initial gain values */
92void silk_noise_shape_analysis_FLP(
93 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
94 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
95 const silk_float *pitch_res, /* I LPC residual from pitch analysis */
96 const silk_float *x /* I Input signal [frame_length + la_shape] */
97);
98
99/* Autocorrelations for a warped frequency axis */
100void silk_warped_autocorrelation_FLP(
101 silk_float *corr, /* O Result [order + 1] */
102 const silk_float *input, /* I Input data to correlate */
103 const silk_float warping, /* I Warping coefficient */
104 const opus_int length, /* I Length of input */
105 const opus_int order /* I Correlation order (even) */
106);
107
108/* Calculation of LTP state scaling */
109void silk_LTP_scale_ctrl_FLP(
110 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
111 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
112 opus_int condCoding /* I The type of conditional coding to use */
113);
114
115/**********************************************/
116/* Prediction Analysis */
117/**********************************************/
118/* Find pitch lags */
119void silk_find_pitch_lags_FLP(
120 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
121 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
122 silk_float res[], /* O Residual */
123 const silk_float x[], /* I Speech signal */
124 int arch /* I Run-time architecture */
125);
126
127/* Find LPC and LTP coefficients */
128void silk_find_pred_coefs_FLP(
129 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
130 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
131 const silk_float res_pitch[], /* I Residual from pitch analysis */
132 const silk_float x[], /* I Speech signal */
133 opus_int condCoding /* I The type of conditional coding to use */
134);
135
136/* LPC analysis */
137void silk_find_LPC_FLP(
138 silk_encoder_state *psEncC, /* I/O Encoder state */
139 opus_int16 NLSF_Q15[], /* O NLSFs */
140 const silk_float x[], /* I Input signal */
141 const silk_float minInvGain /* I Prediction gain from LTP (dB) */
142);
143
144/* LTP analysis */
145void silk_find_LTP_FLP(
146 silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
147 silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* O Weight for LTP quantization */
148 const silk_float r_ptr[], /* I LPC residual */
149 const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
150 const opus_int subfr_length, /* I Subframe length */
151 const opus_int nb_subfr /* I number of subframes */
152);
153
154void silk_LTP_analysis_filter_FLP(
155 silk_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */
156 const silk_float *x, /* I Input signal, with preceding samples */
157 const silk_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */
158 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
159 const silk_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */
160 const opus_int subfr_length, /* I Length of each subframe */
161 const opus_int nb_subfr, /* I number of subframes */
162 const opus_int pre_length /* I Preceding samples for each subframe */
163);
164
165/* Calculates residual energies of input subframes where all subframes have LPC_order */
166/* of preceding samples */
167void silk_residual_energy_FLP(
168 silk_float nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */
169 const silk_float x[], /* I Input signal */
170 silk_float a[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */
171 const silk_float gains[], /* I Quantization gains */
172 const opus_int subfr_length, /* I Subframe length */
173 const opus_int nb_subfr, /* I number of subframes */
174 const opus_int LPC_order /* I LPC order */
175);
176
177/* 16th order LPC analysis filter */
178void silk_LPC_analysis_filter_FLP(
179 silk_float r_LPC[], /* O LPC residual signal */
180 const silk_float PredCoef[], /* I LPC coefficients */
181 const silk_float s[], /* I Input signal */
182 const opus_int length, /* I Length of input signal */
183 const opus_int Order /* I LPC order */
184);
185
186/* LTP tap quantizer */
187void silk_quant_LTP_gains_FLP(
188 silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */
189 opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */
190 opus_int8 *periodicity_index, /* O Periodicity index */
191 opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */
192 silk_float *pred_gain_dB, /* O LTP prediction gain */
193 const silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Correlation matrix */
194 const silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* I Correlation vector */
195 const opus_int subfr_len, /* I Number of samples per subframe */
196 const opus_int nb_subfr, /* I Number of subframes */
197 int arch /* I Run-time architecture */
198);
199
200/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */
201silk_float silk_residual_energy_covar_FLP( /* O Weighted residual energy */
202 const silk_float *c, /* I Filter coefficients */
203 silk_float *wXX, /* I/O Weighted correlation matrix, reg. out */
204 const silk_float *wXx, /* I Weighted correlation vector */
205 const silk_float wxx, /* I Weighted correlation value */
206 const opus_int D /* I Dimension */
207);
208
209/* Processing of gains */
210void silk_process_gains_FLP(
211 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
212 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
213 opus_int condCoding /* I The type of conditional coding to use */
214);
215
216/******************/
217/* Linear Algebra */
218/******************/
219/* Calculates correlation matrix X'*X */
220void silk_corrMatrix_FLP(
221 const silk_float *x, /* I x vector [ L+order-1 ] used to create X */
222 const opus_int L, /* I Length of vectors */
223 const opus_int Order, /* I Max lag for correlation */
224 silk_float *XX /* O X'*X correlation matrix [order x order] */
225);
226
227/* Calculates correlation vector X'*t */
228void silk_corrVector_FLP(
229 const silk_float *x, /* I x vector [L+order-1] used to create X */
230 const silk_float *t, /* I Target vector [L] */
231 const opus_int L, /* I Length of vecors */
232 const opus_int Order, /* I Max lag for correlation */
233 silk_float *Xt /* O X'*t correlation vector [order] */
234);
235
236/* Apply sine window to signal vector. */
237/* Window types: */
238/* 1 -> sine window from 0 to pi/2 */
239/* 2 -> sine window from pi/2 to pi */
240void silk_apply_sine_window_FLP(
241 silk_float px_win[], /* O Pointer to windowed signal */
242 const silk_float px[], /* I Pointer to input signal */
243 const opus_int win_type, /* I Selects a window type */
244 const opus_int length /* I Window length, multiple of 4 */
245);
246
247/* Wrapper functions. Call flp / fix code */
248
249/* Convert AR filter coefficients to NLSF parameters */
250void silk_A2NLSF_FLP(
251 opus_int16 *NLSF_Q15, /* O NLSF vector [ LPC_order ] */
252 const silk_float *pAR, /* I LPC coefficients [ LPC_order ] */
253 const opus_int LPC_order /* I LPC order */
254);
255
256/* Convert NLSF parameters to AR prediction filter coefficients */
257void silk_NLSF2A_FLP(
258 silk_float *pAR, /* O LPC coefficients [ LPC_order ] */
259 const opus_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */
260 const opus_int LPC_order, /* I LPC order */
261 int arch /* I Run-time architecture */
262);
263
264/* Limit, stabilize, and quantize NLSFs */
265void silk_process_NLSFs_FLP(
266 silk_encoder_state *psEncC, /* I/O Encoder state */
267 silk_float PredCoef[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */
268 opus_int16 NLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */
269 const opus_int16 prev_NLSF_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */
270);
271
272/* Floating-point Silk NSQ wrapper */
273void silk_NSQ_wrapper_FLP(
274 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
275 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
276 SideInfoIndices *psIndices, /* I/O Quantization indices */
277 silk_nsq_state *psNSQ, /* I/O Noise Shaping Quantzation state */
278 opus_int8 pulses[], /* O Quantized pulse signal */
279 const silk_float x[] /* I Prefiltered input signal */
280);
281
282#ifdef __cplusplus
283}
284#endif
285
286#endif
diff --git a/lib/rbcodec/codecs/libopus/silk/float/noise_shape_analysis_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/noise_shape_analysis_FLP.c
new file mode 100644
index 0000000000..cb3d8a50b7
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/noise_shape_analysis_FLP.c
@@ -0,0 +1,350 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FLP.h"
33#include "tuning_parameters.h"
34
35/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */
36/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */
37/* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */
38/* coefficient in an array of coefficients, for monic filters. */
39static OPUS_INLINE silk_float warped_gain(
40 const silk_float *coefs,
41 silk_float lambda,
42 opus_int order
43) {
44 opus_int i;
45 silk_float gain;
46
47 lambda = -lambda;
48 gain = coefs[ order - 1 ];
49 for( i = order - 2; i >= 0; i-- ) {
50 gain = lambda * gain + coefs[ i ];
51 }
52 return (silk_float)( 1.0f / ( 1.0f - lambda * gain ) );
53}
54
55/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */
56/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */
57static OPUS_INLINE void warped_true2monic_coefs(
58 silk_float *coefs,
59 silk_float lambda,
60 silk_float limit,
61 opus_int order
62) {
63 opus_int i, iter, ind = 0;
64 silk_float tmp, maxabs, chirp, gain;
65
66 /* Convert to monic coefficients */
67 for( i = order - 1; i > 0; i-- ) {
68 coefs[ i - 1 ] -= lambda * coefs[ i ];
69 }
70 gain = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs[ 0 ] );
71 for( i = 0; i < order; i++ ) {
72 coefs[ i ] *= gain;
73 }
74
75 /* Limit */
76 for( iter = 0; iter < 10; iter++ ) {
77 /* Find maximum absolute value */
78 maxabs = -1.0f;
79 for( i = 0; i < order; i++ ) {
80 tmp = silk_abs_float( coefs[ i ] );
81 if( tmp > maxabs ) {
82 maxabs = tmp;
83 ind = i;
84 }
85 }
86 if( maxabs <= limit ) {
87 /* Coefficients are within range - done */
88 return;
89 }
90
91 /* Convert back to true warped coefficients */
92 for( i = 1; i < order; i++ ) {
93 coefs[ i - 1 ] += lambda * coefs[ i ];
94 }
95 gain = 1.0f / gain;
96 for( i = 0; i < order; i++ ) {
97 coefs[ i ] *= gain;
98 }
99
100 /* Apply bandwidth expansion */
101 chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) );
102 silk_bwexpander_FLP( coefs, order, chirp );
103
104 /* Convert to monic warped coefficients */
105 for( i = order - 1; i > 0; i-- ) {
106 coefs[ i - 1 ] -= lambda * coefs[ i ];
107 }
108 gain = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs[ 0 ] );
109 for( i = 0; i < order; i++ ) {
110 coefs[ i ] *= gain;
111 }
112 }
113 silk_assert( 0 );
114}
115
116static OPUS_INLINE void limit_coefs(
117 silk_float *coefs,
118 silk_float limit,
119 opus_int order
120) {
121 opus_int i, iter, ind = 0;
122 silk_float tmp, maxabs, chirp;
123
124 for( iter = 0; iter < 10; iter++ ) {
125 /* Find maximum absolute value */
126 maxabs = -1.0f;
127 for( i = 0; i < order; i++ ) {
128 tmp = silk_abs_float( coefs[ i ] );
129 if( tmp > maxabs ) {
130 maxabs = tmp;
131 ind = i;
132 }
133 }
134 if( maxabs <= limit ) {
135 /* Coefficients are within range - done */
136 return;
137 }
138
139 /* Apply bandwidth expansion */
140 chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) );
141 silk_bwexpander_FLP( coefs, order, chirp );
142 }
143 silk_assert( 0 );
144}
145
146/* Compute noise shaping coefficients and initial gain values */
147void silk_noise_shape_analysis_FLP(
148 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
149 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
150 const silk_float *pitch_res, /* I LPC residual from pitch analysis */
151 const silk_float *x /* I Input signal [frame_length + la_shape] */
152)
153{
154 silk_shape_state_FLP *psShapeSt = &psEnc->sShape;
155 opus_int k, nSamples, nSegs;
156 silk_float SNR_adj_dB, HarmShapeGain, Tilt;
157 silk_float nrg, log_energy, log_energy_prev, energy_variation;
158 silk_float BWExp, gain_mult, gain_add, strength, b, warping;
159 silk_float x_windowed[ SHAPE_LPC_WIN_MAX ];
160 silk_float auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ];
161 silk_float rc[ MAX_SHAPE_LPC_ORDER + 1 ];
162 const silk_float *x_ptr, *pitch_res_ptr;
163
164 /* Point to start of first LPC analysis block */
165 x_ptr = x - psEnc->sCmn.la_shape;
166
167 /****************/
168 /* GAIN CONTROL */
169 /****************/
170 SNR_adj_dB = psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f );
171
172 /* Input quality is the average of the quality in the lowest two VAD bands */
173 psEncCtrl->input_quality = 0.5f * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] + psEnc->sCmn.input_quality_bands_Q15[ 1 ] ) * ( 1.0f / 32768.0f );
174
175 /* Coding quality level, between 0.0 and 1.0 */
176 psEncCtrl->coding_quality = silk_sigmoid( 0.25f * ( SNR_adj_dB - 20.0f ) );
177
178 if( psEnc->sCmn.useCBR == 0 ) {
179 /* Reduce coding SNR during low speech activity */
180 b = 1.0f - psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f );
181 SNR_adj_dB -= BG_SNR_DECR_dB * psEncCtrl->coding_quality * ( 0.5f + 0.5f * psEncCtrl->input_quality ) * b * b;
182 }
183
184 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
185 /* Reduce gains for periodic signals */
186 SNR_adj_dB += HARM_SNR_INCR_dB * psEnc->LTPCorr;
187 } else {
188 /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */
189 SNR_adj_dB += ( -0.4f * psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) + 6.0f ) * ( 1.0f - psEncCtrl->input_quality );
190 }
191
192 /*************************/
193 /* SPARSENESS PROCESSING */
194 /*************************/
195 /* Set quantizer offset */
196 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
197 /* Initially set to 0; may be overruled in process_gains(..) */
198 psEnc->sCmn.indices.quantOffsetType = 0;
199 } else {
200 /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
201 nSamples = 2 * psEnc->sCmn.fs_kHz;
202 energy_variation = 0.0f;
203 log_energy_prev = 0.0f;
204 pitch_res_ptr = pitch_res;
205 nSegs = silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2;
206 for( k = 0; k < nSegs; k++ ) {
207 nrg = ( silk_float )nSamples + ( silk_float )silk_energy_FLP( pitch_res_ptr, nSamples );
208 log_energy = silk_log2( nrg );
209 if( k > 0 ) {
210 energy_variation += silk_abs_float( log_energy - log_energy_prev );
211 }
212 log_energy_prev = log_energy;
213 pitch_res_ptr += nSamples;
214 }
215
216 /* Set quantization offset depending on sparseness measure */
217 if( energy_variation > ENERGY_VARIATION_THRESHOLD_QNT_OFFSET * (nSegs-1) ) {
218 psEnc->sCmn.indices.quantOffsetType = 0;
219 } else {
220 psEnc->sCmn.indices.quantOffsetType = 1;
221 }
222 }
223
224 /*******************************/
225 /* Control bandwidth expansion */
226 /*******************************/
227 /* More BWE for signals with high prediction gain */
228 strength = FIND_PITCH_WHITE_NOISE_FRACTION * psEncCtrl->predGain; /* between 0.0 and 1.0 */
229 BWExp = BANDWIDTH_EXPANSION / ( 1.0f + strength * strength );
230
231 /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
232 warping = (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f + 0.01f * psEncCtrl->coding_quality;
233
234 /********************************************/
235 /* Compute noise shaping AR coefs and gains */
236 /********************************************/
237 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
238 /* Apply window: sine slope followed by flat part followed by cosine slope */
239 opus_int shift, slope_part, flat_part;
240 flat_part = psEnc->sCmn.fs_kHz * 3;
241 slope_part = ( psEnc->sCmn.shapeWinLength - flat_part ) / 2;
242
243 silk_apply_sine_window_FLP( x_windowed, x_ptr, 1, slope_part );
244 shift = slope_part;
245 silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(silk_float) );
246 shift += flat_part;
247 silk_apply_sine_window_FLP( x_windowed + shift, x_ptr + shift, 2, slope_part );
248
249 /* Update pointer: next LPC analysis block */
250 x_ptr += psEnc->sCmn.subfr_length;
251
252 if( psEnc->sCmn.warping_Q16 > 0 ) {
253 /* Calculate warped auto correlation */
254 silk_warped_autocorrelation_FLP( auto_corr, x_windowed, warping,
255 psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder );
256 } else {
257 /* Calculate regular auto correlation */
258 silk_autocorrelation_FLP( auto_corr, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 );
259 }
260
261 /* Add white noise, as a fraction of energy */
262 auto_corr[ 0 ] += auto_corr[ 0 ] * SHAPE_WHITE_NOISE_FRACTION + 1.0f;
263
264 /* Convert correlations to prediction coefficients, and compute residual energy */
265 nrg = silk_schur_FLP( rc, auto_corr, psEnc->sCmn.shapingLPCOrder );
266 silk_k2a_FLP( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], rc, psEnc->sCmn.shapingLPCOrder );
267 psEncCtrl->Gains[ k ] = ( silk_float )sqrt( nrg );
268
269 if( psEnc->sCmn.warping_Q16 > 0 ) {
270 /* Adjust gain for warping */
271 psEncCtrl->Gains[ k ] *= warped_gain( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], warping, psEnc->sCmn.shapingLPCOrder );
272 }
273
274 /* Bandwidth expansion for synthesis filter shaping */
275 silk_bwexpander_FLP( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp );
276
277 if( psEnc->sCmn.warping_Q16 > 0 ) {
278 /* Convert to monic warped prediction coefficients and limit absolute values */
279 warped_true2monic_coefs( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], warping, 3.999f, psEnc->sCmn.shapingLPCOrder );
280 } else {
281 /* Limit absolute values */
282 limit_coefs( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], 3.999f, psEnc->sCmn.shapingLPCOrder );
283 }
284 }
285
286 /*****************/
287 /* Gain tweaking */
288 /*****************/
289 /* Increase gains during low speech activity */
290 gain_mult = (silk_float)pow( 2.0f, -0.16f * SNR_adj_dB );
291 gain_add = (silk_float)pow( 2.0f, 0.16f * MIN_QGAIN_DB );
292 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
293 psEncCtrl->Gains[ k ] *= gain_mult;
294 psEncCtrl->Gains[ k ] += gain_add;
295 }
296
297 /************************************************/
298 /* Control low-frequency shaping and noise tilt */
299 /************************************************/
300 /* Less low frequency shaping for noisy inputs */
301 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 ) );
302 strength *= psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f );
303 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
304 /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */
305 /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/
306 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
307 b = 0.2f / psEnc->sCmn.fs_kHz + 3.0f / psEncCtrl->pitchL[ k ];
308 psEncCtrl->LF_MA_shp[ k ] = -1.0f + b;
309 psEncCtrl->LF_AR_shp[ k ] = 1.0f - b - b * strength;
310 }
311 Tilt = - HP_NOISE_COEF -
312 (1 - HP_NOISE_COEF) * HARM_HP_NOISE_COEF * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f );
313 } else {
314 b = 1.3f / psEnc->sCmn.fs_kHz;
315 psEncCtrl->LF_MA_shp[ 0 ] = -1.0f + b;
316 psEncCtrl->LF_AR_shp[ 0 ] = 1.0f - b - b * strength * 0.6f;
317 for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) {
318 psEncCtrl->LF_MA_shp[ k ] = psEncCtrl->LF_MA_shp[ 0 ];
319 psEncCtrl->LF_AR_shp[ k ] = psEncCtrl->LF_AR_shp[ 0 ];
320 }
321 Tilt = -HP_NOISE_COEF;
322 }
323
324 /****************************/
325 /* HARMONIC SHAPING CONTROL */
326 /****************************/
327 if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
328 /* Harmonic noise shaping */
329 HarmShapeGain = HARMONIC_SHAPING;
330
331 /* More harmonic noise shaping for high bitrates or noisy input */
332 HarmShapeGain += HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING *
333 ( 1.0f - ( 1.0f - psEncCtrl->coding_quality ) * psEncCtrl->input_quality );
334
335 /* Less harmonic noise shaping for less periodic signals */
336 HarmShapeGain *= ( silk_float )sqrt( psEnc->LTPCorr );
337 } else {
338 HarmShapeGain = 0.0f;
339 }
340
341 /*************************/
342 /* Smooth over subframes */
343 /*************************/
344 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
345 psShapeSt->HarmShapeGain_smth += SUBFR_SMTH_COEF * ( HarmShapeGain - psShapeSt->HarmShapeGain_smth );
346 psEncCtrl->HarmShapeGain[ k ] = psShapeSt->HarmShapeGain_smth;
347 psShapeSt->Tilt_smth += SUBFR_SMTH_COEF * ( Tilt - psShapeSt->Tilt_smth );
348 psEncCtrl->Tilt[ k ] = psShapeSt->Tilt_smth;
349 }
350}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/pitch_analysis_core_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/pitch_analysis_core_FLP.c
new file mode 100644
index 0000000000..f351bc3718
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/pitch_analysis_core_FLP.c
@@ -0,0 +1,630 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32/*****************************************************************************
33* Pitch analyser function
34******************************************************************************/
35#include "SigProc_FLP.h"
36#include "SigProc_FIX.h"
37#include "pitch_est_defines.h"
38#include "pitch.h"
39
40#define SCRATCH_SIZE 22
41
42/************************************************************/
43/* Internally used functions */
44/************************************************************/
45static void silk_P_Ana_calc_corr_st3(
46 silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
47 const silk_float frame[], /* I vector to correlate */
48 opus_int start_lag, /* I start lag */
49 opus_int sf_length, /* I sub frame length */
50 opus_int nb_subfr, /* I number of subframes */
51 opus_int complexity, /* I Complexity setting */
52 int arch /* I Run-time architecture */
53);
54
55static void silk_P_Ana_calc_energy_st3(
56 silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
57 const silk_float frame[], /* I vector to correlate */
58 opus_int start_lag, /* I start lag */
59 opus_int sf_length, /* I sub frame length */
60 opus_int nb_subfr, /* I number of subframes */
61 opus_int complexity /* I Complexity setting */
62);
63
64/************************************************************/
65/* CORE PITCH ANALYSIS FUNCTION */
66/************************************************************/
67opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, 1 unvoiced */
68 const silk_float *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */
69 opus_int *pitch_out, /* O Pitch lag values [nb_subfr] */
70 opus_int16 *lagIndex, /* O Lag Index */
71 opus_int8 *contourIndex, /* O Pitch contour Index */
72 silk_float *LTPCorr, /* I/O Normalized correlation; input: value from previous frame */
73 opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */
74 const silk_float search_thres1, /* I First stage threshold for lag candidates 0 - 1 */
75 const silk_float search_thres2, /* I Final threshold for lag candidates 0 - 1 */
76 const opus_int Fs_kHz, /* I sample frequency (kHz) */
77 const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */
78 const opus_int nb_subfr, /* I Number of 5 ms subframes */
79 int arch /* I Run-time architecture */
80)
81{
82 opus_int i, k, d, j;
83 silk_float frame_8kHz[ PE_MAX_FRAME_LENGTH_MS * 8 ];
84 silk_float frame_4kHz[ PE_MAX_FRAME_LENGTH_MS * 4 ];
85 opus_int16 frame_8_FIX[ PE_MAX_FRAME_LENGTH_MS * 8 ];
86 opus_int16 frame_4_FIX[ PE_MAX_FRAME_LENGTH_MS * 4 ];
87 opus_int32 filt_state[ 6 ];
88 silk_float threshold, contour_bias;
89 silk_float C[ PE_MAX_NB_SUBFR][ (PE_MAX_LAG >> 1) + 5 ];
90 opus_val32 xcorr[ PE_MAX_LAG_MS * 4 - PE_MIN_LAG_MS * 4 + 1 ];
91 silk_float CC[ PE_NB_CBKS_STAGE2_EXT ];
92 const silk_float *target_ptr, *basis_ptr;
93 double cross_corr, normalizer, energy, energy_tmp;
94 opus_int d_srch[ PE_D_SRCH_LENGTH ];
95 opus_int16 d_comp[ (PE_MAX_LAG >> 1) + 5 ];
96 opus_int length_d_srch, length_d_comp;
97 silk_float Cmax, CCmax, CCmax_b, CCmax_new_b, CCmax_new;
98 opus_int CBimax, CBimax_new, lag, start_lag, end_lag, lag_new;
99 opus_int cbk_size;
100 silk_float lag_log2, prevLag_log2, delta_lag_log2_sqr;
101 silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ];
102 silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ];
103 opus_int lag_counter;
104 opus_int frame_length, frame_length_8kHz, frame_length_4kHz;
105 opus_int sf_length, sf_length_8kHz, sf_length_4kHz;
106 opus_int min_lag, min_lag_8kHz, min_lag_4kHz;
107 opus_int max_lag, max_lag_8kHz, max_lag_4kHz;
108 opus_int nb_cbk_search;
109 const opus_int8 *Lag_CB_ptr;
110
111 /* Check for valid sampling frequency */
112 celt_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
113
114 /* Check for valid complexity setting */
115 celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
116 celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
117
118 silk_assert( search_thres1 >= 0.0f && search_thres1 <= 1.0f );
119 silk_assert( search_thres2 >= 0.0f && search_thres2 <= 1.0f );
120
121 /* Set up frame lengths max / min lag for the sampling frequency */
122 frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz;
123 frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4;
124 frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8;
125 sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz;
126 sf_length_4kHz = PE_SUBFR_LENGTH_MS * 4;
127 sf_length_8kHz = PE_SUBFR_LENGTH_MS * 8;
128 min_lag = PE_MIN_LAG_MS * Fs_kHz;
129 min_lag_4kHz = PE_MIN_LAG_MS * 4;
130 min_lag_8kHz = PE_MIN_LAG_MS * 8;
131 max_lag = PE_MAX_LAG_MS * Fs_kHz - 1;
132 max_lag_4kHz = PE_MAX_LAG_MS * 4;
133 max_lag_8kHz = PE_MAX_LAG_MS * 8 - 1;
134
135 /* Resample from input sampled at Fs_kHz to 8 kHz */
136 if( Fs_kHz == 16 ) {
137 /* Resample to 16 -> 8 khz */
138 opus_int16 frame_16_FIX[ 16 * PE_MAX_FRAME_LENGTH_MS ];
139 silk_float2short_array( frame_16_FIX, frame, frame_length );
140 silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );
141 silk_resampler_down2( filt_state, frame_8_FIX, frame_16_FIX, frame_length );
142 silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz );
143 } else if( Fs_kHz == 12 ) {
144 /* Resample to 12 -> 8 khz */
145 opus_int16 frame_12_FIX[ 12 * PE_MAX_FRAME_LENGTH_MS ];
146 silk_float2short_array( frame_12_FIX, frame, frame_length );
147 silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) );
148 silk_resampler_down2_3( filt_state, frame_8_FIX, frame_12_FIX, frame_length );
149 silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz );
150 } else {
151 celt_assert( Fs_kHz == 8 );
152 silk_float2short_array( frame_8_FIX, frame, frame_length_8kHz );
153 }
154
155 /* Decimate again to 4 kHz */
156 silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );
157 silk_resampler_down2( filt_state, frame_4_FIX, frame_8_FIX, frame_length_8kHz );
158 silk_short2float_array( frame_4kHz, frame_4_FIX, frame_length_4kHz );
159
160 /* Low-pass filter */
161 for( i = frame_length_4kHz - 1; i > 0; i-- ) {
162 frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] );
163 }
164
165 /******************************************************************************
166 * FIRST STAGE, operating in 4 khz
167 ******************************************************************************/
168 silk_memset(C, 0, sizeof(silk_float) * nb_subfr * ((PE_MAX_LAG >> 1) + 5));
169 target_ptr = &frame_4kHz[ silk_LSHIFT( sf_length_4kHz, 2 ) ];
170 for( k = 0; k < nb_subfr >> 1; k++ ) {
171 /* Check that we are within range of the array */
172 celt_assert( target_ptr >= frame_4kHz );
173 celt_assert( target_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
174
175 basis_ptr = target_ptr - min_lag_4kHz;
176
177 /* Check that we are within range of the array */
178 celt_assert( basis_ptr >= frame_4kHz );
179 celt_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
180
181 celt_pitch_xcorr( target_ptr, target_ptr-max_lag_4kHz, xcorr, sf_length_8kHz, max_lag_4kHz - min_lag_4kHz + 1, arch );
182
183 /* Calculate first vector products before loop */
184 cross_corr = xcorr[ max_lag_4kHz - min_lag_4kHz ];
185 normalizer = silk_energy_FLP( target_ptr, sf_length_8kHz ) +
186 silk_energy_FLP( basis_ptr, sf_length_8kHz ) +
187 sf_length_8kHz * 4000.0f;
188
189 C[ 0 ][ min_lag_4kHz ] += (silk_float)( 2 * cross_corr / normalizer );
190
191 /* From now on normalizer is computed recursively */
192 for( d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++ ) {
193 basis_ptr--;
194
195 /* Check that we are within range of the array */
196 silk_assert( basis_ptr >= frame_4kHz );
197 silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
198
199 cross_corr = xcorr[ max_lag_4kHz - d ];
200
201 /* Add contribution of new sample and remove contribution from oldest sample */
202 normalizer +=
203 basis_ptr[ 0 ] * (double)basis_ptr[ 0 ] -
204 basis_ptr[ sf_length_8kHz ] * (double)basis_ptr[ sf_length_8kHz ];
205 C[ 0 ][ d ] += (silk_float)( 2 * cross_corr / normalizer );
206 }
207 /* Update target pointer */
208 target_ptr += sf_length_8kHz;
209 }
210
211 /* Apply short-lag bias */
212 for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) {
213 C[ 0 ][ i ] -= C[ 0 ][ i ] * i / 4096.0f;
214 }
215
216 /* Sort */
217 length_d_srch = 4 + 2 * complexity;
218 celt_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
219 silk_insertion_sort_decreasing_FLP( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch );
220
221 /* Escape if correlation is very low already here */
222 Cmax = C[ 0 ][ min_lag_4kHz ];
223 if( Cmax < 0.2f ) {
224 silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) );
225 *LTPCorr = 0.0f;
226 *lagIndex = 0;
227 *contourIndex = 0;
228 return 1;
229 }
230
231 threshold = search_thres1 * Cmax;
232 for( i = 0; i < length_d_srch; i++ ) {
233 /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */
234 if( C[ 0 ][ min_lag_4kHz + i ] > threshold ) {
235 d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + min_lag_4kHz, 1 );
236 } else {
237 length_d_srch = i;
238 break;
239 }
240 }
241 celt_assert( length_d_srch > 0 );
242
243 for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) {
244 d_comp[ i ] = 0;
245 }
246 for( i = 0; i < length_d_srch; i++ ) {
247 d_comp[ d_srch[ i ] ] = 1;
248 }
249
250 /* Convolution */
251 for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {
252 d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ];
253 }
254
255 length_d_srch = 0;
256 for( i = min_lag_8kHz; i < max_lag_8kHz + 1; i++ ) {
257 if( d_comp[ i + 1 ] > 0 ) {
258 d_srch[ length_d_srch ] = i;
259 length_d_srch++;
260 }
261 }
262
263 /* Convolution */
264 for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) {
265 d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ] + d_comp[ i - 3 ];
266 }
267
268 length_d_comp = 0;
269 for( i = min_lag_8kHz; i < max_lag_8kHz + 4; i++ ) {
270 if( d_comp[ i ] > 0 ) {
271 d_comp[ length_d_comp ] = (opus_int16)( i - 2 );
272 length_d_comp++;
273 }
274 }
275
276 /**********************************************************************************
277 ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation
278 *************************************************************************************/
279 /*********************************************************************************
280 * Find energy of each subframe projected onto its history, for a range of delays
281 *********************************************************************************/
282 silk_memset( C, 0, PE_MAX_NB_SUBFR*((PE_MAX_LAG >> 1) + 5) * sizeof(silk_float));
283
284 if( Fs_kHz == 8 ) {
285 target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * 8 ];
286 } else {
287 target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ];
288 }
289 for( k = 0; k < nb_subfr; k++ ) {
290 energy_tmp = silk_energy_FLP( target_ptr, sf_length_8kHz ) + 1.0;
291 for( j = 0; j < length_d_comp; j++ ) {
292 d = d_comp[ j ];
293 basis_ptr = target_ptr - d;
294 cross_corr = silk_inner_product_FLP( basis_ptr, target_ptr, sf_length_8kHz );
295 if( cross_corr > 0.0f ) {
296 energy = silk_energy_FLP( basis_ptr, sf_length_8kHz );
297 C[ k ][ d ] = (silk_float)( 2 * cross_corr / ( energy + energy_tmp ) );
298 } else {
299 C[ k ][ d ] = 0.0f;
300 }
301 }
302 target_ptr += sf_length_8kHz;
303 }
304
305 /* search over lag range and lags codebook */
306 /* scale factor for lag codebook, as a function of center lag */
307
308 CCmax = 0.0f; /* This value doesn't matter */
309 CCmax_b = -1000.0f;
310
311 CBimax = 0; /* To avoid returning undefined lag values */
312 lag = -1; /* To check if lag with strong enough correlation has been found */
313
314 if( prevLag > 0 ) {
315 if( Fs_kHz == 12 ) {
316 prevLag = silk_LSHIFT( prevLag, 1 ) / 3;
317 } else if( Fs_kHz == 16 ) {
318 prevLag = silk_RSHIFT( prevLag, 1 );
319 }
320 prevLag_log2 = silk_log2( (silk_float)prevLag );
321 } else {
322 prevLag_log2 = 0;
323 }
324
325 /* Set up stage 2 codebook based on number of subframes */
326 if( nb_subfr == PE_MAX_NB_SUBFR ) {
327 cbk_size = PE_NB_CBKS_STAGE2_EXT;
328 Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];
329 if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) {
330 /* If input is 8 khz use a larger codebook here because it is last stage */
331 nb_cbk_search = PE_NB_CBKS_STAGE2_EXT;
332 } else {
333 nb_cbk_search = PE_NB_CBKS_STAGE2;
334 }
335 } else {
336 cbk_size = PE_NB_CBKS_STAGE2_10MS;
337 Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ];
338 nb_cbk_search = PE_NB_CBKS_STAGE2_10MS;
339 }
340
341 for( k = 0; k < length_d_srch; k++ ) {
342 d = d_srch[ k ];
343 for( j = 0; j < nb_cbk_search; j++ ) {
344 CC[j] = 0.0f;
345 for( i = 0; i < nb_subfr; i++ ) {
346 /* Try all codebooks */
347 CC[ j ] += C[ i ][ d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size )];
348 }
349 }
350 /* Find best codebook */
351 CCmax_new = -1000.0f;
352 CBimax_new = 0;
353 for( i = 0; i < nb_cbk_search; i++ ) {
354 if( CC[ i ] > CCmax_new ) {
355 CCmax_new = CC[ i ];
356 CBimax_new = i;
357 }
358 }
359
360 /* Bias towards shorter lags */
361 lag_log2 = silk_log2( (silk_float)d );
362 CCmax_new_b = CCmax_new - PE_SHORTLAG_BIAS * nb_subfr * lag_log2;
363
364 /* Bias towards previous lag */
365 if( prevLag > 0 ) {
366 delta_lag_log2_sqr = lag_log2 - prevLag_log2;
367 delta_lag_log2_sqr *= delta_lag_log2_sqr;
368 CCmax_new_b -= PE_PREVLAG_BIAS * nb_subfr * (*LTPCorr) * delta_lag_log2_sqr / ( delta_lag_log2_sqr + 0.5f );
369 }
370
371 if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */
372 CCmax_new > nb_subfr * search_thres2 /* Correlation needs to be high enough to be voiced */
373 ) {
374 CCmax_b = CCmax_new_b;
375 CCmax = CCmax_new;
376 lag = d;
377 CBimax = CBimax_new;
378 }
379 }
380
381 if( lag == -1 ) {
382 /* No suitable candidate found */
383 silk_memset( pitch_out, 0, PE_MAX_NB_SUBFR * sizeof(opus_int) );
384 *LTPCorr = 0.0f;
385 *lagIndex = 0;
386 *contourIndex = 0;
387 return 1;
388 }
389
390 /* Output normalized correlation */
391 *LTPCorr = (silk_float)( CCmax / nb_subfr );
392 silk_assert( *LTPCorr >= 0.0f );
393
394 if( Fs_kHz > 8 ) {
395 /* Search in original signal */
396
397 /* Compensate for decimation */
398 silk_assert( lag == silk_SAT16( lag ) );
399 if( Fs_kHz == 12 ) {
400 lag = silk_RSHIFT_ROUND( silk_SMULBB( lag, 3 ), 1 );
401 } else { /* Fs_kHz == 16 */
402 lag = silk_LSHIFT( lag, 1 );
403 }
404
405 lag = silk_LIMIT_int( lag, min_lag, max_lag );
406 start_lag = silk_max_int( lag - 2, min_lag );
407 end_lag = silk_min_int( lag + 2, max_lag );
408 lag_new = lag; /* to avoid undefined lag */
409 CBimax = 0; /* to avoid undefined lag */
410
411 CCmax = -1000.0f;
412
413 /* Calculate the correlations and energies needed in stage 3 */
414 silk_P_Ana_calc_corr_st3( cross_corr_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch );
415 silk_P_Ana_calc_energy_st3( energies_st3, frame, start_lag, sf_length, nb_subfr, complexity );
416
417 lag_counter = 0;
418 silk_assert( lag == silk_SAT16( lag ) );
419 contour_bias = PE_FLATCONTOUR_BIAS / lag;
420
421 /* Set up cbk parameters according to complexity setting and frame length */
422 if( nb_subfr == PE_MAX_NB_SUBFR ) {
423 nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ];
424 cbk_size = PE_NB_CBKS_STAGE3_MAX;
425 Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
426 } else {
427 nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
428 cbk_size = PE_NB_CBKS_STAGE3_10MS;
429 Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
430 }
431
432 target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ];
433 energy_tmp = silk_energy_FLP( target_ptr, nb_subfr * sf_length ) + 1.0;
434 for( d = start_lag; d <= end_lag; d++ ) {
435 for( j = 0; j < nb_cbk_search; j++ ) {
436 cross_corr = 0.0;
437 energy = energy_tmp;
438 for( k = 0; k < nb_subfr; k++ ) {
439 cross_corr += cross_corr_st3[ k ][ j ][ lag_counter ];
440 energy += energies_st3[ k ][ j ][ lag_counter ];
441 }
442 if( cross_corr > 0.0 ) {
443 CCmax_new = (silk_float)( 2 * cross_corr / energy );
444 /* Reduce depending on flatness of contour */
445 CCmax_new *= 1.0f - contour_bias * j;
446 } else {
447 CCmax_new = 0.0f;
448 }
449
450 if( CCmax_new > CCmax && ( d + (opus_int)silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) {
451 CCmax = CCmax_new;
452 lag_new = d;
453 CBimax = j;
454 }
455 }
456 lag_counter++;
457 }
458
459 for( k = 0; k < nb_subfr; k++ ) {
460 pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
461 pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz );
462 }
463 *lagIndex = (opus_int16)( lag_new - min_lag );
464 *contourIndex = (opus_int8)CBimax;
465 } else { /* Fs_kHz == 8 */
466 /* Save Lags */
467 for( k = 0; k < nb_subfr; k++ ) {
468 pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size );
469 pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag_8kHz, PE_MAX_LAG_MS * 8 );
470 }
471 *lagIndex = (opus_int16)( lag - min_lag_8kHz );
472 *contourIndex = (opus_int8)CBimax;
473 }
474 celt_assert( *lagIndex >= 0 );
475 /* return as voiced */
476 return 0;
477}
478
479/***********************************************************************
480 * Calculates the correlations used in stage 3 search. In order to cover
481 * the whole lag codebook for all the searched offset lags (lag +- 2),
482 * the following correlations are needed in each sub frame:
483 *
484 * sf1: lag range [-8,...,7] total 16 correlations
485 * sf2: lag range [-4,...,4] total 9 correlations
486 * sf3: lag range [-3,....4] total 8 correltions
487 * sf4: lag range [-6,....8] total 15 correlations
488 *
489 * In total 48 correlations. The direct implementation computed in worst
490 * case 4*12*5 = 240 correlations, but more likely around 120.
491 ***********************************************************************/
492static void silk_P_Ana_calc_corr_st3(
493 silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
494 const silk_float frame[], /* I vector to correlate */
495 opus_int start_lag, /* I start lag */
496 opus_int sf_length, /* I sub frame length */
497 opus_int nb_subfr, /* I number of subframes */
498 opus_int complexity, /* I Complexity setting */
499 int arch /* I Run-time architecture */
500)
501{
502 const silk_float *target_ptr;
503 opus_int i, j, k, lag_counter, lag_low, lag_high;
504 opus_int nb_cbk_search, delta, idx, cbk_size;
505 silk_float scratch_mem[ SCRATCH_SIZE ];
506 opus_val32 xcorr[ SCRATCH_SIZE ];
507 const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
508
509 celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
510 celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
511
512 if( nb_subfr == PE_MAX_NB_SUBFR ) {
513 Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
514 Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
515 nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
516 cbk_size = PE_NB_CBKS_STAGE3_MAX;
517 } else {
518 celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
519 Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
520 Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
521 nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
522 cbk_size = PE_NB_CBKS_STAGE3_10MS;
523 }
524
525 target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */
526 for( k = 0; k < nb_subfr; k++ ) {
527 lag_counter = 0;
528
529 /* Calculate the correlations for each subframe */
530 lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 );
531 lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 );
532 silk_assert(lag_high-lag_low+1 <= SCRATCH_SIZE);
533 celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr, sf_length, lag_high - lag_low + 1, arch );
534 for( j = lag_low; j <= lag_high; j++ ) {
535 silk_assert( lag_counter < SCRATCH_SIZE );
536 scratch_mem[ lag_counter ] = xcorr[ lag_high - j ];
537 lag_counter++;
538 }
539
540 delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );
541 for( i = 0; i < nb_cbk_search; i++ ) {
542 /* Fill out the 3 dim array that stores the correlations for */
543 /* each code_book vector for each start lag */
544 idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;
545 for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
546 silk_assert( idx + j < SCRATCH_SIZE );
547 silk_assert( idx + j < lag_counter );
548 cross_corr_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];
549 }
550 }
551 target_ptr += sf_length;
552 }
553}
554
555/********************************************************************/
556/* Calculate the energies for first two subframes. The energies are */
557/* calculated recursively. */
558/********************************************************************/
559static void silk_P_Ana_calc_energy_st3(
560 silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */
561 const silk_float frame[], /* I vector to correlate */
562 opus_int start_lag, /* I start lag */
563 opus_int sf_length, /* I sub frame length */
564 opus_int nb_subfr, /* I number of subframes */
565 opus_int complexity /* I Complexity setting */
566)
567{
568 const silk_float *target_ptr, *basis_ptr;
569 double energy;
570 opus_int k, i, j, lag_counter;
571 opus_int nb_cbk_search, delta, idx, cbk_size, lag_diff;
572 silk_float scratch_mem[ SCRATCH_SIZE ];
573 const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
574
575 celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
576 celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
577
578 if( nb_subfr == PE_MAX_NB_SUBFR ) {
579 Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
580 Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
581 nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
582 cbk_size = PE_NB_CBKS_STAGE3_MAX;
583 } else {
584 celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
585 Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
586 Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
587 nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
588 cbk_size = PE_NB_CBKS_STAGE3_10MS;
589 }
590
591 target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ];
592 for( k = 0; k < nb_subfr; k++ ) {
593 lag_counter = 0;
594
595 /* Calculate the energy for first lag */
596 basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) );
597 energy = silk_energy_FLP( basis_ptr, sf_length ) + 1e-3;
598 silk_assert( energy >= 0.0 );
599 scratch_mem[lag_counter] = (silk_float)energy;
600 lag_counter++;
601
602 lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) - matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 );
603 for( i = 1; i < lag_diff; i++ ) {
604 /* remove part outside new window */
605 energy -= basis_ptr[sf_length - i] * (double)basis_ptr[sf_length - i];
606 silk_assert( energy >= 0.0 );
607
608 /* add part that comes into window */
609 energy += basis_ptr[ -i ] * (double)basis_ptr[ -i ];
610 silk_assert( energy >= 0.0 );
611 silk_assert( lag_counter < SCRATCH_SIZE );
612 scratch_mem[lag_counter] = (silk_float)energy;
613 lag_counter++;
614 }
615
616 delta = matrix_ptr( Lag_range_ptr, k, 0, 2 );
617 for( i = 0; i < nb_cbk_search; i++ ) {
618 /* Fill out the 3 dim array that stores the correlations for */
619 /* each code_book vector for each start lag */
620 idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta;
621 for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) {
622 silk_assert( idx + j < SCRATCH_SIZE );
623 silk_assert( idx + j < lag_counter );
624 energies_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ];
625 silk_assert( energies_st3[ k ][ i ][ j ] >= 0.0f );
626 }
627 }
628 target_ptr += sf_length;
629 }
630}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/process_gains_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/process_gains_FLP.c
new file mode 100644
index 0000000000..c0da0dae44
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/process_gains_FLP.c
@@ -0,0 +1,103 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FLP.h"
33#include "tuning_parameters.h"
34
35/* Processing of gains */
36void silk_process_gains_FLP(
37 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
38 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
39 opus_int condCoding /* I The type of conditional coding to use */
40)
41{
42 silk_shape_state_FLP *psShapeSt = &psEnc->sShape;
43 opus_int k;
44 opus_int32 pGains_Q16[ MAX_NB_SUBFR ];
45 silk_float s, InvMaxSqrVal, gain, quant_offset;
46
47 /* Gain reduction when LTP coding gain is high */
48 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
49 s = 1.0f - 0.5f * silk_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) );
50 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
51 psEncCtrl->Gains[ k ] *= s;
52 }
53 }
54
55 /* Limit the quantized signal */
56 InvMaxSqrVal = ( silk_float )( pow( 2.0f, 0.33f * ( 21.0f - psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) ) ) / psEnc->sCmn.subfr_length );
57
58 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
59 /* Soft limit on ratio residual energy and squared gains */
60 gain = psEncCtrl->Gains[ k ];
61 gain = ( silk_float )sqrt( gain * gain + psEncCtrl->ResNrg[ k ] * InvMaxSqrVal );
62 psEncCtrl->Gains[ k ] = silk_min_float( gain, 32767.0f );
63 }
64
65 /* Prepare gains for noise shaping quantization */
66 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
67 pGains_Q16[ k ] = (opus_int32)( psEncCtrl->Gains[ k ] * 65536.0f );
68 }
69
70 /* Save unquantized gains and gain Index */
71 silk_memcpy( psEncCtrl->GainsUnq_Q16, pGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
72 psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex;
73
74 /* Quantize gains */
75 silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16,
76 &psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
77
78 /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */
79 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
80 psEncCtrl->Gains[ k ] = pGains_Q16[ k ] / 65536.0f;
81 }
82
83 /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */
84 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
85 if( psEncCtrl->LTPredCodGain + psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f ) > 1.0f ) {
86 psEnc->sCmn.indices.quantOffsetType = 0;
87 } else {
88 psEnc->sCmn.indices.quantOffsetType = 1;
89 }
90 }
91
92 /* Quantizer boundary adjustment */
93 quant_offset = silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ] / 1024.0f;
94 psEncCtrl->Lambda = LAMBDA_OFFSET
95 + LAMBDA_DELAYED_DECISIONS * psEnc->sCmn.nStatesDelayedDecision
96 + LAMBDA_SPEECH_ACT * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f )
97 + LAMBDA_INPUT_QUALITY * psEncCtrl->input_quality
98 + LAMBDA_CODING_QUALITY * psEncCtrl->coding_quality
99 + LAMBDA_QUANT_OFFSET * quant_offset;
100
101 silk_assert( psEncCtrl->Lambda > 0.0f );
102 silk_assert( psEncCtrl->Lambda < 2.0f );
103}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/regularize_correlations_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/regularize_correlations_FLP.c
new file mode 100644
index 0000000000..df4612604c
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/regularize_correlations_FLP.c
@@ -0,0 +1,48 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FLP.h"
33
34/* Add noise to matrix diagonal */
35void silk_regularize_correlations_FLP(
36 silk_float *XX, /* I/O Correlation matrices */
37 silk_float *xx, /* I/O Correlation values */
38 const silk_float noise, /* I Noise energy to add */
39 const opus_int D /* I Dimension of XX */
40)
41{
42 opus_int i;
43
44 for( i = 0; i < D; i++ ) {
45 matrix_ptr( &XX[ 0 ], i, i, D ) += noise;
46 }
47 xx[ 0 ] += noise;
48}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/residual_energy_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/residual_energy_FLP.c
new file mode 100644
index 0000000000..1bd07b33a4
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/residual_energy_FLP.c
@@ -0,0 +1,117 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FLP.h"
33
34#define MAX_ITERATIONS_RESIDUAL_NRG 10
35#define REGULARIZATION_FACTOR 1e-8f
36
37/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */
38silk_float silk_residual_energy_covar_FLP( /* O Weighted residual energy */
39 const silk_float *c, /* I Filter coefficients */
40 silk_float *wXX, /* I/O Weighted correlation matrix, reg. out */
41 const silk_float *wXx, /* I Weighted correlation vector */
42 const silk_float wxx, /* I Weighted correlation value */
43 const opus_int D /* I Dimension */
44)
45{
46 opus_int i, j, k;
47 silk_float tmp, nrg = 0.0f, regularization;
48
49 /* Safety checks */
50 celt_assert( D >= 0 );
51
52 regularization = REGULARIZATION_FACTOR * ( wXX[ 0 ] + wXX[ D * D - 1 ] );
53 for( k = 0; k < MAX_ITERATIONS_RESIDUAL_NRG; k++ ) {
54 nrg = wxx;
55
56 tmp = 0.0f;
57 for( i = 0; i < D; i++ ) {
58 tmp += wXx[ i ] * c[ i ];
59 }
60 nrg -= 2.0f * tmp;
61
62 /* compute c' * wXX * c, assuming wXX is symmetric */
63 for( i = 0; i < D; i++ ) {
64 tmp = 0.0f;
65 for( j = i + 1; j < D; j++ ) {
66 tmp += matrix_c_ptr( wXX, i, j, D ) * c[ j ];
67 }
68 nrg += c[ i ] * ( 2.0f * tmp + matrix_c_ptr( wXX, i, i, D ) * c[ i ] );
69 }
70 if( nrg > 0 ) {
71 break;
72 } else {
73 /* Add white noise */
74 for( i = 0; i < D; i++ ) {
75 matrix_c_ptr( wXX, i, i, D ) += regularization;
76 }
77 /* Increase noise for next run */
78 regularization *= 2.0f;
79 }
80 }
81 if( k == MAX_ITERATIONS_RESIDUAL_NRG ) {
82 silk_assert( nrg == 0 );
83 nrg = 1.0f;
84 }
85
86 return nrg;
87}
88
89/* Calculates residual energies of input subframes where all subframes have LPC_order */
90/* of preceding samples */
91void silk_residual_energy_FLP(
92 silk_float nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */
93 const silk_float x[], /* I Input signal */
94 silk_float a[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */
95 const silk_float gains[], /* I Quantization gains */
96 const opus_int subfr_length, /* I Subframe length */
97 const opus_int nb_subfr, /* I number of subframes */
98 const opus_int LPC_order /* I LPC order */
99)
100{
101 opus_int shift;
102 silk_float *LPC_res_ptr, LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ];
103
104 LPC_res_ptr = LPC_res + LPC_order;
105 shift = LPC_order + subfr_length;
106
107 /* Filter input to create the LPC residual for each frame half, and measure subframe energies */
108 silk_LPC_analysis_filter_FLP( LPC_res, a[ 0 ], x + 0 * shift, 2 * shift, LPC_order );
109 nrgs[ 0 ] = ( silk_float )( gains[ 0 ] * gains[ 0 ] * silk_energy_FLP( LPC_res_ptr + 0 * shift, subfr_length ) );
110 nrgs[ 1 ] = ( silk_float )( gains[ 1 ] * gains[ 1 ] * silk_energy_FLP( LPC_res_ptr + 1 * shift, subfr_length ) );
111
112 if( nb_subfr == MAX_NB_SUBFR ) {
113 silk_LPC_analysis_filter_FLP( LPC_res, a[ 1 ], x + 2 * shift, 2 * shift, LPC_order );
114 nrgs[ 2 ] = ( silk_float )( gains[ 2 ] * gains[ 2 ] * silk_energy_FLP( LPC_res_ptr + 0 * shift, subfr_length ) );
115 nrgs[ 3 ] = ( silk_float )( gains[ 3 ] * gains[ 3 ] * silk_energy_FLP( LPC_res_ptr + 1 * shift, subfr_length ) );
116 }
117}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/scale_copy_vector_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/scale_copy_vector_FLP.c
new file mode 100644
index 0000000000..20db32b3b1
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/scale_copy_vector_FLP.c
@@ -0,0 +1,57 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FLP.h"
33
34/* copy and multiply a vector by a constant */
35void silk_scale_copy_vector_FLP(
36 silk_float *data_out,
37 const silk_float *data_in,
38 silk_float gain,
39 opus_int dataSize
40)
41{
42 opus_int i, dataSize4;
43
44 /* 4x unrolled loop */
45 dataSize4 = dataSize & 0xFFFC;
46 for( i = 0; i < dataSize4; i += 4 ) {
47 data_out[ i + 0 ] = gain * data_in[ i + 0 ];
48 data_out[ i + 1 ] = gain * data_in[ i + 1 ];
49 data_out[ i + 2 ] = gain * data_in[ i + 2 ];
50 data_out[ i + 3 ] = gain * data_in[ i + 3 ];
51 }
52
53 /* any remaining elements */
54 for( ; i < dataSize; i++ ) {
55 data_out[ i ] = gain * data_in[ i ];
56 }
57}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/scale_vector_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/scale_vector_FLP.c
new file mode 100644
index 0000000000..108fdcbed5
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/scale_vector_FLP.c
@@ -0,0 +1,56 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FLP.h"
33
34/* multiply a vector by a constant */
35void silk_scale_vector_FLP(
36 silk_float *data1,
37 silk_float gain,
38 opus_int dataSize
39)
40{
41 opus_int i, dataSize4;
42
43 /* 4x unrolled loop */
44 dataSize4 = dataSize & 0xFFFC;
45 for( i = 0; i < dataSize4; i += 4 ) {
46 data1[ i + 0 ] *= gain;
47 data1[ i + 1 ] *= gain;
48 data1[ i + 2 ] *= gain;
49 data1[ i + 3 ] *= gain;
50 }
51
52 /* any remaining elements */
53 for( ; i < dataSize; i++ ) {
54 data1[ i ] *= gain;
55 }
56}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/schur_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/schur_FLP.c
new file mode 100644
index 0000000000..8526c748d3
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/schur_FLP.c
@@ -0,0 +1,70 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FLP.h"
33
34silk_float silk_schur_FLP( /* O returns residual energy */
35 silk_float refl_coef[], /* O reflection coefficients (length order) */
36 const silk_float auto_corr[], /* I autocorrelation sequence (length order+1) */
37 opus_int order /* I order */
38)
39{
40 opus_int k, n;
41 double C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
42 double Ctmp1, Ctmp2, rc_tmp;
43
44 celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
45
46 /* Copy correlations */
47 k = 0;
48 do {
49 C[ k ][ 0 ] = C[ k ][ 1 ] = auto_corr[ k ];
50 } while( ++k <= order );
51
52 for( k = 0; k < order; k++ ) {
53 /* Get reflection coefficient */
54 rc_tmp = -C[ k + 1 ][ 0 ] / silk_max_float( C[ 0 ][ 1 ], 1e-9f );
55
56 /* Save the output */
57 refl_coef[ k ] = (silk_float)rc_tmp;
58
59 /* Update correlations */
60 for( n = 0; n < order - k; n++ ) {
61 Ctmp1 = C[ n + k + 1 ][ 0 ];
62 Ctmp2 = C[ n ][ 1 ];
63 C[ n + k + 1 ][ 0 ] = Ctmp1 + Ctmp2 * rc_tmp;
64 C[ n ][ 1 ] = Ctmp2 + Ctmp1 * rc_tmp;
65 }
66 }
67
68 /* Return residual energy */
69 return (silk_float)C[ 0 ][ 1 ];
70}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/sort_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/sort_FLP.c
new file mode 100644
index 0000000000..0e18f31950
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/sort_FLP.c
@@ -0,0 +1,83 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32/* Insertion sort (fast for already almost sorted arrays): */
33/* Best case: O(n) for an already sorted array */
34/* Worst case: O(n^2) for an inversely sorted array */
35
36#include "typedef.h"
37#include "SigProc_FLP.h"
38
39void silk_insertion_sort_decreasing_FLP(
40 silk_float *a, /* I/O Unsorted / Sorted vector */
41 opus_int *idx, /* O Index vector for the sorted elements */
42 const opus_int L, /* I Vector length */
43 const opus_int K /* I Number of correctly sorted positions */
44)
45{
46 silk_float value;
47 opus_int i, j;
48
49 /* Safety checks */
50 celt_assert( K > 0 );
51 celt_assert( L > 0 );
52 celt_assert( L >= K );
53
54 /* Write start indices in index vector */
55 for( i = 0; i < K; i++ ) {
56 idx[ i ] = i;
57 }
58
59 /* Sort vector elements by value, decreasing order */
60 for( i = 1; i < K; i++ ) {
61 value = a[ i ];
62 for( j = i - 1; ( j >= 0 ) && ( value > a[ j ] ); j-- ) {
63 a[ j + 1 ] = a[ j ]; /* Shift value */
64 idx[ j + 1 ] = idx[ j ]; /* Shift index */
65 }
66 a[ j + 1 ] = value; /* Write value */
67 idx[ j + 1 ] = i; /* Write index */
68 }
69
70 /* If less than L values are asked check the remaining values, */
71 /* but only spend CPU to ensure that the K first values are correct */
72 for( i = K; i < L; i++ ) {
73 value = a[ i ];
74 if( value > a[ K - 1 ] ) {
75 for( j = K - 2; ( j >= 0 ) && ( value > a[ j ] ); j-- ) {
76 a[ j + 1 ] = a[ j ]; /* Shift value */
77 idx[ j + 1 ] = idx[ j ]; /* Shift index */
78 }
79 a[ j + 1 ] = value; /* Write value */
80 idx[ j + 1 ] = i; /* Write index */
81 }
82 }
83}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/structs_FLP.h b/lib/rbcodec/codecs/libopus/silk/float/structs_FLP.h
new file mode 100644
index 0000000000..3150b386e4
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/structs_FLP.h
@@ -0,0 +1,112 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef SILK_STRUCTS_FLP_H
29#define SILK_STRUCTS_FLP_H
30
31#include "typedef.h"
32#include "main.h"
33#include "structs.h"
34
35#ifdef __cplusplus
36extern "C"
37{
38#endif
39
40/********************************/
41/* Noise shaping analysis state */
42/********************************/
43typedef struct {
44 opus_int8 LastGainIndex;
45 silk_float HarmShapeGain_smth;
46 silk_float Tilt_smth;
47} silk_shape_state_FLP;
48
49/********************************/
50/* Encoder state FLP */
51/********************************/
52typedef struct {
53 silk_encoder_state sCmn; /* Common struct, shared with fixed-point code */
54 silk_shape_state_FLP sShape; /* Noise shaping state */
55
56 /* Buffer for find pitch and noise shape analysis */
57 silk_float x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */
58 silk_float LTPCorr; /* Normalized correlation from pitch lag estimator */
59} silk_encoder_state_FLP;
60
61/************************/
62/* Encoder control FLP */
63/************************/
64typedef struct {
65 /* Prediction and coding parameters */
66 silk_float Gains[ MAX_NB_SUBFR ];
67 silk_float PredCoef[ 2 ][ MAX_LPC_ORDER ]; /* holds interpolated and final coefficients */
68 silk_float LTPCoef[LTP_ORDER * MAX_NB_SUBFR];
69 silk_float LTP_scale;
70 opus_int pitchL[ MAX_NB_SUBFR ];
71
72 /* Noise shaping parameters */
73 silk_float AR[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
74 silk_float LF_MA_shp[ MAX_NB_SUBFR ];
75 silk_float LF_AR_shp[ MAX_NB_SUBFR ];
76 silk_float Tilt[ MAX_NB_SUBFR ];
77 silk_float HarmShapeGain[ MAX_NB_SUBFR ];
78 silk_float Lambda;
79 silk_float input_quality;
80 silk_float coding_quality;
81
82 /* Measures */
83 silk_float predGain;
84 silk_float LTPredCodGain;
85 silk_float ResNrg[ MAX_NB_SUBFR ]; /* Residual energy per subframe */
86
87 /* Parameters for CBR mode */
88 opus_int32 GainsUnq_Q16[ MAX_NB_SUBFR ];
89 opus_int8 lastGainIndexPrev;
90} silk_encoder_control_FLP;
91
92/************************/
93/* Encoder Super Struct */
94/************************/
95typedef struct {
96 silk_encoder_state_FLP state_Fxx[ ENCODER_NUM_CHANNELS ];
97 stereo_enc_state sStereo;
98 opus_int32 nBitsUsedLBRR;
99 opus_int32 nBitsExceeded;
100 opus_int nChannelsAPI;
101 opus_int nChannelsInternal;
102 opus_int nPrevChannelsInternal;
103 opus_int timeSinceSwitchAllowed_ms;
104 opus_int allowBandwidthSwitch;
105 opus_int prev_decode_only_middle;
106} silk_encoder;
107
108#ifdef __cplusplus
109}
110#endif
111
112#endif
diff --git a/lib/rbcodec/codecs/libopus/silk/float/warped_autocorrelation_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/warped_autocorrelation_FLP.c
new file mode 100644
index 0000000000..09186e73d4
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/warped_autocorrelation_FLP.c
@@ -0,0 +1,73 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FLP.h"
33
34/* Autocorrelations for a warped frequency axis */
35void silk_warped_autocorrelation_FLP(
36 silk_float *corr, /* O Result [order + 1] */
37 const silk_float *input, /* I Input data to correlate */
38 const silk_float warping, /* I Warping coefficient */
39 const opus_int length, /* I Length of input */
40 const opus_int order /* I Correlation order (even) */
41)
42{
43 opus_int n, i;
44 double tmp1, tmp2;
45 double state[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
46 double C[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
47
48 /* Order must be even */
49 celt_assert( ( order & 1 ) == 0 );
50
51 /* Loop over samples */
52 for( n = 0; n < length; n++ ) {
53 tmp1 = input[ n ];
54 /* Loop over allpass sections */
55 for( i = 0; i < order; i += 2 ) {
56 /* Output of allpass section */
57 tmp2 = state[ i ] + warping * ( state[ i + 1 ] - tmp1 );
58 state[ i ] = tmp1;
59 C[ i ] += state[ 0 ] * tmp1;
60 /* Output of allpass section */
61 tmp1 = state[ i + 1 ] + warping * ( state[ i + 2 ] - tmp2 );
62 state[ i + 1 ] = tmp2;
63 C[ i + 1 ] += state[ 0 ] * tmp2;
64 }
65 state[ order ] = tmp1;
66 C[ order ] += state[ 0 ] * tmp1;
67 }
68
69 /* Copy correlations in silk_float output format */
70 for( i = 0; i < order + 1; i++ ) {
71 corr[ i ] = ( silk_float )C[ i ];
72 }
73}
diff --git a/lib/rbcodec/codecs/libopus/silk/float/wrappers_FLP.c b/lib/rbcodec/codecs/libopus/silk/float/wrappers_FLP.c
new file mode 100644
index 0000000000..ad90b874a4
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/float/wrappers_FLP.c
@@ -0,0 +1,207 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main_FLP.h"
33
34/* Wrappers. Calls flp / fix code */
35
36/* Convert AR filter coefficients to NLSF parameters */
37void silk_A2NLSF_FLP(
38 opus_int16 *NLSF_Q15, /* O NLSF vector [ LPC_order ] */
39 const silk_float *pAR, /* I LPC coefficients [ LPC_order ] */
40 const opus_int LPC_order /* I LPC order */
41)
42{
43 opus_int i;
44 opus_int32 a_fix_Q16[ MAX_LPC_ORDER ];
45
46 for( i = 0; i < LPC_order; i++ ) {
47 a_fix_Q16[ i ] = silk_float2int( pAR[ i ] * 65536.0f );
48 }
49
50 silk_A2NLSF( NLSF_Q15, a_fix_Q16, LPC_order );
51}
52
53/* Convert LSF parameters to AR prediction filter coefficients */
54void silk_NLSF2A_FLP(
55 silk_float *pAR, /* O LPC coefficients [ LPC_order ] */
56 const opus_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */
57 const opus_int LPC_order, /* I LPC order */
58 int arch /* I Run-time architecture */
59)
60{
61 opus_int i;
62 opus_int16 a_fix_Q12[ MAX_LPC_ORDER ];
63
64 silk_NLSF2A( a_fix_Q12, NLSF_Q15, LPC_order, arch );
65
66 for( i = 0; i < LPC_order; i++ ) {
67 pAR[ i ] = ( silk_float )a_fix_Q12[ i ] * ( 1.0f / 4096.0f );
68 }
69}
70
71/******************************************/
72/* Floating-point NLSF processing wrapper */
73/******************************************/
74void silk_process_NLSFs_FLP(
75 silk_encoder_state *psEncC, /* I/O Encoder state */
76 silk_float PredCoef[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */
77 opus_int16 NLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */
78 const opus_int16 prev_NLSF_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */
79)
80{
81 opus_int i, j;
82 opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];
83
84 silk_process_NLSFs( psEncC, PredCoef_Q12, NLSF_Q15, prev_NLSF_Q15);
85
86 for( j = 0; j < 2; j++ ) {
87 for( i = 0; i < psEncC->predictLPCOrder; i++ ) {
88 PredCoef[ j ][ i ] = ( silk_float )PredCoef_Q12[ j ][ i ] * ( 1.0f / 4096.0f );
89 }
90 }
91}
92
93/****************************************/
94/* Floating-point Silk NSQ wrapper */
95/****************************************/
96void silk_NSQ_wrapper_FLP(
97 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
98 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
99 SideInfoIndices *psIndices, /* I/O Quantization indices */
100 silk_nsq_state *psNSQ, /* I/O Noise Shaping Quantzation state */
101 opus_int8 pulses[], /* O Quantized pulse signal */
102 const silk_float x[] /* I Prefiltered input signal */
103)
104{
105 opus_int i, j;
106 opus_int16 x16[ MAX_FRAME_LENGTH ];
107 opus_int32 Gains_Q16[ MAX_NB_SUBFR ];
108 silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];
109 opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ];
110 opus_int LTP_scale_Q14;
111
112 /* Noise shaping parameters */
113 opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
114 opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */
115 opus_int Lambda_Q10;
116 opus_int Tilt_Q14[ MAX_NB_SUBFR ];
117 opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ];
118
119 /* Convert control struct to fix control struct */
120 /* Noise shape parameters */
121 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
122 for( j = 0; j < psEnc->sCmn.shapingLPCOrder; j++ ) {
123 AR_Q13[ i * MAX_SHAPE_LPC_ORDER + j ] = silk_float2int( psEncCtrl->AR[ i * MAX_SHAPE_LPC_ORDER + j ] * 8192.0f );
124 }
125 }
126
127 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
128 LF_shp_Q14[ i ] = silk_LSHIFT32( silk_float2int( psEncCtrl->LF_AR_shp[ i ] * 16384.0f ), 16 ) |
129 (opus_uint16)silk_float2int( psEncCtrl->LF_MA_shp[ i ] * 16384.0f );
130 Tilt_Q14[ i ] = (opus_int)silk_float2int( psEncCtrl->Tilt[ i ] * 16384.0f );
131 HarmShapeGain_Q14[ i ] = (opus_int)silk_float2int( psEncCtrl->HarmShapeGain[ i ] * 16384.0f );
132 }
133 Lambda_Q10 = ( opus_int )silk_float2int( psEncCtrl->Lambda * 1024.0f );
134
135 /* prediction and coding parameters */
136 for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) {
137 LTPCoef_Q14[ i ] = (opus_int16)silk_float2int( psEncCtrl->LTPCoef[ i ] * 16384.0f );
138 }
139
140 for( j = 0; j < 2; j++ ) {
141 for( i = 0; i < psEnc->sCmn.predictLPCOrder; i++ ) {
142 PredCoef_Q12[ j ][ i ] = (opus_int16)silk_float2int( psEncCtrl->PredCoef[ j ][ i ] * 4096.0f );
143 }
144 }
145
146 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
147 Gains_Q16[ i ] = silk_float2int( psEncCtrl->Gains[ i ] * 65536.0f );
148 silk_assert( Gains_Q16[ i ] > 0 );
149 }
150
151 if( psIndices->signalType == TYPE_VOICED ) {
152 LTP_scale_Q14 = silk_LTPScales_table_Q14[ psIndices->LTP_scaleIndex ];
153 } else {
154 LTP_scale_Q14 = 0;
155 }
156
157 /* Convert input to fix */
158 for( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
159 x16[ i ] = silk_float2int( x[ i ] );
160 }
161
162 /* Call NSQ */
163 if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
164 silk_NSQ_del_dec( &psEnc->sCmn, psNSQ, psIndices, x16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
165 AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch );
166 } else {
167 silk_NSQ( &psEnc->sCmn, psNSQ, psIndices, x16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
168 AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch );
169 }
170}
171
172/***********************************************/
173/* Floating-point Silk LTP quantiation wrapper */
174/***********************************************/
175void silk_quant_LTP_gains_FLP(
176 silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */
177 opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */
178 opus_int8 *periodicity_index, /* O Periodicity index */
179 opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */
180 silk_float *pred_gain_dB, /* O LTP prediction gain */
181 const silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Correlation matrix */
182 const silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* I Correlation vector */
183 const opus_int subfr_len, /* I Number of samples per subframe */
184 const opus_int nb_subfr, /* I Number of subframes */
185 int arch /* I Run-time architecture */
186)
187{
188 opus_int i, pred_gain_dB_Q7;
189 opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ];
190 opus_int32 XX_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ];
191 opus_int32 xX_Q17[ MAX_NB_SUBFR * LTP_ORDER ];
192
193 for( i = 0; i < nb_subfr * LTP_ORDER * LTP_ORDER; i++ ) {
194 XX_Q17[ i ] = (opus_int32)silk_float2int( XX[ i ] * 131072.0f );
195 }
196 for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) {
197 xX_Q17[ i ] = (opus_int32)silk_float2int( xX[ i ] * 131072.0f );
198 }
199
200 silk_quant_LTP_gains( B_Q14, cbk_index, periodicity_index, sum_log_gain_Q7, &pred_gain_dB_Q7, XX_Q17, xX_Q17, subfr_len, nb_subfr, arch );
201
202 for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) {
203 B[ i ] = (silk_float)B_Q14[ i ] * ( 1.0f / 16384.0f );
204 }
205
206 *pred_gain_dB = (silk_float)pred_gain_dB_Q7 * ( 1.0f / 128.0f );
207}
diff --git a/lib/rbcodec/codecs/libopus/silk/gain_quant.c b/lib/rbcodec/codecs/libopus/silk/gain_quant.c
index ed084073b1..ee65245aa3 100644
--- a/lib/rbcodec/codecs/libopus/silk/gain_quant.c
+++ b/lib/rbcodec/codecs/libopus/silk/gain_quant.c
@@ -35,7 +35,6 @@ POSSIBILITY OF SUCH DAMAGE.
35#define SCALE_Q16 ( ( 65536 * ( N_LEVELS_QGAIN - 1 ) ) / ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) 35#define SCALE_Q16 ( ( 65536 * ( N_LEVELS_QGAIN - 1 ) ) / ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) )
36#define INV_SCALE_Q16 ( ( 65536 * ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) / ( N_LEVELS_QGAIN - 1 ) ) 36#define INV_SCALE_Q16 ( ( 65536 * ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) / ( N_LEVELS_QGAIN - 1 ) )
37 37
38#if 0
39/* Gain scalar quantization with hysteresis, uniform on log scale */ 38/* Gain scalar quantization with hysteresis, uniform on log scale */
40void silk_gains_quant( 39void silk_gains_quant(
41 opus_int8 ind[ MAX_NB_SUBFR ], /* O gain indices */ 40 opus_int8 ind[ MAX_NB_SUBFR ], /* O gain indices */
@@ -77,6 +76,7 @@ void silk_gains_quant(
77 /* Accumulate deltas */ 76 /* Accumulate deltas */
78 if( ind[ k ] > double_step_size_threshold ) { 77 if( ind[ k ] > double_step_size_threshold ) {
79 *prev_ind += silk_LSHIFT( ind[ k ], 1 ) - double_step_size_threshold; 78 *prev_ind += silk_LSHIFT( ind[ k ], 1 ) - double_step_size_threshold;
79 *prev_ind = silk_min_int( *prev_ind, N_LEVELS_QGAIN - 1 );
80 } else { 80 } else {
81 *prev_ind += ind[ k ]; 81 *prev_ind += ind[ k ];
82 } 82 }
@@ -89,7 +89,6 @@ void silk_gains_quant(
89 gain_Q16[ k ] = silk_log2lin( silk_min_32( silk_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */ 89 gain_Q16[ k ] = silk_log2lin( silk_min_32( silk_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */
90 } 90 }
91} 91}
92#endif
93 92
94/* Gains scalar dequantization, uniform on log scale */ 93/* Gains scalar dequantization, uniform on log scale */
95void silk_gains_dequant( 94void silk_gains_dequant(
@@ -125,7 +124,6 @@ void silk_gains_dequant(
125 } 124 }
126} 125}
127 126
128#if 0
129/* Compute unique identifier of gain indices vector */ 127/* Compute unique identifier of gain indices vector */
130opus_int32 silk_gains_ID( /* O returns unique identifier of gains */ 128opus_int32 silk_gains_ID( /* O returns unique identifier of gains */
131 const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */ 129 const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */
@@ -142,4 +140,3 @@ opus_int32 silk_gains_ID( /* O returns
142 140
143 return gainsID; 141 return gainsID;
144} 142}
145#endif
diff --git a/lib/rbcodec/codecs/libopus/silk/init_decoder.c b/lib/rbcodec/codecs/libopus/silk/init_decoder.c
index f887c67886..16c03dcd1c 100644
--- a/lib/rbcodec/codecs/libopus/silk/init_decoder.c
+++ b/lib/rbcodec/codecs/libopus/silk/init_decoder.c
@@ -44,6 +44,7 @@ opus_int silk_init_decoder(
44 /* Used to deactivate LSF interpolation */ 44 /* Used to deactivate LSF interpolation */
45 psDec->first_frame_after_reset = 1; 45 psDec->first_frame_after_reset = 1;
46 psDec->prev_gain_Q16 = 65536; 46 psDec->prev_gain_Q16 = 65536;
47 psDec->arch = opus_select_arch();
47 48
48 /* Reset CNG state */ 49 /* Reset CNG state */
49 silk_CNG_Reset( psDec ); 50 silk_CNG_Reset( psDec );
diff --git a/lib/rbcodec/codecs/libopus/silk/init_encoder.c b/lib/rbcodec/codecs/libopus/silk/init_encoder.c
new file mode 100644
index 0000000000..65995c33fa
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/init_encoder.c
@@ -0,0 +1,64 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31#ifdef FIXED_POINT
32#include "main_FIX.h"
33#else
34#include "main_FLP.h"
35#endif
36#include "tuning_parameters.h"
37#include "cpu_support.h"
38
39/*********************************/
40/* Initialize Silk Encoder state */
41/*********************************/
42opus_int silk_init_encoder(
43 silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk FIX encoder state */
44 int arch /* I Run-time architecture */
45)
46{
47 opus_int ret = 0;
48
49 /* Clear the entire encoder state */
50 silk_memset( psEnc, 0, sizeof( silk_encoder_state_Fxx ) );
51
52 psEnc->sCmn.arch = arch;
53
54 psEnc->sCmn.variable_HP_smth1_Q15 = silk_LSHIFT( silk_lin2log( SILK_FIX_CONST( VARIABLE_HP_MIN_CUTOFF_HZ, 16 ) ) - ( 16 << 7 ), 8 );
55 psEnc->sCmn.variable_HP_smth2_Q15 = psEnc->sCmn.variable_HP_smth1_Q15;
56
57 /* Used to deactivate LSF interpolation, pitch prediction */
58 psEnc->sCmn.first_frame_after_reset = 1;
59
60 /* Initialize Silk VAD */
61 ret += silk_VAD_Init( &psEnc->sCmn.sVAD );
62
63 return ret;
64}
diff --git a/lib/rbcodec/codecs/libopus/silk/inner_prod_aligned.c b/lib/rbcodec/codecs/libopus/silk/inner_prod_aligned.c
new file mode 100644
index 0000000000..257ae9e04e
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/inner_prod_aligned.c
@@ -0,0 +1,47 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33
34opus_int32 silk_inner_prod_aligned_scale(
35 const opus_int16 *const inVec1, /* I input vector 1 */
36 const opus_int16 *const inVec2, /* I input vector 2 */
37 const opus_int scale, /* I number of bits to shift */
38 const opus_int len /* I vector lengths */
39)
40{
41 opus_int i;
42 opus_int32 sum = 0;
43 for( i = 0; i < len; i++ ) {
44 sum = silk_ADD_RSHIFT32( sum, silk_SMULBB( inVec1[ i ], inVec2[ i ] ), scale );
45 }
46 return sum;
47}
diff --git a/lib/rbcodec/codecs/libopus/silk/interpolate.c b/lib/rbcodec/codecs/libopus/silk/interpolate.c
new file mode 100644
index 0000000000..833c28ef8e
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/interpolate.c
@@ -0,0 +1,51 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33
34/* Interpolate two vectors */
35void silk_interpolate(
36 opus_int16 xi[ MAX_LPC_ORDER ], /* O interpolated vector */
37 const opus_int16 x0[ MAX_LPC_ORDER ], /* I first vector */
38 const opus_int16 x1[ MAX_LPC_ORDER ], /* I second vector */
39 const opus_int ifact_Q2, /* I interp. factor, weight on 2nd vector */
40 const opus_int d /* I number of parameters */
41)
42{
43 opus_int i;
44
45 celt_assert( ifact_Q2 >= 0 );
46 celt_assert( ifact_Q2 <= 4 );
47
48 for( i = 0; i < d; i++ ) {
49 xi[ i ] = (opus_int16)silk_ADD_RSHIFT( x0[ i ], silk_SMULBB( x1[ i ] - x0[ i ], ifact_Q2 ), 2 );
50 }
51}
diff --git a/lib/rbcodec/codecs/libopus/silk/lin2log.c b/lib/rbcodec/codecs/libopus/silk/lin2log.c
new file mode 100644
index 0000000000..0d5155aa86
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/lin2log.c
@@ -0,0 +1,46 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33/* Approximation of 128 * log2() (very close inverse of silk_log2lin()) */
34/* Convert input to a log scale */
35opus_int32 silk_lin2log(
36 const opus_int32 inLin /* I input in linear scale */
37)
38{
39 opus_int32 lz, frac_Q7;
40
41 silk_CLZ_FRAC( inLin, &lz, &frac_Q7 );
42
43 /* Piece-wise parabolic approximation */
44 return silk_ADD_LSHIFT32( silk_SMLAWB( frac_Q7, silk_MUL( frac_Q7, 128 - frac_Q7 ), 179 ), 31 - lz, 7 );
45}
46
diff --git a/lib/rbcodec/codecs/libopus/silk/log2lin.c b/lib/rbcodec/codecs/libopus/silk/log2lin.c
index a692e009db..b7c48e4740 100644
--- a/lib/rbcodec/codecs/libopus/silk/log2lin.c
+++ b/lib/rbcodec/codecs/libopus/silk/log2lin.c
@@ -33,7 +33,7 @@ POSSIBILITY OF SUCH DAMAGE.
33 33
34/* Approximation of 2^() (very close inverse of silk_lin2log()) */ 34/* Approximation of 2^() (very close inverse of silk_lin2log()) */
35/* Convert input to a linear scale */ 35/* Convert input to a linear scale */
36opus_int32 silk_log2lin( 36opus_int32 silk_log2lin(
37 const opus_int32 inLog_Q7 /* I input on log scale */ 37 const opus_int32 inLog_Q7 /* I input on log scale */
38) 38)
39{ 39{
@@ -42,8 +42,8 @@ opus_int32 silk_log2lin(
42 if( inLog_Q7 < 0 ) { 42 if( inLog_Q7 < 0 ) {
43 return 0; 43 return 0;
44 } else if ( inLog_Q7 >= 3967 ) { 44 } else if ( inLog_Q7 >= 3967 ) {
45 return silk_int32_MAX; 45 return silk_int32_MAX;
46 } 46 }
47 47
48 out = silk_LSHIFT( 1, silk_RSHIFT( inLog_Q7, 7 ) ); 48 out = silk_LSHIFT( 1, silk_RSHIFT( inLog_Q7, 7 ) );
49 frac_Q7 = inLog_Q7 & 0x7F; 49 frac_Q7 = inLog_Q7 & 0x7F;
diff --git a/lib/rbcodec/codecs/libopus/silk/macros.h b/lib/rbcodec/codecs/libopus/silk/macros.h
index 05623b5df8..3c67b6e5d9 100644
--- a/lib/rbcodec/codecs/libopus/silk/macros.h
+++ b/lib/rbcodec/codecs/libopus/silk/macros.h
@@ -34,20 +34,37 @@ POSSIBILITY OF SUCH DAMAGE.
34 34
35#include "opus_types.h" 35#include "opus_types.h"
36#include "opus_defines.h" 36#include "opus_defines.h"
37#include "arch.h"
37 38
38/* This is an OPUS_INLINE header file for general platform. */ 39/* This is an OPUS_INLINE header file for general platform. */
39 40
40/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ 41/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
42#if OPUS_FAST_INT64
43#define silk_SMULWB(a32, b32) ((opus_int32)(((a32) * (opus_int64)((opus_int16)(b32))) >> 16))
44#else
41#define silk_SMULWB(a32, b32) ((((a32) >> 16) * (opus_int32)((opus_int16)(b32))) + ((((a32) & 0x0000FFFF) * (opus_int32)((opus_int16)(b32))) >> 16)) 45#define silk_SMULWB(a32, b32) ((((a32) >> 16) * (opus_int32)((opus_int16)(b32))) + ((((a32) & 0x0000FFFF) * (opus_int32)((opus_int16)(b32))) >> 16))
46#endif
42 47
43/* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */ 48/* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */
49#if OPUS_FAST_INT64
50#define silk_SMLAWB(a32, b32, c32) ((opus_int32)((a32) + (((b32) * (opus_int64)((opus_int16)(c32))) >> 16)))
51#else
44#define silk_SMLAWB(a32, b32, c32) ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16))) 52#define silk_SMLAWB(a32, b32, c32) ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16)))
53#endif
45 54
46/* (a32 * (b32 >> 16)) >> 16 */ 55/* (a32 * (b32 >> 16)) >> 16 */
56#if OPUS_FAST_INT64
57#define silk_SMULWT(a32, b32) ((opus_int32)(((a32) * (opus_int64)((b32) >> 16)) >> 16))
58#else
47#define silk_SMULWT(a32, b32) (((a32) >> 16) * ((b32) >> 16) + ((((a32) & 0x0000FFFF) * ((b32) >> 16)) >> 16)) 59#define silk_SMULWT(a32, b32) (((a32) >> 16) * ((b32) >> 16) + ((((a32) & 0x0000FFFF) * ((b32) >> 16)) >> 16))
60#endif
48 61
49/* a32 + (b32 * (c32 >> 16)) >> 16 */ 62/* a32 + (b32 * (c32 >> 16)) >> 16 */
63#if OPUS_FAST_INT64
64#define silk_SMLAWT(a32, b32, c32) ((opus_int32)((a32) + (((b32) * ((opus_int64)(c32) >> 16)) >> 16)))
65#else
50#define silk_SMLAWT(a32, b32, c32) ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16)) 66#define silk_SMLAWT(a32, b32, c32) ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16))
67#endif
51 68
52/* (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int */ 69/* (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int */
53#define silk_SMULBB(a32, b32) ((opus_int32)((opus_int16)(a32)) * (opus_int32)((opus_int16)(b32))) 70#define silk_SMULBB(a32, b32) ((opus_int32)((opus_int16)(a32)) * (opus_int32)((opus_int16)(b32)))
@@ -65,10 +82,18 @@ POSSIBILITY OF SUCH DAMAGE.
65#define silk_SMLAL(a64, b32, c32) (silk_ADD64((a64), ((opus_int64)(b32) * (opus_int64)(c32)))) 82#define silk_SMLAL(a64, b32, c32) (silk_ADD64((a64), ((opus_int64)(b32) * (opus_int64)(c32))))
66 83
67/* (a32 * b32) >> 16 */ 84/* (a32 * b32) >> 16 */
85#if OPUS_FAST_INT64
86#define silk_SMULWW(a32, b32) ((opus_int32)(((opus_int64)(a32) * (b32)) >> 16))
87#else
68#define silk_SMULWW(a32, b32) silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16)) 88#define silk_SMULWW(a32, b32) silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16))
89#endif
69 90
70/* a32 + ((b32 * c32) >> 16) */ 91/* a32 + ((b32 * c32) >> 16) */
92#if OPUS_FAST_INT64
93#define silk_SMLAWW(a32, b32, c32) ((opus_int32)((a32) + (((opus_int64)(b32) * (c32)) >> 16)))
94#else
71#define silk_SMLAWW(a32, b32, c32) silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16)) 95#define silk_SMLAWW(a32, b32, c32) silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16))
96#endif
72 97
73/* add/subtract with output saturated */ 98/* add/subtract with output saturated */
74#define silk_ADD_SAT32(a, b) ((((opus_uint32)(a) + (opus_uint32)(b)) & 0x80000000) == 0 ? \ 99#define silk_ADD_SAT32(a, b) ((((opus_uint32)(a) + (opus_uint32)(b)) & 0x80000000) == 0 ? \
@@ -118,8 +143,8 @@ static OPUS_INLINE opus_int32 silk_CLZ32(opus_int32 in32)
118#include "arm/macros_armv5e.h" 143#include "arm/macros_armv5e.h"
119#endif 144#endif
120 145
121#ifdef OPUS_CF_INLINE_ASM 146#ifdef OPUS_ARM_PRESUME_AARCH64_NEON_INTR
122#include "cf/macros_cf.h" 147#include "arm/macros_arm64.h"
123#endif 148#endif
124 149
125#endif /* SILK_MACROS_H */ 150#endif /* SILK_MACROS_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/main.h b/lib/rbcodec/codecs/libopus/silk/main.h
index 77524f5b57..1a33eed549 100644
--- a/lib/rbcodec/codecs/libopus/silk/main.h
+++ b/lib/rbcodec/codecs/libopus/silk/main.h
@@ -38,6 +38,14 @@ POSSIBILITY OF SUCH DAMAGE.
38#include "entenc.h" 38#include "entenc.h"
39#include "entdec.h" 39#include "entdec.h"
40 40
41#if defined(OPUS_X86_MAY_HAVE_SSE4_1)
42#include "x86/main_sse.h"
43#endif
44
45#if (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
46#include "arm/NSQ_del_dec_arm.h"
47#endif
48
41/* Convert Left/Right stereo signal to adaptive Mid/Side representation */ 49/* Convert Left/Right stereo signal to adaptive Mid/Side representation */
42void silk_stereo_LR_to_MS( 50void silk_stereo_LR_to_MS(
43 stereo_enc_state *state, /* I/O State */ 51 stereo_enc_state *state, /* I/O State */
@@ -105,22 +113,22 @@ void silk_stereo_decode_mid_only(
105 113
106/* Encodes signs of excitation */ 114/* Encodes signs of excitation */
107void silk_encode_signs( 115void silk_encode_signs(
108 ec_enc *psRangeEnc, /* I/O Compressor data structure */ 116 ec_enc *psRangeEnc, /* I/O Compressor data structure */
109 const opus_int8 pulses[], /* I pulse signal */ 117 const opus_int8 pulses[], /* I pulse signal */
110 opus_int length, /* I length of input */ 118 opus_int length, /* I length of input */
111 const opus_int signalType, /* I Signal type */ 119 const opus_int signalType, /* I Signal type */
112 const opus_int quantOffsetType, /* I Quantization offset type */ 120 const opus_int quantOffsetType, /* I Quantization offset type */
113 const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ 121 const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */
114); 122);
115 123
116/* Decodes signs of excitation */ 124/* Decodes signs of excitation */
117void silk_decode_signs( 125void silk_decode_signs(
118 ec_dec *psRangeDec, /* I/O Compressor data structure */ 126 ec_dec *psRangeDec, /* I/O Compressor data structure */
119 opus_int16 pulses[], /* I/O pulse signal */ 127 opus_int16 pulses[], /* I/O pulse signal */
120 opus_int length, /* I length of input */ 128 opus_int length, /* I length of input */
121 const opus_int signalType, /* I Signal type */ 129 const opus_int signalType, /* I Signal type */
122 const opus_int quantOffsetType, /* I Quantization offset type */ 130 const opus_int quantOffsetType, /* I Quantization offset type */
123 const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ 131 const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */
124); 132);
125 133
126/* Check encoder control struct */ 134/* Check encoder control struct */
@@ -201,43 +209,52 @@ void silk_interpolate(
201 209
202/* LTP tap quantizer */ 210/* LTP tap quantizer */
203void silk_quant_LTP_gains( 211void silk_quant_LTP_gains(
204 opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (un)quantized LTP gains */ 212 opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */
205 opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */ 213 opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */
206 opus_int8 *periodicity_index, /* O Periodicity Index */ 214 opus_int8 *periodicity_index, /* O Periodicity Index */
207 opus_int32 *sum_gain_dB_Q7, /* I/O Cumulative max prediction gain */ 215 opus_int32 *sum_gain_dB_Q7, /* I/O Cumulative max prediction gain */
208 const opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Error Weights in Q18 */ 216 opus_int *pred_gain_dB_Q7, /* O LTP prediction gain */
209 opus_int mu_Q9, /* I Mu value (R/D tradeoff) */ 217 const opus_int32 XX_Q17[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Correlation matrix in Q18 */
210 opus_int lowComplexity, /* I Flag for low complexity */ 218 const opus_int32 xX_Q17[ MAX_NB_SUBFR*LTP_ORDER ], /* I Correlation vector in Q18 */
211 const opus_int nb_subfr /* I number of subframes */ 219 const opus_int subfr_len, /* I Number of samples per subframe */
220 const opus_int nb_subfr, /* I Number of subframes */
221 int arch /* I Run-time architecture */
212); 222);
213 223
214/* Entropy constrained matrix-weighted VQ, for a single input data vector */ 224/* Entropy constrained matrix-weighted VQ, for a single input data vector */
215void silk_VQ_WMat_EC( 225void silk_VQ_WMat_EC_c(
216 opus_int8 *ind, /* O index of best codebook vector */ 226 opus_int8 *ind, /* O index of best codebook vector */
217 opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ 227 opus_int32 *res_nrg_Q15, /* O best residual energy */
228 opus_int32 *rate_dist_Q8, /* O best total bitrate */
218 opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ 229 opus_int *gain_Q7, /* O sum of absolute LTP coefficients */
219 const opus_int16 *in_Q14, /* I input vector to be quantized */ 230 const opus_int32 *XX_Q17, /* I correlation matrix */
220 const opus_int32 *W_Q18, /* I weighting matrix */ 231 const opus_int32 *xX_Q17, /* I correlation vector */
221 const opus_int8 *cb_Q7, /* I codebook */ 232 const opus_int8 *cb_Q7, /* I codebook */
222 const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ 233 const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */
223 const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ 234 const opus_uint8 *cl_Q5, /* I code length for each codebook vector */
224 const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ 235 const opus_int subfr_len, /* I number of samples per subframe */
225 const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ 236 const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
226 opus_int L /* I number of vectors in codebook */ 237 const opus_int L /* I number of vectors in codebook */
227); 238);
228 239
240#if !defined(OVERRIDE_silk_VQ_WMat_EC)
241#define silk_VQ_WMat_EC(ind, res_nrg_Q15, rate_dist_Q8, gain_Q7, XX_Q17, xX_Q17, cb_Q7, cb_gain_Q7, cl_Q5, subfr_len, max_gain_Q7, L, arch) \
242 ((void)(arch),silk_VQ_WMat_EC_c(ind, res_nrg_Q15, rate_dist_Q8, gain_Q7, XX_Q17, xX_Q17, cb_Q7, cb_gain_Q7, cl_Q5, subfr_len, max_gain_Q7, L))
243#endif
244
229/************************************/ 245/************************************/
230/* Noise shaping quantization (NSQ) */ 246/* Noise shaping quantization (NSQ) */
231/************************************/ 247/************************************/
232void silk_NSQ( 248
233 const silk_encoder_state *psEncC, /* I/O Encoder State */ 249void silk_NSQ_c(
250 const silk_encoder_state *psEncC, /* I Encoder State */
234 silk_nsq_state *NSQ, /* I/O NSQ state */ 251 silk_nsq_state *NSQ, /* I/O NSQ state */
235 SideInfoIndices *psIndices, /* I/O Quantization Indices */ 252 SideInfoIndices *psIndices, /* I/O Quantization Indices */
236 const opus_int32 x_Q3[], /* I Prefiltered input signal */ 253 const opus_int16 x16[], /* I Input */
237 opus_int8 pulses[], /* O Quantized pulse signal */ 254 opus_int8 pulses[], /* O Quantized pulse signal */
238 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ 255 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
239 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ 256 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
240 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ 257 const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
241 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ 258 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
242 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ 259 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
243 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ 260 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
@@ -247,16 +264,23 @@ void silk_NSQ(
247 const opus_int LTP_scale_Q14 /* I LTP state scaling */ 264 const opus_int LTP_scale_Q14 /* I LTP state scaling */
248); 265);
249 266
267#if !defined(OVERRIDE_silk_NSQ)
268#define silk_NSQ(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \
269 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \
270 ((void)(arch),silk_NSQ_c(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \
271 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))
272#endif
273
250/* Noise shaping using delayed decision */ 274/* Noise shaping using delayed decision */
251void silk_NSQ_del_dec( 275void silk_NSQ_del_dec_c(
252 const silk_encoder_state *psEncC, /* I/O Encoder State */ 276 const silk_encoder_state *psEncC, /* I Encoder State */
253 silk_nsq_state *NSQ, /* I/O NSQ state */ 277 silk_nsq_state *NSQ, /* I/O NSQ state */
254 SideInfoIndices *psIndices, /* I/O Quantization Indices */ 278 SideInfoIndices *psIndices, /* I/O Quantization Indices */
255 const opus_int32 x_Q3[], /* I Prefiltered input signal */ 279 const opus_int16 x16[], /* I Input */
256 opus_int8 pulses[], /* O Quantized pulse signal */ 280 opus_int8 pulses[], /* O Quantized pulse signal */
257 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ 281 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
258 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ 282 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
259 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ 283 const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
260 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ 284 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
261 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ 285 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
262 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ 286 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
@@ -266,6 +290,13 @@ void silk_NSQ_del_dec(
266 const opus_int LTP_scale_Q14 /* I LTP state scaling */ 290 const opus_int LTP_scale_Q14 /* I LTP state scaling */
267); 291);
268 292
293#if !defined(OVERRIDE_silk_NSQ_del_dec)
294#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \
295 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \
296 ((void)(arch),silk_NSQ_del_dec_c(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \
297 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))
298#endif
299
269/************/ 300/************/
270/* Silk VAD */ 301/* Silk VAD */
271/************/ 302/************/
@@ -275,11 +306,15 @@ opus_int silk_VAD_Init( /* O Return v
275); 306);
276 307
277/* Get speech activity level in Q8 */ 308/* Get speech activity level in Q8 */
278opus_int silk_VAD_GetSA_Q8( /* O Return value, 0 if success */ 309opus_int silk_VAD_GetSA_Q8_c( /* O Return value, 0 if success */
279 silk_encoder_state *psEncC, /* I/O Encoder state */ 310 silk_encoder_state *psEncC, /* I/O Encoder state */
280 const opus_int16 pIn[] /* I PCM input */ 311 const opus_int16 pIn[] /* I PCM input */
281); 312);
282 313
314#if !defined(OVERRIDE_silk_VAD_GetSA_Q8)
315#define silk_VAD_GetSA_Q8(psEnC, pIn, arch) ((void)(arch),silk_VAD_GetSA_Q8_c(psEnC, pIn))
316#endif
317
283/* Low-pass filter with variable cutoff frequency based on */ 318/* Low-pass filter with variable cutoff frequency based on */
284/* piece-wise linear interpolation between elliptic filters */ 319/* piece-wise linear interpolation between elliptic filters */
285/* Start by setting transition_frame_no = 1; */ 320/* Start by setting transition_frame_no = 1; */
@@ -315,6 +350,7 @@ void silk_NLSF_VQ(
315 opus_int32 err_Q26[], /* O Quantization errors [K] */ 350 opus_int32 err_Q26[], /* O Quantization errors [K] */
316 const opus_int16 in_Q15[], /* I Input vectors to be quantized [LPC_order] */ 351 const opus_int16 in_Q15[], /* I Input vectors to be quantized [LPC_order] */
317 const opus_uint8 pCB_Q8[], /* I Codebook vectors [K*LPC_order] */ 352 const opus_uint8 pCB_Q8[], /* I Codebook vectors [K*LPC_order] */
353 const opus_int16 pWght_Q9[], /* I Codebook weights [K*LPC_order] */
318 const opus_int K, /* I Number of codebook vectors */ 354 const opus_int K, /* I Number of codebook vectors */
319 const opus_int LPC_order /* I Number of LPCs */ 355 const opus_int LPC_order /* I Number of LPCs */
320); 356);
@@ -373,7 +409,8 @@ opus_int silk_decode_frame(
373 opus_int16 pOut[], /* O Pointer to output speech frame */ 409 opus_int16 pOut[], /* O Pointer to output speech frame */
374 opus_int32 *pN, /* O Pointer to size of output frame */ 410 opus_int32 *pN, /* O Pointer to size of output frame */
375 opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ 411 opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */
376 opus_int condCoding /* I The type of conditional coding to use */ 412 opus_int condCoding, /* I The type of conditional coding to use */
413 int arch /* I Run-time architecture */
377); 414);
378 415
379/* Decode indices from bitstream */ 416/* Decode indices from bitstream */
@@ -397,7 +434,8 @@ void silk_decode_core(
397 silk_decoder_state *psDec, /* I/O Decoder state */ 434 silk_decoder_state *psDec, /* I/O Decoder state */
398 silk_decoder_control *psDecCtrl, /* I Decoder control */ 435 silk_decoder_control *psDecCtrl, /* I Decoder control */
399 opus_int16 xq[], /* O Decoded speech */ 436 opus_int16 xq[], /* O Decoded speech */
400 const opus_int16 pulses[ MAX_FRAME_LENGTH ] /* I Pulse signal */ 437 const opus_int16 pulses[ MAX_FRAME_LENGTH ], /* I Pulse signal */
438 int arch /* I Run-time architecture */
401); 439);
402 440
403/* Decode quantization indices of excitation (Shell coding) */ 441/* Decode quantization indices of excitation (Shell coding) */
diff --git a/lib/rbcodec/codecs/libopus/silk/mips/NSQ_del_dec_mipsr1.h b/lib/rbcodec/codecs/libopus/silk/mips/NSQ_del_dec_mipsr1.h
new file mode 100644
index 0000000000..cd70713a8f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/mips/NSQ_del_dec_mipsr1.h
@@ -0,0 +1,410 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef __NSQ_DEL_DEC_MIPSR1_H__
29#define __NSQ_DEL_DEC_MIPSR1_H__
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35#include "main.h"
36#include "stack_alloc.h"
37
38#define OVERRIDE_silk_noise_shape_quantizer_del_dec
39static inline void silk_noise_shape_quantizer_del_dec(
40 silk_nsq_state *NSQ, /* I/O NSQ state */
41 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
42 opus_int signalType, /* I Signal type */
43 const opus_int32 x_Q10[], /* I */
44 opus_int8 pulses[], /* O */
45 opus_int16 xq[], /* O */
46 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
47 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
48 const opus_int16 a_Q12[], /* I Short term prediction coefs */
49 const opus_int16 b_Q14[], /* I Long term prediction coefs */
50 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
51 opus_int lag, /* I Pitch lag */
52 opus_int32 HarmShapeFIRPacked_Q14, /* I */
53 opus_int Tilt_Q14, /* I Spectral tilt */
54 opus_int32 LF_shp_Q14, /* I */
55 opus_int32 Gain_Q16, /* I */
56 opus_int Lambda_Q10, /* I */
57 opus_int offset_Q10, /* I */
58 opus_int length, /* I Input length */
59 opus_int subfr, /* I Subframe number */
60 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
61 opus_int predictLPCOrder, /* I Prediction filter order */
62 opus_int warping_Q16, /* I */
63 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
64 opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
65 opus_int decisionDelay, /* I */
66 int arch /* I */
67)
68{
69 opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
70 opus_int32 Winner_rand_state;
71 opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14;
72 opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;
73 opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
74 opus_int32 tmp1, tmp2, sLF_AR_shp_Q14;
75 opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;
76 NSQ_sample_struct psSampleState[ MAX_DEL_DEC_STATES ][ 2 ];
77 NSQ_del_dec_struct *psDD;
78 NSQ_sample_struct *psSS;
79 opus_int16 b_Q14_0, b_Q14_1, b_Q14_2, b_Q14_3, b_Q14_4;
80 opus_int16 a_Q12_0, a_Q12_1, a_Q12_2, a_Q12_3, a_Q12_4, a_Q12_5, a_Q12_6;
81 opus_int16 a_Q12_7, a_Q12_8, a_Q12_9, a_Q12_10, a_Q12_11, a_Q12_12, a_Q12_13;
82 opus_int16 a_Q12_14, a_Q12_15;
83
84 opus_int32 cur, prev, next;
85
86 /*Unused.*/
87 (void)arch;
88
89 //Intialize b_Q14 variables
90 b_Q14_0 = b_Q14[ 0 ];
91 b_Q14_1 = b_Q14[ 1 ];
92 b_Q14_2 = b_Q14[ 2 ];
93 b_Q14_3 = b_Q14[ 3 ];
94 b_Q14_4 = b_Q14[ 4 ];
95
96 //Intialize a_Q12 variables
97 a_Q12_0 = a_Q12[0];
98 a_Q12_1 = a_Q12[1];
99 a_Q12_2 = a_Q12[2];
100 a_Q12_3 = a_Q12[3];
101 a_Q12_4 = a_Q12[4];
102 a_Q12_5 = a_Q12[5];
103 a_Q12_6 = a_Q12[6];
104 a_Q12_7 = a_Q12[7];
105 a_Q12_8 = a_Q12[8];
106 a_Q12_9 = a_Q12[9];
107 a_Q12_10 = a_Q12[10];
108 a_Q12_11 = a_Q12[11];
109 a_Q12_12 = a_Q12[12];
110 a_Q12_13 = a_Q12[13];
111 a_Q12_14 = a_Q12[14];
112 a_Q12_15 = a_Q12[15];
113
114 long long temp64;
115
116 silk_assert( nStatesDelayedDecision > 0 );
117
118 shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
119 pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
120 Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
121
122 for( i = 0; i < length; i++ ) {
123 /* Perform common calculations used in all states */
124
125 /* Long-term prediction */
126 if( signalType == TYPE_VOICED ) {
127 /* Unrolled loop */
128 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
129 temp64 = __builtin_mips_mult(pred_lag_ptr[ 0 ], b_Q14_0 );
130 temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -1 ], b_Q14_1 );
131 temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -2 ], b_Q14_2 );
132 temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -3 ], b_Q14_3 );
133 temp64 = __builtin_mips_madd( temp64, pred_lag_ptr[ -4 ], b_Q14_4 );
134 temp64 += 32768;
135 LTP_pred_Q14 = __builtin_mips_extr_w(temp64, 16);
136 LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */
137 pred_lag_ptr++;
138 } else {
139 LTP_pred_Q14 = 0;
140 }
141
142 /* Long-term shaping */
143 if( lag > 0 ) {
144 /* Symmetric, packed FIR coefficients */
145 n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
146 n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
147 n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */
148 shp_lag_ptr++;
149 } else {
150 n_LTP_Q14 = 0;
151 }
152
153 for( k = 0; k < nStatesDelayedDecision; k++ ) {
154 /* Delayed decision state */
155 psDD = &psDelDec[ k ];
156
157 /* Sample state */
158 psSS = psSampleState[ k ];
159
160 /* Generate dither */
161 psDD->Seed = silk_RAND( psDD->Seed );
162
163 /* Pointer used in short term prediction and shaping */
164 psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];
165 /* Short-term prediction */
166 silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 );
167 temp64 = __builtin_mips_mult(psLPC_Q14[ 0 ], a_Q12_0 );
168 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -1 ], a_Q12_1 );
169 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -2 ], a_Q12_2 );
170 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -3 ], a_Q12_3 );
171 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -4 ], a_Q12_4 );
172 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -5 ], a_Q12_5 );
173 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -6 ], a_Q12_6 );
174 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -7 ], a_Q12_7 );
175 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -8 ], a_Q12_8 );
176 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -9 ], a_Q12_9 );
177 if( predictLPCOrder == 16 ) {
178 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -10 ], a_Q12_10 );
179 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -11 ], a_Q12_11 );
180 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -12 ], a_Q12_12 );
181 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -13 ], a_Q12_13 );
182 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -14 ], a_Q12_14 );
183 temp64 = __builtin_mips_madd( temp64, psLPC_Q14[ -15 ], a_Q12_15 );
184 }
185 temp64 += 32768;
186 LPC_pred_Q14 = __builtin_mips_extr_w(temp64, 16);
187
188 LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */
189
190 /* Noise shape feedback */
191 silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
192 /* Output of lowpass section */
193 tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 );
194 /* Output of allpass section */
195 tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );
196 psDD->sAR2_Q14[ 0 ] = tmp2;
197
198 temp64 = __builtin_mips_mult(tmp2, AR_shp_Q13[ 0 ] );
199
200 prev = psDD->sAR2_Q14[ 1 ];
201
202 /* Loop over allpass sections */
203 for( j = 2; j < shapingLPCOrder; j += 2 ) {
204 cur = psDD->sAR2_Q14[ j ];
205 next = psDD->sAR2_Q14[ j+1 ];
206 /* Output of allpass section */
207 tmp2 = silk_SMLAWB( prev, cur - tmp1, warping_Q16 );
208 psDD->sAR2_Q14[ j - 1 ] = tmp1;
209 temp64 = __builtin_mips_madd( temp64, tmp1, AR_shp_Q13[ j - 1 ] );
210 temp64 = __builtin_mips_madd( temp64, tmp2, AR_shp_Q13[ j ] );
211 /* Output of allpass section */
212 tmp1 = silk_SMLAWB( cur, next - tmp2, warping_Q16 );
213 psDD->sAR2_Q14[ j + 0 ] = tmp2;
214 prev = next;
215 }
216 psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
217 temp64 = __builtin_mips_madd( temp64, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
218 temp64 += 32768;
219 n_AR_Q14 = __builtin_mips_extr_w(temp64, 16);
220 n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */
221 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */
222 n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */
223
224 n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */
225 n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */
226 n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */
227
228 /* Input minus prediction plus noise feedback */
229 /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */
230 tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */
231 tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */
232 tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */
233 tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */
234
235 r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */
236
237 /* Flip sign depending on dither */
238 if ( psDD->Seed < 0 ) {
239 r_Q10 = -r_Q10;
240 }
241 r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
242
243 /* Find two quantization level candidates and measure their rate-distortion */
244 q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
245 q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
246 if( q1_Q0 > 0 ) {
247 q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
248 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
249 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
250 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
251 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
252 } else if( q1_Q0 == 0 ) {
253 q1_Q10 = offset_Q10;
254 q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
255 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
256 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
257 } else if( q1_Q0 == -1 ) {
258 q2_Q10 = offset_Q10;
259 q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
260 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
261 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
262 } else { /* q1_Q0 < -1 */
263 q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
264 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
265 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
266 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
267 rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 );
268 }
269 rr_Q10 = silk_SUB32( r_Q10, q1_Q10 );
270 rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 );
271 rr_Q10 = silk_SUB32( r_Q10, q2_Q10 );
272 rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 );
273
274 if( rd1_Q10 < rd2_Q10 ) {
275 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
276 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
277 psSS[ 0 ].Q_Q10 = q1_Q10;
278 psSS[ 1 ].Q_Q10 = q2_Q10;
279 } else {
280 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
281 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
282 psSS[ 0 ].Q_Q10 = q2_Q10;
283 psSS[ 1 ].Q_Q10 = q1_Q10;
284 }
285
286 /* Update states for best quantization */
287
288 /* Quantized excitation */
289 exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 );
290 if ( psDD->Seed < 0 ) {
291 exc_Q14 = -exc_Q14;
292 }
293
294 /* Add predictions */
295 LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
296 xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
297
298 /* Update states */
299 sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 );
300 psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
301 psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14;
302 psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14;
303 psSS[ 0 ].xq_Q14 = xq_Q14;
304
305 /* Update states for second best quantization */
306
307 /* Quantized excitation */
308 exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 );
309 if ( psDD->Seed < 0 ) {
310 exc_Q14 = -exc_Q14;
311 }
312
313
314 /* Add predictions */
315 LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
316 xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
317
318 /* Update states */
319 sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 );
320 psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
321 psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14;
322 psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14;
323 psSS[ 1 ].xq_Q14 = xq_Q14;
324 }
325
326 *smpl_buf_idx = ( *smpl_buf_idx - 1 ) % DECISION_DELAY;
327 if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY;
328 last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY;
329
330 /* Find winner */
331 RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
332 Winner_ind = 0;
333 for( k = 1; k < nStatesDelayedDecision; k++ ) {
334 if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) {
335 RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
336 Winner_ind = k;
337 }
338 }
339
340 /* Increase RD values of expired states */
341 Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ];
342 for( k = 0; k < nStatesDelayedDecision; k++ ) {
343 if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) {
344 psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 );
345 psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 );
346 silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 );
347 }
348 }
349
350 /* Find worst in first set and best in second set */
351 RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
352 RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10;
353 RDmax_ind = 0;
354 RDmin_ind = 0;
355 for( k = 1; k < nStatesDelayedDecision; k++ ) {
356 /* find worst in first set */
357 if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) {
358 RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
359 RDmax_ind = k;
360 }
361 /* find best in second set */
362 if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) {
363 RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10;
364 RDmin_ind = k;
365 }
366 }
367
368 /* Replace a state if best from second set outperforms worst in first set */
369 if( RDmin_Q10 < RDmax_Q10 ) {
370 silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i,
371 ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) );
372 silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) );
373 }
374
375 /* Write samples from winner to output and long-term filter states */
376 psDD = &psDelDec[ Winner_ind ];
377 if( subfr > 0 || i >= decisionDelay ) {
378 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
379 xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
380 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) );
381 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ];
382 sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ];
383 }
384 NSQ->sLTP_shp_buf_idx++;
385 NSQ->sLTP_buf_idx++;
386
387 /* Update states */
388 for( k = 0; k < nStatesDelayedDecision; k++ ) {
389 psDD = &psDelDec[ k ];
390 psSS = &psSampleState[ k ][ 0 ];
391 psDD->LF_AR_Q14 = psSS->LF_AR_Q14;
392 psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;
393 psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14;
394 psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10;
395 psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 );
396 psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14;
397 psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) );
398 psDD->RandState[ *smpl_buf_idx ] = psDD->Seed;
399 psDD->RD_Q10 = psSS->RD_Q10;
400 }
401 delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10;
402 }
403 /* Update LPC states */
404 for( k = 0; k < nStatesDelayedDecision; k++ ) {
405 psDD = &psDelDec[ k ];
406 silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
407 }
408}
409
410#endif /* __NSQ_DEL_DEC_MIPSR1_H__ */
diff --git a/lib/rbcodec/codecs/libopus/silk/mips/macros_mipsr1.h b/lib/rbcodec/codecs/libopus/silk/mips/macros_mipsr1.h
new file mode 100644
index 0000000000..12ed981a6e
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/mips/macros_mipsr1.h
@@ -0,0 +1,92 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28
29#ifndef __SILK_MACROS_MIPSR1_H__
30#define __SILK_MACROS_MIPSR1_H__
31
32#define mips_clz(x) __builtin_clz(x)
33
34#undef silk_SMULWB
35static inline int silk_SMULWB(int a, int b)
36{
37 long long ac;
38 int c;
39
40 ac = __builtin_mips_mult(a, (opus_int32)(opus_int16)b);
41 c = __builtin_mips_extr_w(ac, 16);
42
43 return c;
44}
45
46#undef silk_SMLAWB
47#define silk_SMLAWB(a32, b32, c32) ((a32) + silk_SMULWB(b32, c32))
48
49#undef silk_SMULWW
50static inline int silk_SMULWW(int a, int b)
51{
52 long long ac;
53 int c;
54
55 ac = __builtin_mips_mult(a, b);
56 c = __builtin_mips_extr_w(ac, 16);
57
58 return c;
59}
60
61#undef silk_SMLAWW
62static inline int silk_SMLAWW(int a, int b, int c)
63{
64 long long ac;
65 int res;
66
67 ac = __builtin_mips_mult(b, c);
68 res = __builtin_mips_extr_w(ac, 16);
69 res += a;
70
71 return res;
72}
73
74#define OVERRIDE_silk_CLZ16
75static inline opus_int32 silk_CLZ16(opus_int16 in16)
76{
77 int re32;
78 opus_int32 in32 = (opus_int32 )in16;
79 re32 = mips_clz(in32);
80 re32-=16;
81 return re32;
82}
83
84#define OVERRIDE_silk_CLZ32
85static inline opus_int32 silk_CLZ32(opus_int32 in32)
86{
87 int re32;
88 re32 = mips_clz(in32);
89 return re32;
90}
91
92#endif /* __SILK_MACROS_MIPSR1_H__ */
diff --git a/lib/rbcodec/codecs/libopus/silk/mips/sigproc_fix_mipsr1.h b/lib/rbcodec/codecs/libopus/silk/mips/sigproc_fix_mipsr1.h
new file mode 100644
index 0000000000..51520c0a6f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/mips/sigproc_fix_mipsr1.h
@@ -0,0 +1,60 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef SILK_SIGPROC_FIX_MIPSR1_H
29#define SILK_SIGPROC_FIX_MIPSR1_H
30
31#undef silk_SAT16
32static inline short int silk_SAT16(int a)
33{
34 int c;
35 c = __builtin_mips_shll_s_w(a, 16);
36 c = c>>16;
37
38 return c;
39}
40
41#undef silk_LSHIFT_SAT32
42static inline int silk_LSHIFT_SAT32(int a, int shift)
43{
44 int r;
45
46 r = __builtin_mips_shll_s_w(a, shift);
47
48 return r;
49}
50
51#undef silk_RSHIFT_ROUND
52static inline int silk_RSHIFT_ROUND(int a, int shift)
53{
54 int r;
55
56 r = __builtin_mips_shra_r_w(a, shift);
57 return r;
58}
59
60#endif /* SILK_SIGPROC_FIX_MIPSR1_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/process_NLSFs.c b/lib/rbcodec/codecs/libopus/silk/process_NLSFs.c
new file mode 100644
index 0000000000..d130809541
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/process_NLSFs.c
@@ -0,0 +1,107 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33
34/* Limit, stabilize, convert and quantize NLSFs */
35void silk_process_NLSFs(
36 silk_encoder_state *psEncC, /* I/O Encoder state */
37 opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */
38 opus_int16 pNLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */
39 const opus_int16 prev_NLSFq_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */
40)
41{
42 opus_int i, doInterpolate;
43 opus_int NLSF_mu_Q20;
44 opus_int16 i_sqr_Q15;
45 opus_int16 pNLSF0_temp_Q15[ MAX_LPC_ORDER ];
46 opus_int16 pNLSFW_QW[ MAX_LPC_ORDER ];
47 opus_int16 pNLSFW0_temp_QW[ MAX_LPC_ORDER ];
48
49 silk_assert( psEncC->speech_activity_Q8 >= 0 );
50 silk_assert( psEncC->speech_activity_Q8 <= SILK_FIX_CONST( 1.0, 8 ) );
51 celt_assert( psEncC->useInterpolatedNLSFs == 1 || psEncC->indices.NLSFInterpCoef_Q2 == ( 1 << 2 ) );
52
53 /***********************/
54 /* Calculate mu values */
55 /***********************/
56 /* NLSF_mu = 0.003 - 0.0015 * psEnc->speech_activity; */
57 NLSF_mu_Q20 = silk_SMLAWB( SILK_FIX_CONST( 0.003, 20 ), SILK_FIX_CONST( -0.001, 28 ), psEncC->speech_activity_Q8 );
58 if( psEncC->nb_subfr == 2 ) {
59 /* Multiply by 1.5 for 10 ms packets */
60 NLSF_mu_Q20 = silk_ADD_RSHIFT( NLSF_mu_Q20, NLSF_mu_Q20, 1 );
61 }
62
63 celt_assert( NLSF_mu_Q20 > 0 );
64 silk_assert( NLSF_mu_Q20 <= SILK_FIX_CONST( 0.005, 20 ) );
65
66 /* Calculate NLSF weights */
67 silk_NLSF_VQ_weights_laroia( pNLSFW_QW, pNLSF_Q15, psEncC->predictLPCOrder );
68
69 /* Update NLSF weights for interpolated NLSFs */
70 doInterpolate = ( psEncC->useInterpolatedNLSFs == 1 ) && ( psEncC->indices.NLSFInterpCoef_Q2 < 4 );
71 if( doInterpolate ) {
72 /* Calculate the interpolated NLSF vector for the first half */
73 silk_interpolate( pNLSF0_temp_Q15, prev_NLSFq_Q15, pNLSF_Q15,
74 psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder );
75
76 /* Calculate first half NLSF weights for the interpolated NLSFs */
77 silk_NLSF_VQ_weights_laroia( pNLSFW0_temp_QW, pNLSF0_temp_Q15, psEncC->predictLPCOrder );
78
79 /* Update NLSF weights with contribution from first half */
80 i_sqr_Q15 = silk_LSHIFT( silk_SMULBB( psEncC->indices.NLSFInterpCoef_Q2, psEncC->indices.NLSFInterpCoef_Q2 ), 11 );
81 for( i = 0; i < psEncC->predictLPCOrder; i++ ) {
82 pNLSFW_QW[ i ] = silk_ADD16( silk_RSHIFT( pNLSFW_QW[ i ], 1 ), silk_RSHIFT(
83 silk_SMULBB( pNLSFW0_temp_QW[ i ], i_sqr_Q15 ), 16) );
84 silk_assert( pNLSFW_QW[ i ] >= 1 );
85 }
86 }
87
88 silk_NLSF_encode( psEncC->indices.NLSFIndices, pNLSF_Q15, psEncC->psNLSF_CB, pNLSFW_QW,
89 NLSF_mu_Q20, psEncC->NLSF_MSVQ_Survivors, psEncC->indices.signalType );
90
91 /* Convert quantized NLSFs back to LPC coefficients */
92 silk_NLSF2A( PredCoef_Q12[ 1 ], pNLSF_Q15, psEncC->predictLPCOrder, psEncC->arch );
93
94 if( doInterpolate ) {
95 /* Calculate the interpolated, quantized LSF vector for the first half */
96 silk_interpolate( pNLSF0_temp_Q15, prev_NLSFq_Q15, pNLSF_Q15,
97 psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder );
98
99 /* Convert back to LPC coefficients */
100 silk_NLSF2A( PredCoef_Q12[ 0 ], pNLSF0_temp_Q15, psEncC->predictLPCOrder, psEncC->arch );
101
102 } else {
103 /* Copy LPC coefficients for first half from second half */
104 celt_assert( psEncC->predictLPCOrder <= MAX_LPC_ORDER );
105 silk_memcpy( PredCoef_Q12[ 0 ], PredCoef_Q12[ 1 ], psEncC->predictLPCOrder * sizeof( opus_int16 ) );
106 }
107}
diff --git a/lib/rbcodec/codecs/libopus/silk/quant_LTP_gains.c b/lib/rbcodec/codecs/libopus/silk/quant_LTP_gains.c
new file mode 100644
index 0000000000..d6b8eff8d1
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/quant_LTP_gains.c
@@ -0,0 +1,132 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33#include "tuning_parameters.h"
34
35void silk_quant_LTP_gains(
36 opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */
37 opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */
38 opus_int8 *periodicity_index, /* O Periodicity Index */
39 opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */
40 opus_int *pred_gain_dB_Q7, /* O LTP prediction gain */
41 const opus_int32 XX_Q17[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Correlation matrix in Q18 */
42 const opus_int32 xX_Q17[ MAX_NB_SUBFR*LTP_ORDER ], /* I Correlation vector in Q18 */
43 const opus_int subfr_len, /* I Number of samples per subframe */
44 const opus_int nb_subfr, /* I Number of subframes */
45 int arch /* I Run-time architecture */
46)
47{
48 opus_int j, k, cbk_size;
49 opus_int8 temp_idx[ MAX_NB_SUBFR ];
50 const opus_uint8 *cl_ptr_Q5;
51 const opus_int8 *cbk_ptr_Q7;
52 const opus_uint8 *cbk_gain_ptr_Q7;
53 const opus_int32 *XX_Q17_ptr, *xX_Q17_ptr;
54 opus_int32 res_nrg_Q15_subfr, res_nrg_Q15, rate_dist_Q7_subfr, rate_dist_Q7, min_rate_dist_Q7;
55 opus_int32 sum_log_gain_tmp_Q7, best_sum_log_gain_Q7, max_gain_Q7;
56 opus_int gain_Q7;
57
58 /***************************************************/
59 /* iterate over different codebooks with different */
60 /* rates/distortions, and choose best */
61 /***************************************************/
62 min_rate_dist_Q7 = silk_int32_MAX;
63 best_sum_log_gain_Q7 = 0;
64 for( k = 0; k < 3; k++ ) {
65 /* Safety margin for pitch gain control, to take into account factors
66 such as state rescaling/rewhitening. */
67 opus_int32 gain_safety = SILK_FIX_CONST( 0.4, 7 );
68
69 cl_ptr_Q5 = silk_LTP_gain_BITS_Q5_ptrs[ k ];
70 cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ k ];
71 cbk_gain_ptr_Q7 = silk_LTP_vq_gain_ptrs_Q7[ k ];
72 cbk_size = silk_LTP_vq_sizes[ k ];
73
74 /* Set up pointers to first subframe */
75 XX_Q17_ptr = XX_Q17;
76 xX_Q17_ptr = xX_Q17;
77
78 res_nrg_Q15 = 0;
79 rate_dist_Q7 = 0;
80 sum_log_gain_tmp_Q7 = *sum_log_gain_Q7;
81 for( j = 0; j < nb_subfr; j++ ) {
82 max_gain_Q7 = silk_log2lin( ( SILK_FIX_CONST( MAX_SUM_LOG_GAIN_DB / 6.0, 7 ) - sum_log_gain_tmp_Q7 )
83 + SILK_FIX_CONST( 7, 7 ) ) - gain_safety;
84 silk_VQ_WMat_EC(
85 &temp_idx[ j ], /* O index of best codebook vector */
86 &res_nrg_Q15_subfr, /* O residual energy */
87 &rate_dist_Q7_subfr, /* O best weighted quantization error + mu * rate */
88 &gain_Q7, /* O sum of absolute LTP coefficients */
89 XX_Q17_ptr, /* I correlation matrix */
90 xX_Q17_ptr, /* I correlation vector */
91 cbk_ptr_Q7, /* I codebook */
92 cbk_gain_ptr_Q7, /* I codebook effective gains */
93 cl_ptr_Q5, /* I code length for each codebook vector */
94 subfr_len, /* I number of samples per subframe */
95 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
96 cbk_size, /* I number of vectors in codebook */
97 arch /* I Run-time architecture */
98 );
99
100 res_nrg_Q15 = silk_ADD_POS_SAT32( res_nrg_Q15, res_nrg_Q15_subfr );
101 rate_dist_Q7 = silk_ADD_POS_SAT32( rate_dist_Q7, rate_dist_Q7_subfr );
102 sum_log_gain_tmp_Q7 = silk_max(0, sum_log_gain_tmp_Q7
103 + silk_lin2log( gain_safety + gain_Q7 ) - SILK_FIX_CONST( 7, 7 ));
104
105 XX_Q17_ptr += LTP_ORDER * LTP_ORDER;
106 xX_Q17_ptr += LTP_ORDER;
107 }
108
109 if( rate_dist_Q7 <= min_rate_dist_Q7 ) {
110 min_rate_dist_Q7 = rate_dist_Q7;
111 *periodicity_index = (opus_int8)k;
112 silk_memcpy( cbk_index, temp_idx, nb_subfr * sizeof( opus_int8 ) );
113 best_sum_log_gain_Q7 = sum_log_gain_tmp_Q7;
114 }
115 }
116
117 cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ *periodicity_index ];
118 for( j = 0; j < nb_subfr; j++ ) {
119 for( k = 0; k < LTP_ORDER; k++ ) {
120 B_Q14[ j * LTP_ORDER + k ] = silk_LSHIFT( cbk_ptr_Q7[ cbk_index[ j ] * LTP_ORDER + k ], 7 );
121 }
122 }
123
124 if( nb_subfr == 2 ) {
125 res_nrg_Q15 = silk_RSHIFT32( res_nrg_Q15, 1 );
126 } else {
127 res_nrg_Q15 = silk_RSHIFT32( res_nrg_Q15, 2 );
128 }
129
130 *sum_log_gain_Q7 = best_sum_log_gain_Q7;
131 *pred_gain_dB_Q7 = (opus_int)silk_SMULBB( -3, silk_lin2log( res_nrg_Q15 ) - ( 15 << 7 ) );
132}
diff --git a/lib/rbcodec/codecs/libopus/silk/resampler.c b/lib/rbcodec/codecs/libopus/silk/resampler.c
index 374fbb3722..1f11e50891 100644
--- a/lib/rbcodec/codecs/libopus/silk/resampler.c
+++ b/lib/rbcodec/codecs/libopus/silk/resampler.c
@@ -91,14 +91,14 @@ opus_int silk_resampler_init(
91 if( forEnc ) { 91 if( forEnc ) {
92 if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 && Fs_Hz_in != 24000 && Fs_Hz_in != 48000 ) || 92 if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 && Fs_Hz_in != 24000 && Fs_Hz_in != 48000 ) ||
93 ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 ) ) { 93 ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 ) ) {
94 silk_assert( 0 ); 94 celt_assert( 0 );
95 return -1; 95 return -1;
96 } 96 }
97 S->inputDelay = delay_matrix_enc[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ]; 97 S->inputDelay = delay_matrix_enc[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ];
98 } else { 98 } else {
99 if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 ) || 99 if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 ) ||
100 ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 && Fs_Hz_out != 24000 && Fs_Hz_out != 48000 ) ) { 100 ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 && Fs_Hz_out != 24000 && Fs_Hz_out != 48000 ) ) {
101 silk_assert( 0 ); 101 celt_assert( 0 );
102 return -1; 102 return -1;
103 } 103 }
104 S->inputDelay = delay_matrix_dec[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ]; 104 S->inputDelay = delay_matrix_dec[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ];
@@ -151,7 +151,7 @@ opus_int silk_resampler_init(
151 S->Coefs = silk_Resampler_1_6_COEFS; 151 S->Coefs = silk_Resampler_1_6_COEFS;
152 } else { 152 } else {
153 /* None available */ 153 /* None available */
154 silk_assert( 0 ); 154 celt_assert( 0 );
155 return -1; 155 return -1;
156 } 156 }
157 } else { 157 } else {
@@ -181,9 +181,9 @@ opus_int silk_resampler(
181 opus_int nSamples; 181 opus_int nSamples;
182 182
183 /* Need at least 1 ms of input data */ 183 /* Need at least 1 ms of input data */
184 silk_assert( inLen >= S->Fs_in_kHz ); 184 celt_assert( inLen >= S->Fs_in_kHz );
185 /* Delay can't exceed the 1 ms of buffering */ 185 /* Delay can't exceed the 1 ms of buffering */
186 silk_assert( S->inputDelay <= S->Fs_in_kHz ); 186 celt_assert( S->inputDelay <= S->Fs_in_kHz );
187 187
188 nSamples = S->Fs_in_kHz - S->inputDelay; 188 nSamples = S->Fs_in_kHz - S->inputDelay;
189 189
diff --git a/lib/rbcodec/codecs/libopus/silk/resampler_down2.c b/lib/rbcodec/codecs/libopus/silk/resampler_down2.c
new file mode 100644
index 0000000000..971d7bfd4a
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/resampler_down2.c
@@ -0,0 +1,74 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33#include "resampler_rom.h"
34
35/* Downsample by a factor 2 */
36void silk_resampler_down2(
37 opus_int32 *S, /* I/O State vector [ 2 ] */
38 opus_int16 *out, /* O Output signal [ floor(len/2) ] */
39 const opus_int16 *in, /* I Input signal [ len ] */
40 opus_int32 inLen /* I Number of input samples */
41)
42{
43 opus_int32 k, len2 = silk_RSHIFT32( inLen, 1 );
44 opus_int32 in32, out32, Y, X;
45
46 celt_assert( silk_resampler_down2_0 > 0 );
47 celt_assert( silk_resampler_down2_1 < 0 );
48
49 /* Internal variables and state are in Q10 format */
50 for( k = 0; k < len2; k++ ) {
51 /* Convert to Q10 */
52 in32 = silk_LSHIFT( (opus_int32)in[ 2 * k ], 10 );
53
54 /* All-pass section for even input sample */
55 Y = silk_SUB32( in32, S[ 0 ] );
56 X = silk_SMLAWB( Y, Y, silk_resampler_down2_1 );
57 out32 = silk_ADD32( S[ 0 ], X );
58 S[ 0 ] = silk_ADD32( in32, X );
59
60 /* Convert to Q10 */
61 in32 = silk_LSHIFT( (opus_int32)in[ 2 * k + 1 ], 10 );
62
63 /* All-pass section for odd input sample, and add to output of previous section */
64 Y = silk_SUB32( in32, S[ 1 ] );
65 X = silk_SMULWB( Y, silk_resampler_down2_0 );
66 out32 = silk_ADD32( out32, S[ 1 ] );
67 out32 = silk_ADD32( out32, X );
68 S[ 1 ] = silk_ADD32( in32, X );
69
70 /* Add, convert back to int16 and store to output */
71 out[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( out32, 11 ) );
72 }
73}
74
diff --git a/lib/rbcodec/codecs/libopus/silk/resampler_down2_3.c b/lib/rbcodec/codecs/libopus/silk/resampler_down2_3.c
new file mode 100644
index 0000000000..4342614dcc
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/resampler_down2_3.c
@@ -0,0 +1,103 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "SigProc_FIX.h"
33#include "resampler_private.h"
34#include "stack_alloc.h"
35
36#define ORDER_FIR 4
37
38/* Downsample by a factor 2/3, low quality */
39void silk_resampler_down2_3(
40 opus_int32 *S, /* I/O State vector [ 6 ] */
41 opus_int16 *out, /* O Output signal [ floor(2*inLen/3) ] */
42 const opus_int16 *in, /* I Input signal [ inLen ] */
43 opus_int32 inLen /* I Number of input samples */
44)
45{
46 opus_int32 nSamplesIn, counter, res_Q6;
47 VARDECL( opus_int32, buf );
48 opus_int32 *buf_ptr;
49 SAVE_STACK;
50
51 ALLOC( buf, RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR, opus_int32 );
52
53 /* Copy buffered samples to start of buffer */
54 silk_memcpy( buf, S, ORDER_FIR * sizeof( opus_int32 ) );
55
56 /* Iterate over blocks of frameSizeIn input samples */
57 while( 1 ) {
58 nSamplesIn = silk_min( inLen, RESAMPLER_MAX_BATCH_SIZE_IN );
59
60 /* Second-order AR filter (output in Q8) */
61 silk_resampler_private_AR2( &S[ ORDER_FIR ], &buf[ ORDER_FIR ], in,
62 silk_Resampler_2_3_COEFS_LQ, nSamplesIn );
63
64 /* Interpolate filtered signal */
65 buf_ptr = buf;
66 counter = nSamplesIn;
67 while( counter > 2 ) {
68 /* Inner product */
69 res_Q6 = silk_SMULWB( buf_ptr[ 0 ], silk_Resampler_2_3_COEFS_LQ[ 2 ] );
70 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 1 ], silk_Resampler_2_3_COEFS_LQ[ 3 ] );
71 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], silk_Resampler_2_3_COEFS_LQ[ 5 ] );
72 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], silk_Resampler_2_3_COEFS_LQ[ 4 ] );
73
74 /* Scale down, saturate and store in output array */
75 *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) );
76
77 res_Q6 = silk_SMULWB( buf_ptr[ 1 ], silk_Resampler_2_3_COEFS_LQ[ 4 ] );
78 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], silk_Resampler_2_3_COEFS_LQ[ 5 ] );
79 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], silk_Resampler_2_3_COEFS_LQ[ 3 ] );
80 res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 4 ], silk_Resampler_2_3_COEFS_LQ[ 2 ] );
81
82 /* Scale down, saturate and store in output array */
83 *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) );
84
85 buf_ptr += 3;
86 counter -= 3;
87 }
88
89 in += nSamplesIn;
90 inLen -= nSamplesIn;
91
92 if( inLen > 0 ) {
93 /* More iterations to do; copy last part of filtered signal to beginning of buffer */
94 silk_memcpy( buf, &buf[ nSamplesIn ], ORDER_FIR * sizeof( opus_int32 ) );
95 } else {
96 break;
97 }
98 }
99
100 /* Copy last part of filtered signal to the state for the next call */
101 silk_memcpy( S, &buf[ nSamplesIn ], ORDER_FIR * sizeof( opus_int32 ) );
102 RESTORE_STACK;
103}
diff --git a/lib/rbcodec/codecs/libopus/silk/resampler_private_down_FIR.c b/lib/rbcodec/codecs/libopus/silk/resampler_private_down_FIR.c
index 783e42b356..3e8735a35a 100644
--- a/lib/rbcodec/codecs/libopus/silk/resampler_private_down_FIR.c
+++ b/lib/rbcodec/codecs/libopus/silk/resampler_private_down_FIR.c
@@ -136,7 +136,7 @@ static OPUS_INLINE opus_int16 *silk_resampler_private_down_FIR_INTERPOL(
136 } 136 }
137 break; 137 break;
138 default: 138 default:
139 silk_assert( 0 ); 139 celt_assert( 0 );
140 } 140 }
141 return out; 141 return out;
142} 142}
diff --git a/lib/rbcodec/codecs/libopus/silk/resampler_rom.c b/lib/rbcodec/codecs/libopus/silk/resampler_rom.c
index 2d502706f9..5e6b04476a 100644
--- a/lib/rbcodec/codecs/libopus/silk/resampler_rom.c
+++ b/lib/rbcodec/codecs/libopus/silk/resampler_rom.c
@@ -41,36 +41,36 @@ POSSIBILITY OF SUCH DAMAGE.
41 41
42/* Tables with IIR and FIR coefficients for fractional downsamplers (123 Words) */ 42/* Tables with IIR and FIR coefficients for fractional downsamplers (123 Words) */
43silk_DWORD_ALIGN const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = { 43silk_DWORD_ALIGN const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = {
44 -20694, -13867, 44 -20694, -13867,
45 -49, 64, 17, -157, 353, -496, 163, 11047, 22205, 45 -49, 64, 17, -157, 353, -496, 163, 11047, 22205,
46 -39, 6, 91, -170, 186, 23, -896, 6336, 19928, 46 -39, 6, 91, -170, 186, 23, -896, 6336, 19928,
47 -19, -36, 102, -89, -24, 328, -951, 2568, 15909, 47 -19, -36, 102, -89, -24, 328, -951, 2568, 15909,
48}; 48};
49 49
50silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = { 50silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = {
51 -14457, -14019, 51 -14457, -14019,
52 64, 128, -122, 36, 310, -768, 584, 9267, 17733, 52 64, 128, -122, 36, 310, -768, 584, 9267, 17733,
53 12, 128, 18, -142, 288, -117, -865, 4123, 14459, 53 12, 128, 18, -142, 288, -117, -865, 4123, 14459,
54}; 54};
55 55
56silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR1 / 2 ] = { 56silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR1 / 2 ] = {
57 616, -14323, 57 616, -14323,
58 -10, 39, 58, -46, -84, 120, 184, -315, -541, 1284, 5380, 9024, 58 -10, 39, 58, -46, -84, 120, 184, -315, -541, 1284, 5380, 9024,
59}; 59};
60 60
61silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { 61silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = {
62 16102, -15162, 62 16102, -15162,
63 -13, 0, 20, 26, 5, -31, -43, -4, 65, 90, 7, -157, -248, -44, 593, 1583, 2612, 3271, 63 -13, 0, 20, 26, 5, -31, -43, -4, 65, 90, 7, -157, -248, -44, 593, 1583, 2612, 3271,
64}; 64};
65 65
66silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_4_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { 66silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_4_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = {
67 22500, -15099, 67 22500, -15099,
68 3, -14, -20, -15, 2, 25, 37, 25, -16, -71, -107, -79, 50, 292, 623, 982, 1288, 1464, 68 3, -14, -20, -15, 2, 25, 37, 25, -16, -71, -107, -79, 50, 292, 623, 982, 1288, 1464,
69}; 69};
70 70
71silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_6_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { 71silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_6_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = {
72 27540, -15257, 72 27540, -15257,
73 17, 12, 8, 1, -10, -22, -30, -32, -22, 3, 44, 100, 168, 243, 317, 381, 429, 455, 73 17, 12, 8, 1, -10, -22, -30, -32, -22, 3, 44, 100, 168, 243, 317, 381, 429, 455,
74}; 74};
75 75
76silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = { 76silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = {
@@ -81,16 +81,16 @@ silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = {
81 81
82/* Table with interplation fractions of 1/24, 3/24, 5/24, ... , 23/24 : 23/24 (46 Words) */ 82/* Table with interplation fractions of 1/24, 3/24, 5/24, ... , 23/24 : 23/24 (46 Words) */
83silk_DWORD_ALIGN const opus_int16 silk_resampler_frac_FIR_12[ 12 ][ RESAMPLER_ORDER_FIR_12 / 2 ] = { 83silk_DWORD_ALIGN const opus_int16 silk_resampler_frac_FIR_12[ 12 ][ RESAMPLER_ORDER_FIR_12 / 2 ] = {
84 { 189, -600, 617, 30567 }, 84 { 189, -600, 617, 30567 },
85 { 117, -159, -1070, 29704 }, 85 { 117, -159, -1070, 29704 },
86 { 52, 221, -2392, 28276 }, 86 { 52, 221, -2392, 28276 },
87 { -4, 529, -3350, 26341 }, 87 { -4, 529, -3350, 26341 },
88 { -48, 758, -3956, 23973 }, 88 { -48, 758, -3956, 23973 },
89 { -80, 905, -4235, 21254 }, 89 { -80, 905, -4235, 21254 },
90 { -99, 972, -4222, 18278 }, 90 { -99, 972, -4222, 18278 },
91 { -107, 967, -3957, 15143 }, 91 { -107, 967, -3957, 15143 },
92 { -103, 896, -3487, 11950 }, 92 { -103, 896, -3487, 11950 },
93 { -91, 773, -2865, 8798 }, 93 { -91, 773, -2865, 8798 },
94 { -71, 611, -2143, 5784 }, 94 { -71, 611, -2143, 5784 },
95 { -46, 425, -1375, 2996 }, 95 { -46, 425, -1375, 2996 },
96}; 96};
diff --git a/lib/rbcodec/codecs/libopus/silk/shell_coder.c b/lib/rbcodec/codecs/libopus/silk/shell_coder.c
index d80dd51f9e..4af341474b 100644
--- a/lib/rbcodec/codecs/libopus/silk/shell_coder.c
+++ b/lib/rbcodec/codecs/libopus/silk/shell_coder.c
@@ -45,7 +45,6 @@ static OPUS_INLINE void combine_pulses(
45 } 45 }
46} 46}
47 47
48#if 0
49static OPUS_INLINE void encode_split( 48static OPUS_INLINE void encode_split(
50 ec_enc *psRangeEnc, /* I/O compressor data structure */ 49 ec_enc *psRangeEnc, /* I/O compressor data structure */
51 const opus_int p_child1, /* I pulse amplitude of first child subframe */ 50 const opus_int p_child1, /* I pulse amplitude of first child subframe */
@@ -57,7 +56,6 @@ static OPUS_INLINE void encode_split(
57 ec_enc_icdf( psRangeEnc, p_child1, &shell_table[ silk_shell_code_table_offsets[ p ] ], 8 ); 56 ec_enc_icdf( psRangeEnc, p_child1, &shell_table[ silk_shell_code_table_offsets[ p ] ], 8 );
58 } 57 }
59} 58}
60#endif
61 59
62static OPUS_INLINE void decode_split( 60static OPUS_INLINE void decode_split(
63 opus_int16 *p_child1, /* O pulse amplitude of first child subframe */ 61 opus_int16 *p_child1, /* O pulse amplitude of first child subframe */
@@ -76,7 +74,6 @@ static OPUS_INLINE void decode_split(
76 } 74 }
77} 75}
78 76
79#if 0
80/* Shell encoder, operates on one shell code frame of 16 pulses */ 77/* Shell encoder, operates on one shell code frame of 16 pulses */
81void silk_shell_encoder( 78void silk_shell_encoder(
82 ec_enc *psRangeEnc, /* I/O compressor data structure */ 79 ec_enc *psRangeEnc, /* I/O compressor data structure */
@@ -116,7 +113,6 @@ void silk_shell_encoder(
116 encode_split( psRangeEnc, pulses0[ 12 ], pulses1[ 6 ], silk_shell_code_table0 ); 113 encode_split( psRangeEnc, pulses0[ 12 ], pulses1[ 6 ], silk_shell_code_table0 );
117 encode_split( psRangeEnc, pulses0[ 14 ], pulses1[ 7 ], silk_shell_code_table0 ); 114 encode_split( psRangeEnc, pulses0[ 14 ], pulses1[ 7 ], silk_shell_code_table0 );
118} 115}
119#endif
120 116
121 117
122/* Shell decoder, operates on one shell code frame of 16 pulses */ 118/* Shell decoder, operates on one shell code frame of 16 pulses */
diff --git a/lib/rbcodec/codecs/libopus/silk/sigm_Q15.c b/lib/rbcodec/codecs/libopus/silk/sigm_Q15.c
new file mode 100644
index 0000000000..3c507d255b
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/sigm_Q15.c
@@ -0,0 +1,76 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32/* Approximate sigmoid function */
33
34#include "SigProc_FIX.h"
35
36/* fprintf(1, '%d, ', round(1024 * ([1 ./ (1 + exp(-(1:5))), 1] - 1 ./ (1 + exp(-(0:5)))))); */
37static const opus_int32 sigm_LUT_slope_Q10[ 6 ] = {
38 237, 153, 73, 30, 12, 7
39};
40/* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp(-(0:5))))); */
41static const opus_int32 sigm_LUT_pos_Q15[ 6 ] = {
42 16384, 23955, 28861, 31213, 32178, 32548
43};
44/* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp((0:5))))); */
45static const opus_int32 sigm_LUT_neg_Q15[ 6 ] = {
46 16384, 8812, 3906, 1554, 589, 219
47};
48
49opus_int silk_sigm_Q15(
50 opus_int in_Q5 /* I */
51)
52{
53 opus_int ind;
54
55 if( in_Q5 < 0 ) {
56 /* Negative input */
57 in_Q5 = -in_Q5;
58 if( in_Q5 >= 6 * 32 ) {
59 return 0; /* Clip */
60 } else {
61 /* Linear interpolation of look up table */
62 ind = silk_RSHIFT( in_Q5, 5 );
63 return( sigm_LUT_neg_Q15[ ind ] - silk_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) );
64 }
65 } else {
66 /* Positive input */
67 if( in_Q5 >= 6 * 32 ) {
68 return 32767; /* clip */
69 } else {
70 /* Linear interpolation of look up table */
71 ind = silk_RSHIFT( in_Q5, 5 );
72 return( sigm_LUT_pos_Q15[ ind ] + silk_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) );
73 }
74 }
75}
76
diff --git a/lib/rbcodec/codecs/libopus/silk/sort.c b/lib/rbcodec/codecs/libopus/silk/sort.c
index 2f9930d9ce..4fba16f831 100644
--- a/lib/rbcodec/codecs/libopus/silk/sort.c
+++ b/lib/rbcodec/codecs/libopus/silk/sort.c
@@ -33,11 +33,10 @@ POSSIBILITY OF SUCH DAMAGE.
33/* Best case: O(n) for an already sorted array */ 33/* Best case: O(n) for an already sorted array */
34/* Worst case: O(n^2) for an inversely sorted array */ 34/* Worst case: O(n^2) for an inversely sorted array */
35/* */ 35/* */
36/* Shell short: http://en.wikipedia.org/wiki/Shell_sort */ 36/* Shell short: https://en.wikipedia.org/wiki/Shell_sort */
37 37
38#include "SigProc_FIX.h" 38#include "SigProc_FIX.h"
39 39
40#if 0
41void silk_insertion_sort_increasing( 40void silk_insertion_sort_increasing(
42 opus_int32 *a, /* I/O Unsorted / Sorted vector */ 41 opus_int32 *a, /* I/O Unsorted / Sorted vector */
43 opus_int *idx, /* O Index vector for the sorted elements */ 42 opus_int *idx, /* O Index vector for the sorted elements */
@@ -49,9 +48,9 @@ void silk_insertion_sort_increasing(
49 opus_int i, j; 48 opus_int i, j;
50 49
51 /* Safety checks */ 50 /* Safety checks */
52 silk_assert( K > 0 ); 51 celt_assert( K > 0 );
53 silk_assert( L > 0 ); 52 celt_assert( L > 0 );
54 silk_assert( L >= K ); 53 celt_assert( L >= K );
55 54
56 /* Write start indices in index vector */ 55 /* Write start indices in index vector */
57 for( i = 0; i < K; i++ ) { 56 for( i = 0; i < K; i++ ) {
@@ -83,7 +82,6 @@ void silk_insertion_sort_increasing(
83 } 82 }
84 } 83 }
85} 84}
86#endif
87 85
88#ifdef FIXED_POINT 86#ifdef FIXED_POINT
89/* This function is only used by the fixed-point build */ 87/* This function is only used by the fixed-point build */
@@ -98,9 +96,9 @@ void silk_insertion_sort_decreasing_int16(
98 opus_int value; 96 opus_int value;
99 97
100 /* Safety checks */ 98 /* Safety checks */
101 silk_assert( K > 0 ); 99 celt_assert( K > 0 );
102 silk_assert( L > 0 ); 100 celt_assert( L > 0 );
103 silk_assert( L >= K ); 101 celt_assert( L >= K );
104 102
105 /* Write start indices in index vector */ 103 /* Write start indices in index vector */
106 for( i = 0; i < K; i++ ) { 104 for( i = 0; i < K; i++ ) {
@@ -143,7 +141,7 @@ void silk_insertion_sort_increasing_all_values_int16(
143 opus_int i, j; 141 opus_int i, j;
144 142
145 /* Safety checks */ 143 /* Safety checks */
146 silk_assert( L > 0 ); 144 celt_assert( L > 0 );
147 145
148 /* Sort vector elements by value, increasing order */ 146 /* Sort vector elements by value, increasing order */
149 for( i = 1; i < L; i++ ) { 147 for( i = 1; i < L; i++ ) {
diff --git a/lib/rbcodec/codecs/libopus/silk/stereo_LR_to_MS.c b/lib/rbcodec/codecs/libopus/silk/stereo_LR_to_MS.c
new file mode 100644
index 0000000000..c8226663c8
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/stereo_LR_to_MS.c
@@ -0,0 +1,229 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33#include "stack_alloc.h"
34
35/* Convert Left/Right stereo signal to adaptive Mid/Side representation */
36void silk_stereo_LR_to_MS(
37 stereo_enc_state *state, /* I/O State */
38 opus_int16 x1[], /* I/O Left input signal, becomes mid signal */
39 opus_int16 x2[], /* I/O Right input signal, becomes side signal */
40 opus_int8 ix[ 2 ][ 3 ], /* O Quantization indices */
41 opus_int8 *mid_only_flag, /* O Flag: only mid signal coded */
42 opus_int32 mid_side_rates_bps[], /* O Bitrates for mid and side signals */
43 opus_int32 total_rate_bps, /* I Total bitrate */
44 opus_int prev_speech_act_Q8, /* I Speech activity level in previous frame */
45 opus_int toMono, /* I Last frame before a stereo->mono transition */
46 opus_int fs_kHz, /* I Sample rate (kHz) */
47 opus_int frame_length /* I Number of samples */
48)
49{
50 opus_int n, is10msFrame, denom_Q16, delta0_Q13, delta1_Q13;
51 opus_int32 sum, diff, smooth_coef_Q16, pred_Q13[ 2 ], pred0_Q13, pred1_Q13;
52 opus_int32 LP_ratio_Q14, HP_ratio_Q14, frac_Q16, frac_3_Q16, min_mid_rate_bps, width_Q14, w_Q24, deltaw_Q24;
53 VARDECL( opus_int16, side );
54 VARDECL( opus_int16, LP_mid );
55 VARDECL( opus_int16, HP_mid );
56 VARDECL( opus_int16, LP_side );
57 VARDECL( opus_int16, HP_side );
58 opus_int16 *mid = &x1[ -2 ];
59 SAVE_STACK;
60
61 ALLOC( side, frame_length + 2, opus_int16 );
62 /* Convert to basic mid/side signals */
63 for( n = 0; n < frame_length + 2; n++ ) {
64 sum = x1[ n - 2 ] + (opus_int32)x2[ n - 2 ];
65 diff = x1[ n - 2 ] - (opus_int32)x2[ n - 2 ];
66 mid[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 );
67 side[ n ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( diff, 1 ) );
68 }
69
70 /* Buffering */
71 silk_memcpy( mid, state->sMid, 2 * sizeof( opus_int16 ) );
72 silk_memcpy( side, state->sSide, 2 * sizeof( opus_int16 ) );
73 silk_memcpy( state->sMid, &mid[ frame_length ], 2 * sizeof( opus_int16 ) );
74 silk_memcpy( state->sSide, &side[ frame_length ], 2 * sizeof( opus_int16 ) );
75
76 /* LP and HP filter mid signal */
77 ALLOC( LP_mid, frame_length, opus_int16 );
78 ALLOC( HP_mid, frame_length, opus_int16 );
79 for( n = 0; n < frame_length; n++ ) {
80 sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 2 );
81 LP_mid[ n ] = sum;
82 HP_mid[ n ] = mid[ n + 1 ] - sum;
83 }
84
85 /* LP and HP filter side signal */
86 ALLOC( LP_side, frame_length, opus_int16 );
87 ALLOC( HP_side, frame_length, opus_int16 );
88 for( n = 0; n < frame_length; n++ ) {
89 sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( side[ n ] + (opus_int32)side[ n + 2 ], side[ n + 1 ], 1 ), 2 );
90 LP_side[ n ] = sum;
91 HP_side[ n ] = side[ n + 1 ] - sum;
92 }
93
94 /* Find energies and predictors */
95 is10msFrame = frame_length == 10 * fs_kHz;
96 smooth_coef_Q16 = is10msFrame ?
97 SILK_FIX_CONST( STEREO_RATIO_SMOOTH_COEF / 2, 16 ) :
98 SILK_FIX_CONST( STEREO_RATIO_SMOOTH_COEF, 16 );
99 smooth_coef_Q16 = silk_SMULWB( silk_SMULBB( prev_speech_act_Q8, prev_speech_act_Q8 ), smooth_coef_Q16 );
100
101 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 );
102 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 );
103 /* Ratio of the norms of residual and mid signals */
104 frac_Q16 = silk_SMLABB( HP_ratio_Q14, LP_ratio_Q14, 3 );
105 frac_Q16 = silk_min( frac_Q16, SILK_FIX_CONST( 1, 16 ) );
106
107 /* Determine bitrate distribution between mid and side, and possibly reduce stereo width */
108 total_rate_bps -= is10msFrame ? 1200 : 600; /* Subtract approximate bitrate for coding stereo parameters */
109 if( total_rate_bps < 1 ) {
110 total_rate_bps = 1;
111 }
112 min_mid_rate_bps = silk_SMLABB( 2000, fs_kHz, 600 );
113 silk_assert( min_mid_rate_bps < 32767 );
114 /* Default bitrate distribution: 8 parts for Mid and (5+3*frac) parts for Side. so: mid_rate = ( 8 / ( 13 + 3 * frac ) ) * total_ rate */
115 frac_3_Q16 = silk_MUL( 3, frac_Q16 );
116 mid_side_rates_bps[ 0 ] = silk_DIV32_varQ( total_rate_bps, SILK_FIX_CONST( 8 + 5, 16 ) + frac_3_Q16, 16+3 );
117 /* If Mid bitrate below minimum, reduce stereo width */
118 if( mid_side_rates_bps[ 0 ] < min_mid_rate_bps ) {
119 mid_side_rates_bps[ 0 ] = min_mid_rate_bps;
120 mid_side_rates_bps[ 1 ] = total_rate_bps - mid_side_rates_bps[ 0 ];
121 /* width = 4 * ( 2 * side_rate - min_rate ) / ( ( 1 + 3 * frac ) * min_rate ) */
122 width_Q14 = silk_DIV32_varQ( silk_LSHIFT( mid_side_rates_bps[ 1 ], 1 ) - min_mid_rate_bps,
123 silk_SMULWB( SILK_FIX_CONST( 1, 16 ) + frac_3_Q16, min_mid_rate_bps ), 14+2 );
124 width_Q14 = silk_LIMIT( width_Q14, 0, SILK_FIX_CONST( 1, 14 ) );
125 } else {
126 mid_side_rates_bps[ 1 ] = total_rate_bps - mid_side_rates_bps[ 0 ];
127 width_Q14 = SILK_FIX_CONST( 1, 14 );
128 }
129
130 /* Smoother */
131 state->smth_width_Q14 = (opus_int16)silk_SMLAWB( state->smth_width_Q14, width_Q14 - state->smth_width_Q14, smooth_coef_Q16 );
132
133 /* At very low bitrates or for inputs that are nearly amplitude panned, switch to panned-mono coding */
134 *mid_only_flag = 0;
135 if( toMono ) {
136 /* Last frame before stereo->mono transition; collapse stereo width */
137 width_Q14 = 0;
138 pred_Q13[ 0 ] = 0;
139 pred_Q13[ 1 ] = 0;
140 silk_stereo_quant_pred( pred_Q13, ix );
141 } else if( state->width_prev_Q14 == 0 &&
142 ( 8 * total_rate_bps < 13 * min_mid_rate_bps || silk_SMULWB( frac_Q16, state->smth_width_Q14 ) < SILK_FIX_CONST( 0.05, 14 ) ) )
143 {
144 /* Code as panned-mono; previous frame already had zero width */
145 /* Scale down and quantize predictors */
146 pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 );
147 pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 );
148 silk_stereo_quant_pred( pred_Q13, ix );
149 /* Collapse stereo width */
150 width_Q14 = 0;
151 pred_Q13[ 0 ] = 0;
152 pred_Q13[ 1 ] = 0;
153 mid_side_rates_bps[ 0 ] = total_rate_bps;
154 mid_side_rates_bps[ 1 ] = 0;
155 *mid_only_flag = 1;
156 } else if( state->width_prev_Q14 != 0 &&
157 ( 8 * total_rate_bps < 11 * min_mid_rate_bps || silk_SMULWB( frac_Q16, state->smth_width_Q14 ) < SILK_FIX_CONST( 0.02, 14 ) ) )
158 {
159 /* Transition to zero-width stereo */
160 /* Scale down and quantize predictors */
161 pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 );
162 pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 );
163 silk_stereo_quant_pred( pred_Q13, ix );
164 /* Collapse stereo width */
165 width_Q14 = 0;
166 pred_Q13[ 0 ] = 0;
167 pred_Q13[ 1 ] = 0;
168 } else if( state->smth_width_Q14 > SILK_FIX_CONST( 0.95, 14 ) ) {
169 /* Full-width stereo coding */
170 silk_stereo_quant_pred( pred_Q13, ix );
171 width_Q14 = SILK_FIX_CONST( 1, 14 );
172 } else {
173 /* Reduced-width stereo coding; scale down and quantize predictors */
174 pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 );
175 pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 );
176 silk_stereo_quant_pred( pred_Q13, ix );
177 width_Q14 = state->smth_width_Q14;
178 }
179
180 /* Make sure to keep on encoding until the tapered output has been transmitted */
181 if( *mid_only_flag == 1 ) {
182 state->silent_side_len += frame_length - STEREO_INTERP_LEN_MS * fs_kHz;
183 if( state->silent_side_len < LA_SHAPE_MS * fs_kHz ) {
184 *mid_only_flag = 0;
185 } else {
186 /* Limit to avoid wrapping around */
187 state->silent_side_len = 10000;
188 }
189 } else {
190 state->silent_side_len = 0;
191 }
192
193 if( *mid_only_flag == 0 && mid_side_rates_bps[ 1 ] < 1 ) {
194 mid_side_rates_bps[ 1 ] = 1;
195 mid_side_rates_bps[ 0 ] = silk_max_int( 1, total_rate_bps - mid_side_rates_bps[ 1 ]);
196 }
197
198 /* Interpolate predictors and subtract prediction from side channel */
199 pred0_Q13 = -state->pred_prev_Q13[ 0 ];
200 pred1_Q13 = -state->pred_prev_Q13[ 1 ];
201 w_Q24 = silk_LSHIFT( state->width_prev_Q14, 10 );
202 denom_Q16 = silk_DIV32_16( (opus_int32)1 << 16, STEREO_INTERP_LEN_MS * fs_kHz );
203 delta0_Q13 = -silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 0 ] - state->pred_prev_Q13[ 0 ], denom_Q16 ), 16 );
204 delta1_Q13 = -silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 1 ] - state->pred_prev_Q13[ 1 ], denom_Q16 ), 16 );
205 deltaw_Q24 = silk_LSHIFT( silk_SMULWB( width_Q14 - state->width_prev_Q14, denom_Q16 ), 10 );
206 for( n = 0; n < STEREO_INTERP_LEN_MS * fs_kHz; n++ ) {
207 pred0_Q13 += delta0_Q13;
208 pred1_Q13 += delta1_Q13;
209 w_Q24 += deltaw_Q24;
210 sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */
211 sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */
212 sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */
213 x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );
214 }
215
216 pred0_Q13 = -pred_Q13[ 0 ];
217 pred1_Q13 = -pred_Q13[ 1 ];
218 w_Q24 = silk_LSHIFT( width_Q14, 10 );
219 for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) {
220 sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */
221 sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */
222 sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */
223 x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );
224 }
225 state->pred_prev_Q13[ 0 ] = (opus_int16)pred_Q13[ 0 ];
226 state->pred_prev_Q13[ 1 ] = (opus_int16)pred_Q13[ 1 ];
227 state->width_prev_Q14 = (opus_int16)width_Q14;
228 RESTORE_STACK;
229}
diff --git a/lib/rbcodec/codecs/libopus/silk/stereo_encode_pred.c b/lib/rbcodec/codecs/libopus/silk/stereo_encode_pred.c
new file mode 100644
index 0000000000..03becb6736
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/stereo_encode_pred.c
@@ -0,0 +1,62 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33
34/* Entropy code the mid/side quantization indices */
35void silk_stereo_encode_pred(
36 ec_enc *psRangeEnc, /* I/O Compressor data structure */
37 opus_int8 ix[ 2 ][ 3 ] /* I Quantization indices */
38)
39{
40 opus_int n;
41
42 /* Entropy coding */
43 n = 5 * ix[ 0 ][ 2 ] + ix[ 1 ][ 2 ];
44 celt_assert( n < 25 );
45 ec_enc_icdf( psRangeEnc, n, silk_stereo_pred_joint_iCDF, 8 );
46 for( n = 0; n < 2; n++ ) {
47 celt_assert( ix[ n ][ 0 ] < 3 );
48 celt_assert( ix[ n ][ 1 ] < STEREO_QUANT_SUB_STEPS );
49 ec_enc_icdf( psRangeEnc, ix[ n ][ 0 ], silk_uniform3_iCDF, 8 );
50 ec_enc_icdf( psRangeEnc, ix[ n ][ 1 ], silk_uniform5_iCDF, 8 );
51 }
52}
53
54/* Entropy code the mid-only flag */
55void silk_stereo_encode_mid_only(
56 ec_enc *psRangeEnc, /* I/O Compressor data structure */
57 opus_int8 mid_only_flag
58)
59{
60 /* Encode flag that only mid channel is coded */
61 ec_enc_icdf( psRangeEnc, mid_only_flag, silk_stereo_only_code_mid_iCDF, 8 );
62}
diff --git a/lib/rbcodec/codecs/libopus/silk/stereo_find_predictor.c b/lib/rbcodec/codecs/libopus/silk/stereo_find_predictor.c
new file mode 100644
index 0000000000..e30e90bddc
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/stereo_find_predictor.c
@@ -0,0 +1,79 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33
34/* Find least-squares prediction gain for one signal based on another and quantize it */
35opus_int32 silk_stereo_find_predictor( /* O Returns predictor in Q13 */
36 opus_int32 *ratio_Q14, /* O Ratio of residual and mid energies */
37 const opus_int16 x[], /* I Basis signal */
38 const opus_int16 y[], /* I Target signal */
39 opus_int32 mid_res_amp_Q0[], /* I/O Smoothed mid, residual norms */
40 opus_int length, /* I Number of samples */
41 opus_int smooth_coef_Q16 /* I Smoothing coefficient */
42)
43{
44 opus_int scale, scale1, scale2;
45 opus_int32 nrgx, nrgy, corr, pred_Q13, pred2_Q10;
46
47 /* Find predictor */
48 silk_sum_sqr_shift( &nrgx, &scale1, x, length );
49 silk_sum_sqr_shift( &nrgy, &scale2, y, length );
50 scale = silk_max_int( scale1, scale2 );
51 scale = scale + ( scale & 1 ); /* make even */
52 nrgy = silk_RSHIFT32( nrgy, scale - scale2 );
53 nrgx = silk_RSHIFT32( nrgx, scale - scale1 );
54 nrgx = silk_max_int( nrgx, 1 );
55 corr = silk_inner_prod_aligned_scale( x, y, scale, length );
56 pred_Q13 = silk_DIV32_varQ( corr, nrgx, 13 );
57 pred_Q13 = silk_LIMIT( pred_Q13, -(1 << 14), 1 << 14 );
58 pred2_Q10 = silk_SMULWB( pred_Q13, pred_Q13 );
59
60 /* Faster update for signals with large prediction parameters */
61 smooth_coef_Q16 = (opus_int)silk_max_int( smooth_coef_Q16, silk_abs( pred2_Q10 ) );
62
63 /* Smoothed mid and residual norms */
64 silk_assert( smooth_coef_Q16 < 32768 );
65 scale = silk_RSHIFT( scale, 1 );
66 mid_res_amp_Q0[ 0 ] = silk_SMLAWB( mid_res_amp_Q0[ 0 ], silk_LSHIFT( silk_SQRT_APPROX( nrgx ), scale ) - mid_res_amp_Q0[ 0 ],
67 smooth_coef_Q16 );
68 /* Residual energy = nrgy - 2 * pred * corr + pred^2 * nrgx */
69 nrgy = silk_SUB_LSHIFT32( nrgy, silk_SMULWB( corr, pred_Q13 ), 3 + 1 );
70 nrgy = silk_ADD_LSHIFT32( nrgy, silk_SMULWB( nrgx, pred2_Q10 ), 6 );
71 mid_res_amp_Q0[ 1 ] = silk_SMLAWB( mid_res_amp_Q0[ 1 ], silk_LSHIFT( silk_SQRT_APPROX( nrgy ), scale ) - mid_res_amp_Q0[ 1 ],
72 smooth_coef_Q16 );
73
74 /* Ratio of smoothed residual and mid norms */
75 *ratio_Q14 = silk_DIV32_varQ( mid_res_amp_Q0[ 1 ], silk_max( mid_res_amp_Q0[ 0 ], 1 ), 14 );
76 *ratio_Q14 = silk_LIMIT( *ratio_Q14, 0, 32767 );
77
78 return pred_Q13;
79}
diff --git a/lib/rbcodec/codecs/libopus/silk/stereo_quant_pred.c b/lib/rbcodec/codecs/libopus/silk/stereo_quant_pred.c
new file mode 100644
index 0000000000..d4ced6c3e8
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/stereo_quant_pred.c
@@ -0,0 +1,73 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "main.h"
33
34/* Quantize mid/side predictors */
35void silk_stereo_quant_pred(
36 opus_int32 pred_Q13[], /* I/O Predictors (out: quantized) */
37 opus_int8 ix[ 2 ][ 3 ] /* O Quantization indices */
38)
39{
40 opus_int i, j, n;
41 opus_int32 low_Q13, step_Q13, lvl_Q13, err_min_Q13, err_Q13, quant_pred_Q13 = 0;
42
43 /* Quantize */
44 for( n = 0; n < 2; n++ ) {
45 /* Brute-force search over quantization levels */
46 err_min_Q13 = silk_int32_MAX;
47 for( i = 0; i < STEREO_QUANT_TAB_SIZE - 1; i++ ) {
48 low_Q13 = silk_stereo_pred_quant_Q13[ i ];
49 step_Q13 = silk_SMULWB( silk_stereo_pred_quant_Q13[ i + 1 ] - low_Q13,
50 SILK_FIX_CONST( 0.5 / STEREO_QUANT_SUB_STEPS, 16 ) );
51 for( j = 0; j < STEREO_QUANT_SUB_STEPS; j++ ) {
52 lvl_Q13 = silk_SMLABB( low_Q13, step_Q13, 2 * j + 1 );
53 err_Q13 = silk_abs( pred_Q13[ n ] - lvl_Q13 );
54 if( err_Q13 < err_min_Q13 ) {
55 err_min_Q13 = err_Q13;
56 quant_pred_Q13 = lvl_Q13;
57 ix[ n ][ 0 ] = i;
58 ix[ n ][ 1 ] = j;
59 } else {
60 /* Error increasing, so we're past the optimum */
61 goto done;
62 }
63 }
64 }
65 done:
66 ix[ n ][ 2 ] = silk_DIV32_16( ix[ n ][ 0 ], 3 );
67 ix[ n ][ 0 ] -= ix[ n ][ 2 ] * 3;
68 pred_Q13[ n ] = quant_pred_Q13;
69 }
70
71 /* Subtract second from first predictor (helps when actually applying these) */
72 pred_Q13[ 0 ] -= pred_Q13[ 1 ];
73}
diff --git a/lib/rbcodec/codecs/libopus/silk/structs.h b/lib/rbcodec/codecs/libopus/silk/structs.h
index 1826b36a80..3380c757b2 100644
--- a/lib/rbcodec/codecs/libopus/silk/structs.h
+++ b/lib/rbcodec/codecs/libopus/silk/structs.h
@@ -48,6 +48,7 @@ typedef struct {
48 opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ]; 48 opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ];
49 opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ]; 49 opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];
50 opus_int32 sLF_AR_shp_Q14; 50 opus_int32 sLF_AR_shp_Q14;
51 opus_int32 sDiff_shp_Q14;
51 opus_int lagPrev; 52 opus_int lagPrev;
52 opus_int sLTP_buf_idx; 53 opus_int sLTP_buf_idx;
53 opus_int sLTP_shp_buf_idx; 54 opus_int sLTP_shp_buf_idx;
@@ -77,6 +78,7 @@ typedef struct {
77 opus_int32 In_LP_State[ 2 ]; /* Low pass filter state */ 78 opus_int32 In_LP_State[ 2 ]; /* Low pass filter state */
78 opus_int32 transition_frame_no; /* Counter which is mapped to a cut-off frequency */ 79 opus_int32 transition_frame_no; /* Counter which is mapped to a cut-off frequency */
79 opus_int mode; /* Operating mode, <0: switch down, >0: switch up; 0: do nothing */ 80 opus_int mode; /* Operating mode, <0: switch down, >0: switch up; 0: do nothing */
81 opus_int32 saved_fs_kHz; /* If non-zero, holds the last sampling rate before a bandwidth switching reset. */
80} silk_LP_state; 82} silk_LP_state;
81 83
82/* Structure containing NLSF codebook */ 84/* Structure containing NLSF codebook */
@@ -86,6 +88,7 @@ typedef struct {
86 const opus_int16 quantStepSize_Q16; 88 const opus_int16 quantStepSize_Q16;
87 const opus_int16 invQuantStepSize_Q6; 89 const opus_int16 invQuantStepSize_Q6;
88 const opus_uint8 *CB1_NLSF_Q8; 90 const opus_uint8 *CB1_NLSF_Q8;
91 const opus_int16 *CB1_Wght_Q9;
89 const opus_uint8 *CB1_iCDF; 92 const opus_uint8 *CB1_iCDF;
90 const opus_uint8 *pred_Q8; 93 const opus_uint8 *pred_Q8;
91 const opus_uint8 *ec_sel; 94 const opus_uint8 *ec_sel;
@@ -169,9 +172,7 @@ typedef struct {
169 opus_int pitchEstimationComplexity; /* Complexity level for pitch estimator */ 172 opus_int pitchEstimationComplexity; /* Complexity level for pitch estimator */
170 opus_int pitchEstimationLPCOrder; /* Whitening filter order for pitch estimator */ 173 opus_int pitchEstimationLPCOrder; /* Whitening filter order for pitch estimator */
171 opus_int32 pitchEstimationThreshold_Q16; /* Threshold for pitch estimator */ 174 opus_int32 pitchEstimationThreshold_Q16; /* Threshold for pitch estimator */
172 opus_int LTPQuantLowComplexity; /* Flag for low complexity LTP quantization */ 175 opus_int32 sum_log_gain_Q7; /* Cumulative max prediction gain */
173 opus_int mu_LTP_Q9; /* Rate-distortion tradeoff in LTP quantization */
174 opus_int32 sum_log_gain_Q7; /* Cumulative max prediction gain */
175 opus_int NLSF_MSVQ_Survivors; /* Number of survivors in NLSF MSVQ */ 176 opus_int NLSF_MSVQ_Survivors; /* Number of survivors in NLSF MSVQ */
176 opus_int first_frame_after_reset; /* Flag for deactivating NLSF interpolation, pitch prediction */ 177 opus_int first_frame_after_reset; /* Flag for deactivating NLSF interpolation, pitch prediction */
177 opus_int controlled_since_last_payload; /* Flag for ensuring codec_control only runs once per packet */ 178 opus_int controlled_since_last_payload; /* Flag for ensuring codec_control only runs once per packet */
@@ -301,6 +302,7 @@ typedef struct {
301 /* Stuff used for PLC */ 302 /* Stuff used for PLC */
302 opus_int lossCnt; 303 opus_int lossCnt;
303 opus_int prevSignalType; 304 opus_int prevSignalType;
305 int arch;
304 306
305 silk_PLC_struct sPLC; 307 silk_PLC_struct sPLC;
306 308
diff --git a/lib/rbcodec/codecs/libopus/silk/sum_sqr_shift.c b/lib/rbcodec/codecs/libopus/silk/sum_sqr_shift.c
index 129df191d8..4fd0c3d7d5 100644
--- a/lib/rbcodec/codecs/libopus/silk/sum_sqr_shift.c
+++ b/lib/rbcodec/codecs/libopus/silk/sum_sqr_shift.c
@@ -41,43 +41,40 @@ void silk_sum_sqr_shift(
41) 41)
42{ 42{
43 opus_int i, shft; 43 opus_int i, shft;
44 opus_int32 nrg_tmp, nrg; 44 opus_uint32 nrg_tmp;
45 opus_int32 nrg;
45 46
46 nrg = 0; 47 /* Do a first run with the maximum shift we could have. */
47 shft = 0; 48 shft = 31-silk_CLZ32(len);
48 len--; 49 /* Let's be conservative with rounding and start with nrg=len. */
49 for( i = 0; i < len; i += 2 ) { 50 nrg = len;
50 nrg = silk_SMLABB_ovflw( nrg, x[ i ], x[ i ] ); 51 for( i = 0; i < len - 1; i += 2 ) {
51 nrg = silk_SMLABB_ovflw( nrg, x[ i + 1 ], x[ i + 1 ] ); 52 nrg_tmp = silk_SMULBB( x[ i ], x[ i ] );
52 if( nrg < 0 ) { 53 nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] );
53 /* Scale down */ 54 nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft );
54 nrg = (opus_int32)silk_RSHIFT_uint( (opus_uint32)nrg, 2 );
55 shft = 2;
56 i+=2;
57 break;
58 }
59 } 55 }
60 for( ; i < len; i += 2 ) { 56 if( i < len ) {
57 /* One sample left to process */
58 nrg_tmp = silk_SMULBB( x[ i ], x[ i ] );
59 nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft );
60 }
61 silk_assert( nrg >= 0 );
62 /* Make sure the result will fit in a 32-bit signed integer with two bits
63 of headroom. */
64 shft = silk_max_32(0, shft+3 - silk_CLZ32(nrg));
65 nrg = 0;
66 for( i = 0 ; i < len - 1; i += 2 ) {
61 nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); 67 nrg_tmp = silk_SMULBB( x[ i ], x[ i ] );
62 nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] ); 68 nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] );
63 nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, (opus_uint32)nrg_tmp, shft ); 69 nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft );
64 if( nrg < 0 ) {
65 /* Scale down */
66 nrg = (opus_int32)silk_RSHIFT_uint( (opus_uint32)nrg, 2 );
67 shft += 2;
68 }
69 } 70 }
70 if( i == len ) { 71 if( i < len ) {
71 /* One sample left to process */ 72 /* One sample left to process */
72 nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); 73 nrg_tmp = silk_SMULBB( x[ i ], x[ i ] );
73 nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); 74 nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft );
74 } 75 }
75 76
76 /* Make sure to have at least one extra leading zero (two leading zeros in total) */ 77 silk_assert( nrg >= 0 );
77 if( nrg & 0xC0000000 ) {
78 nrg = silk_RSHIFT_uint( (opus_uint32)nrg, 2 );
79 shft += 2;
80 }
81 78
82 /* Output arguments */ 79 /* Output arguments */
83 *shift = shft; 80 *shift = shft;
diff --git a/lib/rbcodec/codecs/libopus/silk/tables.h b/lib/rbcodec/codecs/libopus/silk/tables.h
index a91431e854..95230c451a 100644
--- a/lib/rbcodec/codecs/libopus/silk/tables.h
+++ b/lib/rbcodec/codecs/libopus/silk/tables.h
@@ -47,8 +47,8 @@ extern const opus_uint8 silk_pitch_contour_NB_iCDF[ 11 ];
47extern const opus_uint8 silk_pitch_contour_10_ms_iCDF[ 12 ]; /* 12 */ 47extern const opus_uint8 silk_pitch_contour_10_ms_iCDF[ 12 ]; /* 12 */
48extern const opus_uint8 silk_pitch_contour_10_ms_NB_iCDF[ 3 ]; /* 3 */ 48extern const opus_uint8 silk_pitch_contour_10_ms_NB_iCDF[ 3 ]; /* 3 */
49 49
50extern const opus_uint8 silk_pulses_per_block_iCDF[ N_RATE_LEVELS ][ MAX_PULSES + 2 ]; /* 180 */ 50extern const opus_uint8 silk_pulses_per_block_iCDF[ N_RATE_LEVELS ][ SILK_MAX_PULSES + 2 ]; /* 180 */
51extern const opus_uint8 silk_pulses_per_block_BITS_Q5[ N_RATE_LEVELS - 1 ][ MAX_PULSES + 2 ]; /* 162 */ 51extern const opus_uint8 silk_pulses_per_block_BITS_Q5[ N_RATE_LEVELS - 1 ][ SILK_MAX_PULSES + 2 ]; /* 162 */
52 52
53extern const opus_uint8 silk_rate_levels_iCDF[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */ 53extern const opus_uint8 silk_rate_levels_iCDF[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */
54extern const opus_uint8 silk_rate_levels_BITS_Q5[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */ 54extern const opus_uint8 silk_rate_levels_BITS_Q5[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */
@@ -59,7 +59,7 @@ extern const opus_uint8 silk_shell_code_table0[ 152 ];
59extern const opus_uint8 silk_shell_code_table1[ 152 ]; /* 152 */ 59extern const opus_uint8 silk_shell_code_table1[ 152 ]; /* 152 */
60extern const opus_uint8 silk_shell_code_table2[ 152 ]; /* 152 */ 60extern const opus_uint8 silk_shell_code_table2[ 152 ]; /* 152 */
61extern const opus_uint8 silk_shell_code_table3[ 152 ]; /* 152 */ 61extern const opus_uint8 silk_shell_code_table3[ 152 ]; /* 152 */
62extern const opus_uint8 silk_shell_code_table_offsets[ MAX_PULSES + 1 ]; /* 17 */ 62extern const opus_uint8 silk_shell_code_table_offsets[ SILK_MAX_PULSES + 1 ]; /* 17 */
63 63
64extern const opus_uint8 silk_lsb_iCDF[ 2 ]; /* 2 */ 64extern const opus_uint8 silk_lsb_iCDF[ 2 ]; /* 2 */
65 65
@@ -76,10 +76,8 @@ extern const opus_uint8 silk_NLSF_EXT_iCDF[ 7 ];
76extern const opus_uint8 silk_LTP_per_index_iCDF[ 3 ]; /* 3 */ 76extern const opus_uint8 silk_LTP_per_index_iCDF[ 3 ]; /* 3 */
77extern const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[ NB_LTP_CBKS ]; /* 3 */ 77extern const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[ NB_LTP_CBKS ]; /* 3 */
78extern const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[ NB_LTP_CBKS ]; /* 3 */ 78extern const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[ NB_LTP_CBKS ]; /* 3 */
79extern const opus_int16 silk_LTP_gain_middle_avg_RD_Q14;
80extern const opus_int8 * const silk_LTP_vq_ptrs_Q7[ NB_LTP_CBKS ]; /* 168 */ 79extern const opus_int8 * const silk_LTP_vq_ptrs_Q7[ NB_LTP_CBKS ]; /* 168 */
81extern const opus_uint8 * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS]; 80extern const opus_uint8 * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS];
82
83extern const opus_int8 silk_LTP_vq_sizes[ NB_LTP_CBKS ]; /* 3 */ 81extern const opus_int8 silk_LTP_vq_sizes[ NB_LTP_CBKS ]; /* 3 */
84 82
85extern const opus_uint8 silk_LTPscale_iCDF[ 3 ]; /* 4 */ 83extern const opus_uint8 silk_LTPscale_iCDF[ 3 ]; /* 4 */
@@ -99,12 +97,6 @@ extern const opus_uint8 silk_NLSF_interpolation_factor_iCDF[ 5 ];
99extern const silk_NLSF_CB_struct silk_NLSF_CB_WB; /* 1040 */ 97extern const silk_NLSF_CB_struct silk_NLSF_CB_WB; /* 1040 */
100extern const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB; /* 728 */ 98extern const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB; /* 728 */
101 99
102/* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */
103extern const opus_int32 silk_TargetRate_table_NB[ TARGET_RATE_TAB_SZ ]; /* 32 */
104extern const opus_int32 silk_TargetRate_table_MB[ TARGET_RATE_TAB_SZ ]; /* 32 */
105extern const opus_int32 silk_TargetRate_table_WB[ TARGET_RATE_TAB_SZ ]; /* 32 */
106extern const opus_int16 silk_SNR_table_Q1[ TARGET_RATE_TAB_SZ ]; /* 32 */
107
108/* Quantization offsets */ 100/* Quantization offsets */
109extern const opus_int16 silk_Quantization_Offsets_Q10[ 2 ][ 2 ]; /* 8 */ 101extern const opus_int16 silk_Quantization_Offsets_Q10[ 2 ][ 2 ]; /* 8 */
110 102
diff --git a/lib/rbcodec/codecs/libopus/silk/tables_LTP.c b/lib/rbcodec/codecs/libopus/silk/tables_LTP.c
index ea518652b8..5e12c8643e 100644
--- a/lib/rbcodec/codecs/libopus/silk/tables_LTP.c
+++ b/lib/rbcodec/codecs/libopus/silk/tables_LTP.c
@@ -51,9 +51,6 @@ static const opus_uint8 silk_LTP_gain_iCDF_2[32] = {
51 24, 20, 16, 12, 9, 5, 2, 0 51 24, 20, 16, 12, 9, 5, 2, 0
52}; 52};
53 53
54#if 0
55const opus_int16 silk_LTP_gain_middle_avg_RD_Q14 = 12304;
56
57static const opus_uint8 silk_LTP_gain_BITS_Q5_0[8] = { 54static const opus_uint8 silk_LTP_gain_BITS_Q5_0[8] = {
58 15, 131, 138, 138, 155, 155, 173, 173 55 15, 131, 138, 138, 155, 155, 173, 173
59}; 56};
@@ -69,7 +66,6 @@ static const opus_uint8 silk_LTP_gain_BITS_Q5_2[32] = {
69 160, 160, 166, 166, 173, 173, 182, 192, 66 160, 160, 166, 166, 173, 173, 182, 192,
70 182, 192, 192, 192, 205, 192, 205, 224 67 182, 192, 192, 192, 205, 192, 205, 224
71}; 68};
72#endif
73 69
74const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[NB_LTP_CBKS] = { 70const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[NB_LTP_CBKS] = {
75 silk_LTP_gain_iCDF_0, 71 silk_LTP_gain_iCDF_0,
@@ -77,13 +73,11 @@ const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[NB_LTP_CBKS] = {
77 silk_LTP_gain_iCDF_2 73 silk_LTP_gain_iCDF_2
78}; 74};
79 75
80#if 0
81const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[NB_LTP_CBKS] = { 76const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[NB_LTP_CBKS] = {
82 silk_LTP_gain_BITS_Q5_0, 77 silk_LTP_gain_BITS_Q5_0,
83 silk_LTP_gain_BITS_Q5_1, 78 silk_LTP_gain_BITS_Q5_1,
84 silk_LTP_gain_BITS_Q5_2 79 silk_LTP_gain_BITS_Q5_2
85}; 80};
86#endif
87 81
88static const opus_int8 silk_LTP_gain_vq_0[8][5] = 82static const opus_int8 silk_LTP_gain_vq_0[8][5] =
89{ 83{
@@ -271,7 +265,6 @@ const opus_int8 * const silk_LTP_vq_ptrs_Q7[NB_LTP_CBKS] = {
271 (opus_int8 *)&silk_LTP_gain_vq_2[0][0] 265 (opus_int8 *)&silk_LTP_gain_vq_2[0][0]
272}; 266};
273 267
274#if 0
275/* Maximum frequency-dependent response of the pitch taps above, 268/* Maximum frequency-dependent response of the pitch taps above,
276 computed as max(abs(freqz(taps))) */ 269 computed as max(abs(freqz(taps))) */
277static const opus_uint8 silk_LTP_gain_vq_0_gain[8] = { 270static const opus_uint8 silk_LTP_gain_vq_0_gain[8] = {
@@ -299,4 +292,3 @@ const opus_uint8 * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS] = {
299const opus_int8 silk_LTP_vq_sizes[NB_LTP_CBKS] = { 292const opus_int8 silk_LTP_vq_sizes[NB_LTP_CBKS] = {
300 8, 16, 32 293 8, 16, 32
301}; 294};
302#endif
diff --git a/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_NB_MB.c b/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_NB_MB.c
index 8c59d207aa..195d5b95bd 100644
--- a/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_NB_MB.c
+++ b/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_NB_MB.c
@@ -74,6 +74,41 @@ static const opus_uint8 silk_NLSF_CB1_NB_MB_Q8[ 320 ] = {
74 64, 84, 104, 118, 156, 177, 201, 230 74 64, 84, 104, 118, 156, 177, 201, 230
75}; 75};
76 76
77static const opus_int16 silk_NLSF_CB1_Wght_Q9[ 320 ] = {
78 2897, 2314, 2314, 2314, 2287, 2287, 2314, 2300, 2327, 2287,
79 2888, 2580, 2394, 2367, 2314, 2274, 2274, 2274, 2274, 2194,
80 2487, 2340, 2340, 2314, 2314, 2314, 2340, 2340, 2367, 2354,
81 3216, 2766, 2340, 2340, 2314, 2274, 2221, 2207, 2261, 2194,
82 2460, 2474, 2367, 2394, 2394, 2394, 2394, 2367, 2407, 2314,
83 3479, 3056, 2127, 2207, 2274, 2274, 2274, 2287, 2314, 2261,
84 3282, 3141, 2580, 2394, 2247, 2221, 2207, 2194, 2194, 2114,
85 4096, 3845, 2221, 2620, 2620, 2407, 2314, 2394, 2367, 2074,
86 3178, 3244, 2367, 2221, 2553, 2434, 2340, 2314, 2167, 2221,
87 3338, 3488, 2726, 2194, 2261, 2460, 2354, 2367, 2207, 2101,
88 2354, 2420, 2327, 2367, 2394, 2420, 2420, 2420, 2460, 2367,
89 3779, 3629, 2434, 2527, 2367, 2274, 2274, 2300, 2207, 2048,
90 3254, 3225, 2713, 2846, 2447, 2327, 2300, 2300, 2274, 2127,
91 3263, 3300, 2753, 2806, 2447, 2261, 2261, 2247, 2127, 2101,
92 2873, 2981, 2633, 2367, 2407, 2354, 2194, 2247, 2247, 2114,
93 3225, 3197, 2633, 2580, 2274, 2181, 2247, 2221, 2221, 2141,
94 3178, 3310, 2740, 2407, 2274, 2274, 2274, 2287, 2194, 2114,
95 3141, 3272, 2460, 2061, 2287, 2500, 2367, 2487, 2434, 2181,
96 3507, 3282, 2314, 2700, 2647, 2474, 2367, 2394, 2340, 2127,
97 3423, 3535, 3038, 3056, 2300, 1950, 2221, 2274, 2274, 2274,
98 3404, 3366, 2087, 2687, 2873, 2354, 2420, 2274, 2474, 2540,
99 3760, 3488, 1950, 2660, 2897, 2527, 2394, 2367, 2460, 2261,
100 3028, 3272, 2740, 2888, 2740, 2154, 2127, 2287, 2234, 2247,
101 3695, 3657, 2025, 1969, 2660, 2700, 2580, 2500, 2327, 2367,
102 3207, 3413, 2354, 2074, 2888, 2888, 2340, 2487, 2247, 2167,
103 3338, 3366, 2846, 2780, 2327, 2154, 2274, 2287, 2114, 2061,
104 2327, 2300, 2181, 2167, 2181, 2367, 2633, 2700, 2700, 2553,
105 2407, 2434, 2221, 2261, 2221, 2221, 2340, 2420, 2607, 2700,
106 3038, 3244, 2806, 2888, 2474, 2074, 2300, 2314, 2354, 2380,
107 2221, 2154, 2127, 2287, 2500, 2793, 2793, 2620, 2580, 2367,
108 3676, 3713, 2234, 1838, 2181, 2753, 2726, 2673, 2513, 2207,
109 2793, 3160, 2726, 2553, 2846, 2513, 2181, 2394, 2221, 2181
110};
111
77static const opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = { 112static const opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = {
78 212, 178, 148, 129, 108, 96, 85, 82, 113 212, 178, 148, 129, 108, 96, 85, 82,
79 79, 77, 61, 59, 57, 56, 51, 49, 114 79, 77, 61, 59, 57, 56, 51, 49,
@@ -150,6 +185,7 @@ const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB =
150 SILK_FIX_CONST( 0.18, 16 ), 185 SILK_FIX_CONST( 0.18, 16 ),
151 SILK_FIX_CONST( 1.0 / 0.18, 6 ), 186 SILK_FIX_CONST( 1.0 / 0.18, 6 ),
152 silk_NLSF_CB1_NB_MB_Q8, 187 silk_NLSF_CB1_NB_MB_Q8,
188 silk_NLSF_CB1_Wght_Q9,
153 silk_NLSF_CB1_iCDF_NB_MB, 189 silk_NLSF_CB1_iCDF_NB_MB,
154 silk_NLSF_PRED_NB_MB_Q8, 190 silk_NLSF_PRED_NB_MB_Q8,
155 silk_NLSF_CB2_SELECT_NB_MB, 191 silk_NLSF_CB2_SELECT_NB_MB,
diff --git a/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_WB.c b/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_WB.c
index 50af87eb2e..5cc9f57bff 100644
--- a/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_WB.c
+++ b/lib/rbcodec/codecs/libopus/silk/tables_NLSF_CB_WB.c
@@ -98,6 +98,41 @@ static const opus_uint8 silk_NLSF_CB1_WB_Q8[ 512 ] = {
98 110, 119, 129, 141, 175, 198, 218, 237 98 110, 119, 129, 141, 175, 198, 218, 237
99}; 99};
100 100
101static const opus_int16 silk_NLSF_CB1_WB_Wght_Q9[ 512 ] = {
102 3657, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2963, 2963, 2925, 2846,
103 3216, 3085, 2972, 3056, 3056, 3010, 3010, 3010, 2963, 2963, 3010, 2972, 2888, 2846, 2846, 2726,
104 3920, 4014, 2981, 3207, 3207, 2934, 3056, 2846, 3122, 3244, 2925, 2846, 2620, 2553, 2780, 2925,
105 3516, 3197, 3010, 3103, 3019, 2888, 2925, 2925, 2925, 2925, 2888, 2888, 2888, 2888, 2888, 2753,
106 5054, 5054, 2934, 3573, 3385, 3056, 3085, 2793, 3160, 3160, 2972, 2846, 2513, 2540, 2753, 2888,
107 4428, 4149, 2700, 2753, 2972, 3010, 2925, 2846, 2981, 3019, 2925, 2925, 2925, 2925, 2888, 2726,
108 3620, 3019, 2972, 3056, 3056, 2873, 2806, 3056, 3216, 3047, 2981, 3291, 3291, 2981, 3310, 2991,
109 5227, 5014, 2540, 3338, 3526, 3385, 3197, 3094, 3376, 2981, 2700, 2647, 2687, 2793, 2846, 2673,
110 5081, 5174, 4615, 4428, 2460, 2897, 3047, 3207, 3169, 2687, 2740, 2888, 2846, 2793, 2846, 2700,
111 3122, 2888, 2963, 2925, 2925, 2925, 2925, 2963, 2963, 2963, 2963, 2925, 2925, 2963, 2963, 2963,
112 4202, 3207, 2981, 3103, 3010, 2888, 2888, 2925, 2972, 2873, 2916, 3019, 2972, 3010, 3197, 2873,
113 3760, 3760, 3244, 3103, 2981, 2888, 2925, 2888, 2972, 2934, 2793, 2793, 2846, 2888, 2888, 2660,
114 3854, 4014, 3207, 3122, 3244, 2934, 3047, 2963, 2963, 3085, 2846, 2793, 2793, 2793, 2793, 2580,
115 3845, 4080, 3357, 3516, 3094, 2740, 3010, 2934, 3122, 3085, 2846, 2846, 2647, 2647, 2846, 2806,
116 5147, 4894, 3225, 3845, 3441, 3169, 2897, 3413, 3451, 2700, 2580, 2673, 2740, 2846, 2806, 2753,
117 4109, 3789, 3291, 3160, 2925, 2888, 2888, 2925, 2793, 2740, 2793, 2740, 2793, 2846, 2888, 2806,
118 5081, 5054, 3047, 3545, 3244, 3056, 3085, 2944, 3103, 2897, 2740, 2740, 2740, 2846, 2793, 2620,
119 4309, 4309, 2860, 2527, 3207, 3376, 3376, 3075, 3075, 3376, 3056, 2846, 2647, 2580, 2726, 2753,
120 3056, 2916, 2806, 2888, 2740, 2687, 2897, 3103, 3150, 3150, 3216, 3169, 3056, 3010, 2963, 2846,
121 4375, 3882, 2925, 2888, 2846, 2888, 2846, 2846, 2888, 2888, 2888, 2846, 2888, 2925, 2888, 2846,
122 2981, 2916, 2916, 2981, 2981, 3056, 3122, 3216, 3150, 3056, 3010, 2972, 2972, 2972, 2925, 2740,
123 4229, 4149, 3310, 3347, 2925, 2963, 2888, 2981, 2981, 2846, 2793, 2740, 2846, 2846, 2846, 2793,
124 4080, 4014, 3103, 3010, 2925, 2925, 2925, 2888, 2925, 2925, 2846, 2846, 2846, 2793, 2888, 2780,
125 4615, 4575, 3169, 3441, 3207, 2981, 2897, 3038, 3122, 2740, 2687, 2687, 2687, 2740, 2793, 2700,
126 4149, 4269, 3789, 3657, 2726, 2780, 2888, 2888, 3010, 2972, 2925, 2846, 2687, 2687, 2793, 2888,
127 4215, 3554, 2753, 2846, 2846, 2888, 2888, 2888, 2925, 2925, 2888, 2925, 2925, 2925, 2963, 2888,
128 5174, 4921, 2261, 3432, 3789, 3479, 3347, 2846, 3310, 3479, 3150, 2897, 2460, 2487, 2753, 2925,
129 3451, 3685, 3122, 3197, 3357, 3047, 3207, 3207, 2981, 3216, 3085, 2925, 2925, 2687, 2540, 2434,
130 2981, 3010, 2793, 2793, 2740, 2793, 2846, 2972, 3056, 3103, 3150, 3150, 3150, 3103, 3010, 3010,
131 2944, 2873, 2687, 2726, 2780, 3010, 3432, 3545, 3357, 3244, 3056, 3010, 2963, 2925, 2888, 2846,
132 3019, 2944, 2897, 3010, 3010, 2972, 3019, 3103, 3056, 3056, 3010, 2888, 2846, 2925, 2925, 2888,
133 3920, 3967, 3010, 3197, 3357, 3216, 3291, 3291, 3479, 3704, 3441, 2726, 2181, 2460, 2580, 2607
134};
135
101static const opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = { 136static const opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = {
102 225, 204, 201, 184, 183, 175, 158, 154, 137 225, 204, 201, 184, 183, 175, 158, 154,
103 153, 135, 119, 115, 113, 110, 109, 99, 138 153, 135, 119, 115, 113, 110, 109, 99,
@@ -188,6 +223,7 @@ const silk_NLSF_CB_struct silk_NLSF_CB_WB =
188 SILK_FIX_CONST( 0.15, 16 ), 223 SILK_FIX_CONST( 0.15, 16 ),
189 SILK_FIX_CONST( 1.0 / 0.15, 6 ), 224 SILK_FIX_CONST( 1.0 / 0.15, 6 ),
190 silk_NLSF_CB1_WB_Q8, 225 silk_NLSF_CB1_WB_Q8,
226 silk_NLSF_CB1_WB_Wght_Q9,
191 silk_NLSF_CB1_iCDF_WB, 227 silk_NLSF_CB1_iCDF_WB,
192 silk_NLSF_PRED_WB_Q8, 228 silk_NLSF_PRED_WB_Q8,
193 silk_NLSF_CB2_SELECT_WB, 229 silk_NLSF_CB2_SELECT_WB,
diff --git a/lib/rbcodec/codecs/libopus/silk/tables_other.c b/lib/rbcodec/codecs/libopus/silk/tables_other.c
index 398686bf26..e34d90777b 100644
--- a/lib/rbcodec/codecs/libopus/silk/tables_other.c
+++ b/lib/rbcodec/codecs/libopus/silk/tables_other.c
@@ -38,20 +38,6 @@ extern "C"
38{ 38{
39#endif 39#endif
40 40
41/* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */
42const opus_int32 silk_TargetRate_table_NB[ TARGET_RATE_TAB_SZ ] = {
43 0, 8000, 9400, 11500, 13500, 17500, 25000, MAX_TARGET_RATE_BPS
44};
45const opus_int32 silk_TargetRate_table_MB[ TARGET_RATE_TAB_SZ ] = {
46 0, 9000, 12000, 14500, 18500, 24500, 35500, MAX_TARGET_RATE_BPS
47};
48const opus_int32 silk_TargetRate_table_WB[ TARGET_RATE_TAB_SZ ] = {
49 0, 10500, 14000, 17000, 21500, 28500, 42000, MAX_TARGET_RATE_BPS
50};
51const opus_int16 silk_SNR_table_Q1[ TARGET_RATE_TAB_SZ ] = {
52 18, 29, 38, 40, 46, 52, 62, 84
53};
54
55/* Tables for stereo predictor coding */ 41/* Tables for stereo predictor coding */
56const opus_int16 silk_stereo_pred_quant_Q13[ STEREO_QUANT_TAB_SIZE ] = { 42const opus_int16 silk_stereo_pred_quant_Q13[ STEREO_QUANT_TAB_SIZE ] = {
57 -13732, -10050, -8266, -7526, -6500, -5000, -2950, -820, 43 -13732, -10050, -8266, -7526, -6500, -5000, -2950, -820,
diff --git a/lib/rbcodec/codecs/libopus/silk/tests/test_unit_LPC_inv_pred_gain.c b/lib/rbcodec/codecs/libopus/silk/tests/test_unit_LPC_inv_pred_gain.c
new file mode 100644
index 0000000000..67067cead7
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/tests/test_unit_LPC_inv_pred_gain.c
@@ -0,0 +1,129 @@
1/***********************************************************************
2Copyright (c) 2017 Google Inc., Jean-Marc Valin
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <stdio.h>
33#include <stdlib.h>
34#include "celt/stack_alloc.h"
35#include "cpu_support.h"
36#include "SigProc_FIX.h"
37
38/* Computes the impulse response of the filter so we
39 can catch filters that are definitely unstable. Some
40 unstable filters may be classified as stable, but not
41 the other way around. */
42int check_stability(opus_int16 *A_Q12, int order) {
43 int i;
44 int j;
45 int sum_a, sum_abs_a;
46 sum_a = sum_abs_a = 0;
47 for( j = 0; j < order; j++ ) {
48 sum_a += A_Q12[ j ];
49 sum_abs_a += silk_abs( A_Q12[ j ] );
50 }
51 /* Check DC stability. */
52 if( sum_a >= 4096 ) {
53 return 0;
54 }
55 /* If the sum of absolute values is less than 1, the filter
56 has to be stable. */
57 if( sum_abs_a < 4096 ) {
58 return 1;
59 }
60 double y[SILK_MAX_ORDER_LPC] = {0};
61 y[0] = 1;
62 for( i = 0; i < 10000; i++ ) {
63 double sum = 0;
64 for( j = 0; j < order; j++ ) {
65 sum += y[ j ]*A_Q12[ j ];
66 }
67 for( j = order - 1; j > 0; j-- ) {
68 y[ j ] = y[ j - 1 ];
69 }
70 y[ 0 ] = sum*(1./4096);
71 /* If impulse response reaches +/- 10000, the filter
72 is definitely unstable. */
73 if( !(y[ 0 ] < 10000 && y[ 0 ] > -10000) ) {
74 return 0;
75 }
76 /* Test every 8 sample for low amplitude. */
77 if( ( i & 0x7 ) == 0 ) {
78 double amp = 0;
79 for( j = 0; j < order; j++ ) {
80 amp += fabs(y[j]);
81 }
82 if( amp < 0.00001 ) {
83 return 1;
84 }
85 }
86 }
87 return 1;
88}
89
90int main(void) {
91 const int arch = opus_select_arch();
92 /* Set to 10000 so all branches in C function are triggered */
93 const int loop_num = 10000;
94 int count = 0;
95 ALLOC_STACK;
96
97 /* FIXME: Make the seed random (with option to set it explicitly)
98 so we get wider coverage. */
99 srand(0);
100
101 printf("Testing silk_LPC_inverse_pred_gain() optimization ...\n");
102 for( count = 0; count < loop_num; count++ ) {
103 unsigned int i;
104 opus_int order;
105 unsigned int shift;
106 opus_int16 A_Q12[ SILK_MAX_ORDER_LPC ];
107 opus_int32 gain;
108
109 for( order = 2; order <= SILK_MAX_ORDER_LPC; order += 2 ) { /* order must be even. */
110 for( shift = 0; shift < 16; shift++ ) { /* Different dynamic range. */
111 for( i = 0; i < SILK_MAX_ORDER_LPC; i++ ) {
112 A_Q12[i] = ((opus_int16)rand()) >> shift;
113 }
114 gain = silk_LPC_inverse_pred_gain(A_Q12, order, arch);
115 /* Look for filters that silk_LPC_inverse_pred_gain() thinks are
116 stable but definitely aren't. */
117 if( gain != 0 && !check_stability(A_Q12, order) ) {
118 fprintf(stderr, "**Loop %4d failed!**\n", count);
119 return 1;
120 }
121 }
122 }
123 if( !(count % 500) ) {
124 printf("Loop %4d passed\n", count);
125 }
126 }
127 printf("silk_LPC_inverse_pred_gain() optimization passed\n");
128 return 0;
129}
diff --git a/lib/rbcodec/codecs/libopus/silk/tuning_parameters.h b/lib/rbcodec/codecs/libopus/silk/tuning_parameters.h
new file mode 100644
index 0000000000..d70275fd8f
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/tuning_parameters.h
@@ -0,0 +1,155 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY OF SUCH DAMAGE.
26***********************************************************************/
27
28#ifndef SILK_TUNING_PARAMETERS_H
29#define SILK_TUNING_PARAMETERS_H
30
31#ifdef __cplusplus
32extern "C"
33{
34#endif
35
36/* Decay time for bitreservoir */
37#define BITRESERVOIR_DECAY_TIME_MS 500
38
39/*******************/
40/* Pitch estimator */
41/*******************/
42
43/* Level of noise floor for whitening filter LPC analysis in pitch analysis */
44#define FIND_PITCH_WHITE_NOISE_FRACTION 1e-3f
45
46/* Bandwidth expansion for whitening filter in pitch analysis */
47#define FIND_PITCH_BANDWIDTH_EXPANSION 0.99f
48
49/*********************/
50/* Linear prediction */
51/*********************/
52
53/* LPC analysis regularization */
54#define FIND_LPC_COND_FAC 1e-5f
55
56/* Max cumulative LTP gain */
57#define MAX_SUM_LOG_GAIN_DB 250.0f
58
59/* LTP analysis defines */
60#define LTP_CORR_INV_MAX 0.03f
61
62/***********************/
63/* High pass filtering */
64/***********************/
65
66/* Smoothing parameters for low end of pitch frequency range estimation */
67#define VARIABLE_HP_SMTH_COEF1 0.1f
68#define VARIABLE_HP_SMTH_COEF2 0.015f
69#define VARIABLE_HP_MAX_DELTA_FREQ 0.4f
70
71/* Min and max cut-off frequency values (-3 dB points) */
72#define VARIABLE_HP_MIN_CUTOFF_HZ 60
73#define VARIABLE_HP_MAX_CUTOFF_HZ 100
74
75/***********/
76/* Various */
77/***********/
78
79/* VAD threshold */
80#define SPEECH_ACTIVITY_DTX_THRES 0.05f
81
82/* Speech Activity LBRR enable threshold */
83#define LBRR_SPEECH_ACTIVITY_THRES 0.3f
84
85/*************************/
86/* Perceptual parameters */
87/*************************/
88
89/* reduction in coding SNR during low speech activity */
90#define BG_SNR_DECR_dB 2.0f
91
92/* factor for reducing quantization noise during voiced speech */
93#define HARM_SNR_INCR_dB 2.0f
94
95/* factor for reducing quantization noise for unvoiced sparse signals */
96#define SPARSE_SNR_INCR_dB 2.0f
97
98/* threshold for sparseness measure above which to use lower quantization offset during unvoiced */
99#define ENERGY_VARIATION_THRESHOLD_QNT_OFFSET 0.6f
100
101/* warping control */
102#define WARPING_MULTIPLIER 0.015f
103
104/* fraction added to first autocorrelation value */
105#define SHAPE_WHITE_NOISE_FRACTION 3e-5f
106
107/* noise shaping filter chirp factor */
108#define BANDWIDTH_EXPANSION 0.94f
109
110/* harmonic noise shaping */
111#define HARMONIC_SHAPING 0.3f
112
113/* extra harmonic noise shaping for high bitrates or noisy input */
114#define HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING 0.2f
115
116/* parameter for shaping noise towards higher frequencies */
117#define HP_NOISE_COEF 0.25f
118
119/* parameter for shaping noise even more towards higher frequencies during voiced speech */
120#define HARM_HP_NOISE_COEF 0.35f
121
122/* parameter for applying a high-pass tilt to the input signal */
123#define INPUT_TILT 0.05f
124
125/* parameter for extra high-pass tilt to the input signal at high rates */
126#define HIGH_RATE_INPUT_TILT 0.1f
127
128/* parameter for reducing noise at the very low frequencies */
129#define LOW_FREQ_SHAPING 4.0f
130
131/* less reduction of noise at the very low frequencies for signals with low SNR at low frequencies */
132#define LOW_QUALITY_LOW_FREQ_SHAPING_DECR 0.5f
133
134/* subframe smoothing coefficient for HarmBoost, HarmShapeGain, Tilt (lower -> more smoothing) */
135#define SUBFR_SMTH_COEF 0.4f
136
137/* parameters defining the R/D tradeoff in the residual quantizer */
138#define LAMBDA_OFFSET 1.2f
139#define LAMBDA_SPEECH_ACT -0.2f
140#define LAMBDA_DELAYED_DECISIONS -0.05f
141#define LAMBDA_INPUT_QUALITY -0.1f
142#define LAMBDA_CODING_QUALITY -0.2f
143#define LAMBDA_QUANT_OFFSET 0.8f
144
145/* Compensation in bitrate calculations for 10 ms modes */
146#define REDUCE_BITRATE_10_MS_BPS 2200
147
148/* Maximum time before allowing a bandwidth transition */
149#define MAX_BANDWIDTH_SWITCH_DELAY_MS 5000
150
151#ifdef __cplusplus
152}
153#endif
154
155#endif /* SILK_TUNING_PARAMETERS_H */
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/NSQ_del_dec_sse4_1.c b/lib/rbcodec/codecs/libopus/silk/x86/NSQ_del_dec_sse4_1.c
new file mode 100644
index 0000000000..2c75ede2dd
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/x86/NSQ_del_dec_sse4_1.c
@@ -0,0 +1,859 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <xmmintrin.h>
33#include <emmintrin.h>
34#include <smmintrin.h>
35#include "main.h"
36#include "celt/x86/x86cpu.h"
37
38#include "stack_alloc.h"
39
40typedef struct {
41 opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ];
42 opus_int32 RandState[ DECISION_DELAY ];
43 opus_int32 Q_Q10[ DECISION_DELAY ];
44 opus_int32 Xq_Q14[ DECISION_DELAY ];
45 opus_int32 Pred_Q15[ DECISION_DELAY ];
46 opus_int32 Shape_Q14[ DECISION_DELAY ];
47 opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];
48 opus_int32 LF_AR_Q14;
49 opus_int32 Seed;
50 opus_int32 SeedInit;
51 opus_int32 RD_Q10;
52} NSQ_del_dec_struct;
53
54typedef struct {
55 opus_int32 Q_Q10;
56 opus_int32 RD_Q10;
57 opus_int32 xq_Q14;
58 opus_int32 LF_AR_Q14;
59 opus_int32 sLTP_shp_Q14;
60 opus_int32 LPC_exc_Q14;
61} NSQ_sample_struct;
62
63typedef NSQ_sample_struct NSQ_sample_pair[ 2 ];
64
65static OPUS_INLINE void silk_nsq_del_dec_scale_states_sse4_1(
66 const silk_encoder_state *psEncC, /* I Encoder State */
67 silk_nsq_state *NSQ, /* I/O NSQ state */
68 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
69 const opus_int32 x_Q3[], /* I Input in Q3 */
70 opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
71 const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
72 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
73 opus_int subfr, /* I Subframe number */
74 opus_int nStatesDelayedDecision, /* I Number of del dec states */
75 const opus_int LTP_scale_Q14, /* I LTP state scaling */
76 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
77 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
78 const opus_int signal_type, /* I Signal type */
79 const opus_int decisionDelay /* I Decision delay */
80);
81
82/******************************************/
83/* Noise shape quantizer for one subframe */
84/******************************************/
85static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1(
86 silk_nsq_state *NSQ, /* I/O NSQ state */
87 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
88 opus_int signalType, /* I Signal type */
89 const opus_int32 x_Q10[], /* I */
90 opus_int8 pulses[], /* O */
91 opus_int16 xq[], /* O */
92 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
93 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
94 const opus_int16 a_Q12[], /* I Short term prediction coefs */
95 const opus_int16 b_Q14[], /* I Long term prediction coefs */
96 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
97 opus_int lag, /* I Pitch lag */
98 opus_int32 HarmShapeFIRPacked_Q14, /* I */
99 opus_int Tilt_Q14, /* I Spectral tilt */
100 opus_int32 LF_shp_Q14, /* I */
101 opus_int32 Gain_Q16, /* I */
102 opus_int Lambda_Q10, /* I */
103 opus_int offset_Q10, /* I */
104 opus_int length, /* I Input length */
105 opus_int subfr, /* I Subframe number */
106 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
107 opus_int predictLPCOrder, /* I Prediction filter order */
108 opus_int warping_Q16, /* I */
109 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
110 opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
111 opus_int decisionDelay /* I */
112);
113
114void silk_NSQ_del_dec_sse4_1(
115 const silk_encoder_state *psEncC, /* I Encoder State */
116 silk_nsq_state *NSQ, /* I/O NSQ state */
117 SideInfoIndices *psIndices, /* I/O Quantization Indices */
118 const opus_int32 x_Q3[], /* I Prefiltered input signal */
119 opus_int8 pulses[], /* O Quantized pulse signal */
120 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
121 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
122 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
123 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
124 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
125 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
126 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
127 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
128 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
129 const opus_int LTP_scale_Q14 /* I LTP state scaling */
130)
131{
132 opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
133 opus_int last_smple_idx, smpl_buf_idx, decisionDelay;
134 const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
135 opus_int16 *pxq;
136 VARDECL( opus_int32, sLTP_Q15 );
137 VARDECL( opus_int16, sLTP );
138 opus_int32 HarmShapeFIRPacked_Q14;
139 opus_int offset_Q10;
140 opus_int32 RDmin_Q10, Gain_Q10;
141 VARDECL( opus_int32, x_sc_Q10 );
142 VARDECL( opus_int32, delayedGain_Q10 );
143 VARDECL( NSQ_del_dec_struct, psDelDec );
144 NSQ_del_dec_struct *psDD;
145 SAVE_STACK;
146
147 /* Set unvoiced lag to the previous one, overwrite later for voiced */
148 lag = NSQ->lagPrev;
149
150 silk_assert( NSQ->prev_gain_Q16 != 0 );
151
152 /* Initialize delayed decision states */
153 ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct );
154 silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) );
155 for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {
156 psDD = &psDelDec[ k ];
157 psDD->Seed = ( k + psIndices->Seed ) & 3;
158 psDD->SeedInit = psDD->Seed;
159 psDD->RD_Q10 = 0;
160 psDD->LF_AR_Q14 = NSQ->sLF_AR_shp_Q14;
161 psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ];
162 silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
163 silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) );
164 }
165
166 offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];
167 smpl_buf_idx = 0; /* index of oldest samples */
168
169 decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length );
170
171 /* For voiced frames limit the decision delay to lower than the pitch lag */
172 if( psIndices->signalType == TYPE_VOICED ) {
173 for( k = 0; k < psEncC->nb_subfr; k++ ) {
174 decisionDelay = silk_min_int( decisionDelay, pitchL[ k ] - LTP_ORDER / 2 - 1 );
175 }
176 } else {
177 if( lag > 0 ) {
178 decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 );
179 }
180 }
181
182 if( psIndices->NLSFInterpCoef_Q2 == 4 ) {
183 LSF_interpolation_flag = 0;
184 } else {
185 LSF_interpolation_flag = 1;
186 }
187
188 ALLOC( sLTP_Q15,
189 psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
190 ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
191 ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
192 ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 );
193 /* Set up pointers to start of sub frame */
194 pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
195 NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
196 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
197 subfr = 0;
198 for( k = 0; k < psEncC->nb_subfr; k++ ) {
199 A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];
200 B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
201 AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ];
202
203 /* Noise shape parameters */
204 silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
205 HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
206 HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
207
208 NSQ->rewhite_flag = 0;
209 if( psIndices->signalType == TYPE_VOICED ) {
210 /* Voiced */
211 lag = pitchL[ k ];
212
213 /* Re-whitening */
214 if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
215 if( k == 2 ) {
216 /* RESET DELAYED DECISIONS */
217 /* Find winner */
218 RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
219 Winner_ind = 0;
220 for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) {
221 if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) {
222 RDmin_Q10 = psDelDec[ i ].RD_Q10;
223 Winner_ind = i;
224 }
225 }
226 for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) {
227 if( i != Winner_ind ) {
228 psDelDec[ i ].RD_Q10 += ( silk_int32_MAX >> 4 );
229 silk_assert( psDelDec[ i ].RD_Q10 >= 0 );
230 }
231 }
232
233 /* Copy final part of signals from winner state to output and long-term filter states */
234 psDD = &psDelDec[ Winner_ind ];
235 last_smple_idx = smpl_buf_idx + decisionDelay;
236 for( i = 0; i < decisionDelay; i++ ) {
237 last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY;
238 if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY;
239 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
240 pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
241 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) );
242 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];
243 }
244
245 subfr = 0;
246 }
247
248 /* Rewhiten with new A coefs */
249 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
250 celt_assert( start_idx > 0 );
251
252 silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
253 A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
254
255 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
256 NSQ->rewhite_flag = 1;
257 }
258 }
259
260 silk_nsq_del_dec_scale_states_sse4_1( psEncC, NSQ, psDelDec, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k,
261 psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );
262
263 silk_noise_shape_quantizer_del_dec_sse4_1( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,
264 delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ],
265 Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,
266 psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay );
267
268 x_Q3 += psEncC->subfr_length;
269 pulses += psEncC->subfr_length;
270 pxq += psEncC->subfr_length;
271 }
272
273 /* Find winner */
274 RDmin_Q10 = psDelDec[ 0 ].RD_Q10;
275 Winner_ind = 0;
276 for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) {
277 if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) {
278 RDmin_Q10 = psDelDec[ k ].RD_Q10;
279 Winner_ind = k;
280 }
281 }
282
283 /* Copy final part of signals from winner state to output and long-term filter states */
284 psDD = &psDelDec[ Winner_ind ];
285 psIndices->Seed = psDD->SeedInit;
286 last_smple_idx = smpl_buf_idx + decisionDelay;
287 Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 );
288 for( i = 0; i < decisionDelay; i++ ) {
289 last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY;
290 if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY;
291 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
292 pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
293 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) );
294 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ];
295 }
296 silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
297 silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) );
298
299 /* Update states */
300 NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14;
301 NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
302
303 /* Save quantized speech signal */
304 silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
305 silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
306 RESTORE_STACK;
307}
308
309/******************************************/
310/* Noise shape quantizer for one subframe */
311/******************************************/
312static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1(
313 silk_nsq_state *NSQ, /* I/O NSQ state */
314 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
315 opus_int signalType, /* I Signal type */
316 const opus_int32 x_Q10[], /* I */
317 opus_int8 pulses[], /* O */
318 opus_int16 xq[], /* O */
319 opus_int32 sLTP_Q15[], /* I/O LTP filter state */
320 opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
321 const opus_int16 a_Q12[], /* I Short term prediction coefs */
322 const opus_int16 b_Q14[], /* I Long term prediction coefs */
323 const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
324 opus_int lag, /* I Pitch lag */
325 opus_int32 HarmShapeFIRPacked_Q14, /* I */
326 opus_int Tilt_Q14, /* I Spectral tilt */
327 opus_int32 LF_shp_Q14, /* I */
328 opus_int32 Gain_Q16, /* I */
329 opus_int Lambda_Q10, /* I */
330 opus_int offset_Q10, /* I */
331 opus_int length, /* I Input length */
332 opus_int subfr, /* I Subframe number */
333 opus_int shapingLPCOrder, /* I Shaping LPC filter order */
334 opus_int predictLPCOrder, /* I Prediction filter order */
335 opus_int warping_Q16, /* I */
336 opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
337 opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
338 opus_int decisionDelay /* I */
339)
340{
341 opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
342 opus_int32 Winner_rand_state;
343 opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14;
344 opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10;
345 opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
346 opus_int32 tmp1, tmp2, sLF_AR_shp_Q14;
347 opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;
348 VARDECL( NSQ_sample_pair, psSampleState );
349 NSQ_del_dec_struct *psDD;
350 NSQ_sample_struct *psSS;
351
352 __m128i a_Q12_0123, a_Q12_4567, a_Q12_89AB, a_Q12_CDEF;
353 __m128i b_Q12_0123, b_sr_Q12_0123;
354 SAVE_STACK;
355
356 celt_assert( nStatesDelayedDecision > 0 );
357 ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair );
358
359 shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
360 pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
361 Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
362
363 a_Q12_0123 = OP_CVTEPI16_EPI32_M64( a_Q12 );
364 a_Q12_4567 = OP_CVTEPI16_EPI32_M64( a_Q12 + 4 );
365
366 if( opus_likely( predictLPCOrder == 16 ) ) {
367 a_Q12_89AB = OP_CVTEPI16_EPI32_M64( a_Q12 + 8 );
368 a_Q12_CDEF = OP_CVTEPI16_EPI32_M64( a_Q12 + 12 );
369 }
370
371 if( signalType == TYPE_VOICED ){
372 b_Q12_0123 = OP_CVTEPI16_EPI32_M64( b_Q14 );
373 b_sr_Q12_0123 = _mm_shuffle_epi32( b_Q12_0123, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */
374 }
375 for( i = 0; i < length; i++ ) {
376 /* Perform common calculations used in all states */
377
378 /* Long-term prediction */
379 if( signalType == TYPE_VOICED ) {
380 /* Unrolled loop */
381 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
382 LTP_pred_Q14 = 2;
383 {
384 __m128i tmpa, tmpb, pred_lag_ptr_tmp;
385 pred_lag_ptr_tmp = _mm_loadu_si128( (__m128i *)(&pred_lag_ptr[ -3 ] ) );
386 pred_lag_ptr_tmp = _mm_shuffle_epi32( pred_lag_ptr_tmp, 0x1B );
387 tmpa = _mm_mul_epi32( pred_lag_ptr_tmp, b_Q12_0123 );
388 tmpa = _mm_srli_si128( tmpa, 2 );
389
390 pred_lag_ptr_tmp = _mm_shuffle_epi32( pred_lag_ptr_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) );/* equal shift right 4 bytes */
391 pred_lag_ptr_tmp = _mm_mul_epi32( pred_lag_ptr_tmp, b_sr_Q12_0123 );
392 pred_lag_ptr_tmp = _mm_srli_si128( pred_lag_ptr_tmp, 2 );
393 pred_lag_ptr_tmp = _mm_add_epi32( pred_lag_ptr_tmp, tmpa );
394
395 tmpb = _mm_shuffle_epi32( pred_lag_ptr_tmp, _MM_SHUFFLE( 0, 0, 3, 2 ) );/* equal shift right 8 bytes */
396 pred_lag_ptr_tmp = _mm_add_epi32( pred_lag_ptr_tmp, tmpb );
397 LTP_pred_Q14 += _mm_cvtsi128_si32( pred_lag_ptr_tmp );
398
399 LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
400 LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */
401 pred_lag_ptr++;
402 }
403 } else {
404 LTP_pred_Q14 = 0;
405 }
406
407 /* Long-term shaping */
408 if( lag > 0 ) {
409 /* Symmetric, packed FIR coefficients */
410 n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
411 n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
412 n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */
413 shp_lag_ptr++;
414 } else {
415 n_LTP_Q14 = 0;
416 }
417 {
418 __m128i tmpa, tmpb, psLPC_Q14_tmp, a_Q12_tmp;
419
420 for( k = 0; k < nStatesDelayedDecision; k++ ) {
421 /* Delayed decision state */
422 psDD = &psDelDec[ k ];
423
424 /* Sample state */
425 psSS = psSampleState[ k ];
426
427 /* Generate dither */
428 psDD->Seed = silk_RAND( psDD->Seed );
429
430 /* Pointer used in short term prediction and shaping */
431 psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];
432 /* Short-term prediction */
433 silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 );
434 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
435 LPC_pred_Q14 = silk_RSHIFT( predictLPCOrder, 1 );
436
437 tmpb = _mm_setzero_si128();
438
439 /* step 1 */
440 psLPC_Q14_tmp = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -3 ] ) ); /* -3, -2 , -1, 0 */
441 psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B ); /* 0, -1, -2, -3 */
442 tmpa = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_0123 ); /* 0, -1, -2, -3 * 0123 -> 0*0, 2*-2 */
443
444 tmpa = _mm_srli_epi64( tmpa, 16 );
445 tmpb = _mm_add_epi32( tmpb, tmpa );
446
447 psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */
448 a_Q12_tmp = _mm_shuffle_epi32( a_Q12_0123, _MM_SHUFFLE(0, 3, 2, 1 ) ); /* equal shift right 4 bytes */
449 psLPC_Q14_tmp = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp ); /* 1*-1, 3*-3 */
450 psLPC_Q14_tmp = _mm_srli_epi64( psLPC_Q14_tmp, 16 );
451 tmpb = _mm_add_epi32( tmpb, psLPC_Q14_tmp );
452
453 /* step 2 */
454 psLPC_Q14_tmp = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -7 ] ) );
455 psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B );
456 tmpa = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_4567 );
457 tmpa = _mm_srli_epi64( tmpa, 16 );
458 tmpb = _mm_add_epi32( tmpb, tmpa );
459
460 psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */
461 a_Q12_tmp = _mm_shuffle_epi32( a_Q12_4567, _MM_SHUFFLE(0, 3, 2, 1 ) ); /* equal shift right 4 bytes */
462 psLPC_Q14_tmp = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp );
463 psLPC_Q14_tmp = _mm_srli_epi64( psLPC_Q14_tmp, 16 );
464 tmpb = _mm_add_epi32( tmpb, psLPC_Q14_tmp );
465
466 if ( opus_likely( predictLPCOrder == 16 ) )
467 {
468 /* step 3 */
469 psLPC_Q14_tmp = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -11 ] ) );
470 psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B );
471 tmpa = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_89AB );
472 tmpa = _mm_srli_epi64( tmpa, 16 );
473 tmpb = _mm_add_epi32( tmpb, tmpa );
474
475 psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */
476 a_Q12_tmp = _mm_shuffle_epi32( a_Q12_89AB, _MM_SHUFFLE(0, 3, 2, 1 ) );/* equal shift right 4 bytes */
477 psLPC_Q14_tmp = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp );
478 psLPC_Q14_tmp = _mm_srli_epi64( psLPC_Q14_tmp, 16 );
479 tmpb = _mm_add_epi32( tmpb, psLPC_Q14_tmp );
480
481 /* setp 4 */
482 psLPC_Q14_tmp = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -15 ] ) );
483 psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, 0x1B );
484 tmpa = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_CDEF );
485 tmpa = _mm_srli_epi64( tmpa, 16 );
486 tmpb = _mm_add_epi32( tmpb, tmpa );
487
488 psLPC_Q14_tmp = _mm_shuffle_epi32( psLPC_Q14_tmp, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* equal shift right 4 bytes */
489 a_Q12_tmp = _mm_shuffle_epi32( a_Q12_CDEF, _MM_SHUFFLE(0, 3, 2, 1 ) ); /* equal shift right 4 bytes */
490 psLPC_Q14_tmp = _mm_mul_epi32( psLPC_Q14_tmp, a_Q12_tmp );
491 psLPC_Q14_tmp = _mm_srli_epi64( psLPC_Q14_tmp, 16 );
492 tmpb = _mm_add_epi32( tmpb, psLPC_Q14_tmp );
493
494 /* add at last */
495 /* equal shift right 8 bytes*/
496 tmpa = _mm_shuffle_epi32( tmpb, _MM_SHUFFLE( 0, 0, 3, 2 ) );
497 tmpb = _mm_add_epi32( tmpb, tmpa );
498 LPC_pred_Q14 += _mm_cvtsi128_si32( tmpb );
499 }
500 else
501 {
502 /* add at last */
503 tmpa = _mm_shuffle_epi32( tmpb, _MM_SHUFFLE( 0, 0, 3, 2 ) ); /* equal shift right 8 bytes*/
504 tmpb = _mm_add_epi32( tmpb, tmpa );
505 LPC_pred_Q14 += _mm_cvtsi128_si32( tmpb );
506
507 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -8 ], a_Q12[ 8 ] );
508 LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -9 ], a_Q12[ 9 ] );
509 }
510
511 LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */
512
513 /* Noise shape feedback */
514 silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
515 /* Output of lowpass section */
516 tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 );
517 /* Output of allpass section */
518 tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );
519 psDD->sAR2_Q14[ 0 ] = tmp2;
520 n_AR_Q14 = silk_RSHIFT( shapingLPCOrder, 1 );
521 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ 0 ] );
522 /* Loop over allpass sections */
523 for( j = 2; j < shapingLPCOrder; j += 2 ) {
524 /* Output of allpass section */
525 tmp2 = silk_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 );
526 psDD->sAR2_Q14[ j - 1 ] = tmp1;
527 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ j - 1 ] );
528 /* Output of allpass section */
529 tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 );
530 psDD->sAR2_Q14[ j + 0 ] = tmp2;
531 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ j ] );
532 }
533 psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
534 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
535
536 n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */
537 n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */
538 n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */
539
540 n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */
541 n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */
542 n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */
543
544 /* Input minus prediction plus noise feedback */
545 /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */
546 tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */
547 tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */
548 tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */
549 tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */
550
551 r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */
552
553 /* Flip sign depending on dither */
554 if ( psDD->Seed < 0 ) {
555 r_Q10 = -r_Q10;
556 }
557 r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
558
559 /* Find two quantization level candidates and measure their rate-distortion */
560 q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
561 q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
562 if( q1_Q0 > 0 ) {
563 q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
564 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
565 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
566 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
567 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
568 } else if( q1_Q0 == 0 ) {
569 q1_Q10 = offset_Q10;
570 q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
571 rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 );
572 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
573 } else if( q1_Q0 == -1 ) {
574 q2_Q10 = offset_Q10;
575 q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 );
576 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
577 rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 );
578 } else { /* q1_Q0 < -1 */
579 q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
580 q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
581 q2_Q10 = silk_ADD32( q1_Q10, 1024 );
582 rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 );
583 rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 );
584 }
585 rr_Q10 = silk_SUB32( r_Q10, q1_Q10 );
586 rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 );
587 rr_Q10 = silk_SUB32( r_Q10, q2_Q10 );
588 rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 );
589
590 if( rd1_Q10 < rd2_Q10 ) {
591 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
592 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
593 psSS[ 0 ].Q_Q10 = q1_Q10;
594 psSS[ 1 ].Q_Q10 = q2_Q10;
595 } else {
596 psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 );
597 psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 );
598 psSS[ 0 ].Q_Q10 = q2_Q10;
599 psSS[ 1 ].Q_Q10 = q1_Q10;
600 }
601
602 /* Update states for best quantization */
603
604 /* Quantized excitation */
605 exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 );
606 if ( psDD->Seed < 0 ) {
607 exc_Q14 = -exc_Q14;
608 }
609
610 /* Add predictions */
611 LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
612 xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
613
614 /* Update states */
615 sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 );
616 psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
617 psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14;
618 psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14;
619 psSS[ 0 ].xq_Q14 = xq_Q14;
620
621 /* Update states for second best quantization */
622
623 /* Quantized excitation */
624 exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 );
625 if ( psDD->Seed < 0 ) {
626 exc_Q14 = -exc_Q14;
627 }
628
629
630 /* Add predictions */
631 LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
632 xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
633
634 /* Update states */
635 sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 );
636 psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
637 psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14;
638 psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14;
639 psSS[ 1 ].xq_Q14 = xq_Q14;
640 }
641 }
642 *smpl_buf_idx = ( *smpl_buf_idx - 1 ) % DECISION_DELAY;
643 if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY;
644 last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY;
645
646 /* Find winner */
647 RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
648 Winner_ind = 0;
649 for( k = 1; k < nStatesDelayedDecision; k++ ) {
650 if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) {
651 RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
652 Winner_ind = k;
653 }
654 }
655
656 /* Increase RD values of expired states */
657 Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ];
658 for( k = 0; k < nStatesDelayedDecision; k++ ) {
659 if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) {
660 psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 );
661 psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 );
662 silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 );
663 }
664 }
665
666 /* Find worst in first set and best in second set */
667 RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
668 RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10;
669 RDmax_ind = 0;
670 RDmin_ind = 0;
671 for( k = 1; k < nStatesDelayedDecision; k++ ) {
672 /* find worst in first set */
673 if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) {
674 RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10;
675 RDmax_ind = k;
676 }
677 /* find best in second set */
678 if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) {
679 RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10;
680 RDmin_ind = k;
681 }
682 }
683
684 /* Replace a state if best from second set outperforms worst in first set */
685 if( RDmin_Q10 < RDmax_Q10 ) {
686 silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i,
687 ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) );
688 silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) );
689 }
690
691 /* Write samples from winner to output and long-term filter states */
692 psDD = &psDelDec[ Winner_ind ];
693 if( subfr > 0 || i >= decisionDelay ) {
694 pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
695 xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
696 silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) );
697 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ];
698 sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ];
699 }
700 NSQ->sLTP_shp_buf_idx++;
701 NSQ->sLTP_buf_idx++;
702
703 /* Update states */
704 for( k = 0; k < nStatesDelayedDecision; k++ ) {
705 psDD = &psDelDec[ k ];
706 psSS = &psSampleState[ k ][ 0 ];
707 psDD->LF_AR_Q14 = psSS->LF_AR_Q14;
708 psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;
709 psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14;
710 psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10;
711 psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 );
712 psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14;
713 psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) );
714 psDD->RandState[ *smpl_buf_idx ] = psDD->Seed;
715 psDD->RD_Q10 = psSS->RD_Q10;
716 }
717 delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10;
718 }
719 /* Update LPC states */
720 for( k = 0; k < nStatesDelayedDecision; k++ ) {
721 psDD = &psDelDec[ k ];
722 silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
723 }
724 RESTORE_STACK;
725}
726
727static OPUS_INLINE void silk_nsq_del_dec_scale_states_sse4_1(
728 const silk_encoder_state *psEncC, /* I Encoder State */
729 silk_nsq_state *NSQ, /* I/O NSQ state */
730 NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
731 const opus_int32 x_Q3[], /* I Input in Q3 */
732 opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
733 const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
734 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
735 opus_int subfr, /* I Subframe number */
736 opus_int nStatesDelayedDecision, /* I Number of del dec states */
737 const opus_int LTP_scale_Q14, /* I LTP state scaling */
738 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
739 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
740 const opus_int signal_type, /* I Signal type */
741 const opus_int decisionDelay /* I Decision delay */
742)
743{
744 opus_int i, k, lag;
745 opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23;
746 NSQ_del_dec_struct *psDD;
747 __m128i xmm_inv_gain_Q23, xmm_x_Q3_x2x0, xmm_x_Q3_x3x1;
748
749 lag = pitchL[ subfr ];
750 inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
751
752 silk_assert( inv_gain_Q31 != 0 );
753
754 /* Calculate gain adjustment factor */
755 if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
756 gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
757 } else {
758 gain_adj_Q16 = (opus_int32)1 << 16;
759 }
760
761 /* Scale input */
762 inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 );
763
764 /* prepare inv_gain_Q23 in packed 4 32-bits */
765 xmm_inv_gain_Q23 = _mm_set1_epi32(inv_gain_Q23);
766
767 for( i = 0; i < psEncC->subfr_length - 3; i += 4 ) {
768 xmm_x_Q3_x2x0 = _mm_loadu_si128( (__m128i *)(&(x_Q3[ i ] ) ) );
769 /* equal shift right 4 bytes*/
770 xmm_x_Q3_x3x1 = _mm_shuffle_epi32( xmm_x_Q3_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );
771
772 xmm_x_Q3_x2x0 = _mm_mul_epi32( xmm_x_Q3_x2x0, xmm_inv_gain_Q23 );
773 xmm_x_Q3_x3x1 = _mm_mul_epi32( xmm_x_Q3_x3x1, xmm_inv_gain_Q23 );
774
775 xmm_x_Q3_x2x0 = _mm_srli_epi64( xmm_x_Q3_x2x0, 16 );
776 xmm_x_Q3_x3x1 = _mm_slli_epi64( xmm_x_Q3_x3x1, 16 );
777
778 xmm_x_Q3_x2x0 = _mm_blend_epi16( xmm_x_Q3_x2x0, xmm_x_Q3_x3x1, 0xCC );
779
780 _mm_storeu_si128( (__m128i *)(&(x_sc_Q10[ i ])), xmm_x_Q3_x2x0 );
781 }
782
783 for( ; i < psEncC->subfr_length; i++ ) {
784 x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 );
785 }
786
787 /* Save inverse gain */
788 NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
789
790 /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
791 if( NSQ->rewhite_flag ) {
792 if( subfr == 0 ) {
793 /* Do LTP downscaling */
794 inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
795 }
796 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
797 silk_assert( i < MAX_FRAME_LENGTH );
798 sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );
799 }
800 }
801
802 /* Adjust for changing gain */
803 if( gain_adj_Q16 != (opus_int32)1 << 16 ) {
804 /* Scale long-term shaping state */
805 {
806 __m128i xmm_gain_adj_Q16, xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1;
807
808 /* prepare gain_adj_Q16 in packed 4 32-bits */
809 xmm_gain_adj_Q16 = _mm_set1_epi32( gain_adj_Q16 );
810
811 for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 3; i += 4 )
812 {
813 xmm_sLTP_shp_Q14_x2x0 = _mm_loadu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ) );
814 /* equal shift right 4 bytes*/
815 xmm_sLTP_shp_Q14_x3x1 = _mm_shuffle_epi32( xmm_sLTP_shp_Q14_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );
816
817 xmm_sLTP_shp_Q14_x2x0 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x2x0, xmm_gain_adj_Q16 );
818 xmm_sLTP_shp_Q14_x3x1 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x3x1, xmm_gain_adj_Q16 );
819
820 xmm_sLTP_shp_Q14_x2x0 = _mm_srli_epi64( xmm_sLTP_shp_Q14_x2x0, 16 );
821 xmm_sLTP_shp_Q14_x3x1 = _mm_slli_epi64( xmm_sLTP_shp_Q14_x3x1, 16 );
822
823 xmm_sLTP_shp_Q14_x2x0 = _mm_blend_epi16( xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1, 0xCC );
824
825 _mm_storeu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ), xmm_sLTP_shp_Q14_x2x0 );
826 }
827
828 for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) {
829 NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
830 }
831
832 /* Scale long-term prediction state */
833 if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
834 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
835 sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
836 }
837 }
838
839 for( k = 0; k < nStatesDelayedDecision; k++ ) {
840 psDD = &psDelDec[ k ];
841
842 /* Scale scalar states */
843 psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 );
844
845 /* Scale short-term prediction and shaping states */
846 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
847 psDD->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] );
848 }
849 for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
850 psDD->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] );
851 }
852 for( i = 0; i < DECISION_DELAY; i++ ) {
853 psDD->Pred_Q15[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Pred_Q15[ i ] );
854 psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] );
855 }
856 }
857 }
858 }
859}
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/NSQ_sse4_1.c b/lib/rbcodec/codecs/libopus/silk/x86/NSQ_sse4_1.c
new file mode 100644
index 0000000000..b0315e35fc
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/x86/NSQ_sse4_1.c
@@ -0,0 +1,719 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <xmmintrin.h>
33#include <emmintrin.h>
34#include <smmintrin.h>
35#include "main.h"
36#include "celt/x86/x86cpu.h"
37#include "stack_alloc.h"
38
39static OPUS_INLINE void silk_nsq_scale_states_sse4_1(
40 const silk_encoder_state *psEncC, /* I Encoder State */
41 silk_nsq_state *NSQ, /* I/O NSQ state */
42 const opus_int32 x_Q3[], /* I input in Q3 */
43 opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
44 const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */
45 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
46 opus_int subfr, /* I subframe number */
47 const opus_int LTP_scale_Q14, /* I */
48 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
49 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
50 const opus_int signal_type /* I Signal type */
51);
52
53static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1(
54 silk_nsq_state *NSQ, /* I/O NSQ state */
55 opus_int signalType, /* I Signal type */
56 const opus_int32 x_sc_Q10[], /* I */
57 opus_int8 pulses[], /* O */
58 opus_int16 xq[], /* O */
59 opus_int32 sLTP_Q15[], /* I/O LTP state */
60 const opus_int16 a_Q12[], /* I Short term prediction coefs */
61 const opus_int16 b_Q14[], /* I Long term prediction coefs */
62 const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
63 opus_int lag, /* I Pitch lag */
64 opus_int32 HarmShapeFIRPacked_Q14, /* I */
65 opus_int Tilt_Q14, /* I Spectral tilt */
66 opus_int32 LF_shp_Q14, /* I */
67 opus_int32 Gain_Q16, /* I */
68 opus_int offset_Q10, /* I */
69 opus_int length, /* I Input length */
70 opus_int32 table[][4] /* I */
71);
72
73void silk_NSQ_sse4_1(
74 const silk_encoder_state *psEncC, /* I Encoder State */
75 silk_nsq_state *NSQ, /* I/O NSQ state */
76 SideInfoIndices *psIndices, /* I/O Quantization Indices */
77 const opus_int32 x_Q3[], /* I Prefiltered input signal */
78 opus_int8 pulses[], /* O Quantized pulse signal */
79 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
80 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
81 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
82 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
83 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
84 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
85 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
86 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
87 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
88 const opus_int LTP_scale_Q14 /* I LTP state scaling */
89)
90{
91 opus_int k, lag, start_idx, LSF_interpolation_flag;
92 const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
93 opus_int16 *pxq;
94 VARDECL( opus_int32, sLTP_Q15 );
95 VARDECL( opus_int16, sLTP );
96 opus_int32 HarmShapeFIRPacked_Q14;
97 opus_int offset_Q10;
98 VARDECL( opus_int32, x_sc_Q10 );
99
100 opus_int32 table[ 64 ][ 4 ];
101 opus_int32 tmp1;
102 opus_int32 q1_Q10, q2_Q10, rd1_Q20, rd2_Q20;
103
104 SAVE_STACK;
105
106 NSQ->rand_seed = psIndices->Seed;
107
108 /* Set unvoiced lag to the previous one, overwrite later for voiced */
109 lag = NSQ->lagPrev;
110
111 silk_assert( NSQ->prev_gain_Q16 != 0 );
112
113 offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];
114
115 /* 0 */
116 q1_Q10 = offset_Q10;
117 q2_Q10 = offset_Q10 + ( 1024 - QUANT_LEVEL_ADJUST_Q10 );
118 rd1_Q20 = q1_Q10 * Lambda_Q10;
119 rd2_Q20 = q2_Q10 * Lambda_Q10;
120
121 table[ 32 ][ 0 ] = q1_Q10;
122 table[ 32 ][ 1 ] = q2_Q10;
123 table[ 32 ][ 2 ] = 2 * (q1_Q10 - q2_Q10);
124 table[ 32 ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10);
125
126 /* -1 */
127 q1_Q10 = offset_Q10 - ( 1024 - QUANT_LEVEL_ADJUST_Q10 );
128 q2_Q10 = offset_Q10;
129 rd1_Q20 = - q1_Q10 * Lambda_Q10;
130 rd2_Q20 = q2_Q10 * Lambda_Q10;
131
132 table[ 31 ][ 0 ] = q1_Q10;
133 table[ 31 ][ 1 ] = q2_Q10;
134 table[ 31 ][ 2 ] = 2 * (q1_Q10 - q2_Q10);
135 table[ 31 ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10);
136
137 /* > 0 */
138 for (k = 1; k <= 31; k++)
139 {
140 tmp1 = offset_Q10 + silk_LSHIFT( k, 10 );
141
142 q1_Q10 = tmp1 - QUANT_LEVEL_ADJUST_Q10;
143 q2_Q10 = tmp1 - QUANT_LEVEL_ADJUST_Q10 + 1024;
144 rd1_Q20 = q1_Q10 * Lambda_Q10;
145 rd2_Q20 = q2_Q10 * Lambda_Q10;
146
147 table[ 32 + k ][ 0 ] = q1_Q10;
148 table[ 32 + k ][ 1 ] = q2_Q10;
149 table[ 32 + k ][ 2 ] = 2 * (q1_Q10 - q2_Q10);
150 table[ 32 + k ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10);
151 }
152
153 /* < -1 */
154 for (k = -32; k <= -2; k++)
155 {
156 tmp1 = offset_Q10 + silk_LSHIFT( k, 10 );
157
158 q1_Q10 = tmp1 + QUANT_LEVEL_ADJUST_Q10;
159 q2_Q10 = tmp1 + QUANT_LEVEL_ADJUST_Q10 + 1024;
160 rd1_Q20 = - q1_Q10 * Lambda_Q10;
161 rd2_Q20 = - q2_Q10 * Lambda_Q10;
162
163 table[ 32 + k ][ 0 ] = q1_Q10;
164 table[ 32 + k ][ 1 ] = q2_Q10;
165 table[ 32 + k ][ 2 ] = 2 * (q1_Q10 - q2_Q10);
166 table[ 32 + k ][ 3 ] = (rd1_Q20 - rd2_Q20) + (q1_Q10 * q1_Q10 - q2_Q10 * q2_Q10);
167 }
168
169 if( psIndices->NLSFInterpCoef_Q2 == 4 ) {
170 LSF_interpolation_flag = 0;
171 } else {
172 LSF_interpolation_flag = 1;
173 }
174
175 ALLOC( sLTP_Q15,
176 psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
177 ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
178 ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
179 /* Set up pointers to start of sub frame */
180 NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
181 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
182 pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
183 for( k = 0; k < psEncC->nb_subfr; k++ ) {
184 A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ];
185 B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
186 AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ];
187
188 /* Noise shape parameters */
189 silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
190 HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
191 HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
192
193 NSQ->rewhite_flag = 0;
194 if( psIndices->signalType == TYPE_VOICED ) {
195 /* Voiced */
196 lag = pitchL[ k ];
197
198 /* Re-whitening */
199 if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
200 /* Rewhiten with new A coefs */
201 start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
202 celt_assert( start_idx > 0 );
203
204 silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
205 A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
206
207 NSQ->rewhite_flag = 1;
208 NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
209 }
210 }
211
212 silk_nsq_scale_states_sse4_1( psEncC, NSQ, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType );
213
214 if ( opus_likely( ( 10 == psEncC->shapingLPCOrder ) && ( 16 == psEncC->predictLPCOrder) ) )
215 {
216 silk_noise_shape_quantizer_10_16_sse4_1( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14,
217 AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ],
218 offset_Q10, psEncC->subfr_length, &(table[32]) );
219 }
220 else
221 {
222 silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14,
223 AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,
224 offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->arch );
225 }
226
227 x_Q3 += psEncC->subfr_length;
228 pulses += psEncC->subfr_length;
229 pxq += psEncC->subfr_length;
230 }
231
232 /* Update lagPrev for next frame */
233 NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
234
235 /* Save quantized speech and noise shaping signals */
236 silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
237 silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
238 RESTORE_STACK;
239}
240
241/***********************************/
242/* silk_noise_shape_quantizer_10_16 */
243/***********************************/
244static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1(
245 silk_nsq_state *NSQ, /* I/O NSQ state */
246 opus_int signalType, /* I Signal type */
247 const opus_int32 x_sc_Q10[], /* I */
248 opus_int8 pulses[], /* O */
249 opus_int16 xq[], /* O */
250 opus_int32 sLTP_Q15[], /* I/O LTP state */
251 const opus_int16 a_Q12[], /* I Short term prediction coefs */
252 const opus_int16 b_Q14[], /* I Long term prediction coefs */
253 const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
254 opus_int lag, /* I Pitch lag */
255 opus_int32 HarmShapeFIRPacked_Q14, /* I */
256 opus_int Tilt_Q14, /* I Spectral tilt */
257 opus_int32 LF_shp_Q14, /* I */
258 opus_int32 Gain_Q16, /* I */
259 opus_int offset_Q10, /* I */
260 opus_int length, /* I Input length */
261 opus_int32 table[][4] /* I */
262)
263{
264 opus_int i;
265 opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13;
266 opus_int32 n_LF_Q12, r_Q10, q1_Q0, q1_Q10, q2_Q10;
267 opus_int32 exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
268 opus_int32 tmp1, tmp2, sLF_AR_shp_Q14;
269 opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr;
270
271 __m128i xmm_tempa, xmm_tempb;
272
273 __m128i xmm_one;
274
275 __m128i psLPC_Q14_hi_01234567, psLPC_Q14_hi_89ABCDEF;
276 __m128i psLPC_Q14_lo_01234567, psLPC_Q14_lo_89ABCDEF;
277 __m128i a_Q12_01234567, a_Q12_89ABCDEF;
278
279 __m128i sAR2_Q14_hi_76543210, sAR2_Q14_lo_76543210;
280 __m128i AR_shp_Q13_76543210;
281
282 shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
283 pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
284 Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
285
286 /* Set up short term AR state */
287 psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ];
288
289 sLF_AR_shp_Q14 = NSQ->sLF_AR_shp_Q14;
290 xq_Q14 = psLPC_Q14[ 0 ];
291 LTP_pred_Q13 = 0;
292
293 /* load a_Q12 */
294 xmm_one = _mm_set_epi8( 1, 0, 3, 2, 5, 4, 7, 6, 9, 8, 11, 10, 13, 12, 15, 14 );
295
296 /* load a_Q12[0] - a_Q12[7] */
297 a_Q12_01234567 = _mm_loadu_si128( (__m128i *)(&a_Q12[ 0 ] ) );
298 /* load a_Q12[ 8 ] - a_Q12[ 15 ] */
299 a_Q12_89ABCDEF = _mm_loadu_si128( (__m128i *)(&a_Q12[ 8 ] ) );
300
301 a_Q12_01234567 = _mm_shuffle_epi8( a_Q12_01234567, xmm_one );
302 a_Q12_89ABCDEF = _mm_shuffle_epi8( a_Q12_89ABCDEF, xmm_one );
303
304 /* load AR_shp_Q13 */
305 AR_shp_Q13_76543210 = _mm_loadu_si128( (__m128i *)(&AR_shp_Q13[0] ) );
306
307 /* load psLPC_Q14 */
308 xmm_one = _mm_set_epi8(15, 14, 11, 10, 7, 6, 3, 2, 13, 12, 9, 8, 5, 4, 1, 0 );
309
310 xmm_tempa = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[-16]) );
311 xmm_tempb = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[-12]) );
312
313 xmm_tempa = _mm_shuffle_epi8( xmm_tempa, xmm_one );
314 xmm_tempb = _mm_shuffle_epi8( xmm_tempb, xmm_one );
315
316 psLPC_Q14_hi_89ABCDEF = _mm_unpackhi_epi64( xmm_tempa, xmm_tempb );
317 psLPC_Q14_lo_89ABCDEF = _mm_unpacklo_epi64( xmm_tempa, xmm_tempb );
318
319 xmm_tempa = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -8 ]) );
320 xmm_tempb = _mm_loadu_si128( (__m128i *)(&psLPC_Q14[ -4 ]) );
321
322 xmm_tempa = _mm_shuffle_epi8( xmm_tempa, xmm_one );
323 xmm_tempb = _mm_shuffle_epi8( xmm_tempb, xmm_one );
324
325 psLPC_Q14_hi_01234567 = _mm_unpackhi_epi64( xmm_tempa, xmm_tempb );
326 psLPC_Q14_lo_01234567 = _mm_unpacklo_epi64( xmm_tempa, xmm_tempb );
327
328 /* load sAR2_Q14 */
329 xmm_tempa = _mm_loadu_si128( (__m128i *)(&(NSQ->sAR2_Q14[ 0 ]) ) );
330 xmm_tempb = _mm_loadu_si128( (__m128i *)(&(NSQ->sAR2_Q14[ 4 ]) ) );
331
332 xmm_tempa = _mm_shuffle_epi8( xmm_tempa, xmm_one );
333 xmm_tempb = _mm_shuffle_epi8( xmm_tempb, xmm_one );
334
335 sAR2_Q14_hi_76543210 = _mm_unpackhi_epi64( xmm_tempa, xmm_tempb );
336 sAR2_Q14_lo_76543210 = _mm_unpacklo_epi64( xmm_tempa, xmm_tempb );
337
338 /* prepare 1 in 8 * 16bit */
339 xmm_one = _mm_set1_epi16(1);
340
341 for( i = 0; i < length; i++ )
342 {
343 /* Short-term prediction */
344 __m128i xmm_hi_07, xmm_hi_8F, xmm_lo_07, xmm_lo_8F;
345
346 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
347 LPC_pred_Q10 = 8; /* silk_RSHIFT( predictLPCOrder, 1 ); */
348
349 /* shift psLPC_Q14 */
350 psLPC_Q14_hi_89ABCDEF = _mm_alignr_epi8( psLPC_Q14_hi_01234567, psLPC_Q14_hi_89ABCDEF, 2 );
351 psLPC_Q14_lo_89ABCDEF = _mm_alignr_epi8( psLPC_Q14_lo_01234567, psLPC_Q14_lo_89ABCDEF, 2 );
352
353 psLPC_Q14_hi_01234567 = _mm_srli_si128( psLPC_Q14_hi_01234567, 2 );
354 psLPC_Q14_lo_01234567 = _mm_srli_si128( psLPC_Q14_lo_01234567, 2 );
355
356 psLPC_Q14_hi_01234567 = _mm_insert_epi16( psLPC_Q14_hi_01234567, (xq_Q14 >> 16), 7 );
357 psLPC_Q14_lo_01234567 = _mm_insert_epi16( psLPC_Q14_lo_01234567, (xq_Q14), 7 );
358
359 /* high part, use pmaddwd, results in 4 32-bit */
360 xmm_hi_07 = _mm_madd_epi16( psLPC_Q14_hi_01234567, a_Q12_01234567 );
361 xmm_hi_8F = _mm_madd_epi16( psLPC_Q14_hi_89ABCDEF, a_Q12_89ABCDEF );
362
363 /* low part, use pmulhw, results in 8 16-bit, note we need simulate unsigned * signed, _mm_srai_epi16(psLPC_Q14_lo_01234567, 15) */
364 xmm_tempa = _mm_cmpgt_epi16( _mm_setzero_si128(), psLPC_Q14_lo_01234567 );
365 xmm_tempb = _mm_cmpgt_epi16( _mm_setzero_si128(), psLPC_Q14_lo_89ABCDEF );
366
367 xmm_tempa = _mm_and_si128( xmm_tempa, a_Q12_01234567 );
368 xmm_tempb = _mm_and_si128( xmm_tempb, a_Q12_89ABCDEF );
369
370 xmm_lo_07 = _mm_mulhi_epi16( psLPC_Q14_lo_01234567, a_Q12_01234567 );
371 xmm_lo_8F = _mm_mulhi_epi16( psLPC_Q14_lo_89ABCDEF, a_Q12_89ABCDEF );
372
373 xmm_lo_07 = _mm_add_epi16( xmm_lo_07, xmm_tempa );
374 xmm_lo_8F = _mm_add_epi16( xmm_lo_8F, xmm_tempb );
375
376 xmm_lo_07 = _mm_madd_epi16( xmm_lo_07, xmm_one );
377 xmm_lo_8F = _mm_madd_epi16( xmm_lo_8F, xmm_one );
378
379 /* accumulate */
380 xmm_hi_07 = _mm_add_epi32( xmm_hi_07, xmm_hi_8F );
381 xmm_lo_07 = _mm_add_epi32( xmm_lo_07, xmm_lo_8F );
382
383 xmm_hi_07 = _mm_add_epi32( xmm_hi_07, xmm_lo_07 );
384
385 xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_unpackhi_epi64(xmm_hi_07, xmm_hi_07 ) );
386 xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_shufflelo_epi16(xmm_hi_07, 0x0E ) );
387
388 LPC_pred_Q10 += _mm_cvtsi128_si32( xmm_hi_07 );
389
390 /* Long-term prediction */
391 if ( opus_likely( signalType == TYPE_VOICED ) ) {
392 /* Unrolled loop */
393 /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
394 LTP_pred_Q13 = 2;
395 {
396 __m128i b_Q14_3210, b_Q14_0123, pred_lag_ptr_0123;
397
398 b_Q14_3210 = OP_CVTEPI16_EPI32_M64( b_Q14 );
399 b_Q14_0123 = _mm_shuffle_epi32( b_Q14_3210, 0x1B );
400
401 /* loaded: [0] [-1] [-2] [-3] */
402 pred_lag_ptr_0123 = _mm_loadu_si128( (__m128i *)(&pred_lag_ptr[ -3 ] ) );
403 /* shuffle to [-3] [-2] [-1] [0] and to new xmm */
404 xmm_tempa = _mm_shuffle_epi32( pred_lag_ptr_0123, 0x1B );
405 /*64-bit multiply, a[2] * b[-2], a[0] * b[0] */
406 xmm_tempa = _mm_mul_epi32( xmm_tempa, b_Q14_3210 );
407 /* right shift 2 bytes (16 bits), zero extended */
408 xmm_tempa = _mm_srli_si128( xmm_tempa, 2 );
409
410 /* a[1] * b[-1], a[3] * b[-3] */
411 pred_lag_ptr_0123 = _mm_mul_epi32( pred_lag_ptr_0123, b_Q14_0123 );
412 pred_lag_ptr_0123 = _mm_srli_si128( pred_lag_ptr_0123, 2 );
413
414 pred_lag_ptr_0123 = _mm_add_epi32( pred_lag_ptr_0123, xmm_tempa );
415 /* equal shift right 8 bytes*/
416 xmm_tempa = _mm_shuffle_epi32( pred_lag_ptr_0123, _MM_SHUFFLE( 0, 0, 3, 2 ) );
417 xmm_tempa = _mm_add_epi32( xmm_tempa, pred_lag_ptr_0123 );
418
419 LTP_pred_Q13 += _mm_cvtsi128_si32( xmm_tempa );
420
421 LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
422 pred_lag_ptr++;
423 }
424 }
425
426 /* Noise shape feedback */
427 NSQ->sAR2_Q14[ 9 ] = NSQ->sAR2_Q14[ 8 ];
428 NSQ->sAR2_Q14[ 8 ] = _mm_cvtsi128_si32( _mm_srli_si128(_mm_unpackhi_epi16( sAR2_Q14_lo_76543210, sAR2_Q14_hi_76543210 ), 12 ) );
429
430 sAR2_Q14_hi_76543210 = _mm_slli_si128( sAR2_Q14_hi_76543210, 2 );
431 sAR2_Q14_lo_76543210 = _mm_slli_si128( sAR2_Q14_lo_76543210, 2 );
432
433 sAR2_Q14_hi_76543210 = _mm_insert_epi16( sAR2_Q14_hi_76543210, (xq_Q14 >> 16), 0 );
434 sAR2_Q14_lo_76543210 = _mm_insert_epi16( sAR2_Q14_lo_76543210, (xq_Q14), 0 );
435
436 /* high part, use pmaddwd, results in 4 32-bit */
437 xmm_hi_07 = _mm_madd_epi16( sAR2_Q14_hi_76543210, AR_shp_Q13_76543210 );
438
439 /* low part, use pmulhw, results in 8 16-bit, note we need simulate unsigned * signed,_mm_srai_epi16(sAR2_Q14_lo_76543210, 15) */
440 xmm_tempa = _mm_cmpgt_epi16( _mm_setzero_si128(), sAR2_Q14_lo_76543210 );
441 xmm_tempa = _mm_and_si128( xmm_tempa, AR_shp_Q13_76543210 );
442
443 xmm_lo_07 = _mm_mulhi_epi16( sAR2_Q14_lo_76543210, AR_shp_Q13_76543210 );
444 xmm_lo_07 = _mm_add_epi16( xmm_lo_07, xmm_tempa );
445
446 xmm_lo_07 = _mm_madd_epi16( xmm_lo_07, xmm_one );
447
448 /* accumulate */
449 xmm_hi_07 = _mm_add_epi32( xmm_hi_07, xmm_lo_07 );
450
451 xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_unpackhi_epi64(xmm_hi_07, xmm_hi_07 ) );
452 xmm_hi_07 = _mm_add_epi32( xmm_hi_07, _mm_shufflelo_epi16(xmm_hi_07, 0x0E ) );
453
454 n_AR_Q12 = 5 + _mm_cvtsi128_si32( xmm_hi_07 );
455
456 n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sAR2_Q14[ 8 ], AR_shp_Q13[ 8 ] );
457 n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sAR2_Q14[ 9 ], AR_shp_Q13[ 9 ] );
458
459 n_AR_Q12 = silk_LSHIFT32( n_AR_Q12, 1 ); /* Q11 -> Q12 */
460 n_AR_Q12 = silk_SMLAWB( n_AR_Q12, sLF_AR_shp_Q14, Tilt_Q14 );
461
462 n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 );
463 n_LF_Q12 = silk_SMLAWT( n_LF_Q12, sLF_AR_shp_Q14, LF_shp_Q14 );
464
465 silk_assert( lag > 0 || signalType != TYPE_VOICED );
466
467 /* Combine prediction and noise shaping signals */
468 tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 ); /* Q12 */
469 tmp1 = silk_SUB32( tmp1, n_LF_Q12 ); /* Q12 */
470 if( lag > 0 ) {
471 /* Symmetric, packed FIR coefficients */
472 n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
473 n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
474 n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 );
475 shp_lag_ptr++;
476
477 tmp2 = silk_SUB32( LTP_pred_Q13, n_LTP_Q13 ); /* Q13 */
478 tmp1 = silk_ADD_LSHIFT32( tmp2, tmp1, 1 ); /* Q13 */
479 tmp1 = silk_RSHIFT_ROUND( tmp1, 3 ); /* Q10 */
480 } else {
481 tmp1 = silk_RSHIFT_ROUND( tmp1, 2 ); /* Q10 */
482 }
483
484 r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 ); /* residual error Q10 */
485
486 /* Generate dither */
487 NSQ->rand_seed = silk_RAND( NSQ->rand_seed );
488
489 /* Flip sign depending on dither */
490 tmp2 = -r_Q10;
491 if ( NSQ->rand_seed < 0 ) r_Q10 = tmp2;
492
493 r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
494
495 /* Find two quantization level candidates and measure their rate-distortion */
496 q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
497 q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
498
499 q1_Q10 = table[q1_Q0][0];
500 q2_Q10 = table[q1_Q0][1];
501
502 if (r_Q10 * table[q1_Q0][2] - table[q1_Q0][3] < 0)
503 {
504 q1_Q10 = q2_Q10;
505 }
506
507 pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 );
508
509 /* Excitation */
510 exc_Q14 = silk_LSHIFT( q1_Q10, 4 );
511
512 tmp2 = -exc_Q14;
513 if ( NSQ->rand_seed < 0 ) exc_Q14 = tmp2;
514
515 /* Add predictions */
516 LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 );
517 xq_Q14 = silk_ADD_LSHIFT32( LPC_exc_Q14, LPC_pred_Q10, 4 );
518
519 /* Update states */
520 psLPC_Q14++;
521 *psLPC_Q14 = xq_Q14;
522 sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, n_AR_Q12, 2 );
523
524 NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 );
525 sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 );
526 NSQ->sLTP_shp_buf_idx++;
527 NSQ->sLTP_buf_idx++;
528
529 /* Make dither dependent on quantized signal */
530 NSQ->rand_seed = silk_ADD32_ovflw( NSQ->rand_seed, pulses[ i ] );
531 }
532
533 NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14;
534
535 /* Scale XQ back to normal level before saving */
536 psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH ];
537
538 /* write back sAR2_Q14 */
539 xmm_tempa = _mm_unpackhi_epi16( sAR2_Q14_lo_76543210, sAR2_Q14_hi_76543210 );
540 xmm_tempb = _mm_unpacklo_epi16( sAR2_Q14_lo_76543210, sAR2_Q14_hi_76543210 );
541 _mm_storeu_si128( (__m128i *)(&NSQ->sAR2_Q14[ 4 ]), xmm_tempa );
542 _mm_storeu_si128( (__m128i *)(&NSQ->sAR2_Q14[ 0 ]), xmm_tempb );
543
544 /* xq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psLPC_Q14[ i ], Gain_Q10 ), 8 ) ); */
545 {
546 __m128i xmm_Gain_Q10;
547 __m128i xmm_xq_Q14_3210, xmm_xq_Q14_x3x1, xmm_xq_Q14_7654, xmm_xq_Q14_x7x5;
548
549 /* prepare (1 << 7) in packed 4 32-bits */
550 xmm_tempa = _mm_set1_epi32( (1 << 7) );
551
552 /* prepare Gain_Q10 in packed 4 32-bits */
553 xmm_Gain_Q10 = _mm_set1_epi32( Gain_Q10 );
554
555 /* process xq */
556 for (i = 0; i < length - 7; i += 8)
557 {
558 xmm_xq_Q14_3210 = _mm_loadu_si128( (__m128i *)(&(psLPC_Q14[ i + 0 ] ) ) );
559 xmm_xq_Q14_7654 = _mm_loadu_si128( (__m128i *)(&(psLPC_Q14[ i + 4 ] ) ) );
560
561 /* equal shift right 4 bytes*/
562 xmm_xq_Q14_x3x1 = _mm_shuffle_epi32( xmm_xq_Q14_3210, _MM_SHUFFLE( 0, 3, 2, 1 ) );
563 /* equal shift right 4 bytes*/
564 xmm_xq_Q14_x7x5 = _mm_shuffle_epi32( xmm_xq_Q14_7654, _MM_SHUFFLE( 0, 3, 2, 1 ) );
565
566 xmm_xq_Q14_3210 = _mm_mul_epi32( xmm_xq_Q14_3210, xmm_Gain_Q10 );
567 xmm_xq_Q14_x3x1 = _mm_mul_epi32( xmm_xq_Q14_x3x1, xmm_Gain_Q10 );
568 xmm_xq_Q14_7654 = _mm_mul_epi32( xmm_xq_Q14_7654, xmm_Gain_Q10 );
569 xmm_xq_Q14_x7x5 = _mm_mul_epi32( xmm_xq_Q14_x7x5, xmm_Gain_Q10 );
570
571 xmm_xq_Q14_3210 = _mm_srli_epi64( xmm_xq_Q14_3210, 16 );
572 xmm_xq_Q14_x3x1 = _mm_slli_epi64( xmm_xq_Q14_x3x1, 16 );
573 xmm_xq_Q14_7654 = _mm_srli_epi64( xmm_xq_Q14_7654, 16 );
574 xmm_xq_Q14_x7x5 = _mm_slli_epi64( xmm_xq_Q14_x7x5, 16 );
575
576 xmm_xq_Q14_3210 = _mm_blend_epi16( xmm_xq_Q14_3210, xmm_xq_Q14_x3x1, 0xCC );
577 xmm_xq_Q14_7654 = _mm_blend_epi16( xmm_xq_Q14_7654, xmm_xq_Q14_x7x5, 0xCC );
578
579 /* silk_RSHIFT_ROUND(xq, 8) */
580 xmm_xq_Q14_3210 = _mm_add_epi32( xmm_xq_Q14_3210, xmm_tempa );
581 xmm_xq_Q14_7654 = _mm_add_epi32( xmm_xq_Q14_7654, xmm_tempa );
582
583 xmm_xq_Q14_3210 = _mm_srai_epi32( xmm_xq_Q14_3210, 8 );
584 xmm_xq_Q14_7654 = _mm_srai_epi32( xmm_xq_Q14_7654, 8 );
585
586 /* silk_SAT16 */
587 xmm_xq_Q14_3210 = _mm_packs_epi32( xmm_xq_Q14_3210, xmm_xq_Q14_7654 );
588
589 /* save to xq */
590 _mm_storeu_si128( (__m128i *)(&xq[ i ] ), xmm_xq_Q14_3210 );
591 }
592 }
593 for ( ; i < length; i++)
594 {
595 xq[i] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psLPC_Q14[ i ], Gain_Q10 ), 8 ) );
596 }
597
598 /* Update LPC synth buffer */
599 silk_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
600}
601
602static OPUS_INLINE void silk_nsq_scale_states_sse4_1(
603 const silk_encoder_state *psEncC, /* I Encoder State */
604 silk_nsq_state *NSQ, /* I/O NSQ state */
605 const opus_int32 x_Q3[], /* I input in Q3 */
606 opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
607 const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */
608 opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
609 opus_int subfr, /* I subframe number */
610 const opus_int LTP_scale_Q14, /* I */
611 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
612 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
613 const opus_int signal_type /* I Signal type */
614)
615{
616 opus_int i, lag;
617 opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23;
618 __m128i xmm_inv_gain_Q23, xmm_x_Q3_x2x0, xmm_x_Q3_x3x1;
619
620 lag = pitchL[ subfr ];
621 inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
622 silk_assert( inv_gain_Q31 != 0 );
623
624 /* Calculate gain adjustment factor */
625 if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
626 gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
627 } else {
628 gain_adj_Q16 = (opus_int32)1 << 16;
629 }
630
631 /* Scale input */
632 inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 );
633
634 /* prepare inv_gain_Q23 in packed 4 32-bits */
635 xmm_inv_gain_Q23 = _mm_set1_epi32(inv_gain_Q23);
636
637 for( i = 0; i < psEncC->subfr_length - 3; i += 4 ) {
638 xmm_x_Q3_x2x0 = _mm_loadu_si128( (__m128i *)(&(x_Q3[ i ] ) ) );
639
640 /* equal shift right 4 bytes*/
641 xmm_x_Q3_x3x1 = _mm_shuffle_epi32( xmm_x_Q3_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );
642
643 xmm_x_Q3_x2x0 = _mm_mul_epi32( xmm_x_Q3_x2x0, xmm_inv_gain_Q23 );
644 xmm_x_Q3_x3x1 = _mm_mul_epi32( xmm_x_Q3_x3x1, xmm_inv_gain_Q23 );
645
646 xmm_x_Q3_x2x0 = _mm_srli_epi64( xmm_x_Q3_x2x0, 16 );
647 xmm_x_Q3_x3x1 = _mm_slli_epi64( xmm_x_Q3_x3x1, 16 );
648
649 xmm_x_Q3_x2x0 = _mm_blend_epi16( xmm_x_Q3_x2x0, xmm_x_Q3_x3x1, 0xCC );
650
651 _mm_storeu_si128( (__m128i *)(&(x_sc_Q10[ i ] ) ), xmm_x_Q3_x2x0 );
652 }
653
654 for( ; i < psEncC->subfr_length; i++ ) {
655 x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 );
656 }
657
658 /* Save inverse gain */
659 NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
660
661 /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
662 if( NSQ->rewhite_flag ) {
663 if( subfr == 0 ) {
664 /* Do LTP downscaling */
665 inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
666 }
667 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
668 silk_assert( i < MAX_FRAME_LENGTH );
669 sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] );
670 }
671 }
672
673 /* Adjust for changing gain */
674 if( gain_adj_Q16 != (opus_int32)1 << 16 ) {
675 /* Scale long-term shaping state */
676 __m128i xmm_gain_adj_Q16, xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1;
677
678 /* prepare gain_adj_Q16 in packed 4 32-bits */
679 xmm_gain_adj_Q16 = _mm_set1_epi32(gain_adj_Q16);
680
681 for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 3; i += 4 )
682 {
683 xmm_sLTP_shp_Q14_x2x0 = _mm_loadu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ) );
684 /* equal shift right 4 bytes*/
685 xmm_sLTP_shp_Q14_x3x1 = _mm_shuffle_epi32( xmm_sLTP_shp_Q14_x2x0, _MM_SHUFFLE( 0, 3, 2, 1 ) );
686
687 xmm_sLTP_shp_Q14_x2x0 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x2x0, xmm_gain_adj_Q16 );
688 xmm_sLTP_shp_Q14_x3x1 = _mm_mul_epi32( xmm_sLTP_shp_Q14_x3x1, xmm_gain_adj_Q16 );
689
690 xmm_sLTP_shp_Q14_x2x0 = _mm_srli_epi64( xmm_sLTP_shp_Q14_x2x0, 16 );
691 xmm_sLTP_shp_Q14_x3x1 = _mm_slli_epi64( xmm_sLTP_shp_Q14_x3x1, 16 );
692
693 xmm_sLTP_shp_Q14_x2x0 = _mm_blend_epi16( xmm_sLTP_shp_Q14_x2x0, xmm_sLTP_shp_Q14_x3x1, 0xCC );
694
695 _mm_storeu_si128( (__m128i *)(&(NSQ->sLTP_shp_Q14[ i ] ) ), xmm_sLTP_shp_Q14_x2x0 );
696 }
697
698 for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) {
699 NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
700 }
701
702 /* Scale long-term prediction state */
703 if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
704 for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) {
705 sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
706 }
707 }
708
709 NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 );
710
711 /* Scale short-term prediction and shaping states */
712 for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
713 NSQ->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] );
714 }
715 for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
716 NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] );
717 }
718 }
719}
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/SigProc_FIX_sse.h b/lib/rbcodec/codecs/libopus/silk/x86/SigProc_FIX_sse.h
new file mode 100644
index 0000000000..61efa8da41
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/x86/SigProc_FIX_sse.h
@@ -0,0 +1,94 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifndef SIGPROC_FIX_SSE_H
29#define SIGPROC_FIX_SSE_H
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35#if defined(OPUS_X86_MAY_HAVE_SSE4_1)
36void silk_burg_modified_sse4_1(
37 opus_int32 *res_nrg, /* O Residual energy */
38 opus_int *res_nrg_Q, /* O Residual energy Q value */
39 opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
40 const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
41 const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
42 const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */
43 const opus_int nb_subfr, /* I Number of subframes stacked in x */
44 const opus_int D, /* I Order */
45 int arch /* I Run-time architecture */
46);
47
48#if defined(OPUS_X86_PRESUME_SSE4_1)
49#define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \
50 ((void)(arch), silk_burg_modified_sse4_1(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch))
51
52#else
53
54extern void (*const SILK_BURG_MODIFIED_IMPL[OPUS_ARCHMASK + 1])(
55 opus_int32 *res_nrg, /* O Residual energy */
56 opus_int *res_nrg_Q, /* O Residual energy Q value */
57 opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
58 const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
59 const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
60 const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */
61 const opus_int nb_subfr, /* I Number of subframes stacked in x */
62 const opus_int D, /* I Order */
63 int arch /* I Run-time architecture */);
64
65# define silk_burg_modified(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch) \
66 ((*SILK_BURG_MODIFIED_IMPL[(arch) & OPUS_ARCHMASK])(res_nrg, res_nrg_Q, A_Q16, x, minInvGain_Q30, subfr_length, nb_subfr, D, arch))
67
68#endif
69
70opus_int64 silk_inner_prod16_aligned_64_sse4_1(
71 const opus_int16 *inVec1,
72 const opus_int16 *inVec2,
73 const opus_int len
74);
75
76
77#if defined(OPUS_X86_PRESUME_SSE4_1)
78
79#define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \
80 ((void)(arch),silk_inner_prod16_aligned_64_sse4_1(inVec1, inVec2, len))
81
82#else
83
84extern opus_int64 (*const SILK_INNER_PROD16_ALIGNED_64_IMPL[OPUS_ARCHMASK + 1])(
85 const opus_int16 *inVec1,
86 const opus_int16 *inVec2,
87 const opus_int len);
88
89# define silk_inner_prod16_aligned_64(inVec1, inVec2, len, arch) \
90 ((*SILK_INNER_PROD16_ALIGNED_64_IMPL[(arch) & OPUS_ARCHMASK])(inVec1, inVec2, len))
91
92#endif
93#endif
94#endif
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/VAD_sse4_1.c b/lib/rbcodec/codecs/libopus/silk/x86/VAD_sse4_1.c
new file mode 100644
index 0000000000..d02ddf4ad0
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/x86/VAD_sse4_1.c
@@ -0,0 +1,277 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <xmmintrin.h>
33#include <emmintrin.h>
34#include <smmintrin.h>
35
36#include "main.h"
37#include "stack_alloc.h"
38
39/* Weighting factors for tilt measure */
40static const opus_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 };
41
42/***************************************/
43/* Get the speech activity level in Q8 */
44/***************************************/
45opus_int silk_VAD_GetSA_Q8_sse4_1( /* O Return value, 0 if success */
46 silk_encoder_state *psEncC, /* I/O Encoder state */
47 const opus_int16 pIn[] /* I PCM input */
48)
49{
50 opus_int SA_Q15, pSNR_dB_Q7, input_tilt;
51 opus_int decimated_framelength1, decimated_framelength2;
52 opus_int decimated_framelength;
53 opus_int dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;
54 opus_int32 sumSquared, smooth_coef_Q16;
55 opus_int16 HPstateTmp;
56 VARDECL( opus_int16, X );
57 opus_int32 Xnrg[ VAD_N_BANDS ];
58 opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];
59 opus_int32 speech_nrg, x_tmp;
60 opus_int X_offset[ VAD_N_BANDS ];
61 opus_int ret = 0;
62 silk_VAD_state *psSilk_VAD = &psEncC->sVAD;
63
64 SAVE_STACK;
65
66 /* Safety checks */
67 silk_assert( VAD_N_BANDS == 4 );
68 celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
69 celt_assert( psEncC->frame_length <= 512 );
70 celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
71
72 /***********************/
73 /* Filter and Decimate */
74 /***********************/
75 decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 );
76 decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 );
77 decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 );
78 /* Decimate into 4 bands:
79 0 L 3L L 3L 5L
80 - -- - -- --
81 8 8 2 4 4
82
83 [0-1 kHz| temp. |1-2 kHz| 2-4 kHz | 4-8 kHz |
84
85 They're arranged to allow the minimal ( frame_length / 4 ) extra
86 scratch space during the downsampling process */
87 X_offset[ 0 ] = 0;
88 X_offset[ 1 ] = decimated_framelength + decimated_framelength2;
89 X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength;
90 X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2;
91 ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 );
92
93 /* 0-8 kHz to 0-4 kHz and 4-8 kHz */
94 silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[ 0 ],
95 X, &X[ X_offset[ 3 ] ], psEncC->frame_length );
96
97 /* 0-4 kHz to 0-2 kHz and 2-4 kHz */
98 silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ],
99 X, &X[ X_offset[ 2 ] ], decimated_framelength1 );
100
101 /* 0-2 kHz to 0-1 kHz and 1-2 kHz */
102 silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ],
103 X, &X[ X_offset[ 1 ] ], decimated_framelength2 );
104
105 /*********************************************/
106 /* HP filter on lowest band (differentiator) */
107 /*********************************************/
108 X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 );
109 HPstateTmp = X[ decimated_framelength - 1 ];
110 for( i = decimated_framelength - 1; i > 0; i-- ) {
111 X[ i - 1 ] = silk_RSHIFT( X[ i - 1 ], 1 );
112 X[ i ] -= X[ i - 1 ];
113 }
114 X[ 0 ] -= psSilk_VAD->HPstate;
115 psSilk_VAD->HPstate = HPstateTmp;
116
117 /*************************************/
118 /* Calculate the energy in each band */
119 /*************************************/
120 for( b = 0; b < VAD_N_BANDS; b++ ) {
121 /* Find the decimated framelength in the non-uniformly divided bands */
122 decimated_framelength = silk_RSHIFT( psEncC->frame_length, silk_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) );
123
124 /* Split length into subframe lengths */
125 dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );
126 dec_subframe_offset = 0;
127
128 /* Compute energy per sub-frame */
129 /* initialize with summed energy of last subframe */
130 Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];
131 for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {
132 __m128i xmm_X, xmm_acc;
133 sumSquared = 0;
134
135 xmm_acc = _mm_setzero_si128();
136
137 for( i = 0; i < dec_subframe_length - 7; i += 8 )
138 {
139 xmm_X = _mm_loadu_si128( (__m128i *)&(X[ X_offset[ b ] + i + dec_subframe_offset ] ) );
140 xmm_X = _mm_srai_epi16( xmm_X, 3 );
141 xmm_X = _mm_madd_epi16( xmm_X, xmm_X );
142 xmm_acc = _mm_add_epi32( xmm_acc, xmm_X );
143 }
144
145 xmm_acc = _mm_add_epi32( xmm_acc, _mm_unpackhi_epi64( xmm_acc, xmm_acc ) );
146 xmm_acc = _mm_add_epi32( xmm_acc, _mm_shufflelo_epi16( xmm_acc, 0x0E ) );
147
148 sumSquared += _mm_cvtsi128_si32( xmm_acc );
149
150 for( ; i < dec_subframe_length; i++ ) {
151 /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2. */
152 /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128) */
153 x_tmp = silk_RSHIFT(
154 X[ X_offset[ b ] + i + dec_subframe_offset ], 3 );
155 sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp );
156
157 /* Safety check */
158 silk_assert( sumSquared >= 0 );
159 }
160
161 /* Add/saturate summed energy of current subframe */
162 if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {
163 Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared );
164 } else {
165 /* Look-ahead subframe */
166 Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) );
167 }
168
169 dec_subframe_offset += dec_subframe_length;
170 }
171 psSilk_VAD->XnrgSubfr[ b ] = sumSquared;
172 }
173
174 /********************/
175 /* Noise estimation */
176 /********************/
177 silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD );
178
179 /***********************************************/
180 /* Signal-plus-noise to noise ratio estimation */
181 /***********************************************/
182 sumSquared = 0;
183 input_tilt = 0;
184 for( b = 0; b < VAD_N_BANDS; b++ ) {
185 speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];
186 if( speech_nrg > 0 ) {
187 /* Divide, with sufficient resolution */
188 if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) {
189 NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 );
190 } else {
191 NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 );
192 }
193
194 /* Convert to log domain */
195 SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128;
196
197 /* Sum-of-squares */
198 sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 ); /* Q14 */
199
200 /* Tilt measure */
201 if( speech_nrg < ( (opus_int32)1 << 20 ) ) {
202 /* Scale down SNR value for small subband speech energies */
203 SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );
204 }
205 input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );
206 } else {
207 NrgToNoiseRatio_Q8[ b ] = 256;
208 }
209 }
210
211 /* Mean-of-squares */
212 sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */
213
214 /* Root-mean-square approximation, scale to dBs, and write to output pointer */
215 pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */
216
217 /*********************************/
218 /* Speech Probability Estimation */
219 /*********************************/
220 SA_Q15 = silk_sigm_Q15( silk_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 );
221
222 /**************************/
223 /* Frequency Tilt Measure */
224 /**************************/
225 psEncC->input_tilt_Q15 = silk_LSHIFT( silk_sigm_Q15( input_tilt ) - 16384, 1 );
226
227 /**************************************************/
228 /* Scale the sigmoid output based on power levels */
229 /**************************************************/
230 speech_nrg = 0;
231 for( b = 0; b < VAD_N_BANDS; b++ ) {
232 /* Accumulate signal-without-noise energies, higher frequency bands have more weight */
233 speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );
234 }
235
236 /* Power scaling */
237 if( speech_nrg <= 0 ) {
238 SA_Q15 = silk_RSHIFT( SA_Q15, 1 );
239 } else if( speech_nrg < 32768 ) {
240 if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {
241 speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 16 );
242 } else {
243 speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 15 );
244 }
245
246 /* square-root */
247 speech_nrg = silk_SQRT_APPROX( speech_nrg );
248 SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 );
249 }
250
251 /* Copy the resulting speech activity in Q8 */
252 psEncC->speech_activity_Q8 = silk_min_int( silk_RSHIFT( SA_Q15, 7 ), silk_uint8_MAX );
253
254 /***********************************/
255 /* Energy Level and SNR estimation */
256 /***********************************/
257 /* Smoothing coefficient */
258 smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) );
259
260 if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {
261 smooth_coef_Q16 >>= 1;
262 }
263
264 for( b = 0; b < VAD_N_BANDS; b++ ) {
265 /* compute smoothed energy-to-noise ratio per band */
266 psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ],
267 NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 );
268
269 /* signal to noise ratio in dB per band */
270 SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 );
271 /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */
272 psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) );
273 }
274
275 RESTORE_STACK;
276 return( ret );
277}
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/VQ_WMat_EC_sse4_1.c b/lib/rbcodec/codecs/libopus/silk/x86/VQ_WMat_EC_sse4_1.c
new file mode 100644
index 0000000000..74d6c6d0ec
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/x86/VQ_WMat_EC_sse4_1.c
@@ -0,0 +1,142 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <xmmintrin.h>
33#include <emmintrin.h>
34#include <smmintrin.h>
35#include "main.h"
36#include "celt/x86/x86cpu.h"
37
38/* Entropy constrained matrix-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */
39void silk_VQ_WMat_EC_sse4_1(
40 opus_int8 *ind, /* O index of best codebook vector */
41 opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */
42 opus_int *gain_Q7, /* O sum of absolute LTP coefficients */
43 const opus_int16 *in_Q14, /* I input vector to be quantized */
44 const opus_int32 *W_Q18, /* I weighting matrix */
45 const opus_int8 *cb_Q7, /* I codebook */
46 const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */
47 const opus_uint8 *cl_Q5, /* I code length for each codebook vector */
48 const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */
49 const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
50 opus_int L /* I number of vectors in codebook */
51)
52{
53 opus_int k, gain_tmp_Q7;
54 const opus_int8 *cb_row_Q7;
55 opus_int16 diff_Q14[ 5 ];
56 opus_int32 sum1_Q14, sum2_Q16;
57
58 __m128i C_tmp1, C_tmp2, C_tmp3, C_tmp4, C_tmp5;
59 /* Loop over codebook */
60 *rate_dist_Q14 = silk_int32_MAX;
61 cb_row_Q7 = cb_Q7;
62 for( k = 0; k < L; k++ ) {
63 gain_tmp_Q7 = cb_gain_Q7[k];
64
65 diff_Q14[ 0 ] = in_Q14[ 0 ] - silk_LSHIFT( cb_row_Q7[ 0 ], 7 );
66
67 C_tmp1 = OP_CVTEPI16_EPI32_M64( &in_Q14[ 1 ] );
68 C_tmp2 = OP_CVTEPI8_EPI32_M32( &cb_row_Q7[ 1 ] );
69 C_tmp2 = _mm_slli_epi32( C_tmp2, 7 );
70 C_tmp1 = _mm_sub_epi32( C_tmp1, C_tmp2 );
71
72 diff_Q14[ 1 ] = _mm_extract_epi16( C_tmp1, 0 );
73 diff_Q14[ 2 ] = _mm_extract_epi16( C_tmp1, 2 );
74 diff_Q14[ 3 ] = _mm_extract_epi16( C_tmp1, 4 );
75 diff_Q14[ 4 ] = _mm_extract_epi16( C_tmp1, 6 );
76
77 /* Weighted rate */
78 sum1_Q14 = silk_SMULBB( mu_Q9, cl_Q5[ k ] );
79
80 /* Penalty for too large gain */
81 sum1_Q14 = silk_ADD_LSHIFT32( sum1_Q14, silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 10 );
82
83 silk_assert( sum1_Q14 >= 0 );
84
85 /* first row of W_Q18 */
86 C_tmp3 = _mm_loadu_si128( (__m128i *)(&W_Q18[ 1 ] ) );
87 C_tmp4 = _mm_mul_epi32( C_tmp3, C_tmp1 );
88 C_tmp4 = _mm_srli_si128( C_tmp4, 2 );
89
90 C_tmp1 = _mm_shuffle_epi32( C_tmp1, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* shift right 4 bytes */
91 C_tmp3 = _mm_shuffle_epi32( C_tmp3, _MM_SHUFFLE( 0, 3, 2, 1 ) ); /* shift right 4 bytes */
92
93 C_tmp5 = _mm_mul_epi32( C_tmp3, C_tmp1 );
94 C_tmp5 = _mm_srli_si128( C_tmp5, 2 );
95
96 C_tmp5 = _mm_add_epi32( C_tmp4, C_tmp5 );
97 C_tmp5 = _mm_slli_epi32( C_tmp5, 1 );
98
99 C_tmp5 = _mm_add_epi32( C_tmp5, _mm_shuffle_epi32( C_tmp5, _MM_SHUFFLE( 0, 0, 0, 2 ) ) );
100 sum2_Q16 = _mm_cvtsi128_si32( C_tmp5 );
101
102 sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 0 ], diff_Q14[ 0 ] );
103 sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 0 ] );
104
105 /* second row of W_Q18 */
106 sum2_Q16 = silk_SMULWB( W_Q18[ 7 ], diff_Q14[ 2 ] );
107 sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 8 ], diff_Q14[ 3 ] );
108 sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 9 ], diff_Q14[ 4 ] );
109 sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );
110 sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 6 ], diff_Q14[ 1 ] );
111 sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 1 ] );
112
113 /* third row of W_Q18 */
114 sum2_Q16 = silk_SMULWB( W_Q18[ 13 ], diff_Q14[ 3 ] );
115 sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 14 ], diff_Q14[ 4 ] );
116 sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );
117 sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 12 ], diff_Q14[ 2 ] );
118 sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 2 ] );
119
120 /* fourth row of W_Q18 */
121 sum2_Q16 = silk_SMULWB( W_Q18[ 19 ], diff_Q14[ 4 ] );
122 sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );
123 sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 18 ], diff_Q14[ 3 ] );
124 sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 3 ] );
125
126 /* last row of W_Q18 */
127 sum2_Q16 = silk_SMULWB( W_Q18[ 24 ], diff_Q14[ 4 ] );
128 sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 4 ] );
129
130 silk_assert( sum1_Q14 >= 0 );
131
132 /* find best */
133 if( sum1_Q14 < *rate_dist_Q14 ) {
134 *rate_dist_Q14 = sum1_Q14;
135 *ind = (opus_int8)k;
136 *gain_Q7 = gain_tmp_Q7;
137 }
138
139 /* Go to next cbk vector */
140 cb_row_Q7 += LTP_ORDER;
141 }
142}
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/main_sse.h b/lib/rbcodec/codecs/libopus/silk/x86/main_sse.h
new file mode 100644
index 0000000000..2f15d44869
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/x86/main_sse.h
@@ -0,0 +1,248 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifndef MAIN_SSE_H
29#define MAIN_SSE_H
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35# if defined(OPUS_X86_MAY_HAVE_SSE4_1)
36
37#if 0 /* FIXME: SSE disabled until silk_VQ_WMat_EC_sse4_1() gets updated. */
38# define OVERRIDE_silk_VQ_WMat_EC
39
40void silk_VQ_WMat_EC_sse4_1(
41 opus_int8 *ind, /* O index of best codebook vector */
42 opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */
43 opus_int *gain_Q7, /* O sum of absolute LTP coefficients */
44 const opus_int16 *in_Q14, /* I input vector to be quantized */
45 const opus_int32 *W_Q18, /* I weighting matrix */
46 const opus_int8 *cb_Q7, /* I codebook */
47 const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */
48 const opus_uint8 *cl_Q5, /* I code length for each codebook vector */
49 const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */
50 const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
51 opus_int L /* I number of vectors in codebook */
52);
53
54#if defined OPUS_X86_PRESUME_SSE4_1
55
56#define silk_VQ_WMat_EC(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \
57 mu_Q9, max_gain_Q7, L, arch) \
58 ((void)(arch),silk_VQ_WMat_EC_sse4_1(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \
59 mu_Q9, max_gain_Q7, L))
60
61#else
62
63extern void (*const SILK_VQ_WMAT_EC_IMPL[OPUS_ARCHMASK + 1])(
64 opus_int8 *ind, /* O index of best codebook vector */
65 opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */
66 opus_int *gain_Q7, /* O sum of absolute LTP coefficients */
67 const opus_int16 *in_Q14, /* I input vector to be quantized */
68 const opus_int32 *W_Q18, /* I weighting matrix */
69 const opus_int8 *cb_Q7, /* I codebook */
70 const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */
71 const opus_uint8 *cl_Q5, /* I code length for each codebook vector */
72 const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */
73 const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
74 opus_int L /* I number of vectors in codebook */
75);
76
77# define silk_VQ_WMat_EC(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \
78 mu_Q9, max_gain_Q7, L, arch) \
79 ((*SILK_VQ_WMAT_EC_IMPL[(arch) & OPUS_ARCHMASK])(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \
80 mu_Q9, max_gain_Q7, L))
81
82#endif
83#endif
84
85#if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */
86# define OVERRIDE_silk_NSQ
87
88void silk_NSQ_sse4_1(
89 const silk_encoder_state *psEncC, /* I Encoder State */
90 silk_nsq_state *NSQ, /* I/O NSQ state */
91 SideInfoIndices *psIndices, /* I/O Quantization Indices */
92 const opus_int32 x_Q3[], /* I Prefiltered input signal */
93 opus_int8 pulses[], /* O Quantized pulse signal */
94 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
95 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
96 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
97 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
98 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
99 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
100 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
101 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
102 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
103 const opus_int LTP_scale_Q14 /* I LTP state scaling */
104);
105
106#if defined OPUS_X86_PRESUME_SSE4_1
107
108#define silk_NSQ(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
109 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \
110 ((void)(arch),silk_NSQ_sse4_1(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
111 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))
112
113#else
114
115extern void (*const SILK_NSQ_IMPL[OPUS_ARCHMASK + 1])(
116 const silk_encoder_state *psEncC, /* I Encoder State */
117 silk_nsq_state *NSQ, /* I/O NSQ state */
118 SideInfoIndices *psIndices, /* I/O Quantization Indices */
119 const opus_int32 x_Q3[], /* I Prefiltered input signal */
120 opus_int8 pulses[], /* O Quantized pulse signal */
121 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
122 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
123 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
124 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
125 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
126 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
127 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
128 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
129 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
130 const opus_int LTP_scale_Q14 /* I LTP state scaling */
131);
132
133# define silk_NSQ(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
134 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \
135 ((*SILK_NSQ_IMPL[(arch) & OPUS_ARCHMASK])(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
136 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))
137
138#endif
139
140# define OVERRIDE_silk_NSQ_del_dec
141
142void silk_NSQ_del_dec_sse4_1(
143 const silk_encoder_state *psEncC, /* I Encoder State */
144 silk_nsq_state *NSQ, /* I/O NSQ state */
145 SideInfoIndices *psIndices, /* I/O Quantization Indices */
146 const opus_int32 x_Q3[], /* I Prefiltered input signal */
147 opus_int8 pulses[], /* O Quantized pulse signal */
148 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
149 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
150 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
151 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
152 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
153 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
154 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
155 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
156 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
157 const opus_int LTP_scale_Q14 /* I LTP state scaling */
158);
159
160#if defined OPUS_X86_PRESUME_SSE4_1
161
162#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
163 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \
164 ((void)(arch),silk_NSQ_del_dec_sse4_1(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
165 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))
166
167#else
168
169extern void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])(
170 const silk_encoder_state *psEncC, /* I Encoder State */
171 silk_nsq_state *NSQ, /* I/O NSQ state */
172 SideInfoIndices *psIndices, /* I/O Quantization Indices */
173 const opus_int32 x_Q3[], /* I Prefiltered input signal */
174 opus_int8 pulses[], /* O Quantized pulse signal */
175 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
176 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
177 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
178 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
179 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
180 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
181 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
182 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
183 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
184 const opus_int LTP_scale_Q14 /* I LTP state scaling */
185);
186
187# define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
188 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \
189 ((*SILK_NSQ_DEL_DEC_IMPL[(arch) & OPUS_ARCHMASK])(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
190 HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))
191
192#endif
193#endif
194
195void silk_noise_shape_quantizer(
196 silk_nsq_state *NSQ, /* I/O NSQ state */
197 opus_int signalType, /* I Signal type */
198 const opus_int32 x_sc_Q10[], /* I */
199 opus_int8 pulses[], /* O */
200 opus_int16 xq[], /* O */
201 opus_int32 sLTP_Q15[], /* I/O LTP state */
202 const opus_int16 a_Q12[], /* I Short term prediction coefs */
203 const opus_int16 b_Q14[], /* I Long term prediction coefs */
204 const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */
205 opus_int lag, /* I Pitch lag */
206 opus_int32 HarmShapeFIRPacked_Q14, /* I */
207 opus_int Tilt_Q14, /* I Spectral tilt */
208 opus_int32 LF_shp_Q14, /* I */
209 opus_int32 Gain_Q16, /* I */
210 opus_int Lambda_Q10, /* I */
211 opus_int offset_Q10, /* I */
212 opus_int length, /* I Input length */
213 opus_int shapingLPCOrder, /* I Noise shaping AR filter order */
214 opus_int predictLPCOrder, /* I Prediction filter order */
215 int arch /* I Architecture */
216);
217
218/**************************/
219/* Noise level estimation */
220/**************************/
221void silk_VAD_GetNoiseLevels(
222 const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */
223 silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */
224);
225
226# define OVERRIDE_silk_VAD_GetSA_Q8
227
228opus_int silk_VAD_GetSA_Q8_sse4_1(
229 silk_encoder_state *psEnC,
230 const opus_int16 pIn[]
231);
232
233#if defined(OPUS_X86_PRESUME_SSE4_1)
234#define silk_VAD_GetSA_Q8(psEnC, pIn, arch) ((void)(arch),silk_VAD_GetSA_Q8_sse4_1(psEnC, pIn))
235
236#else
237
238# define silk_VAD_GetSA_Q8(psEnC, pIn, arch) \
239 ((*SILK_VAD_GETSA_Q8_IMPL[(arch) & OPUS_ARCHMASK])(psEnC, pIn))
240
241extern opus_int (*const SILK_VAD_GETSA_Q8_IMPL[OPUS_ARCHMASK + 1])(
242 silk_encoder_state *psEnC,
243 const opus_int16 pIn[]);
244
245#endif
246
247# endif
248#endif
diff --git a/lib/rbcodec/codecs/libopus/silk/x86/x86_silk_map.c b/lib/rbcodec/codecs/libopus/silk/x86/x86_silk_map.c
new file mode 100644
index 0000000000..32dcc3cab7
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/x86/x86_silk_map.c
@@ -0,0 +1,164 @@
1/* Copyright (c) 2014, Cisco Systems, INC
2 Written by XiangMingZhu WeiZhou MinPeng YanWang
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
6 are met:
7
8 - Redistributions of source code must retain the above copyright
9 notice, this list of conditions and the following disclaimer.
10
11 - Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14
15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#if defined(HAVE_CONFIG_H)
29#include "config.h"
30#endif
31
32#include "celt/x86/x86cpu.h"
33#include "structs.h"
34#include "SigProc_FIX.h"
35#include "pitch.h"
36#include "main.h"
37
38#if !defined(OPUS_X86_PRESUME_SSE4_1)
39
40#if defined(FIXED_POINT)
41
42#include "fixed/main_FIX.h"
43
44opus_int64 (*const SILK_INNER_PROD16_ALIGNED_64_IMPL[ OPUS_ARCHMASK + 1 ] )(
45 const opus_int16 *inVec1,
46 const opus_int16 *inVec2,
47 const opus_int len
48) = {
49 silk_inner_prod16_aligned_64_c, /* non-sse */
50 silk_inner_prod16_aligned_64_c,
51 silk_inner_prod16_aligned_64_c,
52 MAY_HAVE_SSE4_1( silk_inner_prod16_aligned_64 ), /* sse4.1 */
53 MAY_HAVE_SSE4_1( silk_inner_prod16_aligned_64 ) /* avx */
54};
55
56#endif
57
58opus_int (*const SILK_VAD_GETSA_Q8_IMPL[ OPUS_ARCHMASK + 1 ] )(
59 silk_encoder_state *psEncC,
60 const opus_int16 pIn[]
61) = {
62 silk_VAD_GetSA_Q8_c, /* non-sse */
63 silk_VAD_GetSA_Q8_c,
64 silk_VAD_GetSA_Q8_c,
65 MAY_HAVE_SSE4_1( silk_VAD_GetSA_Q8 ), /* sse4.1 */
66 MAY_HAVE_SSE4_1( silk_VAD_GetSA_Q8 ) /* avx */
67};
68
69#if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */
70void (*const SILK_NSQ_IMPL[ OPUS_ARCHMASK + 1 ] )(
71 const silk_encoder_state *psEncC, /* I Encoder State */
72 silk_nsq_state *NSQ, /* I/O NSQ state */
73 SideInfoIndices *psIndices, /* I/O Quantization Indices */
74 const opus_int32 x_Q3[], /* I Prefiltered input signal */
75 opus_int8 pulses[], /* O Quantized pulse signal */
76 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
77 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
78 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
79 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
80 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
81 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
82 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
83 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
84 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
85 const opus_int LTP_scale_Q14 /* I LTP state scaling */
86) = {
87 silk_NSQ_c, /* non-sse */
88 silk_NSQ_c,
89 silk_NSQ_c,
90 MAY_HAVE_SSE4_1( silk_NSQ ), /* sse4.1 */
91 MAY_HAVE_SSE4_1( silk_NSQ ) /* avx */
92};
93#endif
94
95#if 0 /* FIXME: SSE disabled until silk_VQ_WMat_EC_sse4_1() gets updated. */
96void (*const SILK_VQ_WMAT_EC_IMPL[ OPUS_ARCHMASK + 1 ] )(
97 opus_int8 *ind, /* O index of best codebook vector */
98 opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */
99 opus_int *gain_Q7, /* O sum of absolute LTP coefficients */
100 const opus_int16 *in_Q14, /* I input vector to be quantized */
101 const opus_int32 *W_Q18, /* I weighting matrix */
102 const opus_int8 *cb_Q7, /* I codebook */
103 const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */
104 const opus_uint8 *cl_Q5, /* I code length for each codebook vector */
105 const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */
106 const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
107 opus_int L /* I number of vectors in codebook */
108) = {
109 silk_VQ_WMat_EC_c, /* non-sse */
110 silk_VQ_WMat_EC_c,
111 silk_VQ_WMat_EC_c,
112 MAY_HAVE_SSE4_1( silk_VQ_WMat_EC ), /* sse4.1 */
113 MAY_HAVE_SSE4_1( silk_VQ_WMat_EC ) /* avx */
114};
115#endif
116
117#if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */
118void (*const SILK_NSQ_DEL_DEC_IMPL[ OPUS_ARCHMASK + 1 ] )(
119 const silk_encoder_state *psEncC, /* I Encoder State */
120 silk_nsq_state *NSQ, /* I/O NSQ state */
121 SideInfoIndices *psIndices, /* I/O Quantization Indices */
122 const opus_int32 x_Q3[], /* I Prefiltered input signal */
123 opus_int8 pulses[], /* O Quantized pulse signal */
124 const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
125 const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
126 const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
127 const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
128 const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
129 const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
130 const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
131 const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
132 const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
133 const opus_int LTP_scale_Q14 /* I LTP state scaling */
134) = {
135 silk_NSQ_del_dec_c, /* non-sse */
136 silk_NSQ_del_dec_c,
137 silk_NSQ_del_dec_c,
138 MAY_HAVE_SSE4_1( silk_NSQ_del_dec ), /* sse4.1 */
139 MAY_HAVE_SSE4_1( silk_NSQ_del_dec ) /* avx */
140};
141#endif
142
143#if defined(FIXED_POINT)
144
145void (*const SILK_BURG_MODIFIED_IMPL[ OPUS_ARCHMASK + 1 ] )(
146 opus_int32 *res_nrg, /* O Residual energy */
147 opus_int *res_nrg_Q, /* O Residual energy Q value */
148 opus_int32 A_Q16[], /* O Prediction coefficients (length order) */
149 const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */
150 const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */
151 const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */
152 const opus_int nb_subfr, /* I Number of subframes stacked in x */
153 const opus_int D, /* I Order */
154 int arch /* I Run-time architecture */
155) = {
156 silk_burg_modified_c, /* non-sse */
157 silk_burg_modified_c,
158 silk_burg_modified_c,
159 MAY_HAVE_SSE4_1( silk_burg_modified ), /* sse4.1 */
160 MAY_HAVE_SSE4_1( silk_burg_modified ) /* avx */
161};
162
163#endif
164#endif
diff --git a/lib/rbcodec/codecs/libopus/tansig_table.h b/lib/rbcodec/codecs/libopus/tansig_table.h
new file mode 100644
index 0000000000..c76f844a72
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/tansig_table.h
@@ -0,0 +1,45 @@
1/* This file is auto-generated by gen_tables */
2
3static const float tansig_table[201] = {
40.000000f, 0.039979f, 0.079830f, 0.119427f, 0.158649f,
50.197375f, 0.235496f, 0.272905f, 0.309507f, 0.345214f,
60.379949f, 0.413644f, 0.446244f, 0.477700f, 0.507977f,
70.537050f, 0.564900f, 0.591519f, 0.616909f, 0.641077f,
80.664037f, 0.685809f, 0.706419f, 0.725897f, 0.744277f,
90.761594f, 0.777888f, 0.793199f, 0.807569f, 0.821040f,
100.833655f, 0.845456f, 0.856485f, 0.866784f, 0.876393f,
110.885352f, 0.893698f, 0.901468f, 0.908698f, 0.915420f,
120.921669f, 0.927473f, 0.932862f, 0.937863f, 0.942503f,
130.946806f, 0.950795f, 0.954492f, 0.957917f, 0.961090f,
140.964028f, 0.966747f, 0.969265f, 0.971594f, 0.973749f,
150.975743f, 0.977587f, 0.979293f, 0.980869f, 0.982327f,
160.983675f, 0.984921f, 0.986072f, 0.987136f, 0.988119f,
170.989027f, 0.989867f, 0.990642f, 0.991359f, 0.992020f,
180.992631f, 0.993196f, 0.993718f, 0.994199f, 0.994644f,
190.995055f, 0.995434f, 0.995784f, 0.996108f, 0.996407f,
200.996682f, 0.996937f, 0.997172f, 0.997389f, 0.997590f,
210.997775f, 0.997946f, 0.998104f, 0.998249f, 0.998384f,
220.998508f, 0.998623f, 0.998728f, 0.998826f, 0.998916f,
230.999000f, 0.999076f, 0.999147f, 0.999213f, 0.999273f,
240.999329f, 0.999381f, 0.999428f, 0.999472f, 0.999513f,
250.999550f, 0.999585f, 0.999617f, 0.999646f, 0.999673f,
260.999699f, 0.999722f, 0.999743f, 0.999763f, 0.999781f,
270.999798f, 0.999813f, 0.999828f, 0.999841f, 0.999853f,
280.999865f, 0.999875f, 0.999885f, 0.999893f, 0.999902f,
290.999909f, 0.999916f, 0.999923f, 0.999929f, 0.999934f,
300.999939f, 0.999944f, 0.999948f, 0.999952f, 0.999956f,
310.999959f, 0.999962f, 0.999965f, 0.999968f, 0.999970f,
320.999973f, 0.999975f, 0.999977f, 0.999978f, 0.999980f,
330.999982f, 0.999983f, 0.999984f, 0.999986f, 0.999987f,
340.999988f, 0.999989f, 0.999990f, 0.999990f, 0.999991f,
350.999992f, 0.999992f, 0.999993f, 0.999994f, 0.999994f,
360.999994f, 0.999995f, 0.999995f, 0.999996f, 0.999996f,
370.999996f, 0.999997f, 0.999997f, 0.999997f, 0.999997f,
380.999997f, 0.999998f, 0.999998f, 0.999998f, 0.999998f,
390.999998f, 0.999998f, 0.999999f, 0.999999f, 0.999999f,
400.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f,
410.999999f, 0.999999f, 0.999999f, 0.999999f, 0.999999f,
421.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
431.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
441.000000f,
45};