summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml9
-rw-r--r--SConstruct1
-rw-r--r--core/math/face3.cpp2
-rw-r--r--doc/classes/EditorVCSInterface.xml2
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.cpp21
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.h1
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp6
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp17
-rw-r--r--drivers/gles2/shaders/scene.glsl17
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp23
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.h1
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp37
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h2
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp153
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h1
-rw-r--r--drivers/gles3/shaders/cubemap_filter.glsl119
-rw-r--r--drivers/gles3/shaders/scene.glsl29
-rw-r--r--editor/editor_settings.cpp1
-rw-r--r--editor/editor_vcs_interface.cpp10
-rw-r--r--editor/editor_vcs_interface.h4
-rw-r--r--editor/import/editor_scene_importer_gltf.cpp1
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp36
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h4
-rw-r--r--editor/plugins/version_control_editor_plugin.cpp5
-rw-r--r--editor/plugins/version_control_editor_plugin.h2
-rw-r--r--editor/script_editor_debugger.cpp13
-rw-r--r--editor/script_editor_debugger.h4
-rw-r--r--modules/arkit/arkit_interface.mm19
-rw-r--r--modules/assimp/import_utils.h2
-rw-r--r--modules/gdscript/gdscript_editor.cpp3
-rw-r--r--modules/mono/build_scripts/mono_configure.py5
-rw-r--r--modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs4
-rw-r--r--modules/mono/glue/Managed/Files/NodePath.cs2
-rw-r--r--modules/mono/glue/Managed/Files/RID.cs2
-rw-r--r--modules/opus/SCsub14
-rw-r--r--modules/regex/SCsub4
-rw-r--r--platform/javascript/detect.py5
-rw-r--r--platform/uwp/detect.py1
-rw-r--r--scene/gui/gradient_edit.cpp5
-rw-r--r--scene/main/viewport.cpp2
-rw-r--r--servers/visual/shader_language.cpp4
-rw-r--r--thirdparty/README.md6
-rw-r--r--thirdparty/opus/analysis.c777
-rw-r--r--thirdparty/opus/analysis.h38
-rw-r--r--thirdparty/opus/celt/_kiss_fft_guts.h16
-rw-r--r--thirdparty/opus/celt/arch.h52
-rwxr-xr-xthirdparty/opus/celt/arm/arm2gnu.pl4
-rw-r--r--thirdparty/opus/celt/arm/arm_celt_map.c21
-rw-r--r--thirdparty/opus/celt/arm/celt_ne10_fft.c (renamed from thirdparty/opus/celt/arm/celt_fft_ne10.c)3
-rw-r--r--thirdparty/opus/celt/arm/celt_ne10_mdct.c (renamed from thirdparty/opus/celt/arm/celt_mdct_ne10.c)2
-rw-r--r--thirdparty/opus/celt/arm/celt_neon_intr.c110
-rw-r--r--thirdparty/opus/celt/arm/celt_pitch_xcorr_arm-gnu.S14
-rw-r--r--thirdparty/opus/celt/arm/celt_pitch_xcorr_arm.s6
-rw-r--r--thirdparty/opus/celt/arm/fft_arm.h1
-rw-r--r--thirdparty/opus/celt/arm/fixed_armv4.h6
-rw-r--r--thirdparty/opus/celt/arm/fixed_armv5e.h4
-rw-r--r--thirdparty/opus/celt/arm/mdct_arm.h1
-rw-r--r--thirdparty/opus/celt/arm/pitch_arm.h56
-rw-r--r--thirdparty/opus/celt/arm/pitch_neon_intr.c290
-rw-r--r--thirdparty/opus/celt/bands.c323
-rw-r--r--thirdparty/opus/celt/bands.h9
-rw-r--r--thirdparty/opus/celt/celt.c25
-rw-r--r--thirdparty/opus/celt/celt.h32
-rw-r--r--thirdparty/opus/celt/celt_decoder.c190
-rw-r--r--thirdparty/opus/celt/celt_encoder.c399
-rw-r--r--thirdparty/opus/celt/celt_lpc.c62
-rw-r--r--thirdparty/opus/celt/celt_lpc.h5
-rw-r--r--thirdparty/opus/celt/cwrs.c2
-rw-r--r--thirdparty/opus/celt/entcode.h4
-rw-r--r--thirdparty/opus/celt/entdec.h2
-rw-r--r--thirdparty/opus/celt/entenc.h2
-rw-r--r--thirdparty/opus/celt/fixed_debug.h13
-rw-r--r--thirdparty/opus/celt/fixed_generic.h11
-rw-r--r--thirdparty/opus/celt/float_cast.h14
-rw-r--r--thirdparty/opus/celt/kiss_fft.c56
-rw-r--r--thirdparty/opus/celt/mathops.c5
-rw-r--r--thirdparty/opus/celt/mathops.h36
-rw-r--r--thirdparty/opus/celt/mdct.c16
-rw-r--r--thirdparty/opus/celt/mips/celt_mipsr1.h1
-rw-r--r--thirdparty/opus/celt/mips/vq_mipsr1.h11
-rw-r--r--thirdparty/opus/celt/modes.c2
-rw-r--r--thirdparty/opus/celt/pitch.c46
-rw-r--r--thirdparty/opus/celt/pitch.h14
-rw-r--r--thirdparty/opus/celt/quant_bands.c11
-rw-r--r--thirdparty/opus/celt/rate.c13
-rw-r--r--thirdparty/opus/celt/rate.h2
-rw-r--r--thirdparty/opus/celt/static_modes_fixed_arm_ne10.h2
-rw-r--r--thirdparty/opus/celt/static_modes_float_arm_ne10.h2
-rw-r--r--thirdparty/opus/celt/tests/test_unit_cwrs32.c161
-rw-r--r--thirdparty/opus/celt/tests/test_unit_dft.c189
-rw-r--r--thirdparty/opus/celt/tests/test_unit_entropy.c382
-rw-r--r--thirdparty/opus/celt/tests/test_unit_laplace.c93
-rw-r--r--thirdparty/opus/celt/tests/test_unit_mathops.c304
-rw-r--r--thirdparty/opus/celt/tests/test_unit_mdct.c230
-rw-r--r--thirdparty/opus/celt/tests/test_unit_rotation.c120
-rw-r--r--thirdparty/opus/celt/tests/test_unit_types.c (renamed from thirdparty/opus/celt/arm/armopts.s)33
-rw-r--r--thirdparty/opus/celt/vq.c118
-rw-r--r--thirdparty/opus/celt/vq.h20
-rw-r--r--thirdparty/opus/celt/x86/celt_lpc_sse.c (renamed from thirdparty/opus/celt/x86/celt_lpc_sse4_1.c)57
-rw-r--r--thirdparty/opus/celt/x86/celt_lpc_sse.h10
-rw-r--r--thirdparty/opus/celt/x86/vq_sse.h50
-rw-r--r--thirdparty/opus/celt/x86/vq_sse2.c217
-rw-r--r--thirdparty/opus/celt/x86/x86_celt_map.c14
-rw-r--r--thirdparty/opus/celt/x86/x86cpu.h4
-rw-r--r--thirdparty/opus/config.h132
-rw-r--r--thirdparty/opus/info.c75
-rw-r--r--thirdparty/opus/internal.h23
-rw-r--r--thirdparty/opus/mapping_matrix.c378
-rw-r--r--thirdparty/opus/mapping_matrix.h133
-rw-r--r--thirdparty/opus/mlp.c155
-rw-r--r--thirdparty/opus/mlp.h35
-rw-r--r--thirdparty/opus/mlp_data.c755
-rw-r--r--thirdparty/opus/opus.c4
-rw-r--r--thirdparty/opus/opus/opus.h2
-rw-r--r--thirdparty/opus/opus/opus_defines.h52
-rw-r--r--thirdparty/opus/opus/opus_multistream.h4
-rw-r--r--thirdparty/opus/opus/opus_projection.h568
-rw-r--r--thirdparty/opus/opus/opus_types.h27
-rw-r--r--thirdparty/opus/opus/opusfile.h59
-rw-r--r--thirdparty/opus/opus_compare.c3
-rw-r--r--thirdparty/opus/opus_decoder.c117
-rw-r--r--thirdparty/opus/opus_encoder.c1409
-rw-r--r--thirdparty/opus/opus_multistream_decoder.c90
-rw-r--r--thirdparty/opus/opus_multistream_encoder.c351
-rw-r--r--thirdparty/opus/opus_private.h85
-rw-r--r--thirdparty/opus/opus_projection_decoder.c258
-rw-r--r--thirdparty/opus/opus_projection_encoder.c468
-rw-r--r--thirdparty/opus/opusfile.c264
-rw-r--r--thirdparty/opus/repacketizer.c3
-rw-r--r--thirdparty/opus/silk/A2NLSF.c8
-rw-r--r--thirdparty/opus/silk/API.h3
-rw-r--r--thirdparty/opus/silk/CNG.c12
-rw-r--r--thirdparty/opus/silk/LPC_analysis_filter.c25
-rw-r--r--thirdparty/opus/silk/LPC_fit.c81
-rw-r--r--thirdparty/opus/silk/LPC_inv_pred_gain.c97
-rw-r--r--thirdparty/opus/silk/LP_variable_cutoff.c2
-rw-r--r--thirdparty/opus/silk/MacroCount.h10
-rw-r--r--thirdparty/opus/silk/MacroDebug.h3
-rw-r--r--thirdparty/opus/silk/NLSF2A.c59
-rw-r--r--thirdparty/opus/silk/NLSF_VQ.c44
-rw-r--r--thirdparty/opus/silk/NLSF_VQ_weights_laroia.c4
-rw-r--r--thirdparty/opus/silk/NLSF_decode.c22
-rw-r--r--thirdparty/opus/silk/NLSF_del_dec_quant.c8
-rw-r--r--thirdparty/opus/silk/NLSF_encode.c37
-rw-r--r--thirdparty/opus/silk/NSQ.c72
-rw-r--r--thirdparty/opus/silk/NSQ_del_dec.c93
-rw-r--r--thirdparty/opus/silk/PLC.c12
-rw-r--r--thirdparty/opus/silk/SigProc_FIX.h56
-rw-r--r--thirdparty/opus/silk/VAD.c22
-rw-r--r--thirdparty/opus/silk/VQ_WMat_EC.c129
-rw-r--r--thirdparty/opus/silk/arm/LPC_inv_pred_gain_arm.h57
-rw-r--r--thirdparty/opus/silk/arm/LPC_inv_pred_gain_neon_intr.c280
-rw-r--r--thirdparty/opus/silk/arm/NSQ_del_dec_arm.h100
-rw-r--r--thirdparty/opus/silk/arm/NSQ_del_dec_neon_intr.c1124
-rw-r--r--thirdparty/opus/silk/arm/NSQ_neon.h33
-rw-r--r--thirdparty/opus/silk/arm/arm_silk_map.c68
-rw-r--r--thirdparty/opus/silk/arm/biquad_alt_arm.h68
-rw-r--r--thirdparty/opus/silk/arm/biquad_alt_neon_intr.c156
-rw-r--r--thirdparty/opus/silk/arm/macros_armv4.h13
-rw-r--r--thirdparty/opus/silk/arm/macros_armv5e.h9
-rw-r--r--thirdparty/opus/silk/biquad_alt.c53
-rw-r--r--thirdparty/opus/silk/bwexpander.c2
-rw-r--r--thirdparty/opus/silk/check_control_input.c22
-rw-r--r--thirdparty/opus/silk/control.h8
-rw-r--r--thirdparty/opus/silk/control_SNR.c103
-rw-r--r--thirdparty/opus/silk/control_audio_bandwidth.c16
-rw-r--r--thirdparty/opus/silk/control_codec.c105
-rw-r--r--thirdparty/opus/silk/debug.h21
-rw-r--r--thirdparty/opus/silk/dec_API.c6
-rw-r--r--thirdparty/opus/silk/decode_core.c6
-rw-r--r--thirdparty/opus/silk/decode_frame.c7
-rw-r--r--thirdparty/opus/silk/decode_indices.c2
-rw-r--r--thirdparty/opus/silk/decode_parameters.c4
-rw-r--r--thirdparty/opus/silk/decode_pitch.c4
-rw-r--r--thirdparty/opus/silk/decode_pulses.c2
-rw-r--r--thirdparty/opus/silk/decoder_set_fs.c8
-rw-r--r--thirdparty/opus/silk/define.h17
-rw-r--r--thirdparty/opus/silk/enc_API.c47
-rw-r--r--thirdparty/opus/silk/encode_indices.c6
-rw-r--r--thirdparty/opus/silk/encode_pulses.c2
-rw-r--r--thirdparty/opus/silk/fixed/apply_sine_window_FIX.c8
-rw-r--r--thirdparty/opus/silk/fixed/arm/warped_autocorrelation_FIX_arm.h68
-rw-r--r--thirdparty/opus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c260
-rw-r--r--thirdparty/opus/silk/fixed/burg_modified_FIX.c4
-rw-r--r--thirdparty/opus/silk/fixed/corrMatrix_FIX.c38
-rw-r--r--thirdparty/opus/silk/fixed/encode_frame_FIX.c123
-rw-r--r--thirdparty/opus/silk/fixed/find_LPC_FIX.c4
-rw-r--r--thirdparty/opus/silk/fixed/find_LTP_FIX.c238
-rw-r--r--thirdparty/opus/silk/fixed/find_pitch_lags_FIX.c20
-rw-r--r--thirdparty/opus/silk/fixed/find_pred_coefs_FIX.c27
-rw-r--r--thirdparty/opus/silk/fixed/k2a_FIX.c13
-rw-r--r--thirdparty/opus/silk/fixed/k2a_Q16_FIX.c15
-rw-r--r--thirdparty/opus/silk/fixed/main_FIX.h74
-rw-r--r--thirdparty/opus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h6
-rw-r--r--thirdparty/opus/silk/fixed/mips/prefilter_FIX_mipsr1.h184
-rw-r--r--thirdparty/opus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h4
-rw-r--r--thirdparty/opus/silk/fixed/noise_shape_analysis_FIX.c160
-rw-r--r--thirdparty/opus/silk/fixed/pitch_analysis_core_FIX.c125
-rw-r--r--thirdparty/opus/silk/fixed/prefilter_FIX.c221
-rw-r--r--thirdparty/opus/silk/fixed/residual_energy16_FIX.c8
-rw-r--r--thirdparty/opus/silk/fixed/residual_energy_FIX.c2
-rw-r--r--thirdparty/opus/silk/fixed/schur64_FIX.c7
-rw-r--r--thirdparty/opus/silk/fixed/schur_FIX.c15
-rw-r--r--thirdparty/opus/silk/fixed/solve_LS_FIX.c249
-rw-r--r--thirdparty/opus/silk/fixed/structs_FIX.h22
-rw-r--r--thirdparty/opus/silk/fixed/warped_autocorrelation_FIX.c11
-rw-r--r--thirdparty/opus/silk/fixed/x86/burg_modified_FIX_sse.c (renamed from thirdparty/opus/silk/fixed/x86/burg_modified_FIX_sse4_1.c)2
-rw-r--r--thirdparty/opus/silk/fixed/x86/prefilter_FIX_sse.c160
-rw-r--r--thirdparty/opus/silk/fixed/x86/vector_ops_FIX_sse.c (renamed from thirdparty/opus/silk/fixed/x86/vector_ops_FIX_sse4_1.c)0
-rw-r--r--thirdparty/opus/silk/float/LPC_analysis_filter_FLP.c4
-rw-r--r--thirdparty/opus/silk/float/LPC_inv_pred_gain_FLP.c37
-rw-r--r--thirdparty/opus/silk/float/SigProc_FLP.h7
-rw-r--r--thirdparty/opus/silk/float/apply_sine_window_FLP.c4
-rw-r--r--thirdparty/opus/silk/float/burg_modified_FLP.c2
-rw-r--r--thirdparty/opus/silk/float/encode_frame_FLP.c105
-rw-r--r--thirdparty/opus/silk/float/energy_FLP.c5
-rw-r--r--thirdparty/opus/silk/float/find_LPC_FLP.c4
-rw-r--r--thirdparty/opus/silk/float/find_LTP_FLP.c108
-rw-r--r--thirdparty/opus/silk/float/find_pitch_lags_FLP.c2
-rw-r--r--thirdparty/opus/silk/float/find_pred_coefs_FLP.c14
-rw-r--r--thirdparty/opus/silk/float/inner_product_FLP.c5
-rw-r--r--thirdparty/opus/silk/float/k2a_FLP.c15
-rw-r--r--thirdparty/opus/silk/float/levinsondurbin_FLP.c81
-rw-r--r--thirdparty/opus/silk/float/main_FLP.h55
-rw-r--r--thirdparty/opus/silk/float/noise_shape_analysis_FLP.c149
-rw-r--r--thirdparty/opus/silk/float/pitch_analysis_core_FLP.c36
-rw-r--r--thirdparty/opus/silk/float/prefilter_FLP.c206
-rw-r--r--thirdparty/opus/silk/float/residual_energy_FLP.c2
-rw-r--r--thirdparty/opus/silk/float/schur_FLP.c16
-rw-r--r--thirdparty/opus/silk/float/solve_LS_FLP.c207
-rw-r--r--thirdparty/opus/silk/float/sort_FLP.c6
-rw-r--r--thirdparty/opus/silk/float/structs_FLP.h22
-rw-r--r--thirdparty/opus/silk/float/warped_autocorrelation_FLP.c6
-rw-r--r--thirdparty/opus/silk/float/wrappers_FLP.c49
-rw-r--r--thirdparty/opus/silk/gain_quant.c1
-rw-r--r--thirdparty/opus/silk/init_decoder.c1
-rw-r--r--thirdparty/opus/silk/interpolate.c4
-rw-r--r--thirdparty/opus/silk/lin2log.c2
-rw-r--r--thirdparty/opus/silk/macros.h8
-rw-r--r--thirdparty/opus/silk/main.h77
-rw-r--r--thirdparty/opus/silk/mips/NSQ_del_dec_mipsr1.h7
-rw-r--r--thirdparty/opus/silk/mips/sigproc_fix_mipsr1.h5
-rw-r--r--thirdparty/opus/silk/process_NLSFs.c10
-rw-r--r--thirdparty/opus/silk/quant_LTP_gains.c67
-rw-r--r--thirdparty/opus/silk/resampler.c10
-rw-r--r--thirdparty/opus/silk/resampler_down2.c4
-rw-r--r--thirdparty/opus/silk/resampler_private_down_FIR.c2
-rw-r--r--thirdparty/opus/silk/sort.c14
-rw-r--r--thirdparty/opus/silk/stereo_LR_to_MS.c2
-rw-r--r--thirdparty/opus/silk/stereo_encode_pred.c6
-rw-r--r--thirdparty/opus/silk/structs.h6
-rw-r--r--thirdparty/opus/silk/sum_sqr_shift.c51
-rw-r--r--thirdparty/opus/silk/tables.h8
-rw-r--r--thirdparty/opus/silk/tables_LTP.c2
-rw-r--r--thirdparty/opus/silk/tables_NLSF_CB_NB_MB.c36
-rw-r--r--thirdparty/opus/silk/tables_NLSF_CB_WB.c36
-rw-r--r--thirdparty/opus/silk/tables_other.c14
-rw-r--r--thirdparty/opus/silk/tuning_parameters.h28
-rw-r--r--thirdparty/opus/silk/x86/NSQ_del_dec_sse.c (renamed from thirdparty/opus/silk/x86/NSQ_del_dec_sse4_1.c)22
-rw-r--r--thirdparty/opus/silk/x86/NSQ_sse.c (renamed from thirdparty/opus/silk/x86/NSQ_sse4_1.c)5
-rw-r--r--thirdparty/opus/silk/x86/VAD_sse.c (renamed from thirdparty/opus/silk/x86/VAD_sse4_1.c)6
-rw-r--r--thirdparty/opus/silk/x86/VQ_WMat_EC_sse.c (renamed from thirdparty/opus/silk/x86/VQ_WMat_EC_sse4_1.c)0
-rw-r--r--thirdparty/opus/silk/x86/main_sse.h45
-rw-r--r--thirdparty/opus/silk/x86/x86_silk_map.c26
-rw-r--r--thirdparty/opus/stream.c6
265 files changed, 7158 insertions, 10478 deletions
diff --git a/.travis.yml b/.travis.yml
index 8a6f80002b..7bf968ba4c 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -47,15 +47,6 @@ matrix:
- &linux_deps [libasound2-dev, libgl1-mesa-dev, libglu1-mesa-dev, libx11-dev, libxcursor-dev, libxi-dev, libxinerama-dev, libxrandr-dev]
- &linux_mono_deps [mono-devel, msbuild, nuget]
- coverity_scan:
- project:
- name: "godotengine/godot"
- description: "Godot Engine Coverity scans"
- notification_email: coverity@godotengine.org
- build_command_prepend: ""
- build_command: "scons p=x11 -j2 $OPTIONS"
- branch_pattern: coverity_scan
-
- name: Linux export template (release, Clang)
stage: build
env: PLATFORM=x11 TOOLS=no TARGET=release CACHE_NAME=${PLATFORM}-clang EXTRA_ARGS="warnings=extra werror=yes"
diff --git a/SConstruct b/SConstruct
index cdbb47faea..0e282a1f12 100644
--- a/SConstruct
+++ b/SConstruct
@@ -150,6 +150,7 @@ opts.Add(BoolVariable('builtin_mbedtls', "Use the built-in mbedTLS library", Tru
opts.Add(BoolVariable('builtin_miniupnpc', "Use the built-in miniupnpc library", True))
opts.Add(BoolVariable('builtin_opus', "Use the built-in Opus library", True))
opts.Add(BoolVariable('builtin_pcre2', "Use the built-in PCRE2 library", True))
+opts.Add(BoolVariable('builtin_pcre2_with_jit', "Use JIT compiler for the built-in PCRE2 library", True))
opts.Add(BoolVariable('builtin_recast', "Use the built-in Recast library", True))
opts.Add(BoolVariable('builtin_squish', "Use the built-in squish library", True))
opts.Add(BoolVariable('builtin_xatlas', "Use the built-in xatlas library", True))
diff --git a/core/math/face3.cpp b/core/math/face3.cpp
index ab09142b2d..666d214f98 100644
--- a/core/math/face3.cpp
+++ b/core/math/face3.cpp
@@ -393,7 +393,7 @@ Vector3 Face3::get_closest_point_to(const Vector3 &p_point) const {
s = CLAMP(numer / denom, 0.f, 1.f);
t = 1 - s;
} else {
- s = CLAMP(-e / c, 0.f, 1.f);
+ s = CLAMP(-d / a, 0.f, 1.f);
t = 0.f;
}
} else {
diff --git a/doc/classes/EditorVCSInterface.xml b/doc/classes/EditorVCSInterface.xml
index f67c1c9eb5..3ae19e5dce 100644
--- a/doc/classes/EditorVCSInterface.xml
+++ b/doc/classes/EditorVCSInterface.xml
@@ -34,7 +34,7 @@
- [code]"offset"[/code] to store the offset of the line change since the first contextual line content.
</description>
</method>
- <method name="get_is_vcs_intialized">
+ <method name="is_vcs_initialized">
<return type="bool">
</return>
<description>
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp
index 52dfb44a9d..ac54af722c 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.cpp
+++ b/drivers/gles2/rasterizer_canvas_gles2.cpp
@@ -291,6 +291,10 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(con
void RasterizerCanvasGLES2::_draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor, const float *p_weights, const int *p_bones) {
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
+#ifndef GLES_OVER_GL
+ // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
+ glBufferData(GL_ARRAY_BUFFER, data.polygon_buffer_size, NULL, GL_DYNAMIC_DRAW);
+#endif
uint32_t buffer_ofs = 0;
@@ -339,6 +343,11 @@ void RasterizerCanvasGLES2::_draw_polygon(const int *p_indices, int p_index_coun
}
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
+#ifndef GLES_OVER_GL
+ // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer_size, NULL, GL_DYNAMIC_DRAW);
+#endif
+
if (storage->config.support_32_bits_indices) { //should check for
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(int) * p_index_count, p_indices);
glDrawElements(GL_TRIANGLES, p_index_count, GL_UNSIGNED_INT, 0);
@@ -358,6 +367,10 @@ void RasterizerCanvasGLES2::_draw_polygon(const int *p_indices, int p_index_coun
void RasterizerCanvasGLES2::_draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) {
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
+#ifndef GLES_OVER_GL
+ // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
+ glBufferData(GL_ARRAY_BUFFER, data.polygon_buffer_size, NULL, GL_DYNAMIC_DRAW);
+#endif
uint32_t buffer_ofs = 0;
@@ -435,6 +448,10 @@ void RasterizerCanvasGLES2::_draw_gui_primitive(int p_points, const Vector2 *p_v
}
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
+#ifndef GLES_OVER_GL
+ // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
+ glBufferData(GL_ARRAY_BUFFER, data.polygon_buffer_size, NULL, GL_DYNAMIC_DRAW);
+#endif
glBufferSubData(GL_ARRAY_BUFFER, 0, p_points * stride * 4 * sizeof(float), buffer_data);
glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, stride * sizeof(float), NULL);
@@ -887,7 +904,7 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
}
glBindBuffer(GL_ARRAY_BUFFER, data.ninepatch_vertices);
- glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * (16 + 16) * 2, buffer);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(float) * (16 + 16) * 2, buffer, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.ninepatch_elements);
@@ -2038,6 +2055,8 @@ void RasterizerCanvasGLES2::initialize() {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_size, NULL, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+ data.polygon_index_buffer_size = index_size;
}
// ninepatch buffers
diff --git a/drivers/gles2/rasterizer_canvas_gles2.h b/drivers/gles2/rasterizer_canvas_gles2.h
index ab636dca71..ba636a9763 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.h
+++ b/drivers/gles2/rasterizer_canvas_gles2.h
@@ -65,6 +65,7 @@ public:
GLuint polygon_index_buffer;
uint32_t polygon_buffer_size;
+ uint32_t polygon_index_buffer_size;
GLuint ninepatch_vertices;
GLuint ninepatch_elements;
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index 6bcda62e7f..bc47fb46f5 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -2342,9 +2342,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
if (accum_pass) { //accum pass force pass
blend_mode = RasterizerStorageGLES2::Shader::Spatial::BLEND_MODE_ADD;
- if (rebind_light && light && light->light_ptr->negative) {
- glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+ if (light && light->light_ptr->negative) {
blend_mode = RasterizerStorageGLES2::Shader::Spatial::BLEND_MODE_SUB;
}
}
@@ -2704,7 +2702,7 @@ void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const C
}
glBindBuffer(GL_ARRAY_BUFFER, state.sky_verts);
- glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector3) * 8, vertices);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(Vector3) * 8, vertices, GL_DYNAMIC_DRAW);
// bind sky vertex array....
glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vector3) * 2, 0);
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index 82cb1ef90b..147bab9d1f 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -4583,13 +4583,24 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
GLuint color_internal_format;
GLuint color_format;
GLuint color_type = GL_UNSIGNED_BYTE;
+ Image::Format image_format;
if (rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
+#ifdef GLES_OVER_GL
+ color_internal_format = GL_RGBA8;
+#else
color_internal_format = GL_RGBA;
+#endif
color_format = GL_RGBA;
+ image_format = Image::FORMAT_RGBA8;
} else {
+#ifdef GLES_OVER_GL
+ color_internal_format = GL_RGB8;
+#else
color_internal_format = GL_RGB;
+#endif
color_format = GL_RGB;
+ image_format = Image::FORMAT_RGB8;
}
rt->used_dof_blur_near = false;
@@ -4676,10 +4687,10 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
return;
}
- texture->format = Image::FORMAT_RGBA8;
- texture->gl_format_cache = GL_RGBA;
+ texture->format = image_format;
+ texture->gl_format_cache = color_format;
texture->gl_type_cache = GL_UNSIGNED_BYTE;
- texture->gl_internal_format_cache = GL_RGBA;
+ texture->gl_internal_format_cache = color_internal_format;
texture->tex_id = rt->color;
texture->width = rt->width;
texture->alloc_width = rt->width;
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index e36e776881..2a220658a1 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -1547,7 +1547,11 @@ FRAGMENT_SHADER_CODE
#endif // !USE_SHADOW_TO_OPACITY
#ifdef BASE_PASS
- //none
+
+ // IBL precalculations
+ float ndotv = clamp(dot(normal, eye_position), 0.0, 1.0);
+ vec3 f0 = F0(metallic, specular, albedo);
+ vec3 F = f0 + (max(vec3(1.0 - roughness), f0) - f0) * pow(1.0 - ndotv, 5.0);
#ifdef AMBIENT_LIGHT_DISABLED
ambient_light = vec3(0.0, 0.0, 0.0);
@@ -1561,12 +1565,15 @@ FRAGMENT_SHADER_CODE
ref_vec.z *= -1.0;
specular_light = textureCubeLod(radiance_map, ref_vec, roughness * RADIANCE_MAX_LOD).xyz * bg_energy;
+#ifndef USE_LIGHTMAP
{
vec3 ambient_dir = normalize((radiance_inverse_xform * vec4(normal, 0.0)).xyz);
- vec3 env_ambient = textureCubeLod(radiance_map, ambient_dir, RADIANCE_MAX_LOD).xyz * bg_energy;
+ vec3 env_ambient = textureCubeLod(radiance_map, ambient_dir, 4.0).xyz * bg_energy;
+ env_ambient *= 1.0 - F;
ambient_light = mix(ambient_color.rgb, env_ambient, ambient_sky_contribution);
}
+#endif
#else
@@ -1574,7 +1581,6 @@ FRAGMENT_SHADER_CODE
specular_light = bg_color.rgb * bg_energy;
#endif
-
#endif // AMBIENT_LIGHT_DISABLED
ambient_light *= ambient_energy;
@@ -1646,12 +1652,9 @@ FRAGMENT_SHADER_CODE
const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);
vec4 r = roughness * c0 + c1;
- float ndotv = clamp(dot(normal, eye_position), 0.0, 1.0);
float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;
-
- vec3 f0 = F0(metallic, specular, albedo);
- specular_light *= env.x * f0 + env.y;
+ specular_light *= env.x * F + env.y;
#endif
}
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index edffe852a2..55d16a6c2e 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -128,7 +128,7 @@ void RasterizerCanvasGLES3::light_internal_update(RID p_rid, Light *p_light) {
li->ubo_data.shadow_distance_mult = (p_light->radius_cache * 1.1);
glBindBuffer(GL_UNIFORM_BUFFER, li->ubo);
- glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(LightInternal::UBOData), &li->ubo_data);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(LightInternal::UBOData), &li->ubo_data, GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
@@ -326,6 +326,12 @@ void RasterizerCanvasGLES3::_draw_polygon(const int *p_indices, int p_index_coun
glBindVertexArray(data.polygon_buffer_pointer_array);
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
+#ifndef GLES_OVER_GL
+ // Orphan the buffers to avoid CPU/GPU sync points caused by glBufferSubData
+ glBufferData(GL_ARRAY_BUFFER, data.polygon_buffer_size, NULL, GL_DYNAMIC_DRAW);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer_size, NULL, GL_DYNAMIC_DRAW);
+#endif
+
uint32_t buffer_ofs = 0;
//vertex
@@ -417,6 +423,12 @@ void RasterizerCanvasGLES3::_draw_generic(GLuint p_primitive, int p_vertex_count
glBindVertexArray(data.polygon_buffer_pointer_array);
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
+#ifndef GLES_OVER_GL
+ // Orphan the buffers to avoid CPU/GPU sync points caused by glBufferSubData
+ glBufferData(GL_ARRAY_BUFFER, data.polygon_buffer_size, NULL, GL_DYNAMIC_DRAW);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer_size, NULL, GL_DYNAMIC_DRAW);
+#endif
+
uint32_t buffer_ofs = 0;
//vertex
@@ -508,6 +520,11 @@ void RasterizerCanvasGLES3::_draw_gui_primitive(int p_points, const Vector2 *p_v
}
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
+#ifndef GLES_OVER_GL
+ // Orphan the buffer to avoid CPU/GPU sync points caused by glBufferSubData
+ glBufferData(GL_ARRAY_BUFFER, data.polygon_buffer_size, NULL, GL_DYNAMIC_DRAW);
+#endif
+ //TODO the below call may need to be replaced with: glBufferSubData(GL_ARRAY_BUFFER, 0, p_points * stride * 4 * sizeof(float), &b[0]);
glBufferSubData(GL_ARRAY_BUFFER, 0, p_points * stride * 4, &b[0]);
glBindVertexArray(data.polygon_buffer_quad_arrays[version]);
glDrawArrays(prim[p_points], 0, p_points);
@@ -1882,7 +1899,7 @@ void RasterizerCanvasGLES3::reset_canvas() {
state.canvas_item_ubo_data.time = storage->frame.time[0];
glBindBuffer(GL_UNIFORM_BUFFER, state.canvas_item_ubo);
- glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(CanvasItemUBO), &state.canvas_item_ubo_data);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(CanvasItemUBO), &state.canvas_item_ubo_data, GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
state.canvas_texscreen_used = false;
@@ -2109,6 +2126,8 @@ void RasterizerCanvasGLES3::initialize() {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_size, NULL, GL_DYNAMIC_DRAW); //allocate max size
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+ data.polygon_index_buffer_size = index_size;
}
store_transform(Transform(), state.canvas_item_ubo_data.projection_matrix);
diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h
index bf5ef30820..382b1e5640 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.h
+++ b/drivers/gles3/rasterizer_canvas_gles3.h
@@ -64,6 +64,7 @@ public:
GLuint particle_quad_array;
uint32_t polygon_buffer_size;
+ uint32_t polygon_index_buffer_size;
} data;
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 519fdf2b3b..9815936d1e 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -2011,7 +2011,7 @@ void RasterizerSceneGLES3::_set_cull(bool p_front, bool p_disabled, bool p_rever
}
}
-void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_element_count, const Transform &p_view_transform, const CameraMatrix &p_projection, GLuint p_base_env, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add, bool p_directional_shadows) {
+void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_element_count, const Transform &p_view_transform, const CameraMatrix &p_projection, RasterizerStorageGLES3::Sky *p_sky, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add, bool p_directional_shadows) {
glBindBufferBase(GL_UNIFORM_BUFFER, 0, state.scene_ubo); //bind globals ubo
@@ -2019,14 +2019,15 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
if (!p_shadow && !p_directional_add) {
glBindBufferBase(GL_UNIFORM_BUFFER, 2, state.env_radiance_ubo); //bind environment radiance info
- if (p_base_env) {
+ if (p_sky != NULL) {
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
if (storage->config.use_texture_array_environment) {
- glBindTexture(GL_TEXTURE_2D_ARRAY, p_base_env);
+ glBindTexture(GL_TEXTURE_2D_ARRAY, p_sky->radiance);
} else {
- glBindTexture(GL_TEXTURE_2D, p_base_env);
+ glBindTexture(GL_TEXTURE_2D, p_sky->radiance);
}
-
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 6);
+ glBindTexture(GL_TEXTURE_2D, p_sky->irradiance);
state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP, true);
state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP_ARRAY, storage->config.use_texture_array_environment);
use_radiance_map = true;
@@ -2550,7 +2551,7 @@ void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const C
}
glBindBuffer(GL_ARRAY_BUFFER, state.sky_verts);
- glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector3) * 8, vertices);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(Vector3) * 8, vertices, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
glBindVertexArray(state.sky_array);
@@ -2690,7 +2691,7 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
}
glBindBuffer(GL_UNIFORM_BUFFER, state.scene_ubo);
- glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(State::SceneDataUBO), &state.ubo_data);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(State::SceneDataUBO), &state.ubo_data, GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
//fill up environment
@@ -2698,7 +2699,7 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
store_transform(sky_orientation * p_cam_transform, state.env_radiance_data.transform);
glBindBuffer(GL_UNIFORM_BUFFER, state.env_radiance_ubo);
- glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(State::EnvironmentRadianceUBO), &state.env_radiance_data);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(State::EnvironmentRadianceUBO), &state.env_radiance_data, GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
@@ -2808,7 +2809,7 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform
}
glBindBuffer(GL_UNIFORM_BUFFER, state.directional_ubo);
- glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(LightDataUBO), &ubo_data);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(LightDataUBO), &ubo_data, GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
directional_light = li;
@@ -4231,7 +4232,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
_fill_render_list(p_cull_result, p_cull_count, true, false);
render_list.sort_by_key(false);
state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_DEPTH, true);
- _render_list(render_list.elements, render_list.element_count, p_cam_transform, p_cam_projection, 0, false, false, true, false, false);
+ _render_list(render_list.elements, render_list.element_count, p_cam_transform, p_cam_projection, NULL, false, false, true, false, false);
state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_DEPTH, false);
glColorMask(1, 1, 1, 1);
@@ -4355,7 +4356,6 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
RasterizerStorageGLES3::Sky *sky = NULL;
Ref<CameraFeed> feed;
- GLuint env_radiance_tex = 0;
if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
clear_color = Color(0, 0, 0, 0);
@@ -4409,9 +4409,6 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
sky = storage->sky_owner.getornull(env->sky);
- if (sky) {
- env_radiance_tex = sky->radiance;
- }
break;
case VS::ENV_BG_CANVAS:
//copy canvas to 3d buffer and convert it to linear
@@ -4505,7 +4502,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
}
if (probe && probe->probe_ptr->interior) {
- env_radiance_tex = 0; //for rendering probe interiors, radiance must not be used.
+ sky = NULL; //for rendering probe interiors, radiance must not be used.
}
state.texscreen_copied = false;
@@ -4524,7 +4521,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
if (state.directional_light_count == 0) {
directional_light = NULL;
- _render_list(render_list.elements, render_list.element_count, p_cam_transform, p_cam_projection, env_radiance_tex, false, false, false, false, shadow_atlas != NULL);
+ _render_list(render_list.elements, render_list.element_count, p_cam_transform, p_cam_projection, sky, false, false, false, false, shadow_atlas != NULL);
} else {
for (int i = 0; i < state.directional_light_count; i++) {
directional_light = directional_lights[i];
@@ -4532,7 +4529,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glEnable(GL_BLEND);
}
_setup_directional_light(i, p_cam_transform.affine_inverse(), shadow_atlas != NULL && shadow_atlas->size > 0);
- _render_list(render_list.elements, render_list.element_count, p_cam_transform, p_cam_projection, env_radiance_tex, false, false, false, i > 0, shadow_atlas != NULL);
+ _render_list(render_list.elements, render_list.element_count, p_cam_transform, p_cam_projection, sky, false, false, false, i > 0, shadow_atlas != NULL);
}
}
@@ -4610,12 +4607,12 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
if (state.directional_light_count == 0) {
directional_light = NULL;
- _render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, p_cam_transform, p_cam_projection, env_radiance_tex, false, true, false, false, shadow_atlas != NULL);
+ _render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, p_cam_transform, p_cam_projection, sky, false, true, false, false, shadow_atlas != NULL);
} else {
for (int i = 0; i < state.directional_light_count; i++) {
directional_light = directional_lights[i];
_setup_directional_light(i, p_cam_transform.affine_inverse(), shadow_atlas != NULL && shadow_atlas->size > 0);
- _render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, p_cam_transform, p_cam_projection, env_radiance_tex, false, true, false, i > 0, shadow_atlas != NULL);
+ _render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, p_cam_transform, p_cam_projection, sky, false, true, false, i > 0, shadow_atlas != NULL);
}
}
@@ -4898,7 +4895,7 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_
if (light->reverse_cull) {
flip_facing = !flip_facing;
}
- _render_list(render_list.elements, render_list.element_count, light_transform, light_projection, 0, flip_facing, false, true, false, false);
+ _render_list(render_list.elements, render_list.element_count, light_transform, light_projection, NULL, flip_facing, false, true, false, false);
state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_DEPTH, false);
state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_DEPTH_DUAL_PARABOLOID, false);
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index e6d2449653..a756ce251e 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -837,7 +837,7 @@ public:
_FORCE_INLINE_ void _render_geometry(RenderList::Element *e);
_FORCE_INLINE_ void _setup_light(RenderList::Element *e, const Transform &p_view_transform);
- void _render_list(RenderList::Element **p_elements, int p_element_count, const Transform &p_view_transform, const CameraMatrix &p_projection, GLuint p_base_env, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add, bool p_directional_shadows);
+ void _render_list(RenderList::Element **p_elements, int p_element_count, const Transform &p_view_transform, const CameraMatrix &p_projection, RasterizerStorageGLES3::Sky *p_sky, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add, bool p_directional_shadows);
_FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_pass, bool p_shadow_pass);
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 71737426a9..71a3a79eb3 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1757,6 +1757,7 @@ RID RasterizerStorageGLES3::sky_create() {
Sky *sky = memnew(Sky);
sky->radiance = 0;
+ sky->irradiance = 0;
return sky_owner.make_rid(sky);
}
@@ -1768,7 +1769,9 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
if (sky->panorama.is_valid()) {
sky->panorama = RID();
glDeleteTextures(1, &sky->radiance);
+ glDeleteTextures(1, &sky->irradiance);
sky->radiance = 0;
+ sky->irradiance = 0;
}
sky->panorama = p_panorama;
@@ -1791,10 +1794,14 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->target, texture->tex_id);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //need this for proper sampling
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 10);
+ // Need Mipmaps regardless of whether they are set in import by user
+ glGenerateMipmap(texture->target);
+ glTexParameterf(texture->target, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(texture->target, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameterf(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameterf(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
if (config.srgb_decode_supported && texture->srgb && !texture->using_srgb) {
@@ -1808,6 +1815,66 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
#endif
}
+ {
+ //Irradiance map
+ glActiveTexture(GL_TEXTURE1);
+ glGenTextures(1, &sky->irradiance);
+ glBindTexture(GL_TEXTURE_2D, sky->irradiance);
+
+ GLuint tmp_fb;
+
+ glGenFramebuffers(1, &tmp_fb);
+ glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb);
+
+ int size = 64;
+
+ bool use_float = config.framebuffer_half_float_supported;
+
+ GLenum internal_format = use_float ? GL_RGBA16F : GL_RGB10_A2;
+ GLenum format = GL_RGBA;
+ GLenum type = use_float ? GL_HALF_FLOAT : GL_UNSIGNED_INT_2_10_10_10_REV;
+
+ glTexImage2D(GL_TEXTURE_2D, 0, internal_format, size, size * 2, 0, format, type, NULL);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
+ glTexParameterf(texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sky->irradiance, 0);
+
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, true);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, true);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::COMPUTE_IRRADIANCE, true);
+ shaders.cubemap_filter.bind();
+
+ // Very large Panoramas require way too much effort to compute irradiance so use a mipmap
+ // level that corresponds to a panorama of 1024x512
+ shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::SOURCE_MIP_LEVEL, MAX(Math::log(float(texture->width)) / Math::log(2.0f) - 10.0f, 0.0f));
+
+ for (int i = 0; i < 2; i++) {
+ glViewport(0, i * size, size, size);
+ glBindVertexArray(resources.quadie_array);
+
+ shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, i > 0);
+
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ glBindVertexArray(0);
+ }
+
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, false);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, false);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::COMPUTE_IRRADIANCE, false);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
+ glDeleteFramebuffers(1, &tmp_fb);
+ }
+
+ // Now compute radiance
+
glActiveTexture(GL_TEXTURE1);
glGenTextures(1, &sky->radiance);
@@ -1833,8 +1900,8 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, internal_format, size, size * 2, array_level, 0, format, type, NULL);
- glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
GLuint tmp_fb2;
GLuint tmp_tex;
@@ -1846,8 +1913,8 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
glBindTexture(GL_TEXTURE_2D, tmp_tex);
glTexImage2D(GL_TEXTURE_2D, 0, internal_format, size, size * 2, 0, format, type, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tmp_tex, 0);
- glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
#ifdef DEBUG_ENABLED
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
@@ -1858,25 +1925,25 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb2);
- if (j == 0) {
+ if (j < 3) {
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, true);
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, true);
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DIRECT_WRITE, true);
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_DUAL_PARABOLOID_ARRAY, false);
shaders.cubemap_filter.bind();
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->target, texture->tex_id);
+ shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::SOURCE_RESOLUTION, float(texture->width / 4));
} else {
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, true);
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, false);
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_DUAL_PARABOLOID_ARRAY, true);
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DIRECT_WRITE, false);
shaders.cubemap_filter.bind();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D_ARRAY, sky->radiance);
shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::SOURCE_ARRAY_INDEX, j - 1); //read from previous to ensure better blur
+ shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::SOURCE_RESOLUTION, float(size / 2));
}
for (int i = 0; i < 2; i++) {
@@ -1902,7 +1969,6 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, false);
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, false);
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_DUAL_PARABOLOID_ARRAY, false);
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DIRECT_WRITE, false);
//restore ranges
glActiveTexture(GL_TEXTURE0);
@@ -1947,23 +2013,64 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipmaps - 1);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ GLuint tmp_fb2;
+ GLuint tmp_tex;
+ {
+ // Need a temporary framebuffer for rendering so we can read from previous iterations
+ glGenFramebuffers(1, &tmp_fb2);
+ glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb2);
+ glGenTextures(1, &tmp_tex);
+ glBindTexture(GL_TEXTURE_2D, tmp_tex);
+ glTexImage2D(GL_TEXTURE_2D, 0, internal_format, size, size * 2, 0, format, type, NULL);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tmp_tex, 0);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+#ifdef DEBUG_ENABLED
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
+#endif
+ }
lod = 0;
mm_level = mipmaps;
size = p_radiance_size;
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, true);
- shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, true);
- shaders.cubemap_filter.bind();
-
while (mm_level) {
-
+ glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sky->radiance, lod);
+
#ifdef DEBUG_ENABLED
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE);
#endif
+ glBindTexture(GL_TEXTURE_2D, tmp_tex);
+ glTexImage2D(GL_TEXTURE_2D, 0, internal_format, size, size * 2, 0, format, type, NULL);
+ glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb2);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tmp_tex, 0);
+ if (lod < 3) {
+
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, true);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, true);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_DUAL_PARABOLOID, false);
+ shaders.cubemap_filter.bind();
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(texture->target, texture->tex_id);
+ shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::SOURCE_RESOLUTION, float(texture->width / 4));
+ } else {
+
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, true);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_PANORAMA, false);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_SOURCE_DUAL_PARABOLOID, true);
+ shaders.cubemap_filter.bind();
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, sky->radiance);
+ shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::SOURCE_MIP_LEVEL, lod - 1); //read from previous to ensure better blur
+ shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::SOURCE_RESOLUTION, float(size));
+ }
for (int i = 0; i < 2; i++) {
glViewport(0, i * size, size, size);
@@ -1976,6 +2083,14 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
glBindVertexArray(0);
}
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, tmp_fb);
+ glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, sky->radiance, 0, lod);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, tmp_fb2);
+ glReadBuffer(GL_COLOR_ATTACHMENT0);
+ glBlitFramebuffer(0, 0, size, size * 2, 0, 0, size, size * 2, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+
if (size > 1)
size >>= 1;
lod++;
@@ -1995,6 +2110,8 @@ void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
glDeleteFramebuffers(1, &tmp_fb);
+ glDeleteFramebuffers(1, &tmp_fb2);
+ glDeleteTextures(1, &tmp_tex);
}
}
@@ -3099,7 +3216,7 @@ void RasterizerStorageGLES3::_update_material(Material *material) {
}
glBindBuffer(GL_UNIFORM_BUFFER, material->ubo_id);
- glBufferSubData(GL_UNIFORM_BUFFER, 0, material->ubo_size, local_ubo);
+ glBufferData(GL_UNIFORM_BUFFER, material->ubo_size, local_ubo, GL_STATIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 3b1021d0e1..350b259b2b 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -388,6 +388,7 @@ public:
RID panorama;
GLuint radiance;
+ GLuint irradiance;
int radiance_size;
};
diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl
index 619e29b130..d83a109cb9 100644
--- a/drivers/gles3/shaders/cubemap_filter.glsl
+++ b/drivers/gles3/shaders/cubemap_filter.glsl
@@ -30,12 +30,22 @@ uniform sampler2DArray source_dual_paraboloid_array; //texunit:0
uniform int source_array_index;
#endif
-#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA)
+#ifdef USE_SOURCE_DUAL_PARABOLOID
+uniform sampler2D source_dual_paraboloid; //texunit:0
+#endif
+
+#if defined(USE_SOURCE_DUAL_PARABOLOID) || defined(COMPUTE_IRRADIANCE)
+uniform int source_mip_level;
+#endif
+
+#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA) && !defined(USE_SOURCE_DUAL_PARABOLOID)
uniform samplerCube source_cube; //texunit:0
#endif
uniform int face_id;
uniform float roughness;
+uniform float source_resolution;
+
in highp vec2 uv_interp;
layout(location = 0) out vec4 frag_color;
@@ -133,6 +143,19 @@ vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) {
return TangentX * H.x + TangentY * H.y + N * H.z;
}
+float DistributionGGX(vec3 N, vec3 H, float roughness) {
+ float a = roughness * roughness;
+ float a2 = a * a;
+ float NdotH = max(dot(N, H), 0.0);
+ float NdotH2 = NdotH * NdotH;
+
+ float nom = a2;
+ float denom = (NdotH2 * (a2 - 1.0) + 1.0);
+ denom = M_PI * denom * denom;
+
+ return nom / denom;
+}
+
// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
float GGX(float NdotV, float a) {
float k = a / 2.0;
@@ -160,10 +183,12 @@ vec2 Hammersley(uint i, uint N) {
#ifdef LOW_QUALITY
#define SAMPLE_COUNT 64u
+#define SAMPLE_DELTA 0.05
#else
-#define SAMPLE_COUNT 1024u
+#define SAMPLE_COUNT 512u
+#define SAMPLE_DELTA 0.01
#endif
@@ -171,7 +196,7 @@ uniform bool z_flip;
#ifdef USE_SOURCE_PANORAMA
-vec4 texturePanorama(vec3 normal, sampler2D pano) {
+vec4 texturePanorama(vec3 normal, sampler2D pano, float mipLevel) {
vec2 st = vec2(
atan(normal.x, normal.z),
@@ -182,7 +207,7 @@ vec4 texturePanorama(vec3 normal, sampler2D pano) {
st /= vec2(M_PI * 2.0, M_PI);
- return textureLod(pano, st, 0.0);
+ return textureLod(pano, st, mipLevel);
}
#endif
@@ -202,6 +227,20 @@ vec4 textureDualParaboloidArray(vec3 normal) {
#endif
+#ifdef USE_SOURCE_DUAL_PARABOLOID
+vec4 textureDualParaboloid(vec3 normal) {
+
+ vec3 norm = normalize(normal);
+ norm.xy /= 1.0 + abs(norm.z);
+ norm.xy = norm.xy * vec2(0.5, 0.25) + vec2(0.5, 0.25);
+ if (norm.z < 0.0) {
+ norm.y = 0.5 - norm.y + 0.5;
+ }
+ return textureLod(source_dual_paraboloid, norm.xy, float(source_mip_level));
+}
+
+#endif
+
void main() {
#ifdef USE_DUAL_PARABOLOID
@@ -225,7 +264,7 @@ void main() {
#ifdef USE_SOURCE_PANORAMA
- frag_color = vec4(texturePanorama(N, source_panorama).rgb, 1.0);
+ frag_color = vec4(texturePanorama(N, source_panorama, 0.0).rgb, 1.0);
#endif
#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY
@@ -233,12 +272,51 @@ void main() {
frag_color = vec4(textureDualParaboloidArray(N).rgb, 1.0);
#endif
-#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA)
+#ifdef USE_SOURCE_DUAL_PARABOLOID
+
+ frag_color = vec4(textureDualParaboloid(N).rgb, 1.0);
+#endif
+
+#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA) && !defined(USE_SOURCE_DUAL_PARABOLOID)
N.y = -N.y;
frag_color = vec4(texture(N, source_cube).rgb, 1.0);
#endif
+#else // USE_DIRECT_WRITE
+
+#ifdef COMPUTE_IRRADIANCE
+
+ vec3 irradiance = vec3(0.0);
+
+ // tangent space calculation from origin point
+ vec3 UpVector = vec3(0.0, 1.0, 0.0);
+ vec3 TangentX = cross(UpVector, N);
+ vec3 TangentY = cross(N, TangentX);
+
+ float num_samples = 0.0f;
+
+ for (float phi = 0.0; phi < 2.0 * M_PI; phi += SAMPLE_DELTA) {
+ for (float theta = 0.0; theta < 0.5 * M_PI; theta += SAMPLE_DELTA) {
+ // Calculate sample positions
+ vec3 tangentSample = vec3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
+ // Find world vector of sample position
+ vec3 H = tangentSample.x * TangentX + tangentSample.y * TangentY + tangentSample.z * N;
+
+ vec2 st = vec2(atan(H.x, H.z), acos(H.y));
+ if (st.x < 0.0) {
+ st.x += M_PI * 2.0;
+ }
+ st /= vec2(M_PI * 2.0, M_PI);
+
+ irradiance += texture(source_panorama, st, source_mip_level).rgb * cos(theta) * sin(theta);
+ num_samples++;
+ }
+ }
+ irradiance = M_PI * irradiance * (1.0 / float(num_samples));
+
+ frag_color = vec4(irradiance, 1.0);
+
#else
vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
@@ -246,15 +324,26 @@ void main() {
for (uint sampleNum = 0u; sampleNum < SAMPLE_COUNT; sampleNum++) {
vec2 xi = Hammersley(sampleNum, SAMPLE_COUNT);
- vec3 H = ImportanceSampleGGX(xi, roughness, N);
+ vec3 H = normalize(ImportanceSampleGGX(xi, roughness, N));
vec3 V = N;
- vec3 L = (2.0 * dot(V, H) * H - V);
+ vec3 L = normalize(2.0 * dot(V, H) * H - V);
- float ndotl = clamp(dot(N, L), 0.0, 1.0);
+ float ndotl = max(dot(N, L), 0.0);
if (ndotl > 0.0) {
+
+ float D = DistributionGGX(N, H, roughness);
+ float ndoth = max(dot(N, H), 0.0);
+ float hdotv = max(dot(H, V), 0.0);
+ float pdf = D * ndoth / (4.0 * hdotv) + 0.0001;
+
+ float saTexel = 4.0 * M_PI / (6.0 * source_resolution * source_resolution);
+ float saSample = 1.0 / (float(SAMPLE_COUNT) * pdf + 0.0001);
+
+ float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel);
+
#ifdef USE_SOURCE_PANORAMA
- sum.rgb += texturePanorama(L, source_panorama).rgb * ndotl;
+ sum.rgb += texturePanorama(L, source_panorama, mipLevel).rgb * ndotl;
#endif
#ifdef USE_SOURCE_DUAL_PARABOLOID_ARRAY
@@ -262,7 +351,12 @@ void main() {
sum.rgb += textureDualParaboloidArray(L).rgb * ndotl;
#endif
-#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA)
+#ifdef USE_SOURCE_DUAL_PARABOLOID
+
+ sum.rgb += textureDualParaboloid(L).rgb * ndotl;
+#endif
+
+#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA) && !defined(USE_SOURCE_DUAL_PARABOLOID)
L.y = -L.y;
sum.rgb += textureLod(source_cube, L, 0.0).rgb * ndotl;
#endif
@@ -273,5 +367,6 @@ void main() {
frag_color = vec4(sum.rgb, 1.0);
-#endif
+#endif // COMPUTE_IRRADIANCE
+#endif // USE_DIRECT_WRITE
}
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 403de25dd0..e1b0e9f595 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -627,6 +627,8 @@ layout(std140) uniform Radiance { // ubo:2
#define RADIANCE_MAX_LOD 5.0
+uniform sampler2D irradiance_map; // texunit:-6
+
#ifdef USE_RADIANCE_MAP_ARRAY
uniform sampler2DArray radiance_map; // texunit:-2
@@ -1766,6 +1768,11 @@ FRAGMENT_SHADER_CODE
vec3 eye_vec = view;
+ // IBL precalculations
+ float ndotv = clamp(dot(normal, eye_vec), 0.0, 1.0);
+ vec3 f0 = F0(metallic, specular, albedo);
+ vec3 F = f0 + (max(vec3(1.0 - roughness), f0) - f0) * pow(1.0 - ndotv, 5.0);
+
#ifdef USE_RADIANCE_MAP
#ifdef AMBIENT_LIGHT_DISABLED
@@ -1775,22 +1782,27 @@ FRAGMENT_SHADER_CODE
{ //read radiance from dual paraboloid
- vec3 ref_vec = reflect(-eye_vec, normal); //2.0 * ndotv * normal - view; // reflect(v, n);
+ vec3 ref_vec = reflect(-eye_vec, normal);
ref_vec = normalize((radiance_inverse_xform * vec4(ref_vec, 0.0)).xyz);
vec3 radiance = textureDualParaboloid(radiance_map, ref_vec, roughness) * bg_energy;
env_reflection_light = radiance;
}
- //no longer a cubemap
- //vec3 radiance = textureLod(radiance_cube, r, lod).xyz * ( brdf.x + brdf.y);
}
#ifndef USE_LIGHTMAP
{
- vec3 ambient_dir = normalize((radiance_inverse_xform * vec4(normal, 0.0)).xyz);
- vec3 env_ambient = textureDualParaboloid(radiance_map, ambient_dir, 1.0) * bg_energy;
+ vec3 norm = normal;
+ norm = normalize((radiance_inverse_xform * vec4(norm, 0.0)).xyz);
+ norm.xy /= 1.0 + abs(norm.z);
+ norm.xy = norm.xy * vec2(0.5, 0.25) + vec2(0.5, 0.25);
+ if (norm.z > 0.0) {
+ norm.y = 0.5 - norm.y + 0.5;
+ }
+
+ vec3 env_ambient = texture(irradiance_map, norm.xy).rgb * bg_energy;
+ env_ambient *= 1.0 - F;
ambient_light = mix(ambient_light_color.rgb, env_ambient, radiance_ambient_contribution);
- //ambient_light=vec3(0.0,0.0,0.0);
}
#endif
#endif //AMBIENT_LIGHT_DISABLED
@@ -1892,12 +1904,9 @@ FRAGMENT_SHADER_CODE
const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);
vec4 r = roughness * c0 + c1;
- float ndotv = clamp(dot(normal, eye_vec), 0.0, 1.0);
float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y;
vec2 env = vec2(-1.04, 1.04) * a004 + r.zw;
-
- vec3 f0 = F0(metallic, specular, albedo);
- specular_light *= env.x * f0 + env.y;
+ specular_light *= env.x * F + env.y;
#endif
}
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index a3a02dbd4c..87e8a53e94 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -727,6 +727,7 @@ static Dictionary _get_builtin_script_templates() {
templates["no_comments.gd"] =
"extends %BASE%\n"
"\n"
+ "\n"
"func _ready()%VOID_RETURN%:\n"
"%TS%pass\n";
diff --git a/editor/editor_vcs_interface.cpp b/editor/editor_vcs_interface.cpp
index 4df2a06736..766f9c3913 100644
--- a/editor/editor_vcs_interface.cpp
+++ b/editor/editor_vcs_interface.cpp
@@ -36,7 +36,7 @@ void EditorVCSInterface::_bind_methods() {
// Proxy end points that act as fallbacks to unavailability of a function in the VCS addon
ClassDB::bind_method(D_METHOD("_initialize", "project_root_path"), &EditorVCSInterface::_initialize);
- ClassDB::bind_method(D_METHOD("_get_is_vcs_intialized"), &EditorVCSInterface::_get_is_vcs_intialized);
+ ClassDB::bind_method(D_METHOD("_is_vcs_initialized"), &EditorVCSInterface::_is_vcs_initialized);
ClassDB::bind_method(D_METHOD("_get_vcs_name"), &EditorVCSInterface::_get_vcs_name);
ClassDB::bind_method(D_METHOD("_shut_down"), &EditorVCSInterface::_shut_down);
ClassDB::bind_method(D_METHOD("_get_project_name"), &EditorVCSInterface::_get_project_name);
@@ -50,7 +50,7 @@ void EditorVCSInterface::_bind_methods() {
// API methods that redirect calls to the proxy end points
ClassDB::bind_method(D_METHOD("initialize", "project_root_path"), &EditorVCSInterface::initialize);
- ClassDB::bind_method(D_METHOD("get_is_vcs_intialized"), &EditorVCSInterface::get_is_vcs_intialized);
+ ClassDB::bind_method(D_METHOD("is_vcs_initialized"), &EditorVCSInterface::is_vcs_initialized);
ClassDB::bind_method(D_METHOD("get_modified_files_data"), &EditorVCSInterface::get_modified_files_data);
ClassDB::bind_method(D_METHOD("stage_file", "file_path"), &EditorVCSInterface::stage_file);
ClassDB::bind_method(D_METHOD("unstage_file", "file_path"), &EditorVCSInterface::unstage_file);
@@ -67,7 +67,7 @@ bool EditorVCSInterface::_initialize(String p_project_root_path) {
return true;
}
-bool EditorVCSInterface::_get_is_vcs_intialized() {
+bool EditorVCSInterface::_is_vcs_initialized() {
return false;
}
@@ -112,9 +112,9 @@ bool EditorVCSInterface::initialize(String p_project_root_path) {
return is_initialized;
}
-bool EditorVCSInterface::get_is_vcs_intialized() {
+bool EditorVCSInterface::is_vcs_initialized() {
- return call("_get_is_vcs_intialized");
+ return call("_is_vcs_initialized");
}
Dictionary EditorVCSInterface::get_modified_files_data() {
diff --git a/editor/editor_vcs_interface.h b/editor/editor_vcs_interface.h
index 896193ed92..394a18f974 100644
--- a/editor/editor_vcs_interface.h
+++ b/editor/editor_vcs_interface.h
@@ -48,7 +48,7 @@ protected:
// Implemented by addons as end points for the proxy functions
bool _initialize(String p_project_root_path);
- bool _get_is_vcs_intialized();
+ bool _is_vcs_initialized();
Dictionary _get_modified_files_data();
void _stage_file(String p_file_path);
void _unstage_file(String p_file_path);
@@ -66,7 +66,7 @@ public:
// Proxy functions to the editor for use
bool initialize(String p_project_root_path);
- bool get_is_vcs_intialized();
+ bool is_vcs_initialized();
Dictionary get_modified_files_data();
void stage_file(String p_file_path);
void unstage_file(String p_file_path);
diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp
index fcf0e4af6f..30e2aae020 100644
--- a/editor/import/editor_scene_importer_gltf.cpp
+++ b/editor/import/editor_scene_importer_gltf.cpp
@@ -229,6 +229,7 @@ Error EditorSceneImporterGLTF::_parse_scenes(GLTFState &state) {
ERR_FAIL_COND_V(!state.json.has("scenes"), ERR_FILE_CORRUPT);
const Array &scenes = state.json["scenes"];
+ ERR_FAIL_COND_V(!scenes.size(), ERR_FILE_CORRUPT);
for (int i = 0; i < 1; i++) { //only first scene is imported
const Dictionary &s = scenes[i];
ERR_FAIL_COND_V(!s.has("nodes"), ERR_UNAVAILABLE);
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 336d908637..20b4cf43bf 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -794,6 +794,7 @@ bool CanvasItemEditor::_select_click_on_item(CanvasItem *item, Point2 p_click_po
editor_selection->add_node(item);
// Reselect
if (Engine::get_singleton()->is_editor_hint()) {
+ selected_from_canvas = true;
editor->call("edit_node", item);
}
}
@@ -3671,7 +3672,7 @@ void CanvasItemEditor::_notification(int p_what) {
int nb_having_pivot = 0;
// Update the viewport if the canvas_item changes
- List<CanvasItem *> selection = _get_edited_canvas_items();
+ List<CanvasItem *> selection = _get_edited_canvas_items(true);
for (List<CanvasItem *>::Element *E = selection.front(); E; E = E->next()) {
CanvasItem *canvas_item = E->get();
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
@@ -3911,6 +3912,11 @@ void CanvasItemEditor::_selection_changed() {
}
anchors_mode = (nbValidControls == nbAnchorsMode);
anchor_mode_button->set_pressed(anchors_mode);
+
+ if (!selected_from_canvas) {
+ drag_type = DRAG_NONE;
+ }
+ selected_from_canvas = false;
}
void CanvasItemEditor::edit(CanvasItem *p_canvas_item) {
@@ -3971,9 +3977,9 @@ void CanvasItemEditor::_update_scrollbars() {
updating_scroll = true;
// Move the zoom buttons
- Point2 zoom_hb_begin = Point2(5, 5);
- zoom_hb_begin += (show_rulers) ? Point2(RULER_WIDTH, RULER_WIDTH) : Point2();
- zoom_hb->set_begin(zoom_hb_begin);
+ Point2 controls_vb_begin = Point2(5, 5);
+ controls_vb_begin += (show_rulers) ? Point2(RULER_WIDTH, RULER_WIDTH) : Point2();
+ controls_vb->set_begin(controls_vb_begin);
// Move and resize the scrollbars
Size2 size = viewport->get_size();
@@ -5253,6 +5259,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
snap_target[0] = SNAP_TARGET_NONE;
snap_target[1] = SNAP_TARGET_NONE;
+ selected_from_canvas = false;
anchors_mode = false;
skeleton_show_bones = true;
@@ -5310,6 +5317,14 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
scene_tree->set_anchors_and_margins_preset(Control::PRESET_WIDE);
scene_tree->add_child(p_editor->get_scene_root());
+ controls_vb = memnew(VBoxContainer);
+ controls_vb->set_begin(Point2(5, 5));
+
+ zoom_hb = memnew(HBoxContainer);
+ // Bring the zoom percentage closer to the zoom buttons
+ zoom_hb->add_constant_override("separation", Math::round(-8 * EDSCALE));
+ controls_vb->add_child(zoom_hb);
+
viewport = memnew(CanvasItemEditorViewport(p_editor, this));
viewport_scrollable->add_child(viewport);
viewport->set_mouse_filter(MOUSE_FILTER_PASS);
@@ -5353,11 +5368,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
v_scroll->connect("value_changed", this, "_update_scroll");
v_scroll->hide();
- zoom_hb = memnew(HBoxContainer);
- viewport->add_child(zoom_hb);
- zoom_hb->set_begin(Point2(5, 5));
- // Bring the zoom percentage closer to the zoom buttons
- zoom_hb->add_constant_override("separation", Math::round(-8 * EDSCALE));
+ viewport->add_child(controls_vb);
zoom_minus = memnew(ToolButton);
zoom_hb->add_child(zoom_minus);
@@ -5744,8 +5755,6 @@ void CanvasItemEditorViewport::_on_change_type_closed() {
}
void CanvasItemEditorViewport::_create_preview(const Vector<String> &files) const {
- label->set_position(get_global_position() + Point2(14, 14) * EDSCALE);
- label_desc->set_position(label->get_position() + Point2(0, label->get_size().height));
bool add_preview = false;
for (int i = 0; i < files.size(); i++) {
String path = files[i];
@@ -6167,7 +6176,7 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte
label->add_color_override("font_color_shadow", Color(0, 0, 0, 1));
label->add_constant_override("shadow_as_outline", 1 * EDSCALE);
label->hide();
- editor->get_gui_base()->add_child(label);
+ canvas_item_editor->get_controls_container()->add_child(label);
label_desc = memnew(Label);
label_desc->set_text(TTR("Drag & drop + Shift : Add node as sibling\nDrag & drop + Alt : Change node type"));
@@ -6176,7 +6185,8 @@ CanvasItemEditorViewport::CanvasItemEditorViewport(EditorNode *p_node, CanvasIte
label_desc->add_constant_override("shadow_as_outline", 1 * EDSCALE);
label_desc->add_constant_override("line_spacing", 0);
label_desc->hide();
- editor->get_gui_base()->add_child(label_desc);
+ canvas_item_editor->get_controls_container()->add_child(label_desc);
+
VS::get_singleton()->canvas_set_disable_scale(true);
}
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 3fdf00d611..74adb882d1 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -252,6 +252,7 @@ private:
Point2 view_offset;
Point2 previous_update_view_offset;
+ bool selected_from_canvas;
bool anchors_mode;
Point2 grid_offset;
@@ -530,6 +531,7 @@ private:
void _button_toggle_anchor_mode(bool p_status);
+ VBoxContainer *controls_vb;
HBoxContainer *zoom_hb;
void _zoom_on_position(float p_zoom, Point2 p_position = Point2());
void _update_zoom_label();
@@ -627,6 +629,8 @@ public:
Control *get_viewport_control() { return viewport; }
+ Control *get_controls_container() { return controls_vb; }
+
void update_viewport();
Tool get_current_tool() { return tool; }
diff --git a/editor/plugins/version_control_editor_plugin.cpp b/editor/plugins/version_control_editor_plugin.cpp
index 783797ada4..aa3bd74c49 100644
--- a/editor/plugins/version_control_editor_plugin.cpp
+++ b/editor/plugins/version_control_editor_plugin.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "version_control_editor_plugin.h"
+
#include "core/script_language.h"
#include "editor/editor_file_system.h"
#include "editor/editor_node.h"
@@ -398,9 +399,9 @@ void VersionControlEditorPlugin::shut_down() {
}
}
-bool VersionControlEditorPlugin::get_is_vcs_intialized() const {
+bool VersionControlEditorPlugin::is_vcs_initialized() const {
- return EditorVCSInterface::get_singleton() ? EditorVCSInterface::get_singleton()->get_is_vcs_intialized() : false;
+ return EditorVCSInterface::get_singleton() ? EditorVCSInterface::get_singleton()->is_vcs_initialized() : false;
}
const String VersionControlEditorPlugin::get_vcs_name() const {
diff --git a/editor/plugins/version_control_editor_plugin.h b/editor/plugins/version_control_editor_plugin.h
index 450ebccce1..f9f8437e15 100644
--- a/editor/plugins/version_control_editor_plugin.h
+++ b/editor/plugins/version_control_editor_plugin.h
@@ -129,7 +129,7 @@ public:
PanelContainer *get_version_control_dock() const { return version_control_dock; }
List<StringName> get_available_vcs_names() const { return available_addons; }
- bool get_is_vcs_intialized() const;
+ bool is_vcs_initialized() const;
const String get_vcs_name() const;
void register_editor();
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index 76dcd10b50..8e7aac896a 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -492,7 +492,7 @@ void ScriptEditorDebugger::_video_mem_request() {
Size2 ScriptEditorDebugger::get_minimum_size() const {
- Size2 ms = Control::get_minimum_size();
+ Size2 ms = MarginContainer::get_minimum_size();
ms.y = MAX(ms.y, 250 * EDSCALE);
return ms;
}
@@ -1426,11 +1426,12 @@ void ScriptEditorDebugger::_notification(int p_what) {
} break;
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
+ add_constant_override("margin_left", -EditorNode::get_singleton()->get_gui_base()->get_stylebox("BottomPanelDebuggerOverride", "EditorStyles")->get_margin(MARGIN_LEFT));
+ add_constant_override("margin_right", -EditorNode::get_singleton()->get_gui_base()->get_stylebox("BottomPanelDebuggerOverride", "EditorStyles")->get_margin(MARGIN_RIGHT));
+
tabs->add_style_override("panel", editor->get_gui_base()->get_stylebox("DebuggerPanel", "EditorStyles"));
tabs->add_style_override("tab_fg", editor->get_gui_base()->get_stylebox("DebuggerTabFG", "EditorStyles"));
tabs->add_style_override("tab_bg", editor->get_gui_base()->get_stylebox("DebuggerTabBG", "EditorStyles"));
- tabs->set_margin(MARGIN_LEFT, -EditorNode::get_singleton()->get_gui_base()->get_stylebox("BottomPanelDebuggerOverride", "EditorStyles")->get_margin(MARGIN_LEFT));
- tabs->set_margin(MARGIN_RIGHT, EditorNode::get_singleton()->get_gui_base()->get_stylebox("BottomPanelDebuggerOverride", "EditorStyles")->get_margin(MARGIN_RIGHT));
copy->set_icon(get_icon("ActionCopy", "EditorIcons"));
step->set_icon(get_icon("DebugStep", "EditorIcons"));
@@ -2242,6 +2243,9 @@ void ScriptEditorDebugger::_bind_methods() {
ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
+ add_constant_override("margin_left", -EditorNode::get_singleton()->get_gui_base()->get_stylebox("BottomPanelDebuggerOverride", "EditorStyles")->get_margin(MARGIN_LEFT));
+ add_constant_override("margin_right", -EditorNode::get_singleton()->get_gui_base()->get_stylebox("BottomPanelDebuggerOverride", "EditorStyles")->get_margin(MARGIN_RIGHT));
+
ppeer = Ref<PacketPeerStream>(memnew(PacketPeerStream));
ppeer->set_input_buffer_max_size(1024 * 1024 * 8); //8mb should be enough
editor = p_editor;
@@ -2253,9 +2257,6 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
tabs->add_style_override("tab_fg", editor->get_gui_base()->get_stylebox("DebuggerTabFG", "EditorStyles"));
tabs->add_style_override("tab_bg", editor->get_gui_base()->get_stylebox("DebuggerTabBG", "EditorStyles"));
- tabs->set_anchors_and_margins_preset(Control::PRESET_WIDE);
- tabs->set_margin(MARGIN_LEFT, -editor->get_gui_base()->get_stylebox("BottomPanelDebuggerOverride", "EditorStyles")->get_margin(MARGIN_LEFT));
- tabs->set_margin(MARGIN_RIGHT, editor->get_gui_base()->get_stylebox("BottomPanelDebuggerOverride", "EditorStyles")->get_margin(MARGIN_RIGHT));
add_child(tabs);
{ //debugger
diff --git a/editor/script_editor_debugger.h b/editor/script_editor_debugger.h
index 14b024d066..c885614dab 100644
--- a/editor/script_editor_debugger.h
+++ b/editor/script_editor_debugger.h
@@ -55,9 +55,9 @@ class EditorNetworkProfiler;
class ScriptEditorDebuggerInspectedObject;
-class ScriptEditorDebugger : public Control {
+class ScriptEditorDebugger : public MarginContainer {
- GDCLASS(ScriptEditorDebugger, Control);
+ GDCLASS(ScriptEditorDebugger, MarginContainer);
public:
enum CameraOverride {
diff --git a/modules/arkit/arkit_interface.mm b/modules/arkit/arkit_interface.mm
index 9614f775a5..71642cfc30 100644
--- a/modules/arkit/arkit_interface.mm
+++ b/modules/arkit/arkit_interface.mm
@@ -37,6 +37,8 @@
#import <ARKit/ARKit.h>
#import <UIKit/UIKit.h>
+#include <dlfcn.h>
+
#include "arkit_interface.h"
#include "arkit_session_delegate.h"
@@ -53,7 +55,10 @@ void ARKitInterface::start_session() {
// Ignore this if we're not initialized...
if (initialized) {
print_line("Starting ARKit session");
- ARWorldTrackingConfiguration *configuration = [ARWorldTrackingConfiguration new];
+
+ Class ARWorldTrackingConfigurationClass = NSClassFromString(@"ARWorldTrackingConfiguration");
+ ARWorldTrackingConfiguration *configuration = [ARWorldTrackingConfigurationClass new];
+
configuration.lightEstimationEnabled = light_estimation_is_enabled;
if (plane_detection_is_enabled) {
configuration.planeDetection = ARPlaneDetectionVertical | ARPlaneDetectionHorizontal;
@@ -221,7 +226,17 @@ bool ARKitInterface::initialize() {
print_line("initializing ARKit");
// create our ar session and delegate
- ar_session = [ARSession new];
+ Class ARSessionClass = NSClassFromString(@"ARSession");
+ if (ARSessionClass == Nil) {
+ void *arkit_handle = dlopen("/System/Library/Frameworks/ARKit.framework/ARKit", RTLD_NOW);
+ if (arkit_handle) {
+ ARSessionClass = NSClassFromString(@"ARSession");
+ } else {
+ print_line("ARKit init failed");
+ return false;
+ }
+ }
+ ar_session = [ARSessionClass new];
ar_delegate = [ARKitSessionDelegate new];
ar_delegate.arkit_interface = this;
ar_session.delegate = ar_delegate;
diff --git a/modules/assimp/import_utils.h b/modules/assimp/import_utils.h
index 7b14804ddc..8135b352c6 100644
--- a/modules/assimp/import_utils.h
+++ b/modules/assimp/import_utils.h
@@ -394,7 +394,9 @@ public:
return Ref<Image>();
} else {
Ref<Texture> texture = ResourceLoader::load(p_path);
+ ERR_FAIL_COND_V(texture.is_null(), Ref<Image>());
Ref<Image> image = texture->get_data();
+ ERR_FAIL_COND_V(image.is_null(), Ref<Image>());
state.path_to_image_cache.insert(p_path, image);
return image;
}
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index 1d82735328..280bc37dc0 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -84,14 +84,17 @@ String GDScriptLanguage::_get_processed_template(const String &p_template, const
Ref<Script> GDScriptLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const {
String _template = "extends %BASE%\n"
"\n"
+ "\n"
"# Declare member variables here. Examples:\n"
"# var a%INT_TYPE% = 2\n"
"# var b%STRING_TYPE% = \"text\"\n"
"\n"
+ "\n"
"# Called when the node enters the scene tree for the first time.\n"
"func _ready()%VOID_RETURN%:\n"
"%TS%pass # Replace with function body.\n"
"\n"
+ "\n"
"# Called every frame. 'delta' is the elapsed time since the previous frame.\n"
"#func _process(delta%FLOAT_TYPE%)%VOID_RETURN%:\n"
"#%TS%pass\n";
diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py
index e83c3f19a6..5388061f84 100644
--- a/modules/mono/build_scripts/mono_configure.py
+++ b/modules/mono/build_scripts/mono_configure.py
@@ -432,6 +432,11 @@ def copy_mono_shared_libs(env, mono_root, target_mono_root_dir):
os.makedirs(target_mono_bin_dir)
copy(os.path.join(mono_root, 'bin', 'MonoPosixHelper.dll'), target_mono_bin_dir)
+
+ # For newer versions
+ btls_dll_path = os.path.join(mono_root, 'bin', 'libmono-btls-shared.dll')
+ if os.path.isfile(btls_dll_path):
+ copy(btls_dll_path, target_mono_bin_dir)
else:
target_mono_lib_dir = get_android_out_dir(env) if platform == 'android' else os.path.join(target_mono_root_dir, 'lib')
diff --git a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
index f65d2a39f4..cf3823fd16 100644
--- a/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
+++ b/modules/mono/editor/GodotTools/GodotTools/Export/ExportPlugin.cs
@@ -164,12 +164,12 @@ namespace GodotTools.Export
Directory.Delete(aotTempDir, recursive: true);
// TODO: Just a workaround until the export plugins can be made to abort with errors
- if (string.IsNullOrEmpty(maybeLastExportError)) // Check empty as well, because it's set to empty after hot-reloading
+ if (!string.IsNullOrEmpty(maybeLastExportError)) // Check empty as well, because it's set to empty after hot-reloading
{
string lastExportError = maybeLastExportError;
maybeLastExportError = null;
- GodotSharpEditor.Instance.ShowErrorDialog(lastExportError, "C# export failed");
+ GodotSharpEditor.Instance.ShowErrorDialog(lastExportError, "Failed to export C# project");
}
}
diff --git a/modules/mono/glue/Managed/Files/NodePath.cs b/modules/mono/glue/Managed/Files/NodePath.cs
index 4de4e1e6a9..8c5872ba5a 100644
--- a/modules/mono/glue/Managed/Files/NodePath.cs
+++ b/modules/mono/glue/Managed/Files/NodePath.cs
@@ -12,7 +12,7 @@ namespace Godot
internal static IntPtr GetPtr(NodePath instance)
{
if (instance == null)
- return IntPtr.Zero;
+ throw new NullReferenceException($"The instance of type {nameof(NodePath)} is null.");
if (instance.disposed)
throw new ObjectDisposedException(instance.GetType().FullName);
diff --git a/modules/mono/glue/Managed/Files/RID.cs b/modules/mono/glue/Managed/Files/RID.cs
index 12064beca2..94761531b1 100644
--- a/modules/mono/glue/Managed/Files/RID.cs
+++ b/modules/mono/glue/Managed/Files/RID.cs
@@ -12,7 +12,7 @@ namespace Godot
internal static IntPtr GetPtr(RID instance)
{
if (instance == null)
- return IntPtr.Zero;
+ throw new NullReferenceException($"The instance of type {nameof(RID)} is null.");
if (instance.disposed)
throw new ObjectDisposedException(instance.GetType().FullName);
diff --git a/modules/opus/SCsub b/modules/opus/SCsub
index 8af4f16a26..1db5b0987e 100644
--- a/modules/opus/SCsub
+++ b/modules/opus/SCsub
@@ -20,9 +20,6 @@ if env['builtin_opus']:
"opus_multistream.c",
"opus_multistream_encoder.c",
"opus_multistream_decoder.c",
- "opus_projection_encoder.c",
- "opus_projection_decoder.c",
- "mapping_matrix.c",
"repacketizer.c",
"analysis.c",
@@ -56,10 +53,9 @@ if env['builtin_opus']:
"celt/vq.c",
#"celt/arm/arm_celt_map.c",
#"celt/arm/armcpu.c",
- #"celt/arm/celt_fft_ne10.c",
- #"celt/arm/celt_mdct_ne10.c",
+ #"celt/arm/celt_ne10_fft.c",
+ #"celt/arm/celt_ne10_mdct.c",
#"celt/arm/celt_neon_intr.c",
- #"celt/arm/pitch_neon_intr.c",
# Sync with silk_sources.mk
"silk/CNG.c",
@@ -117,7 +113,6 @@ if env['builtin_opus']:
"silk/lin2log.c",
"silk/log2lin.c",
"silk/LPC_analysis_filter.c",
- "silk/LPC_fit.c",
"silk/LPC_inv_pred_gain.c",
"silk/table_LSF_cos.c",
"silk/NLSF2A.c",
@@ -155,10 +150,12 @@ if env['builtin_opus']:
"silk/fixed/find_pitch_lags_FIX.c",
"silk/fixed/find_pred_coefs_FIX.c",
"silk/fixed/noise_shape_analysis_FIX.c",
+ "silk/fixed/prefilter_FIX.c",
"silk/fixed/process_gains_FIX.c",
"silk/fixed/regularize_correlations_FIX.c",
"silk/fixed/residual_energy16_FIX.c",
"silk/fixed/residual_energy_FIX.c",
+ "silk/fixed/solve_LS_FIX.c",
"silk/fixed/warped_autocorrelation_FIX.c",
"silk/fixed/apply_sine_window_FIX.c",
"silk/fixed/autocorr_FIX.c",
@@ -183,9 +180,11 @@ if env['builtin_opus']:
"silk/float/LTP_analysis_filter_FLP.c",
"silk/float/LTP_scale_ctrl_FLP.c",
"silk/float/noise_shape_analysis_FLP.c",
+ "silk/float/prefilter_FLP.c",
"silk/float/process_gains_FLP.c",
"silk/float/regularize_correlations_FLP.c",
"silk/float/residual_energy_FLP.c",
+ "silk/float/solve_LS_FLP.c",
"silk/float/warped_autocorrelation_FLP.c",
"silk/float/wrappers_FLP.c",
"silk/float/autocorrelation_FLP.c",
@@ -194,6 +193,7 @@ if env['builtin_opus']:
"silk/float/energy_FLP.c",
"silk/float/inner_product_FLP.c",
"silk/float/k2a_FLP.c",
+ "silk/float/levinsondurbin_FLP.c",
"silk/float/LPC_inv_pred_gain_FLP.c",
"silk/float/pitch_analysis_core_FLP.c",
"silk/float/scale_copy_vector_FLP.c",
diff --git a/modules/regex/SCsub b/modules/regex/SCsub
index 1be5af02a5..6238cd3d9f 100644
--- a/modules/regex/SCsub
+++ b/modules/regex/SCsub
@@ -6,12 +6,10 @@ Import('env_modules')
env_regex = env_modules.Clone()
if env['builtin_pcre2']:
- jit_blacklist = ['javascript', 'uwp']
-
thirdparty_dir = '#thirdparty/pcre2/src/'
thirdparty_flags = ['PCRE2_STATIC', 'HAVE_CONFIG_H']
- if 'platform' in env and env['platform'] not in jit_blacklist:
+ if env['builtin_pcre2_with_jit']:
thirdparty_flags.append('SUPPORT_JIT')
thirdparty_sources = [
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index 172072db3c..c05b765c5e 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -24,6 +24,7 @@ def get_opts():
def get_flags():
return [
('tools', False),
+ ('builtin_pcre2_with_jit', False),
# Disabling the mbedtls module reduces file size.
# The module has little use due to the limited networking functionality
# in this platform. For the available networking methods, the browser
@@ -124,6 +125,10 @@ def configure(env):
## Link flags
+ # We use IDBFS in javascript_main.cpp. Since Emscripten 1.39.1 it needs to
+ # be linked explicitly.
+ env.Append(LIBS=['idbfs.js'])
+
env.Append(LINKFLAGS=['-s', 'BINARYEN=1'])
# Allow increasing memory buffer size during runtime. This is efficient
diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py
index 7da93eafae..000bd18e7d 100644
--- a/platform/uwp/detect.py
+++ b/platform/uwp/detect.py
@@ -34,6 +34,7 @@ def get_flags():
return [
('tools', False),
('xaudio2', True),
+ ('builtin_pcre2_with_jit', False),
]
diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp
index 09ef6f26bf..5958106419 100644
--- a/scene/gui/gradient_edit.cpp
+++ b/scene/gui/gradient_edit.cpp
@@ -277,12 +277,13 @@ void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
if (points[i].offset == newofs && i != grabbed) {
valid = false;
+ break;
}
}
- if (!valid)
+ if (!valid || grabbed == -1) {
return;
-
+ }
points.write[grabbed].offset = newofs;
points.sort();
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 563fcb9961..3ad44a4a2e 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -3187,7 +3187,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "transparent_bg"), "set_transparent_background", "has_transparent_background");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "handle_input_locally"), "set_handle_input_locally", "is_handling_input_locally");
ADD_GROUP("Rendering", "");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,External 2x,External 4x"), "set_msaa", "get_msaa");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x,AndroidVR 2x,AndroidVR 4x"), "set_msaa", "get_msaa");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hdr"), "set_hdr", "get_hdr");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "keep_3d_linear"), "set_keep_3d_linear", "get_keep_3d_linear");
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 9babc99349..316a94556d 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -3769,8 +3769,8 @@ ShaderLanguage::Node *ShaderLanguage::_reduce_expression(BlockNode *p_block, Sha
nv.sint = -cn->values[i].sint;
} break;
case TYPE_UINT: {
- // FIXME: This can't work on uint
- nv.uint = -cn->values[i].uint;
+ // Intentionally wrap the unsigned int value, because GLSL does.
+ nv.uint = 0 - cn->values[i].uint;
} break;
case TYPE_FLOAT: {
nv.real = -cn->values[i].real;
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 27cfe41238..9571ee49b9 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -397,19 +397,17 @@ Files extracted from the upstream source:
## opus
- Upstream: https://opus-codec.org
-- Version: 1.3.1 (opus) and 0.11 (opusfile)
+- Version: 1.1.5 (opus) and 0.8 (opusfile)
- License: BSD-3-Clause
Files extracted from upstream source:
-- Run `opus/configure` and copy/sync changes to `config.h`
- (note that this file may have Godot-specific options enabled)
- all .c and .h files in src/ (both opus and opusfile)
- all .h files in include/ (both opus and opusfile) as opus/
- remove unused `opus_demo.c`,
- remove `http.c`, `wincerts.c` and `winerrno.h` (part of
unused libopusurl)
-- celt/ and silk/ subfolders (minus tests folders)
+- celt/ and silk/ subfolders
- COPYING
diff --git a/thirdparty/opus/analysis.c b/thirdparty/opus/analysis.c
index cb46dec582..663431a436 100644
--- a/thirdparty/opus/analysis.c
+++ b/thirdparty/opus/analysis.c
@@ -29,29 +29,20 @@
#include "config.h"
#endif
-#define ANALYSIS_C
-
-#include <stdio.h>
-
-#include "mathops.h"
#include "kiss_fft.h"
#include "celt.h"
#include "modes.h"
#include "arch.h"
#include "quant_bands.h"
+#include <stdio.h>
#include "analysis.h"
#include "mlp.h"
#include "stack_alloc.h"
-#include "float_cast.h"
#ifndef M_PI
#define M_PI 3.141592653
#endif
-#ifndef DISABLE_FLOAT_API
-
-#define TRANSITION_PENALTY 10
-
static const float dct_table[128] = {
0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f,
0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f,
@@ -105,118 +96,52 @@ static const float analysis_window[240] = {
};
static const int tbands[NB_TBANDS+1] = {
- 4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 136, 160, 192, 240
+ 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120
};
-#define NB_TONAL_SKIP_BANDS 9
+static const int extra_bands[NB_TOT_BANDS+1] = {
+ 1, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120, 160, 200
+};
-static opus_val32 silk_resampler_down2_hp(
- opus_val32 *S, /* I/O State vector [ 2 ] */
- opus_val32 *out, /* O Output signal [ floor(len/2) ] */
- const opus_val32 *in, /* I Input signal [ len ] */
- int inLen /* I Number of input samples */
-)
-{
- int k, len2 = inLen/2;
- opus_val32 in32, out32, out32_hp, Y, X;
- opus_val64 hp_ener = 0;
- /* Internal variables and state are in Q10 format */
- for( k = 0; k < len2; k++ ) {
- /* Convert to Q10 */
- in32 = in[ 2 * k ];
-
- /* All-pass section for even input sample */
- Y = SUB32( in32, S[ 0 ] );
- X = MULT16_32_Q15(QCONST16(0.6074371f, 15), Y);
- out32 = ADD32( S[ 0 ], X );
- S[ 0 ] = ADD32( in32, X );
- out32_hp = out32;
- /* Convert to Q10 */
- in32 = in[ 2 * k + 1 ];
-
- /* All-pass section for odd input sample, and add to output of previous section */
- Y = SUB32( in32, S[ 1 ] );
- X = MULT16_32_Q15(QCONST16(0.15063f, 15), Y);
- out32 = ADD32( out32, S[ 1 ] );
- out32 = ADD32( out32, X );
- S[ 1 ] = ADD32( in32, X );
-
- Y = SUB32( -in32, S[ 2 ] );
- X = MULT16_32_Q15(QCONST16(0.15063f, 15), Y);
- out32_hp = ADD32( out32_hp, S[ 2 ] );
- out32_hp = ADD32( out32_hp, X );
- S[ 2 ] = ADD32( -in32, X );
-
- hp_ener += out32_hp*(opus_val64)out32_hp;
- /* Add, convert back to int16 and store to output */
- out[ k ] = HALF32(out32);
- }
-#ifdef FIXED_POINT
- /* len2 can be up to 480, so we shift by 8 more to make it fit. */
- hp_ener = hp_ener >> (2*SIG_SHIFT + 8);
-#endif
- return (opus_val32)hp_ener;
-}
+/*static const float tweight[NB_TBANDS+1] = {
+ .3, .4, .5, .6, .7, .8, .9, 1., 1., 1., 1., 1., 1., 1., .8, .7, .6, .5
+};*/
-static 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)
-{
- VARDECL(opus_val32, tmp);
- opus_val32 scale;
- int j;
- opus_val32 ret = 0;
- SAVE_STACK;
-
- if (subframe==0) return 0;
- if (Fs == 48000)
- {
- subframe *= 2;
- offset *= 2;
- } else if (Fs == 16000) {
- subframe = subframe*2/3;
- offset = offset*2/3;
- }
- ALLOC(tmp, subframe, opus_val32);
+#define NB_TONAL_SKIP_BANDS 9
- downmix(_x, tmp, subframe, offset, c1, c2, C);
-#ifdef FIXED_POINT
- scale = (1<<SIG_SHIFT);
-#else
- scale = 1.f/32768;
-#endif
- if (c2==-2)
- scale /= C;
- else if (c2>-1)
- scale /= 2;
- for (j=0;j<subframe;j++)
- tmp[j] *= scale;
- if (Fs == 48000)
+#define cA 0.43157974f
+#define cB 0.67848403f
+#define cC 0.08595542f
+#define cE ((float)M_PI/2)
+static OPUS_INLINE float fast_atan2f(float y, float x) {
+ float x2, y2;
+ /* Should avoid underflow on the values we'll get */
+ if (ABS16(x)+ABS16(y)<1e-9f)
{
- ret = silk_resampler_down2_hp(S, y, tmp, subframe);
- } else if (Fs == 24000) {
- OPUS_COPY(y, tmp, subframe);
- } else if (Fs == 16000) {
- VARDECL(opus_val32, tmp3x);
- ALLOC(tmp3x, 3*subframe, opus_val32);
- /* Don't do this at home! This resampler is horrible and it's only (barely)
- usable for the purpose of the analysis because we don't care about all
- the aliasing between 8 kHz and 12 kHz. */
- for (j=0;j<subframe;j++)
- {
- tmp3x[3*j] = tmp[j];
- tmp3x[3*j+1] = tmp[j];
- tmp3x[3*j+2] = tmp[j];
- }
- silk_resampler_down2_hp(S, y, tmp3x, 3*subframe);
+ x*=1e12f;
+ y*=1e12f;
+ }
+ x2 = x*x;
+ y2 = y*y;
+ if(x2<y2){
+ float den = (y2 + cB*x2) * (y2 + cC*x2);
+ if (den!=0)
+ return -x*y*(y2 + cA*x2) / den + (y<0 ? -cE : cE);
+ else
+ return (y<0 ? -cE : cE);
+ }else{
+ float den = (x2 + cB*y2) * (x2 + cC*y2);
+ if (den!=0)
+ return x*y*(x2 + cA*y2) / den + (y<0 ? -cE : cE) - (x*y<0 ? -cE : cE);
+ else
+ return (y<0 ? -cE : cE) - (x*y<0 ? -cE : cE);
}
- RESTORE_STACK;
- return ret;
}
-void tonality_analysis_init(TonalityAnalysisState *tonal, opus_int32 Fs)
+void tonality_analysis_init(TonalityAnalysisState *tonal)
{
/* Initialize reusable fields. */
tonal->arch = opus_select_arch();
- tonal->Fs = Fs;
/* Clear remaining fields. */
tonality_analysis_reset(tonal);
}
@@ -232,34 +157,15 @@ void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int
{
int pos;
int curr_lookahead;
- float tonality_max;
- float tonality_avg;
- int tonality_count;
+ float psum;
int i;
- int pos0;
- float prob_avg;
- float prob_count;
- float prob_min, prob_max;
- float vad_prob;
- int mpos, vpos;
- int bandwidth_span;
pos = tonal->read_pos;
curr_lookahead = tonal->write_pos-tonal->read_pos;
if (curr_lookahead<0)
curr_lookahead += DETECT_SIZE;
- tonal->read_subframe += len/(tonal->Fs/400);
- while (tonal->read_subframe>=8)
- {
- tonal->read_subframe -= 8;
- tonal->read_pos++;
- }
- if (tonal->read_pos>=DETECT_SIZE)
- tonal->read_pos-=DETECT_SIZE;
-
- /* On long frames, look at the second analysis window rather than the first. */
- if (len > tonal->Fs/50 && pos != tonal->write_pos)
+ if (len > 480 && pos != tonal->write_pos)
{
pos++;
if (pos==DETECT_SIZE)
@@ -269,177 +175,32 @@ void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int
pos--;
if (pos<0)
pos = DETECT_SIZE-1;
- pos0 = pos;
OPUS_COPY(info_out, &tonal->info[pos], 1);
- if (!info_out->valid)
- return;
- tonality_max = tonality_avg = info_out->tonality;
- tonality_count = 1;
- /* Look at the neighbouring frames and pick largest bandwidth found (to be safe). */
- bandwidth_span = 6;
- /* If possible, look ahead for a tone to compensate for the delay in the tone detector. */
- for (i=0;i<3;i++)
- {
- pos++;
- if (pos==DETECT_SIZE)
- pos = 0;
- if (pos == tonal->write_pos)
- break;
- tonality_max = MAX32(tonality_max, tonal->info[pos].tonality);
- tonality_avg += tonal->info[pos].tonality;
- tonality_count++;
- info_out->bandwidth = IMAX(info_out->bandwidth, tonal->info[pos].bandwidth);
- bandwidth_span--;
- }
- pos = pos0;
- /* Look back in time to see if any has a wider bandwidth than the current frame. */
- for (i=0;i<bandwidth_span;i++)
- {
- pos--;
- if (pos < 0)
- pos = DETECT_SIZE-1;
- if (pos == tonal->write_pos)
- break;
- info_out->bandwidth = IMAX(info_out->bandwidth, tonal->info[pos].bandwidth);
- }
- info_out->tonality = MAX32(tonality_avg/tonality_count, tonality_max-.2f);
-
- mpos = vpos = pos0;
- /* If we have enough look-ahead, compensate for the ~5-frame delay in the music prob and
- ~1 frame delay in the VAD prob. */
- if (curr_lookahead > 15)
+ tonal->read_subframe += len/120;
+ while (tonal->read_subframe>=4)
{
- mpos += 5;
- if (mpos>=DETECT_SIZE)
- mpos -= DETECT_SIZE;
- vpos += 1;
- if (vpos>=DETECT_SIZE)
- vpos -= DETECT_SIZE;
- }
-
- /* The following calculations attempt to minimize a "badness function"
- for the transition. When switching from speech to music, the badness
- of switching at frame k is
- b_k = S*v_k + \sum_{i=0}^{k-1} v_i*(p_i - T)
- where
- v_i is the activity probability (VAD) at frame i,
- p_i is the music probability at frame i
- T is the probability threshold for switching
- S is the penalty for switching during active audio rather than silence
- the current frame has index i=0
-
- Rather than apply badness to directly decide when to switch, what we compute
- instead is the threshold for which the optimal switching point is now. When
- considering whether to switch now (frame 0) or at frame k, we have:
- S*v_0 = S*v_k + \sum_{i=0}^{k-1} v_i*(p_i - T)
- which gives us:
- T = ( \sum_{i=0}^{k-1} v_i*p_i + S*(v_k-v_0) ) / ( \sum_{i=0}^{k-1} v_i )
- We take the min threshold across all positive values of k (up to the maximum
- amount of lookahead we have) to give us the threshold for which the current
- frame is the optimal switch point.
-
- The last step is that we need to consider whether we want to switch at all.
- For that we use the average of the music probability over the entire window.
- If the threshold is higher than that average we're not going to
- switch, so we compute a min with the average as well. The result of all these
- min operations is music_prob_min, which gives the threshold for switching to music
- if we're currently encoding for speech.
-
- We do the exact opposite to compute music_prob_max which is used for switching
- from music to speech.
- */
- prob_min = 1.f;
- prob_max = 0.f;
- vad_prob = tonal->info[vpos].activity_probability;
- prob_count = MAX16(.1f, vad_prob);
- prob_avg = MAX16(.1f, vad_prob)*tonal->info[mpos].music_prob;
- while (1)
- {
- float pos_vad;
- mpos++;
- if (mpos==DETECT_SIZE)
- mpos = 0;
- if (mpos == tonal->write_pos)
- break;
- vpos++;
- if (vpos==DETECT_SIZE)
- vpos = 0;
- if (vpos == tonal->write_pos)
- break;
- pos_vad = tonal->info[vpos].activity_probability;
- prob_min = MIN16((prob_avg - TRANSITION_PENALTY*(vad_prob - pos_vad))/prob_count, prob_min);
- prob_max = MAX16((prob_avg + TRANSITION_PENALTY*(vad_prob - pos_vad))/prob_count, prob_max);
- prob_count += MAX16(.1f, pos_vad);
- prob_avg += MAX16(.1f, pos_vad)*tonal->info[mpos].music_prob;
- }
- info_out->music_prob = prob_avg/prob_count;
- prob_min = MIN16(prob_avg/prob_count, prob_min);
- prob_max = MAX16(prob_avg/prob_count, prob_max);
- prob_min = MAX16(prob_min, 0.f);
- prob_max = MIN16(prob_max, 1.f);
-
- /* If we don't have enough look-ahead, do our best to make a decent decision. */
- if (curr_lookahead < 10)
- {
- float pmin, pmax;
- pmin = prob_min;
- pmax = prob_max;
- pos = pos0;
- /* Look for min/max in the past. */
- for (i=0;i<IMIN(tonal->count-1, 15);i++)
- {
- pos--;
- if (pos < 0)
- pos = DETECT_SIZE-1;
- pmin = MIN16(pmin, tonal->info[pos].music_prob);
- pmax = MAX16(pmax, tonal->info[pos].music_prob);
- }
- /* Bias against switching on active audio. */
- pmin = MAX16(0.f, pmin - .1f*vad_prob);
- pmax = MIN16(1.f, pmax + .1f*vad_prob);
- prob_min += (1.f-.1f*curr_lookahead)*(pmin - prob_min);
- prob_max += (1.f-.1f*curr_lookahead)*(pmax - prob_max);
+ tonal->read_subframe -= 4;
+ tonal->read_pos++;
}
- info_out->music_prob_min = prob_min;
- info_out->music_prob_max = prob_max;
-
- /* printf("%f %f %f %f %f\n", prob_min, prob_max, prob_avg/prob_count, vad_prob, info_out->music_prob); */
-}
-
-static const float std_feature_bias[9] = {
- 5.684947f, 3.475288f, 1.770634f, 1.599784f, 3.773215f,
- 2.163313f, 1.260756f, 1.116868f, 1.918795f
-};
-
-#define LEAKAGE_OFFSET 2.5f
-#define LEAKAGE_SLOPE 2.f
-
-#ifdef FIXED_POINT
-/* For fixed-point, the input is +/-2^15 shifted up by SIG_SHIFT, so we need to
- compensate for that in the energy. */
-#define SCALE_COMPENS (1.f/((opus_int32)1<<(15+SIG_SHIFT)))
-#define SCALE_ENER(e) ((SCALE_COMPENS*SCALE_COMPENS)*(e))
-#else
-#define SCALE_ENER(e) (e)
-#endif
-
-#ifdef FIXED_POINT
-static int is_digital_silence32(const opus_val32* pcm, int frame_size, int channels, int lsb_depth)
-{
- int silence = 0;
- opus_val32 sample_max = 0;
-#ifdef MLP_TRAINING
- return 0;
-#endif
- sample_max = celt_maxabs32(pcm, frame_size*channels);
+ if (tonal->read_pos>=DETECT_SIZE)
+ tonal->read_pos-=DETECT_SIZE;
- silence = (sample_max == 0);
- (void)lsb_depth;
- return silence;
+ /* Compensate for the delay in the features themselves.
+ FIXME: Need a better estimate the 10 I just made up */
+ curr_lookahead = IMAX(curr_lookahead-10, 0);
+
+ psum=0;
+ /* Summing the probability of transition patterns that involve music at
+ time (DETECT_SIZE-curr_lookahead-1) */
+ for (i=0;i<DETECT_SIZE-curr_lookahead;i++)
+ psum += tonal->pmusic[i];
+ for (;i<DETECT_SIZE;i++)
+ psum += tonal->pspeech[i];
+ psum = psum*tonal->music_confidence + (1-psum)*tonal->speech_confidence;
+ /*printf("%f %f %f\n", psum, info_out->music_prob, info_out->tonality);*/
+
+ info_out->music_prob = psum;
}
-#else
-#define is_digital_silence32(pcm, frame_size, channels, lsb_depth) is_digital_silence(pcm, frame_size, channels, lsb_depth)
-#endif
static 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)
{
@@ -469,50 +230,24 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
float alpha, alphaE, alphaE2;
float frame_loudness;
float bandwidth_mask;
- int is_masked[NB_TBANDS+1];
int bandwidth=0;
float maxE = 0;
float noise_floor;
int remaining;
AnalysisInfo *info;
- float hp_ener;
- float tonality2[240];
- float midE[8];
- float spec_variability=0;
- float band_log2[NB_TBANDS+1];
- float leakage_from[NB_TBANDS+1];
- float leakage_to[NB_TBANDS+1];
- float layer_out[MAX_NEURONS];
- float below_max_pitch;
- float above_max_pitch;
- int is_silence;
SAVE_STACK;
- if (!tonal->initialized)
- {
- tonal->mem_fill = 240;
- tonal->initialized = 1;
- }
- alpha = 1.f/IMIN(10, 1+tonal->count);
- alphaE = 1.f/IMIN(25, 1+tonal->count);
- /* Noise floor related decay for bandwidth detection: -2.2 dB/second */
- alphaE2 = 1.f/IMIN(100, 1+tonal->count);
- if (tonal->count <= 1) alphaE2 = 1;
-
- if (tonal->Fs == 48000)
- {
- /* len and offset are now at 24 kHz. */
- len/= 2;
- offset /= 2;
- } else if (tonal->Fs == 16000) {
- len = 3*len/2;
- offset = 3*offset/2;
- }
+ tonal->last_transition++;
+ alpha = 1.f/IMIN(20, 1+tonal->count);
+ alphaE = 1.f/IMIN(50, 1+tonal->count);
+ alphaE2 = 1.f/IMIN(1000, 1+tonal->count);
+ if (tonal->count<4)
+ tonal->music_prob = .5;
kfft = celt_mode->mdct.kfft[0];
- tonal->hp_ener_accum += (float)downmix_and_resample(downmix, x,
- &tonal->inmem[tonal->mem_fill], tonal->downmix_state,
- IMIN(len, ANALYSIS_BUF_SIZE-tonal->mem_fill), offset, c1, c2, C, tonal->Fs);
+ if (tonal->count==0)
+ tonal->mem_fill = 240;
+ downmix(x, &tonal->inmem[tonal->mem_fill], IMIN(len, ANALYSIS_BUF_SIZE-tonal->mem_fill), offset, c1, c2, C);
if (tonal->mem_fill+len < ANALYSIS_BUF_SIZE)
{
tonal->mem_fill += len;
@@ -520,13 +255,10 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
RESTORE_STACK;
return;
}
- hp_ener = tonal->hp_ener_accum;
info = &tonal->info[tonal->write_pos++];
if (tonal->write_pos>=DETECT_SIZE)
tonal->write_pos-=DETECT_SIZE;
- is_silence = is_digital_silence32(tonal->inmem, ANALYSIS_BUF_SIZE, 1, lsb_depth);
-
ALLOC(in, 480, kiss_fft_cpx);
ALLOC(out, 480, kiss_fft_cpx);
ALLOC(tonality, 240, float);
@@ -541,20 +273,8 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
}
OPUS_MOVE(tonal->inmem, tonal->inmem+ANALYSIS_BUF_SIZE-240, 240);
remaining = len - (ANALYSIS_BUF_SIZE-tonal->mem_fill);
- tonal->hp_ener_accum = (float)downmix_and_resample(downmix, x,
- &tonal->inmem[240], tonal->downmix_state, remaining,
- offset+ANALYSIS_BUF_SIZE-tonal->mem_fill, c1, c2, C, tonal->Fs);
+ downmix(x, &tonal->inmem[240], remaining, offset+ANALYSIS_BUF_SIZE-tonal->mem_fill, c1, c2, C);
tonal->mem_fill = 240 + remaining;
- if (is_silence)
- {
- /* On silence, copy the previous analysis. */
- int prev_pos = tonal->write_pos-2;
- if (prev_pos < 0)
- prev_pos += DETECT_SIZE;
- OPUS_COPY(info, &tonal->info[prev_pos], 1);
- RESTORE_STACK;
- return;
- }
opus_fft(kfft, in, out, tonal->arch);
#ifndef FIXED_POINT
/* If there's any NaN on the input, the entire output will be NaN, so we only need to check one value. */
@@ -585,31 +305,24 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
d_angle2 = angle2 - angle;
d2_angle2 = d_angle2 - d_angle;
- mod1 = d2_angle - (float)float2int(d2_angle);
+ mod1 = d2_angle - (float)floor(.5+d2_angle);
noisiness[i] = ABS16(mod1);
mod1 *= mod1;
mod1 *= mod1;
- mod2 = d2_angle2 - (float)float2int(d2_angle2);
+ mod2 = d2_angle2 - (float)floor(.5+d2_angle2);
noisiness[i] += ABS16(mod2);
mod2 *= mod2;
mod2 *= mod2;
- avg_mod = .25f*(d2A[i]+mod1+2*mod2);
- /* This introduces an extra delay of 2 frames in the detection. */
+ avg_mod = .25f*(d2A[i]+2.f*mod1+mod2);
tonality[i] = 1.f/(1.f+40.f*16.f*pi4*avg_mod)-.015f;
- /* No delay on this detection, but it's less reliable. */
- tonality2[i] = 1.f/(1.f+40.f*16.f*pi4*mod2)-.015f;
A[i] = angle2;
dA[i] = d_angle2;
d2A[i] = mod2;
}
- for (i=2;i<N2-1;i++)
- {
- float tt = MIN32(tonality2[i], MAX32(tonality2[i-1], tonality2[i+1]));
- tonality[i] = .9f*MAX32(tonality[i], tt-.1f);
- }
+
frame_tonality = 0;
max_frame_tonality = 0;
/*tw_sum = 0;*/
@@ -626,22 +339,6 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
}
relativeE = 0;
frame_loudness = 0;
- /* The energy of the very first band is special because of DC. */
- {
- float E = 0;
- float X1r, X2r;
- X1r = 2*(float)out[0].r;
- X2r = 2*(float)out[0].i;
- E = X1r*X1r + X2r*X2r;
- for (i=1;i<4;i++)
- {
- float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r
- + out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;
- E += binE;
- }
- E = SCALE_ENER(E);
- band_log2[0] = .5f*1.442695f*(float)log(E+1e-10f);
- }
for (b=0;b<NB_TBANDS;b++)
{
float E=0, tE=0, nE=0;
@@ -651,9 +348,12 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
{
float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r
+ out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;
- binE = SCALE_ENER(binE);
+#ifdef FIXED_POINT
+ /* FIXME: It's probably best to change the BFCC filter initial state instead */
+ binE *= 5.55e-17f;
+#endif
E += binE;
- tE += binE*MAX32(0, tonality[i]);
+ tE += binE*tonality[i];
nE += binE*2.f*(.5f-noisiness[i]);
}
#ifndef FIXED_POINT
@@ -671,27 +371,14 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
frame_loudness += (float)sqrt(E+1e-10f);
logE[b] = (float)log(E+1e-10f);
- band_log2[b+1] = .5f*1.442695f*(float)log(E+1e-10f);
- tonal->logE[tonal->E_count][b] = logE[b];
- if (tonal->count==0)
- tonal->highE[b] = tonal->lowE[b] = logE[b];
- if (tonal->highE[b] > tonal->lowE[b] + 7.5)
+ tonal->lowE[b] = MIN32(logE[b], tonal->lowE[b]+.01f);
+ tonal->highE[b] = MAX32(logE[b], tonal->highE[b]-.1f);
+ if (tonal->highE[b] < tonal->lowE[b]+1.f)
{
- if (tonal->highE[b] - logE[b] > logE[b] - tonal->lowE[b])
- tonal->highE[b] -= .01f;
- else
- tonal->lowE[b] += .01f;
+ tonal->highE[b]+=.5f;
+ tonal->lowE[b]-=.5f;
}
- if (logE[b] > tonal->highE[b])
- {
- tonal->highE[b] = logE[b];
- tonal->lowE[b] = MAX32(tonal->highE[b]-15, tonal->lowE[b]);
- } else if (logE[b] < tonal->lowE[b])
- {
- tonal->lowE[b] = logE[b];
- tonal->highE[b] = MIN32(tonal->lowE[b]+15, tonal->highE[b]);
- }
- relativeE += (logE[b]-tonal->lowE[b])/(1e-5f + (tonal->highE[b]-tonal->lowE[b]));
+ relativeE += (logE[b]-tonal->lowE[b])/(1e-15f+tonal->highE[b]-tonal->lowE[b]);
L1=L2=0;
for (i=0;i<NB_FRAMES;i++)
@@ -723,135 +410,45 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
tonal->prev_band_tonality[b] = band_tonality[b];
}
- leakage_from[0] = band_log2[0];
- leakage_to[0] = band_log2[0] - LEAKAGE_OFFSET;
- for (b=1;b<NB_TBANDS+1;b++)
- {
- float leak_slope = LEAKAGE_SLOPE*(tbands[b]-tbands[b-1])/4;
- leakage_from[b] = MIN16(leakage_from[b-1]+leak_slope, band_log2[b]);
- leakage_to[b] = MAX16(leakage_to[b-1]-leak_slope, band_log2[b]-LEAKAGE_OFFSET);
- }
- for (b=NB_TBANDS-2;b>=0;b--)
- {
- float leak_slope = LEAKAGE_SLOPE*(tbands[b+1]-tbands[b])/4;
- leakage_from[b] = MIN16(leakage_from[b+1]+leak_slope, leakage_from[b]);
- leakage_to[b] = MAX16(leakage_to[b+1]-leak_slope, leakage_to[b]);
- }
- celt_assert(NB_TBANDS+1 <= LEAK_BANDS);
- for (b=0;b<NB_TBANDS+1;b++)
- {
- /* leak_boost[] is made up of two terms. The first, based on leakage_to[],
- represents the boost needed to overcome the amount of analysis leakage
- cause in a weaker band b by louder neighbouring bands.
- The second, based on leakage_from[], applies to a loud band b for
- which the quantization noise causes synthesis leakage to the weaker
- neighbouring bands. */
- float boost = MAX16(0, leakage_to[b] - band_log2[b]) +
- MAX16(0, band_log2[b] - (leakage_from[b]+LEAKAGE_OFFSET));
- info->leak_boost[b] = IMIN(255, (int)floor(.5 + 64.f*boost));
- }
- for (;b<LEAK_BANDS;b++) info->leak_boost[b] = 0;
-
- for (i=0;i<NB_FRAMES;i++)
- {
- int j;
- float mindist = 1e15f;
- for (j=0;j<NB_FRAMES;j++)
- {
- int k;
- float dist=0;
- for (k=0;k<NB_TBANDS;k++)
- {
- float tmp;
- tmp = tonal->logE[i][k] - tonal->logE[j][k];
- dist += tmp*tmp;
- }
- if (j!=i)
- mindist = MIN32(mindist, dist);
- }
- spec_variability += mindist;
- }
- spec_variability = (float)sqrt(spec_variability/NB_FRAMES/NB_TBANDS);
bandwidth_mask = 0;
bandwidth = 0;
maxE = 0;
noise_floor = 5.7e-4f/(1<<(IMAX(0,lsb_depth-8)));
+#ifdef FIXED_POINT
+ noise_floor *= 1<<(15+SIG_SHIFT);
+#endif
noise_floor *= noise_floor;
- below_max_pitch=0;
- above_max_pitch=0;
- for (b=0;b<NB_TBANDS;b++)
+ for (b=0;b<NB_TOT_BANDS;b++)
{
float E=0;
- float Em;
int band_start, band_end;
/* Keep a margin of 300 Hz for aliasing */
- band_start = tbands[b];
- band_end = tbands[b+1];
+ band_start = extra_bands[b];
+ band_end = extra_bands[b+1];
for (i=band_start;i<band_end;i++)
{
float binE = out[i].r*(float)out[i].r + out[N-i].r*(float)out[N-i].r
+ out[i].i*(float)out[i].i + out[N-i].i*(float)out[N-i].i;
E += binE;
}
- E = SCALE_ENER(E);
maxE = MAX32(maxE, E);
- if (band_start < 64)
- {
- below_max_pitch += E;
- } else {
- above_max_pitch += E;
- }
tonal->meanE[b] = MAX32((1-alphaE2)*tonal->meanE[b], E);
- Em = MAX32(E, tonal->meanE[b]);
+ E = MAX32(E, tonal->meanE[b]);
+ /* Use a simple follower with 13 dB/Bark slope for spreading function */
+ bandwidth_mask = MAX32(.05f*bandwidth_mask, E);
/* Consider the band "active" only if all these conditions are met:
- 1) less than 90 dB below the peak band (maximal masking possible considering
+ 1) less than 10 dB below the simple follower
+ 2) less than 90 dB below the peak band (maximal masking possible considering
both the ATH and the loudness-dependent slope of the spreading function)
- 2) above the PCM quantization noise floor
- We use b+1 because the first CELT band isn't included in tbands[]
+ 3) above the PCM quantization noise floor
*/
- if (E*1e9f > maxE && (Em > 3*noise_floor*(band_end-band_start) || E > noise_floor*(band_end-band_start)))
- bandwidth = b+1;
- /* Check if the band is masked (see below). */
- is_masked[b] = E < (tonal->prev_bandwidth >= b+1 ? .01f : .05f)*bandwidth_mask;
- /* Use a simple follower with 13 dB/Bark slope for spreading function. */
- bandwidth_mask = MAX32(.05f*bandwidth_mask, E);
+ if (E>.1*bandwidth_mask && E*1e9f > maxE && E > noise_floor*(band_end-band_start))
+ bandwidth = b;
}
- /* Special case for the last two bands, for which we don't have spectrum but only
- the energy above 12 kHz. The difficulty here is that the high-pass we use
- leaks some LF energy, so we need to increase the threshold without accidentally cutting
- off the band. */
- if (tonal->Fs == 48000) {
- float noise_ratio;
- float Em;
- float E = hp_ener*(1.f/(60*60));
- noise_ratio = tonal->prev_bandwidth==20 ? 10.f : 30.f;
-
-#ifdef FIXED_POINT
- /* silk_resampler_down2_hp() shifted right by an extra 8 bits. */
- E *= 256.f*(1.f/Q15ONE)*(1.f/Q15ONE);
-#endif
- above_max_pitch += E;
- tonal->meanE[b] = MAX32((1-alphaE2)*tonal->meanE[b], E);
- Em = MAX32(E, tonal->meanE[b]);
- if (Em > 3*noise_ratio*noise_floor*160 || E > noise_ratio*noise_floor*160)
- bandwidth = 20;
- /* Check if the band is masked (see below). */
- is_masked[b] = E < (tonal->prev_bandwidth == 20 ? .01f : .05f)*bandwidth_mask;
- }
- if (above_max_pitch > below_max_pitch)
- info->max_pitch_ratio = below_max_pitch/above_max_pitch;
- else
- info->max_pitch_ratio = 1;
- /* In some cases, resampling aliasing can create a small amount of energy in the first band
- being cut. So if the last band is masked, we don't include it. */
- if (bandwidth == 20 && is_masked[NB_TBANDS])
- bandwidth-=2;
- else if (bandwidth > 0 && bandwidth <= NB_TBANDS && is_masked[bandwidth-1])
- bandwidth--;
if (tonal->count<=2)
bandwidth = 20;
frame_loudness = 20*(float)log10(frame_loudness);
- tonal->Etracker = MAX32(tonal->Etracker-.003f, frame_loudness);
+ tonal->Etracker = MAX32(tonal->Etracker-.03f, frame_loudness);
tonal->lowECount *= (1-alphaE);
if (frame_loudness < tonal->Etracker-30)
tonal->lowECount += alphaE;
@@ -863,18 +460,11 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
sum += dct_table[i*16+b]*logE[b];
BFCC[i] = sum;
}
- for (i=0;i<8;i++)
- {
- float sum=0;
- for (b=0;b<16;b++)
- sum += dct_table[i*16+b]*.5f*(tonal->highE[b]+tonal->lowE[b]);
- midE[i] = sum;
- }
frame_stationarity /= NB_TBANDS;
relativeE /= NB_TBANDS;
if (tonal->count<10)
- relativeE = .5f;
+ relativeE = .5;
frame_noisiness /= NB_TBANDS;
#if 1
info->activity = frame_noisiness + (1-frame_noisiness)*relativeE;
@@ -889,7 +479,7 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
info->tonality_slope = slope;
tonal->E_count = (tonal->E_count+1)%NB_FRAMES;
- tonal->count = IMIN(tonal->count+1, ANALYSIS_COUNT_MAX);
+ tonal->count++;
info->tonality = frame_tonality;
for (i=0;i<4;i++)
@@ -908,8 +498,6 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
for (i=0;i<9;i++)
tonal->std[i] = (1-alpha)*tonal->std[i] + alpha*features[i]*features[i];
}
- for (i=0;i<4;i++)
- features[i] = BFCC[i]-midE[i];
for (i=0;i<8;i++)
{
@@ -919,31 +507,136 @@ static void tonality_analysis(TonalityAnalysisState *tonal, const CELTMode *celt
tonal->mem[i] = BFCC[i];
}
for (i=0;i<9;i++)
- features[11+i] = (float)sqrt(tonal->std[i]) - std_feature_bias[i];
- features[18] = spec_variability - 0.78f;
- features[20] = info->tonality - 0.154723f;
- features[21] = info->activity - 0.724643f;
- features[22] = frame_stationarity - 0.743717f;
- features[23] = info->tonality_slope + 0.069216f;
- features[24] = tonal->lowECount - 0.067930f;
-
- compute_dense(&layer0, layer_out, features);
- compute_gru(&layer1, tonal->rnn_state, layer_out);
- compute_dense(&layer2, frame_probs, tonal->rnn_state);
-
- /* Probability of speech or music vs noise */
- info->activity_probability = frame_probs[1];
- info->music_prob = frame_probs[0];
-
- /*printf("%f %f %f\n", frame_probs[0], frame_probs[1], info->music_prob);*/
-#ifdef MLP_TRAINING
- for (i=0;i<25;i++)
- printf("%f ", features[i]);
- printf("\n");
+ features[11+i] = (float)sqrt(tonal->std[i]);
+ features[20] = info->tonality;
+ features[21] = info->activity;
+ features[22] = frame_stationarity;
+ features[23] = info->tonality_slope;
+ features[24] = tonal->lowECount;
+
+#ifndef DISABLE_FLOAT_API
+ mlp_process(&net, features, frame_probs);
+ frame_probs[0] = .5f*(frame_probs[0]+1);
+ /* Curve fitting between the MLP probability and the actual probability */
+ frame_probs[0] = .01f + 1.21f*frame_probs[0]*frame_probs[0] - .23f*(float)pow(frame_probs[0], 10);
+ /* Probability of active audio (as opposed to silence) */
+ frame_probs[1] = .5f*frame_probs[1]+.5f;
+ /* Consider that silence has a 50-50 probability. */
+ frame_probs[0] = frame_probs[1]*frame_probs[0] + (1-frame_probs[1])*.5f;
+
+ /*printf("%f %f ", frame_probs[0], frame_probs[1]);*/
+ {
+ /* Probability of state transition */
+ float tau;
+ /* Represents independence of the MLP probabilities, where
+ beta=1 means fully independent. */
+ float beta;
+ /* Denormalized probability of speech (p0) and music (p1) after update */
+ float p0, p1;
+ /* Probabilities for "all speech" and "all music" */
+ float s0, m0;
+ /* Probability sum for renormalisation */
+ float psum;
+ /* Instantaneous probability of speech and music, with beta pre-applied. */
+ float speech0;
+ float music0;
+ float p, q;
+
+ /* One transition every 3 minutes of active audio */
+ tau = .00005f*frame_probs[1];
+ /* Adapt beta based on how "unexpected" the new prob is */
+ p = MAX16(.05f,MIN16(.95f,frame_probs[0]));
+ q = MAX16(.05f,MIN16(.95f,tonal->music_prob));
+ beta = .01f+.05f*ABS16(p-q)/(p*(1-q)+q*(1-p));
+ /* p0 and p1 are the probabilities of speech and music at this frame
+ using only information from previous frame and applying the
+ state transition model */
+ p0 = (1-tonal->music_prob)*(1-tau) + tonal->music_prob *tau;
+ p1 = tonal->music_prob *(1-tau) + (1-tonal->music_prob)*tau;
+ /* We apply the current probability with exponent beta to work around
+ the fact that the probability estimates aren't independent. */
+ p0 *= (float)pow(1-frame_probs[0], beta);
+ p1 *= (float)pow(frame_probs[0], beta);
+ /* Normalise the probabilities to get the Marokv probability of music. */
+ tonal->music_prob = p1/(p0+p1);
+ info->music_prob = tonal->music_prob;
+
+ /* This chunk of code deals with delayed decision. */
+ psum=1e-20f;
+ /* Instantaneous probability of speech and music, with beta pre-applied. */
+ speech0 = (float)pow(1-frame_probs[0], beta);
+ music0 = (float)pow(frame_probs[0], beta);
+ if (tonal->count==1)
+ {
+ tonal->pspeech[0]=.5;
+ tonal->pmusic [0]=.5;
+ }
+ /* Updated probability of having only speech (s0) or only music (m0),
+ before considering the new observation. */
+ s0 = tonal->pspeech[0] + tonal->pspeech[1];
+ m0 = tonal->pmusic [0] + tonal->pmusic [1];
+ /* Updates s0 and m0 with instantaneous probability. */
+ tonal->pspeech[0] = s0*(1-tau)*speech0;
+ tonal->pmusic [0] = m0*(1-tau)*music0;
+ /* Propagate the transition probabilities */
+ for (i=1;i<DETECT_SIZE-1;i++)
+ {
+ tonal->pspeech[i] = tonal->pspeech[i+1]*speech0;
+ tonal->pmusic [i] = tonal->pmusic [i+1]*music0;
+ }
+ /* Probability that the latest frame is speech, when all the previous ones were music. */
+ tonal->pspeech[DETECT_SIZE-1] = m0*tau*speech0;
+ /* Probability that the latest frame is music, when all the previous ones were speech. */
+ tonal->pmusic [DETECT_SIZE-1] = s0*tau*music0;
+
+ /* Renormalise probabilities to 1 */
+ for (i=0;i<DETECT_SIZE;i++)
+ psum += tonal->pspeech[i] + tonal->pmusic[i];
+ psum = 1.f/psum;
+ for (i=0;i<DETECT_SIZE;i++)
+ {
+ tonal->pspeech[i] *= psum;
+ tonal->pmusic [i] *= psum;
+ }
+ psum = tonal->pmusic[0];
+ for (i=1;i<DETECT_SIZE;i++)
+ psum += tonal->pspeech[i];
+
+ /* Estimate our confidence in the speech/music decisions */
+ if (frame_probs[1]>.75)
+ {
+ if (tonal->music_prob>.9)
+ {
+ float adapt;
+ adapt = 1.f/(++tonal->music_confidence_count);
+ tonal->music_confidence_count = IMIN(tonal->music_confidence_count, 500);
+ tonal->music_confidence += adapt*MAX16(-.2f,frame_probs[0]-tonal->music_confidence);
+ }
+ if (tonal->music_prob<.1)
+ {
+ float adapt;
+ adapt = 1.f/(++tonal->speech_confidence_count);
+ tonal->speech_confidence_count = IMIN(tonal->speech_confidence_count, 500);
+ tonal->speech_confidence += adapt*MIN16(.2f,frame_probs[0]-tonal->speech_confidence);
+ }
+ } else {
+ if (tonal->music_confidence_count==0)
+ tonal->music_confidence = .9f;
+ if (tonal->speech_confidence_count==0)
+ tonal->speech_confidence = .1f;
+ }
+ }
+ if (tonal->last_music != (tonal->music_prob>.5f))
+ tonal->last_transition=0;
+ tonal->last_music = tonal->music_prob>.5f;
+#else
+ info->music_prob = 0;
#endif
+ /*for (i=0;i<25;i++)
+ printf("%f ", features[i]);
+ printf("\n");*/
info->bandwidth = bandwidth;
- tonal->prev_bandwidth = bandwidth;
/*printf("%d %d\n", info->bandwidth, info->opus_bandwidth);*/
info->noisiness = frame_noisiness;
info->valid = 1;
@@ -957,25 +650,23 @@ void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, co
int offset;
int pcm_len;
- analysis_frame_size -= analysis_frame_size&1;
if (analysis_pcm != NULL)
{
/* Avoid overflow/wrap-around of the analysis buffer */
- analysis_frame_size = IMIN((DETECT_SIZE-5)*Fs/50, analysis_frame_size);
+ analysis_frame_size = IMIN((DETECT_SIZE-5)*Fs/100, analysis_frame_size);
pcm_len = analysis_frame_size - analysis->analysis_offset;
offset = analysis->analysis_offset;
- while (pcm_len>0) {
- tonality_analysis(analysis, celt_mode, analysis_pcm, IMIN(Fs/50, pcm_len), offset, c1, c2, C, lsb_depth, downmix);
- offset += Fs/50;
- pcm_len -= Fs/50;
- }
+ do {
+ tonality_analysis(analysis, celt_mode, analysis_pcm, IMIN(480, pcm_len), offset, c1, c2, C, lsb_depth, downmix);
+ offset += 480;
+ pcm_len -= 480;
+ } while (pcm_len>0);
analysis->analysis_offset = analysis_frame_size;
analysis->analysis_offset -= frame_size;
}
+ analysis_info->valid = 0;
tonality_get_info(analysis, analysis_info, frame_size);
}
-
-#endif /* DISABLE_FLOAT_API */
diff --git a/thirdparty/opus/analysis.h b/thirdparty/opus/analysis.h
index 0b66555f21..9eae56a525 100644
--- a/thirdparty/opus/analysis.h
+++ b/thirdparty/opus/analysis.h
@@ -30,24 +30,16 @@
#include "celt.h"
#include "opus_private.h"
-#include "mlp.h"
#define NB_FRAMES 8
#define NB_TBANDS 18
-#define ANALYSIS_BUF_SIZE 720 /* 30 ms at 24 kHz */
+#define NB_TOT_BANDS 21
+#define ANALYSIS_BUF_SIZE 720 /* 15 ms at 48 kHz */
-/* At that point we can stop counting frames because it no longer matters. */
-#define ANALYSIS_COUNT_MAX 10000
-
-#define DETECT_SIZE 100
-
-/* Uncomment this to print the MLP features on stdout. */
-/*#define MLP_TRAINING*/
+#define DETECT_SIZE 200
typedef struct {
int arch;
- int application;
- opus_int32 Fs;
#define TONALITY_ANALYSIS_RESET_START angle
float angle[240];
float d_angle[240];
@@ -56,27 +48,35 @@ typedef struct {
int mem_fill; /* number of usable samples in the buffer */
float prev_band_tonality[NB_TBANDS];
float prev_tonality;
- int prev_bandwidth;
float E[NB_FRAMES][NB_TBANDS];
- float logE[NB_FRAMES][NB_TBANDS];
float lowE[NB_TBANDS];
float highE[NB_TBANDS];
- float meanE[NB_TBANDS+1];
+ float meanE[NB_TOT_BANDS];
float mem[32];
float cmean[8];
float std[9];
+ float music_prob;
float Etracker;
float lowECount;
int E_count;
+ int last_music;
+ int last_transition;
int count;
+ float subframe_mem[3];
int analysis_offset;
+ /** Probability of having speech for time i to DETECT_SIZE-1 (and music before).
+ pspeech[0] is the probability that all frames in the window are speech. */
+ float pspeech[DETECT_SIZE];
+ /** Probability of having music for time i to DETECT_SIZE-1 (and speech before).
+ pmusic[0] is the probability that all frames in the window are music. */
+ float pmusic[DETECT_SIZE];
+ float speech_confidence;
+ float music_confidence;
+ int speech_confidence_count;
+ int music_confidence_count;
int write_pos;
int read_pos;
int read_subframe;
- float hp_ener_accum;
- int initialized;
- float rnn_state[MAX_NEURONS];
- opus_val32 downmix_state[3];
AnalysisInfo info[DETECT_SIZE];
} TonalityAnalysisState;
@@ -86,7 +86,7 @@ typedef struct {
* not be repeated every analysis step. No allocated memory is retained
* by the state struct, so no cleanup call is required.
*/
-void tonality_analysis_init(TonalityAnalysisState *analysis, opus_int32 Fs);
+void tonality_analysis_init(TonalityAnalysisState *analysis);
/** Reset a TonalityAnalysisState stuct.
*
diff --git a/thirdparty/opus/celt/_kiss_fft_guts.h b/thirdparty/opus/celt/_kiss_fft_guts.h
index 17392b3e90..5e3d58fd66 100644
--- a/thirdparty/opus/celt/_kiss_fft_guts.h
+++ b/thirdparty/opus/celt/_kiss_fft_guts.h
@@ -58,12 +58,12 @@
# define S_MUL(a,b) MULT16_32_Q15(b, a)
# define C_MUL(m,a,b) \
- do{ (m).r = SUB32_ovflw(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
- (m).i = ADD32_ovflw(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)); }while(0)
+ do{ (m).r = SUB32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
+ (m).i = ADD32(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)); }while(0)
# define C_MULC(m,a,b) \
- do{ (m).r = ADD32_ovflw(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
- (m).i = SUB32_ovflw(S_MUL((a).i,(b).r) , S_MUL((a).r,(b).i)); }while(0)
+ do{ (m).r = ADD32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \
+ (m).i = SUB32(S_MUL((a).i,(b).r) , S_MUL((a).r,(b).i)); }while(0)
# define C_MULBYSCALAR( c, s ) \
do{ (c).r = S_MUL( (c).r , s ) ;\
@@ -77,17 +77,17 @@
DIVSCALAR( (c).i , div); }while (0)
#define C_ADD( res, a,b)\
- do {(res).r=ADD32_ovflw((a).r,(b).r); (res).i=ADD32_ovflw((a).i,(b).i); \
+ do {(res).r=ADD32((a).r,(b).r); (res).i=ADD32((a).i,(b).i); \
}while(0)
#define C_SUB( res, a,b)\
- do {(res).r=SUB32_ovflw((a).r,(b).r); (res).i=SUB32_ovflw((a).i,(b).i); \
+ do {(res).r=SUB32((a).r,(b).r); (res).i=SUB32((a).i,(b).i); \
}while(0)
#define C_ADDTO( res , a)\
- do {(res).r = ADD32_ovflw((res).r, (a).r); (res).i = ADD32_ovflw((res).i,(a).i);\
+ do {(res).r = ADD32((res).r, (a).r); (res).i = ADD32((res).i,(a).i);\
}while(0)
#define C_SUBFROM( res , a)\
- do {(res).r = ADD32_ovflw((res).r,(a).r); (res).i = SUB32_ovflw((res).i,(a).i); \
+ do {(res).r = ADD32((res).r,(a).r); (res).i = SUB32((res).i,(a).i); \
}while(0)
#if defined(OPUS_ARM_INLINE_ASM)
diff --git a/thirdparty/opus/celt/arch.h b/thirdparty/opus/celt/arch.h
index 08b07db598..8ceab5fe10 100644
--- a/thirdparty/opus/celt/arch.h
+++ b/thirdparty/opus/celt/arch.h
@@ -46,50 +46,25 @@
# endif
# endif
-#if OPUS_GNUC_PREREQ(3, 0)
-#define opus_likely(x) (__builtin_expect(!!(x), 1))
-#define opus_unlikely(x) (__builtin_expect(!!(x), 0))
-#else
-#define opus_likely(x) (!!(x))
-#define opus_unlikely(x) (!!(x))
-#endif
-
#define CELT_SIG_SCALE 32768.f
-#define CELT_FATAL(str) celt_fatal(str, __FILE__, __LINE__);
-
-#if defined(ENABLE_ASSERTIONS) || defined(ENABLE_HARDENING)
-#ifdef __GNUC__
-__attribute__((noreturn))
-#endif
-void celt_fatal(const char *str, const char *file, int line);
-
-#if defined(CELT_C) && !defined(OVERRIDE_celt_fatal)
+#define celt_fatal(str) _celt_fatal(str, __FILE__, __LINE__);
+#ifdef ENABLE_ASSERTIONS
#include <stdio.h>
#include <stdlib.h>
#ifdef __GNUC__
__attribute__((noreturn))
#endif
-void celt_fatal(const char *str, const char *file, int line)
+static OPUS_INLINE void _celt_fatal(const char *str, const char *file, int line)
{
fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str);
abort();
}
-#endif
-
-#define celt_assert(cond) {if (!(cond)) {CELT_FATAL("assertion failed: " #cond);}}
-#define celt_assert2(cond, message) {if (!(cond)) {CELT_FATAL("assertion failed: " #cond "\n" message);}}
-#define MUST_SUCCEED(call) celt_assert((call) == OPUS_OK)
+#define celt_assert(cond) {if (!(cond)) {celt_fatal("assertion failed: " #cond);}}
+#define celt_assert2(cond, message) {if (!(cond)) {celt_fatal("assertion failed: " #cond "\n" message);}}
#else
#define celt_assert(cond)
#define celt_assert2(cond, message)
-#define MUST_SUCCEED(call) do {if((call) != OPUS_OK) {RESTORE_STACK; return OPUS_INTERNAL_ERROR;} } while (0)
-#endif
-
-#if defined(ENABLE_ASSERTIONS)
-#define celt_sig_assert(cond) {if (!(cond)) {CELT_FATAL("signal assertion failed: " #cond);}}
-#else
-#define celt_sig_assert(cond)
#endif
#define IMUL32(a,b) ((a)*(b))
@@ -118,20 +93,14 @@ void celt_fatal(const char *str, const char *file, int line)
typedef opus_int16 opus_val16;
typedef opus_int32 opus_val32;
-typedef opus_int64 opus_val64;
typedef opus_val32 celt_sig;
typedef opus_val16 celt_norm;
typedef opus_val32 celt_ener;
-#define celt_isnan(x) 0
-
#define Q15ONE 32767
#define SIG_SHIFT 12
-/* Safe saturation value for 32-bit signals. Should be less than
- 2^31*(1-0.85) to avoid blowing up on DC at deemphasis.*/
-#define SIG_SAT (300000000)
#define NORM_SCALING 16384
@@ -160,7 +129,7 @@ static OPUS_INLINE opus_int16 SAT16(opus_int32 x) {
#ifdef OPUS_ARM_PRESUME_AARCH64_NEON_INTR
#include "arm/fixed_arm64.h"
-#elif defined (OPUS_ARM_INLINE_EDSP)
+#elif OPUS_ARM_INLINE_EDSP
#include "arm/fixed_armv5e.h"
#elif defined (OPUS_ARM_INLINE_ASM)
#include "arm/fixed_armv4.h"
@@ -178,7 +147,6 @@ static OPUS_INLINE opus_int16 SAT16(opus_int32 x) {
typedef float opus_val16;
typedef float opus_val32;
-typedef float opus_val64;
typedef float celt_sig;
typedef float celt_norm;
@@ -218,7 +186,6 @@ static OPUS_INLINE int celt_isnan(float x)
#define NEG16(x) (-(x))
#define NEG32(x) (-(x))
-#define NEG32_ovflw(x) (-(x))
#define EXTRACT16(x) (x)
#define EXTEND32(x) (x)
#define SHR16(a,shift) (a)
@@ -235,7 +202,6 @@ static OPUS_INLINE int celt_isnan(float x)
#define SATURATE16(x) (x)
#define ROUND16(a,shift) (a)
-#define SROUND16(a,shift) (a)
#define HALF16(x) (.5f*(x))
#define HALF32(x) (.5f*(x))
@@ -243,8 +209,6 @@ static OPUS_INLINE int celt_isnan(float x)
#define SUB16(a,b) ((a)-(b))
#define ADD32(a,b) ((a)+(b))
#define SUB32(a,b) ((a)-(b))
-#define ADD32_ovflw(a,b) ((a)+(b))
-#define SUB32_ovflw(a,b) ((a)-(b))
#define MULT16_16_16(a,b) ((a)*(b))
#define MULT16_16(a,b) ((opus_val32)(a)*(opus_val32)(b))
#define MAC16_16(c,a,b) ((c)+(opus_val32)(a)*(opus_val32)(b))
@@ -279,9 +243,9 @@ static OPUS_INLINE int celt_isnan(float x)
#ifndef GLOBAL_STACK_SIZE
#ifdef FIXED_POINT
-#define GLOBAL_STACK_SIZE 120000
+#define GLOBAL_STACK_SIZE 100000
#else
-#define GLOBAL_STACK_SIZE 120000
+#define GLOBAL_STACK_SIZE 100000
#endif
#endif
diff --git a/thirdparty/opus/celt/arm/arm2gnu.pl b/thirdparty/opus/celt/arm/arm2gnu.pl
index a2895f7445..6c922ac819 100755
--- a/thirdparty/opus/celt/arm/arm2gnu.pl
+++ b/thirdparty/opus/celt/arm/arm2gnu.pl
@@ -164,11 +164,11 @@ while (<>) {
$prefix = "";
if ($proc)
{
- $prefix = $prefix.sprintf("\t.type\t%s, %%function", $proc) unless ($apple);
+ $prefix = $prefix.sprintf("\t.type\t%s, %%function; ",$proc) unless ($apple);
# Make sure we $prefix isn't empty here (for the $apple case).
# We handle mangling the label here, make sure it doesn't match
# the label handling below (if $prefix would be empty).
- $prefix = $prefix."; ";
+ $prefix = "; ";
push(@proc_stack, $proc);
s/^[A-Za-z_\.]\w+/$symprefix$&:/;
}
diff --git a/thirdparty/opus/celt/arm/arm_celt_map.c b/thirdparty/opus/celt/arm/arm_celt_map.c
index ca988b66f5..4d4d069a86 100644
--- a/thirdparty/opus/celt/arm/arm_celt_map.c
+++ b/thirdparty/opus/celt/arm/arm_celt_map.c
@@ -35,29 +35,12 @@
#if defined(OPUS_HAVE_RTCD)
-# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)
-opus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x, const opus_val16 *y, int N) = {
- celt_inner_prod_c, /* ARMv4 */
- celt_inner_prod_c, /* EDSP */
- celt_inner_prod_c, /* Media */
- celt_inner_prod_neon /* NEON */
-};
-
-void (*const DUAL_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
- int N, opus_val32 *xy1, opus_val32 *xy2) = {
- dual_inner_prod_c, /* ARMv4 */
- dual_inner_prod_c, /* EDSP */
- dual_inner_prod_c, /* Media */
- dual_inner_prod_neon /* NEON */
-};
-# endif
-
# if defined(FIXED_POINT)
# if ((defined(OPUS_ARM_MAY_HAVE_NEON) && !defined(OPUS_ARM_PRESUME_NEON)) || \
(defined(OPUS_ARM_MAY_HAVE_MEDIA) && !defined(OPUS_ARM_PRESUME_MEDIA)) || \
(defined(OPUS_ARM_MAY_HAVE_EDSP) && !defined(OPUS_ARM_PRESUME_EDSP)))
opus_val32 (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
- const opus_val16 *, opus_val32 *, int, int, int) = {
+ const opus_val16 *, opus_val32 *, int , int) = {
celt_pitch_xcorr_c, /* ARMv4 */
MAY_HAVE_EDSP(celt_pitch_xcorr), /* EDSP */
MAY_HAVE_MEDIA(celt_pitch_xcorr), /* Media */
@@ -68,7 +51,7 @@ opus_val32 (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
# else /* !FIXED_POINT */
# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)
void (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
- const opus_val16 *, opus_val32 *, int, int, int) = {
+ const opus_val16 *, opus_val32 *, int, int) = {
celt_pitch_xcorr_c, /* ARMv4 */
celt_pitch_xcorr_c, /* EDSP */
celt_pitch_xcorr_c, /* Media */
diff --git a/thirdparty/opus/celt/arm/celt_fft_ne10.c b/thirdparty/opus/celt/arm/celt_ne10_fft.c
index ea5fd7808b..42d96a7117 100644
--- a/thirdparty/opus/celt/arm/celt_fft_ne10.c
+++ b/thirdparty/opus/celt/arm/celt_ne10_fft.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2015 Xiph.Org Foundation
Written by Viswanath Puttagunta */
/**
- @file celt_fft_ne10.c
+ @file celt_ne10_fft.c
@brief ARM Neon optimizations for fft using NE10 library
*/
@@ -36,6 +36,7 @@
#endif
#endif
+#include <NE10_init.h>
#include <NE10_dsp.h>
#include "os_support.h"
#include "kiss_fft.h"
diff --git a/thirdparty/opus/celt/arm/celt_mdct_ne10.c b/thirdparty/opus/celt/arm/celt_ne10_mdct.c
index 3531d02d10..293c3efd7a 100644
--- a/thirdparty/opus/celt/arm/celt_mdct_ne10.c
+++ b/thirdparty/opus/celt/arm/celt_ne10_mdct.c
@@ -1,7 +1,7 @@
/* Copyright (c) 2015 Xiph.Org Foundation
Written by Viswanath Puttagunta */
/**
- @file celt_mdct_ne10.c
+ @file celt_ne10_mdct.c
@brief ARM Neon optimizations for mdct using NE10 library
*/
diff --git a/thirdparty/opus/celt/arm/celt_neon_intr.c b/thirdparty/opus/celt/arm/celt_neon_intr.c
index effda769d0..47bbe3dc22 100644
--- a/thirdparty/opus/celt/arm/celt_neon_intr.c
+++ b/thirdparty/opus/celt/arm/celt_neon_intr.c
@@ -191,21 +191,121 @@ static void xcorr_kernel_neon_float(const float32_t *x, const float32_t *y,
vst1q_f32(sum, SUMM);
}
+/*
+ * Function: xcorr_kernel_neon_float_process1
+ * ---------------------------------
+ * Computes single correlation values and stores in *sum
+ */
+static void xcorr_kernel_neon_float_process1(const float32_t *x,
+ const float32_t *y, float32_t *sum, int len) {
+ float32x4_t XX[4];
+ float32x4_t YY[4];
+ float32x2_t XX_2;
+ float32x2_t YY_2;
+ float32x4_t SUMM;
+ float32x2_t SUMM_2[2];
+ const float32_t *xi = x;
+ const float32_t *yi = y;
+
+ SUMM = vdupq_n_f32(0);
+
+ /* Work on 16 values per iteration */
+ while (len >= 16) {
+ XX[0] = vld1q_f32(xi);
+ xi += 4;
+ XX[1] = vld1q_f32(xi);
+ xi += 4;
+ XX[2] = vld1q_f32(xi);
+ xi += 4;
+ XX[3] = vld1q_f32(xi);
+ xi += 4;
+
+ YY[0] = vld1q_f32(yi);
+ yi += 4;
+ YY[1] = vld1q_f32(yi);
+ yi += 4;
+ YY[2] = vld1q_f32(yi);
+ yi += 4;
+ YY[3] = vld1q_f32(yi);
+ yi += 4;
+
+ SUMM = vmlaq_f32(SUMM, YY[0], XX[0]);
+ SUMM = vmlaq_f32(SUMM, YY[1], XX[1]);
+ SUMM = vmlaq_f32(SUMM, YY[2], XX[2]);
+ SUMM = vmlaq_f32(SUMM, YY[3], XX[3]);
+ len -= 16;
+ }
+
+ /* Work on 8 values */
+ if (len >= 8) {
+ XX[0] = vld1q_f32(xi);
+ xi += 4;
+ XX[1] = vld1q_f32(xi);
+ xi += 4;
+
+ YY[0] = vld1q_f32(yi);
+ yi += 4;
+ YY[1] = vld1q_f32(yi);
+ yi += 4;
+
+ SUMM = vmlaq_f32(SUMM, YY[0], XX[0]);
+ SUMM = vmlaq_f32(SUMM, YY[1], XX[1]);
+ len -= 8;
+ }
+
+ /* Work on 4 values */
+ if (len >= 4) {
+ XX[0] = vld1q_f32(xi);
+ xi += 4;
+ YY[0] = vld1q_f32(yi);
+ yi += 4;
+ SUMM = vmlaq_f32(SUMM, YY[0], XX[0]);
+ len -= 4;
+ }
+
+ /* Start accumulating results */
+ SUMM_2[0] = vget_low_f32(SUMM);
+ if (len >= 2) {
+ /* While at it, consume 2 more values if available */
+ XX_2 = vld1_f32(xi);
+ xi += 2;
+ YY_2 = vld1_f32(yi);
+ yi += 2;
+ SUMM_2[0] = vmla_f32(SUMM_2[0], YY_2, XX_2);
+ len -= 2;
+ }
+ SUMM_2[1] = vget_high_f32(SUMM);
+ SUMM_2[0] = vadd_f32(SUMM_2[0], SUMM_2[1]);
+ SUMM_2[0] = vpadd_f32(SUMM_2[0], SUMM_2[0]);
+ /* Ok, now we have result accumulated in SUMM_2[0].0 */
+
+ if (len > 0) {
+ /* Case when you have one value left */
+ XX_2 = vld1_dup_f32(xi);
+ YY_2 = vld1_dup_f32(yi);
+ SUMM_2[0] = vmla_f32(SUMM_2[0], XX_2, YY_2);
+ }
+
+ vst1_lane_f32(sum, SUMM_2[0], 0);
+}
+
void celt_pitch_xcorr_float_neon(const opus_val16 *_x, const opus_val16 *_y,
- opus_val32 *xcorr, int len, int max_pitch, int arch) {
+ opus_val32 *xcorr, int len, int max_pitch) {
int i;
- (void)arch;
celt_assert(max_pitch > 0);
- celt_sig_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0);
+ celt_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0);
for (i = 0; i < (max_pitch-3); i += 4) {
xcorr_kernel_neon_float((const float32_t *)_x, (const float32_t *)_y+i,
(float32_t *)xcorr+i, len);
}
- /* In case max_pitch isn't a multiple of 4, do non-unrolled version. */
+ /* In case max_pitch isn't multiple of 4
+ * compute single correlation value per iteration
+ */
for (; i < max_pitch; i++) {
- xcorr[i] = celt_inner_prod_neon(_x, _y+i, len);
+ xcorr_kernel_neon_float_process1((const float32_t *)_x,
+ (const float32_t *)_y+i, (float32_t *)xcorr+i, len);
}
}
#endif
diff --git a/thirdparty/opus/celt/arm/celt_pitch_xcorr_arm-gnu.S b/thirdparty/opus/celt/arm/celt_pitch_xcorr_arm-gnu.S
index 10668e54a5..5b2ee55a10 100644
--- a/thirdparty/opus/celt/arm/celt_pitch_xcorr_arm-gnu.S
+++ b/thirdparty/opus/celt/arm/celt_pitch_xcorr_arm-gnu.S
@@ -44,7 +44,7 @@
.if OPUS_ARM_MAY_HAVE_NEON
@ Compute sum[k]=sum(x[j]*y[j+k],j=0...len-1), k=0...3
- .type xcorr_kernel_neon, %function; xcorr_kernel_neon: @ PROC
+; xcorr_kernel_neon: @ PROC
xcorr_kernel_neon_start:
@ input:
@ r3 = int len
@@ -156,8 +156,8 @@ xcorr_kernel_neon_process1:
.size xcorr_kernel_neon, .-xcorr_kernel_neon @ ENDP
@ opus_val32 celt_pitch_xcorr_neon(opus_val16 *_x, opus_val16 *_y,
-@ opus_val32 *xcorr, int len, int max_pitch, int arch)
- .type celt_pitch_xcorr_neon, %function; celt_pitch_xcorr_neon: @ PROC
+@ opus_val32 *xcorr, int len, int max_pitch)
+; celt_pitch_xcorr_neon: @ PROC
@ input:
@ r0 = opus_val16 *_x
@ r1 = opus_val16 *_y
@@ -171,8 +171,6 @@ xcorr_kernel_neon_process1:
@ r6 = int max_pitch
@ r12 = int j
@ q15 = int maxcorr[4] (q15 is not used by xcorr_kernel_neon())
- @ ignored:
- @ int arch
STMFD sp!, {r4-r6, lr}
LDR r6, [sp, #16]
VMOV.S32 q15, #1
@@ -262,7 +260,7 @@ celt_pitch_xcorr_neon_done:
@ This will get used on ARMv7 devices without NEON, so it has been optimized
@ to take advantage of dual-issuing where possible.
- .type xcorr_kernel_edsp, %function; xcorr_kernel_edsp: @ PROC
+; xcorr_kernel_edsp: @ PROC
xcorr_kernel_edsp_start:
@ input:
@ r3 = int len
@@ -346,7 +344,7 @@ xcorr_kernel_edsp_done:
LDMFD sp!, {r2,r4,r5,pc}
.size xcorr_kernel_edsp, .-xcorr_kernel_edsp @ ENDP
- .type celt_pitch_xcorr_edsp, %function; celt_pitch_xcorr_edsp: @ PROC
+; celt_pitch_xcorr_edsp: @ PROC
@ input:
@ r0 = opus_val16 *_x (must be 32-bit aligned)
@ r1 = opus_val16 *_y (only needs to be 16-bit aligned)
@@ -363,8 +361,6 @@ xcorr_kernel_edsp_done:
@ r9 = opus_val32 sum3
@ r1 = int max_pitch
@ r12 = int j
- @ ignored:
- @ int arch
STMFD sp!, {r4-r11, lr}
MOV r5, r1
LDR r1, [sp, #36]
diff --git a/thirdparty/opus/celt/arm/celt_pitch_xcorr_arm.s b/thirdparty/opus/celt/arm/celt_pitch_xcorr_arm.s
index 6e873afc37..f96e0a88bb 100644
--- a/thirdparty/opus/celt/arm/celt_pitch_xcorr_arm.s
+++ b/thirdparty/opus/celt/arm/celt_pitch_xcorr_arm.s
@@ -153,7 +153,7 @@ xcorr_kernel_neon_process1
ENDP
; opus_val32 celt_pitch_xcorr_neon(opus_val16 *_x, opus_val16 *_y,
-; opus_val32 *xcorr, int len, int max_pitch, int arch)
+; opus_val32 *xcorr, int len, int max_pitch)
celt_pitch_xcorr_neon PROC
; input:
; r0 = opus_val16 *_x
@@ -168,8 +168,6 @@ celt_pitch_xcorr_neon PROC
; r6 = int max_pitch
; r12 = int j
; q15 = int maxcorr[4] (q15 is not used by xcorr_kernel_neon())
- ; ignored:
- ; int arch
STMFD sp!, {r4-r6, lr}
LDR r6, [sp, #16]
VMOV.S32 q15, #1
@@ -360,8 +358,6 @@ celt_pitch_xcorr_edsp PROC
; r9 = opus_val32 sum3
; r1 = int max_pitch
; r12 = int j
- ; ignored:
- ; int arch
STMFD sp!, {r4-r11, lr}
MOV r5, r1
LDR r1, [sp, #36]
diff --git a/thirdparty/opus/celt/arm/fft_arm.h b/thirdparty/opus/celt/arm/fft_arm.h
index 0b78175f3a..0cb55d8e22 100644
--- a/thirdparty/opus/celt/arm/fft_arm.h
+++ b/thirdparty/opus/celt/arm/fft_arm.h
@@ -34,6 +34,7 @@
#if !defined(FFT_ARM_H)
#define FFT_ARM_H
+#include "config.h"
#include "kiss_fft.h"
#if defined(HAVE_ARM_NE10)
diff --git a/thirdparty/opus/celt/arm/fixed_armv4.h b/thirdparty/opus/celt/arm/fixed_armv4.h
index d84888a772..efb3b1896a 100644
--- a/thirdparty/opus/celt/arm/fixed_armv4.h
+++ b/thirdparty/opus/celt/arm/fixed_armv4.h
@@ -37,7 +37,7 @@ static OPUS_INLINE opus_val32 MULT16_32_Q16_armv4(opus_val16 a, opus_val32 b)
"#MULT16_32_Q16\n\t"
"smull %0, %1, %2, %3\n\t"
: "=&r"(rd_lo), "=&r"(rd_hi)
- : "%r"(b),"r"(SHL32(a,16))
+ : "%r"(b),"r"(a<<16)
);
return rd_hi;
}
@@ -54,10 +54,10 @@ static OPUS_INLINE opus_val32 MULT16_32_Q15_armv4(opus_val16 a, opus_val32 b)
"#MULT16_32_Q15\n\t"
"smull %0, %1, %2, %3\n\t"
: "=&r"(rd_lo), "=&r"(rd_hi)
- : "%r"(b), "r"(SHL32(a,16))
+ : "%r"(b), "r"(a<<16)
);
/*We intentionally don't OR in the high bit of rd_lo for speed.*/
- return SHL32(rd_hi,1);
+ return rd_hi<<1;
}
#define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv4(a, b))
diff --git a/thirdparty/opus/celt/arm/fixed_armv5e.h b/thirdparty/opus/celt/arm/fixed_armv5e.h
index 6bf73cbace..36a6321101 100644
--- a/thirdparty/opus/celt/arm/fixed_armv5e.h
+++ b/thirdparty/opus/celt/arm/fixed_armv5e.h
@@ -59,7 +59,7 @@ static OPUS_INLINE opus_val32 MULT16_32_Q15_armv5e(opus_val16 a, opus_val32 b)
: "=r"(res)
: "r"(b), "r"(a)
);
- return SHL32(res,1);
+ return res<<1;
}
#define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv5e(a, b))
@@ -76,7 +76,7 @@ static OPUS_INLINE opus_val32 MAC16_32_Q15_armv5e(opus_val32 c, opus_val16 a,
"#MAC16_32_Q15\n\t"
"smlawb %0, %1, %2, %3;\n"
: "=r"(res)
- : "r"(SHL32(b,1)), "r"(a), "r"(c)
+ : "r"(b<<1), "r"(a), "r"(c)
);
return res;
}
diff --git a/thirdparty/opus/celt/arm/mdct_arm.h b/thirdparty/opus/celt/arm/mdct_arm.h
index 14200bac4b..49cbb44576 100644
--- a/thirdparty/opus/celt/arm/mdct_arm.h
+++ b/thirdparty/opus/celt/arm/mdct_arm.h
@@ -33,6 +33,7 @@
#if !defined(MDCT_ARM_H)
#define MDCT_ARM_H
+#include "config.h"
#include "mdct.h"
#if defined(HAVE_ARM_NE10)
diff --git a/thirdparty/opus/celt/arm/pitch_arm.h b/thirdparty/opus/celt/arm/pitch_arm.h
index bed8b04eac..14331169ee 100644
--- a/thirdparty/opus/celt/arm/pitch_arm.h
+++ b/thirdparty/opus/celt/arm/pitch_arm.h
@@ -30,47 +30,11 @@
# include "armcpu.h"
-# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
-opus_val32 celt_inner_prod_neon(const opus_val16 *x, const opus_val16 *y, int N);
-void dual_inner_prod_neon(const opus_val16 *x, const opus_val16 *y01,
- const opus_val16 *y02, int N, opus_val32 *xy1, opus_val32 *xy2);
-
-# if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON)
-# define OVERRIDE_CELT_INNER_PROD (1)
-# define OVERRIDE_DUAL_INNER_PROD (1)
-# define celt_inner_prod(x, y, N, arch) ((void)(arch), PRESUME_NEON(celt_inner_prod)(x, y, N))
-# define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) ((void)(arch), PRESUME_NEON(dual_inner_prod)(x, y01, y02, N, xy1, xy2))
-# endif
-# endif
-
-# if !defined(OVERRIDE_CELT_INNER_PROD)
-# if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
-extern opus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x, const opus_val16 *y, int N);
-# define OVERRIDE_CELT_INNER_PROD (1)
-# define celt_inner_prod(x, y, N, arch) ((*CELT_INNER_PROD_IMPL[(arch)&OPUS_ARCHMASK])(x, y, N))
-# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
-# define OVERRIDE_CELT_INNER_PROD (1)
-# define celt_inner_prod(x, y, N, arch) ((void)(arch), celt_inner_prod_neon(x, y, N))
-# endif
-# endif
-
-# if !defined(OVERRIDE_DUAL_INNER_PROD)
-# if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
-extern void (*const DUAL_INNER_PROD_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *x,
- const opus_val16 *y01, const opus_val16 *y02, int N, opus_val32 *xy1, opus_val32 *xy2);
-# define OVERRIDE_DUAL_INNER_PROD (1)
-# define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) ((*DUAL_INNER_PROD_IMPL[(arch)&OPUS_ARCHMASK])(x, y01, y02, N, xy1, xy2))
-# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
-# define OVERRIDE_DUAL_INNER_PROD (1)
-# define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) ((void)(arch), dual_inner_prod_neon(x, y01, y02, N, xy1, xy2))
-# endif
-# endif
-
# if defined(FIXED_POINT)
# if defined(OPUS_ARM_MAY_HAVE_NEON)
opus_val32 celt_pitch_xcorr_neon(const opus_val16 *_x, const opus_val16 *_y,
- opus_val32 *xcorr, int len, int max_pitch, int arch);
+ opus_val32 *xcorr, int len, int max_pitch);
# endif
# if defined(OPUS_ARM_MAY_HAVE_MEDIA)
@@ -79,7 +43,7 @@ opus_val32 celt_pitch_xcorr_neon(const opus_val16 *_x, const opus_val16 *_y,
# if defined(OPUS_ARM_MAY_HAVE_EDSP)
opus_val32 celt_pitch_xcorr_edsp(const opus_val16 *_x, const opus_val16 *_y,
- opus_val32 *xcorr, int len, int max_pitch, int arch);
+ opus_val32 *xcorr, int len, int max_pitch);
# endif
# if defined(OPUS_HAVE_RTCD) && \
@@ -88,17 +52,18 @@ opus_val32 celt_pitch_xcorr_edsp(const opus_val16 *_x, const opus_val16 *_y,
(defined(OPUS_ARM_MAY_HAVE_EDSP) && !defined(OPUS_ARM_PRESUME_EDSP)))
extern opus_val32
(*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
- const opus_val16 *, opus_val32 *, int, int, int);
+ const opus_val16 *, opus_val32 *, int, int);
# define OVERRIDE_PITCH_XCORR (1)
# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
((*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])(_x, _y, \
- xcorr, len, max_pitch, arch))
+ xcorr, len, max_pitch))
# elif defined(OPUS_ARM_PRESUME_EDSP) || \
defined(OPUS_ARM_PRESUME_MEDIA) || \
defined(OPUS_ARM_PRESUME_NEON)
# define OVERRIDE_PITCH_XCORR (1)
-# define celt_pitch_xcorr (PRESUME_NEON(celt_pitch_xcorr))
+# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
+ ((void)(arch),PRESUME_NEON(celt_pitch_xcorr)(_x, _y, xcorr, len, max_pitch))
# endif
@@ -134,24 +99,25 @@ extern void (*const XCORR_KERNEL_IMPL[OPUS_ARCHMASK + 1])(
/* Float case */
#if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
void celt_pitch_xcorr_float_neon(const opus_val16 *_x, const opus_val16 *_y,
- opus_val32 *xcorr, int len, int max_pitch, int arch);
+ opus_val32 *xcorr, int len, int max_pitch);
#endif
# if defined(OPUS_HAVE_RTCD) && \
(defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
extern void
(*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
- const opus_val16 *, opus_val32 *, int, int, int);
+ const opus_val16 *, opus_val32 *, int, int);
# define OVERRIDE_PITCH_XCORR (1)
# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
((*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])(_x, _y, \
- xcorr, len, max_pitch, arch))
+ xcorr, len, max_pitch))
# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
# define OVERRIDE_PITCH_XCORR (1)
-# define celt_pitch_xcorr celt_pitch_xcorr_float_neon
+# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
+ ((void)(arch),celt_pitch_xcorr_float_neon(_x, _y, xcorr, len, max_pitch))
# endif
diff --git a/thirdparty/opus/celt/arm/pitch_neon_intr.c b/thirdparty/opus/celt/arm/pitch_neon_intr.c
deleted file mode 100644
index 1ac38c433a..0000000000
--- a/thirdparty/opus/celt/arm/pitch_neon_intr.c
+++ /dev/null
@@ -1,290 +0,0 @@
-/***********************************************************************
-Copyright (c) 2017 Google Inc.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-- Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-- Neither the name of Internet Society, IETF or IETF Trust, nor the
-names of specific contributors, may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <arm_neon.h>
-#include "pitch.h"
-
-#ifdef FIXED_POINT
-
-opus_val32 celt_inner_prod_neon(const opus_val16 *x, const opus_val16 *y, int N)
-{
- int i;
- opus_val32 xy;
- int16x8_t x_s16x8, y_s16x8;
- int32x4_t xy_s32x4 = vdupq_n_s32(0);
- int64x2_t xy_s64x2;
- int64x1_t xy_s64x1;
-
- for (i = 0; i < N - 7; i += 8) {
- x_s16x8 = vld1q_s16(&x[i]);
- y_s16x8 = vld1q_s16(&y[i]);
- xy_s32x4 = vmlal_s16(xy_s32x4, vget_low_s16 (x_s16x8), vget_low_s16 (y_s16x8));
- xy_s32x4 = vmlal_s16(xy_s32x4, vget_high_s16(x_s16x8), vget_high_s16(y_s16x8));
- }
-
- if (N - i >= 4) {
- const int16x4_t x_s16x4 = vld1_s16(&x[i]);
- const int16x4_t y_s16x4 = vld1_s16(&y[i]);
- xy_s32x4 = vmlal_s16(xy_s32x4, x_s16x4, y_s16x4);
- i += 4;
- }
-
- xy_s64x2 = vpaddlq_s32(xy_s32x4);
- xy_s64x1 = vadd_s64(vget_low_s64(xy_s64x2), vget_high_s64(xy_s64x2));
- xy = vget_lane_s32(vreinterpret_s32_s64(xy_s64x1), 0);
-
- for (; i < N; i++) {
- xy = MAC16_16(xy, x[i], y[i]);
- }
-
-#ifdef OPUS_CHECK_ASM
- celt_assert(celt_inner_prod_c(x, y, N) == xy);
-#endif
-
- return xy;
-}
-
-void dual_inner_prod_neon(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
- int N, opus_val32 *xy1, opus_val32 *xy2)
-{
- int i;
- opus_val32 xy01, xy02;
- int16x8_t x_s16x8, y01_s16x8, y02_s16x8;
- int32x4_t xy01_s32x4 = vdupq_n_s32(0);
- int32x4_t xy02_s32x4 = vdupq_n_s32(0);
- int64x2_t xy01_s64x2, xy02_s64x2;
- int64x1_t xy01_s64x1, xy02_s64x1;
-
- for (i = 0; i < N - 7; i += 8) {
- x_s16x8 = vld1q_s16(&x[i]);
- y01_s16x8 = vld1q_s16(&y01[i]);
- y02_s16x8 = vld1q_s16(&y02[i]);
- xy01_s32x4 = vmlal_s16(xy01_s32x4, vget_low_s16 (x_s16x8), vget_low_s16 (y01_s16x8));
- xy02_s32x4 = vmlal_s16(xy02_s32x4, vget_low_s16 (x_s16x8), vget_low_s16 (y02_s16x8));
- xy01_s32x4 = vmlal_s16(xy01_s32x4, vget_high_s16(x_s16x8), vget_high_s16(y01_s16x8));
- xy02_s32x4 = vmlal_s16(xy02_s32x4, vget_high_s16(x_s16x8), vget_high_s16(y02_s16x8));
- }
-
- if (N - i >= 4) {
- const int16x4_t x_s16x4 = vld1_s16(&x[i]);
- const int16x4_t y01_s16x4 = vld1_s16(&y01[i]);
- const int16x4_t y02_s16x4 = vld1_s16(&y02[i]);
- xy01_s32x4 = vmlal_s16(xy01_s32x4, x_s16x4, y01_s16x4);
- xy02_s32x4 = vmlal_s16(xy02_s32x4, x_s16x4, y02_s16x4);
- i += 4;
- }
-
- xy01_s64x2 = vpaddlq_s32(xy01_s32x4);
- xy02_s64x2 = vpaddlq_s32(xy02_s32x4);
- xy01_s64x1 = vadd_s64(vget_low_s64(xy01_s64x2), vget_high_s64(xy01_s64x2));
- xy02_s64x1 = vadd_s64(vget_low_s64(xy02_s64x2), vget_high_s64(xy02_s64x2));
- xy01 = vget_lane_s32(vreinterpret_s32_s64(xy01_s64x1), 0);
- xy02 = vget_lane_s32(vreinterpret_s32_s64(xy02_s64x1), 0);
-
- for (; i < N; i++) {
- xy01 = MAC16_16(xy01, x[i], y01[i]);
- xy02 = MAC16_16(xy02, x[i], y02[i]);
- }
- *xy1 = xy01;
- *xy2 = xy02;
-
-#ifdef OPUS_CHECK_ASM
- {
- opus_val32 xy1_c, xy2_c;
- dual_inner_prod_c(x, y01, y02, N, &xy1_c, &xy2_c);
- celt_assert(xy1_c == *xy1);
- celt_assert(xy2_c == *xy2);
- }
-#endif
-}
-
-#else /* !FIXED_POINT */
-
-/* ========================================================================== */
-
-#ifdef OPUS_CHECK_ASM
-
-/* This part of code simulates floating-point NEON operations. */
-
-/* celt_inner_prod_neon_float_c_simulation() simulates the floating-point */
-/* operations of celt_inner_prod_neon(), and both functions should have bit */
-/* exact output. */
-static opus_val32 celt_inner_prod_neon_float_c_simulation(const opus_val16 *x, const opus_val16 *y, int N)
-{
- int i;
- opus_val32 xy, xy0 = 0, xy1 = 0, xy2 = 0, xy3 = 0;
- for (i = 0; i < N - 3; i += 4) {
- xy0 = MAC16_16(xy0, x[i + 0], y[i + 0]);
- xy1 = MAC16_16(xy1, x[i + 1], y[i + 1]);
- xy2 = MAC16_16(xy2, x[i + 2], y[i + 2]);
- xy3 = MAC16_16(xy3, x[i + 3], y[i + 3]);
- }
- xy0 += xy2;
- xy1 += xy3;
- xy = xy0 + xy1;
- for (; i < N; i++) {
- xy = MAC16_16(xy, x[i], y[i]);
- }
- return xy;
-}
-
-/* dual_inner_prod_neon_float_c_simulation() simulates the floating-point */
-/* operations of dual_inner_prod_neon(), and both functions should have bit */
-/* exact output. */
-static void dual_inner_prod_neon_float_c_simulation(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
- int N, opus_val32 *xy1, opus_val32 *xy2)
-{
- int i;
- 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;
- for (i = 0; i < N - 3; i += 4) {
- xy01_0 = MAC16_16(xy01_0, x[i + 0], y01[i + 0]);
- xy01_1 = MAC16_16(xy01_1, x[i + 1], y01[i + 1]);
- xy01_2 = MAC16_16(xy01_2, x[i + 2], y01[i + 2]);
- xy01_3 = MAC16_16(xy01_3, x[i + 3], y01[i + 3]);
- xy02_0 = MAC16_16(xy02_0, x[i + 0], y02[i + 0]);
- xy02_1 = MAC16_16(xy02_1, x[i + 1], y02[i + 1]);
- xy02_2 = MAC16_16(xy02_2, x[i + 2], y02[i + 2]);
- xy02_3 = MAC16_16(xy02_3, x[i + 3], y02[i + 3]);
- }
- xy01_0 += xy01_2;
- xy02_0 += xy02_2;
- xy01_1 += xy01_3;
- xy02_1 += xy02_3;
- xy01 = xy01_0 + xy01_1;
- xy02 = xy02_0 + xy02_1;
- for (; i < N; i++) {
- xy01 = MAC16_16(xy01, x[i], y01[i]);
- xy02 = MAC16_16(xy02, x[i], y02[i]);
- }
- *xy1 = xy01;
- *xy2 = xy02;
-}
-
-#endif /* OPUS_CHECK_ASM */
-
-/* ========================================================================== */
-
-opus_val32 celt_inner_prod_neon(const opus_val16 *x, const opus_val16 *y, int N)
-{
- int i;
- opus_val32 xy;
- float32x4_t xy_f32x4 = vdupq_n_f32(0);
- float32x2_t xy_f32x2;
-
- for (i = 0; i < N - 7; i += 8) {
- float32x4_t x_f32x4, y_f32x4;
- x_f32x4 = vld1q_f32(&x[i]);
- y_f32x4 = vld1q_f32(&y[i]);
- xy_f32x4 = vmlaq_f32(xy_f32x4, x_f32x4, y_f32x4);
- x_f32x4 = vld1q_f32(&x[i + 4]);
- y_f32x4 = vld1q_f32(&y[i + 4]);
- xy_f32x4 = vmlaq_f32(xy_f32x4, x_f32x4, y_f32x4);
- }
-
- if (N - i >= 4) {
- const float32x4_t x_f32x4 = vld1q_f32(&x[i]);
- const float32x4_t y_f32x4 = vld1q_f32(&y[i]);
- xy_f32x4 = vmlaq_f32(xy_f32x4, x_f32x4, y_f32x4);
- i += 4;
- }
-
- xy_f32x2 = vadd_f32(vget_low_f32(xy_f32x4), vget_high_f32(xy_f32x4));
- xy_f32x2 = vpadd_f32(xy_f32x2, xy_f32x2);
- xy = vget_lane_f32(xy_f32x2, 0);
-
- for (; i < N; i++) {
- xy = MAC16_16(xy, x[i], y[i]);
- }
-
-#ifdef OPUS_CHECK_ASM
- celt_assert(ABS32(celt_inner_prod_neon_float_c_simulation(x, y, N) - xy) <= VERY_SMALL);
-#endif
-
- return xy;
-}
-
-void dual_inner_prod_neon(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02,
- int N, opus_val32 *xy1, opus_val32 *xy2)
-{
- int i;
- opus_val32 xy01, xy02;
- float32x4_t xy01_f32x4 = vdupq_n_f32(0);
- float32x4_t xy02_f32x4 = vdupq_n_f32(0);
- float32x2_t xy01_f32x2, xy02_f32x2;
-
- for (i = 0; i < N - 7; i += 8) {
- float32x4_t x_f32x4, y01_f32x4, y02_f32x4;
- x_f32x4 = vld1q_f32(&x[i]);
- y01_f32x4 = vld1q_f32(&y01[i]);
- y02_f32x4 = vld1q_f32(&y02[i]);
- xy01_f32x4 = vmlaq_f32(xy01_f32x4, x_f32x4, y01_f32x4);
- xy02_f32x4 = vmlaq_f32(xy02_f32x4, x_f32x4, y02_f32x4);
- x_f32x4 = vld1q_f32(&x[i + 4]);
- y01_f32x4 = vld1q_f32(&y01[i + 4]);
- y02_f32x4 = vld1q_f32(&y02[i + 4]);
- xy01_f32x4 = vmlaq_f32(xy01_f32x4, x_f32x4, y01_f32x4);
- xy02_f32x4 = vmlaq_f32(xy02_f32x4, x_f32x4, y02_f32x4);
- }
-
- if (N - i >= 4) {
- const float32x4_t x_f32x4 = vld1q_f32(&x[i]);
- const float32x4_t y01_f32x4 = vld1q_f32(&y01[i]);
- const float32x4_t y02_f32x4 = vld1q_f32(&y02[i]);
- xy01_f32x4 = vmlaq_f32(xy01_f32x4, x_f32x4, y01_f32x4);
- xy02_f32x4 = vmlaq_f32(xy02_f32x4, x_f32x4, y02_f32x4);
- i += 4;
- }
-
- xy01_f32x2 = vadd_f32(vget_low_f32(xy01_f32x4), vget_high_f32(xy01_f32x4));
- xy02_f32x2 = vadd_f32(vget_low_f32(xy02_f32x4), vget_high_f32(xy02_f32x4));
- xy01_f32x2 = vpadd_f32(xy01_f32x2, xy01_f32x2);
- xy02_f32x2 = vpadd_f32(xy02_f32x2, xy02_f32x2);
- xy01 = vget_lane_f32(xy01_f32x2, 0);
- xy02 = vget_lane_f32(xy02_f32x2, 0);
-
- for (; i < N; i++) {
- xy01 = MAC16_16(xy01, x[i], y01[i]);
- xy02 = MAC16_16(xy02, x[i], y02[i]);
- }
- *xy1 = xy01;
- *xy2 = xy02;
-
-#ifdef OPUS_CHECK_ASM
- {
- opus_val32 xy1_c, xy2_c;
- dual_inner_prod_neon_float_c_simulation(x, y01, y02, N, &xy1_c, &xy2_c);
- celt_assert(ABS32(xy1_c - *xy1) <= VERY_SMALL);
- celt_assert(ABS32(xy2_c - *xy2) <= VERY_SMALL);
- }
-#endif
-}
-
-#endif /* FIXED_POINT */
diff --git a/thirdparty/opus/celt/bands.c b/thirdparty/opus/celt/bands.c
index 2702963c37..87eaa6c031 100644
--- a/thirdparty/opus/celt/bands.c
+++ b/thirdparty/opus/celt/bands.c
@@ -65,19 +65,19 @@ opus_uint32 celt_lcg_rand(opus_uint32 seed)
/* This is a cos() approximation designed to be bit-exact on any platform. Bit exactness
with this approximation is important because it has an impact on the bit allocation */
-opus_int16 bitexact_cos(opus_int16 x)
+static opus_int16 bitexact_cos(opus_int16 x)
{
opus_int32 tmp;
opus_int16 x2;
tmp = (4096+((opus_int32)(x)*(x)))>>13;
- celt_sig_assert(tmp<=32767);
+ celt_assert(tmp<=32767);
x2 = tmp;
x2 = (32767-x2) + FRAC_MUL16(x2, (-7651 + FRAC_MUL16(x2, (8277 + FRAC_MUL16(-626, x2)))));
- celt_sig_assert(x2<=32766);
+ celt_assert(x2<=32766);
return 1+x2;
}
-int bitexact_log2tan(int isin,int icos)
+static int bitexact_log2tan(int isin,int icos)
{
int lc;
int ls;
@@ -92,11 +92,10 @@ int bitexact_log2tan(int isin,int icos)
#ifdef FIXED_POINT
/* Compute the amplitude (sqrt energy) in each of the bands */
-void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM, int arch)
+void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM)
{
int i, c, N;
const opus_int16 *eBands = m->eBands;
- (void)arch;
N = m->shortMdctSize<<LM;
c=0; do {
for (i=0;i<end;i++)
@@ -156,7 +155,7 @@ void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, cel
#else /* FIXED_POINT */
/* Compute the amplitude (sqrt energy) in each of the bands */
-void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM, int arch)
+void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM)
{
int i, c, N;
const opus_int16 *eBands = m->eBands;
@@ -165,7 +164,7 @@ void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *band
for (i=0;i<end;i++)
{
opus_val32 sum;
- 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);
+ sum = 1e-27f + celt_inner_prod_c(&X[c*N+(eBands[i]<<LM)], &X[c*N+(eBands[i]<<LM)], (eBands[i+1]-eBands[i])<<LM);
bandE[i+c*m->nbEBands] = celt_sqrt(sum);
/*printf ("%f ", bandE[i+c*m->nbEBands]);*/
}
@@ -225,9 +224,9 @@ void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
#endif
j=M*eBands[i];
band_end = M*eBands[i+1];
- lg = SATURATE16(ADD32(bandLogE[i], SHL32((opus_val32)eMeans[i],6)));
+ lg = ADD16(bandLogE[i], SHL16((opus_val16)eMeans[i],6));
#ifndef FIXED_POINT
- g = celt_exp2(MIN32(32.f, lg));
+ g = celt_exp2(lg);
#else
/* Handle the integer part of the log energy */
shift = 16-(lg>>DB_SHIFT);
@@ -242,12 +241,12 @@ void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
/* Handle extreme gains with negative shift. */
if (shift<0)
{
- /* For shift <= -2 and g > 16384 we'd be likely to overflow, so we're
- capping the gain here, which is equivalent to a cap of 18 on lg.
- This shouldn't trigger unless the bitstream is already corrupted. */
- if (shift <= -2)
+ /* For shift < -2 we'd be likely to overflow, so we're capping
+ the gain here. This shouldn't happen unless the bitstream is
+ already corrupted. */
+ if (shift < -2)
{
- g = 16384;
+ g = 32767;
shift = -2;
}
do {
@@ -282,7 +281,7 @@ void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_mas
N0 = m->eBands[i+1]-m->eBands[i];
/* depth in 1/8 bits */
- celt_sig_assert(pulses[i]>=0);
+ celt_assert(pulses[i]>=0);
depth = celt_udiv(1+pulses[i], (m->eBands[i+1]-m->eBands[i]))>>LM;
#ifdef FIXED_POINT
@@ -361,30 +360,6 @@ void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_mas
}
}
-/* Compute the weights to use for optimizing normalized distortion across
- channels. We use the amplitude to weight square distortion, which means
- that we use the square root of the value we would have been using if we
- wanted to minimize the MSE in the non-normalized domain. This roughly
- corresponds to some quick-and-dirty perceptual experiments I ran to
- measure inter-aural masking (there doesn't seem to be any published data
- on the topic). */
-static void compute_channel_weights(celt_ener Ex, celt_ener Ey, opus_val16 w[2])
-{
- celt_ener minE;
-#ifdef FIXED_POINT
- int shift;
-#endif
- minE = MIN32(Ex, Ey);
- /* Adjustment to make the weights a bit more conservative. */
- Ex = ADD32(Ex, minE/3);
- Ey = ADD32(Ey, minE/3);
-#ifdef FIXED_POINT
- shift = celt_ilog2(EPSILON+MAX32(Ex, Ey))-14;
-#endif
- w[0] = VSHR32(Ex, shift);
- w[1] = VSHR32(Ey, shift);
-}
-
static 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)
{
int i = bandID;
@@ -478,7 +453,7 @@ static void stereo_merge(celt_norm * OPUS_RESTRICT X, celt_norm * OPUS_RESTRICT
/* Decide whether we should spread the pulses in the current frame */
int spreading_decision(const CELTMode *m, const celt_norm *X, int *average,
int last_decision, int *hf_average, int *tapset_decision, int update_hf,
- int end, int C, int M, const int *spread_weight)
+ int end, int C, int M)
{
int i, c, N0;
int sum = 0, nbBands=0;
@@ -519,8 +494,8 @@ int spreading_decision(const CELTMode *m, const celt_norm *X, int *average,
if (i>m->nbEBands-4)
hf_sum += celt_udiv(32*(tcount[1]+tcount[0]), N);
tmp = (2*tcount[2] >= N) + (2*tcount[1] >= N) + (2*tcount[0] >= N);
- sum += tmp*spread_weight[i];
- nbBands+=spread_weight[i];
+ sum += tmp*256;
+ nbBands++;
}
} while (++c<C);
@@ -544,7 +519,7 @@ int spreading_decision(const CELTMode *m, const celt_norm *X, int *average,
/*printf("%d %d %d\n", hf_sum, *hf_average, *tapset_decision);*/
celt_assert(nbBands>0); /* end has to be non-zero */
celt_assert(sum>=0);
- sum = celt_udiv((opus_int32)sum<<8, nbBands);
+ sum = celt_udiv(sum, nbBands);
/* Recursive averaging */
sum = (sum+*average)>>1;
*average = sum;
@@ -672,7 +647,6 @@ static int compute_qn(int N, int b, int offset, int pulse_cap, int stereo)
struct band_ctx {
int encode;
- int resynth;
const CELTMode *m;
int i;
int intensity;
@@ -683,9 +657,6 @@ struct band_ctx {
const celt_ener *bandE;
opus_uint32 seed;
int arch;
- int theta_round;
- int disable_inv;
- int avoid_split_noise;
};
struct split_ctx {
@@ -743,35 +714,8 @@ static void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx,
if (qn!=1)
{
if (encode)
- {
- if (!stereo || ctx->theta_round == 0)
- {
- itheta = (itheta*(opus_int32)qn+8192)>>14;
- if (!stereo && ctx->avoid_split_noise && itheta > 0 && itheta < qn)
- {
- /* Check if the selected value of theta will cause the bit allocation
- to inject noise on one side. If so, make sure the energy of that side
- is zero. */
- int unquantized = celt_udiv((opus_int32)itheta*16384, qn);
- imid = bitexact_cos((opus_int16)unquantized);
- iside = bitexact_cos((opus_int16)(16384-unquantized));
- delta = FRAC_MUL16((N-1)<<7,bitexact_log2tan(iside,imid));
- if (delta > *b)
- itheta = qn;
- else if (delta < -*b)
- itheta = 0;
- }
- } else {
- int down;
- /* Bias quantization towards itheta=0 and itheta=16384. */
- int bias = itheta > 8192 ? 32767/qn : -32767/qn;
- down = IMIN(qn-1, IMAX(0, (itheta*(opus_int32)qn + bias)>>14));
- if (ctx->theta_round < 0)
- itheta = down;
- else
- itheta = down+1;
- }
- }
+ itheta = (itheta*(opus_int32)qn+8192)>>14;
+
/* Entropy coding of the angle. We use a uniform pdf for the
time split, a step for stereo, and a triangular one for the rest. */
if (stereo && N>2)
@@ -849,7 +793,7 @@ static void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx,
} else if (stereo) {
if (encode)
{
- inv = itheta > 8192 && !ctx->disable_inv;
+ inv = itheta > 8192;
if (inv)
{
int j;
@@ -866,9 +810,6 @@ static void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx,
inv = ec_dec_bit_logp(ec, 2);
} else
inv = 0;
- /* inv flag override to avoid problems with downmixing. */
- if (ctx->disable_inv)
- inv = 0;
itheta = 0;
}
qalloc = ec_tell_frac(ec) - tell;
@@ -904,6 +845,11 @@ static void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx,
static unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, int b,
celt_norm *lowband_out)
{
+#ifdef RESYNTH
+ int resynth = 1;
+#else
+ int resynth = !ctx->encode;
+#endif
int c;
int stereo;
celt_norm *x = X;
@@ -928,7 +874,7 @@ static unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y,
ctx->remaining_bits -= 1<<BITRES;
b-=1<<BITRES;
}
- if (ctx->resynth)
+ if (resynth)
x[0] = sign ? -NORM_SCALING : NORM_SCALING;
x = Y;
} while (++c<1+stereo);
@@ -953,6 +899,11 @@ static unsigned quant_partition(struct band_ctx *ctx, celt_norm *X,
int B0=B;
opus_val16 mid=0, side=0;
unsigned cm=0;
+#ifdef RESYNTH
+ int resynth = 1;
+#else
+ int resynth = !ctx->encode;
+#endif
celt_norm *Y=NULL;
int encode;
const CELTMode *m;
@@ -984,7 +935,8 @@ static unsigned quant_partition(struct band_ctx *ctx, celt_norm *X,
fill = (fill&1)|(fill<<1);
B = (B+1)>>1;
- compute_theta(ctx, &sctx, X, Y, N, &b, B, B0, LM, 0, &fill);
+ compute_theta(ctx, &sctx, X, Y, N, &b, B, B0,
+ LM, 0, &fill);
imid = sctx.imid;
iside = sctx.iside;
delta = sctx.delta;
@@ -1018,20 +970,24 @@ static unsigned quant_partition(struct band_ctx *ctx, celt_norm *X,
rebalance = ctx->remaining_bits;
if (mbits >= sbits)
{
- cm = quant_partition(ctx, X, N, mbits, B, lowband, LM,
+ cm = quant_partition(ctx, X, N, mbits, B,
+ lowband, LM,
MULT16_16_P15(gain,mid), fill);
rebalance = mbits - (rebalance-ctx->remaining_bits);
if (rebalance > 3<<BITRES && itheta!=0)
sbits += rebalance - (3<<BITRES);
- cm |= quant_partition(ctx, Y, N, sbits, B, next_lowband2, LM,
+ cm |= quant_partition(ctx, Y, N, sbits, B,
+ next_lowband2, LM,
MULT16_16_P15(gain,side), fill>>B)<<(B0>>1);
} else {
- cm = quant_partition(ctx, Y, N, sbits, B, next_lowband2, LM,
+ cm = quant_partition(ctx, Y, N, sbits, B,
+ next_lowband2, LM,
MULT16_16_P15(gain,side), fill>>B)<<(B0>>1);
rebalance = sbits - (rebalance-ctx->remaining_bits);
if (rebalance > 3<<BITRES && itheta!=16384)
mbits += rebalance - (3<<BITRES);
- cm |= quant_partition(ctx, X, N, mbits, B, lowband, LM,
+ cm |= quant_partition(ctx, X, N, mbits, B,
+ lowband, LM,
MULT16_16_P15(gain,mid), fill);
}
} else {
@@ -1056,14 +1012,18 @@ static unsigned quant_partition(struct band_ctx *ctx, celt_norm *X,
/* Finally do the actual quantization */
if (encode)
{
- cm = alg_quant(X, N, K, spread, B, ec, gain, ctx->resynth, ctx->arch);
+ cm = alg_quant(X, N, K, spread, B, ec
+#ifdef RESYNTH
+ , gain
+#endif
+ );
} else {
cm = alg_unquant(X, N, K, spread, B, ec, gain);
}
} else {
/* If there's no pulse, fill the band anyway */
int j;
- if (ctx->resynth)
+ if (resynth)
{
unsigned cm_mask;
/* B can be as large as 16, so this shift might overflow an int on a
@@ -1120,6 +1080,11 @@ static unsigned quant_band(struct band_ctx *ctx, celt_norm *X,
int recombine=0;
int longBlocks;
unsigned cm=0;
+#ifdef RESYNTH
+ int resynth = 1;
+#else
+ int resynth = !ctx->encode;
+#endif
int k;
int encode;
int tf_change;
@@ -1186,10 +1151,11 @@ static unsigned quant_band(struct band_ctx *ctx, celt_norm *X,
deinterleave_hadamard(lowband, N_B>>recombine, B0<<recombine, longBlocks);
}
- cm = quant_partition(ctx, X, N, b, B, lowband, LM, gain, fill);
+ cm = quant_partition(ctx, X, N, b, B, lowband,
+ LM, gain, fill);
/* This code is used by the decoder and by the resynthesis-enabled encoder */
- if (ctx->resynth)
+ if (resynth)
{
/* Undo the sample reorganization going from time order to frequency order */
if (B0>1)
@@ -1242,6 +1208,11 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm
int inv = 0;
opus_val16 mid=0, side=0;
unsigned cm=0;
+#ifdef RESYNTH
+ int resynth = 1;
+#else
+ int resynth = !ctx->encode;
+#endif
int mbits, sbits, delta;
int itheta;
int qalloc;
@@ -1261,7 +1232,8 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm
orig_fill = fill;
- compute_theta(ctx, &sctx, X, Y, N, &b, B, B, LM, 1, &fill);
+ compute_theta(ctx, &sctx, X, Y, N, &b, B, B,
+ LM, 1, &fill);
inv = sctx.inv;
imid = sctx.imid;
iside = sctx.iside;
@@ -1309,13 +1281,13 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm
sign = 1-2*sign;
/* We use orig_fill here because we want to fold the side, but if
itheta==16384, we'll have cleared the low bits of fill. */
- cm = quant_band(ctx, x2, N, mbits, B, lowband, LM, lowband_out, Q15ONE,
- lowband_scratch, orig_fill);
+ cm = quant_band(ctx, x2, N, mbits, B, lowband,
+ LM, lowband_out, Q15ONE, lowband_scratch, orig_fill);
/* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse),
and there's no need to worry about mixing with the other channel. */
y2[0] = -sign*x2[1];
y2[1] = sign*x2[0];
- if (ctx->resynth)
+ if (resynth)
{
celt_norm tmp;
X[0] = MULT16_16_Q15(mid, X[0]);
@@ -1342,32 +1314,38 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm
{
/* In stereo mode, we do not apply a scaling to the mid because we need the normalized
mid for folding later. */
- cm = quant_band(ctx, X, N, mbits, B, lowband, LM, lowband_out, Q15ONE,
- lowband_scratch, fill);
+ cm = quant_band(ctx, X, N, mbits, B,
+ lowband, LM, lowband_out,
+ Q15ONE, lowband_scratch, fill);
rebalance = mbits - (rebalance-ctx->remaining_bits);
if (rebalance > 3<<BITRES && itheta!=0)
sbits += rebalance - (3<<BITRES);
/* For a stereo split, the high bits of fill are always zero, so no
folding will be done to the side. */
- cm |= quant_band(ctx, Y, N, sbits, B, NULL, LM, NULL, side, NULL, fill>>B);
+ cm |= quant_band(ctx, Y, N, sbits, B,
+ NULL, LM, NULL,
+ side, NULL, fill>>B);
} else {
/* For a stereo split, the high bits of fill are always zero, so no
folding will be done to the side. */
- cm = quant_band(ctx, Y, N, sbits, B, NULL, LM, NULL, side, NULL, fill>>B);
+ cm = quant_band(ctx, Y, N, sbits, B,
+ NULL, LM, NULL,
+ side, NULL, fill>>B);
rebalance = sbits - (rebalance-ctx->remaining_bits);
if (rebalance > 3<<BITRES && itheta!=16384)
mbits += rebalance - (3<<BITRES);
/* In stereo mode, we do not apply a scaling to the mid because we need the normalized
mid for folding later. */
- cm |= quant_band(ctx, X, N, mbits, B, lowband, LM, lowband_out, Q15ONE,
- lowband_scratch, fill);
+ cm |= quant_band(ctx, X, N, mbits, B,
+ lowband, LM, lowband_out,
+ Q15ONE, lowband_scratch, fill);
}
}
/* This code is used by the decoder and by the resynthesis-enabled encoder */
- if (ctx->resynth)
+ if (resynth)
{
if (N!=2)
stereo_merge(X, Y, mid, N, ctx->arch);
@@ -1381,38 +1359,19 @@ static unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm
return cm;
}
-static void special_hybrid_folding(const CELTMode *m, celt_norm *norm, celt_norm *norm2, int start, int M, int dual_stereo)
-{
- int n1, n2;
- const opus_int16 * OPUS_RESTRICT eBands = m->eBands;
- n1 = M*(eBands[start+1]-eBands[start]);
- n2 = M*(eBands[start+2]-eBands[start+1]);
- /* Duplicate enough of the first band folding data to be able to fold the second band.
- Copies no data for CELT-only mode. */
- OPUS_COPY(&norm[n1], &norm[2*n1 - n2], n2-n1);
- if (dual_stereo)
- OPUS_COPY(&norm2[n1], &norm2[2*n1 - n2], n2-n1);
-}
void quant_all_bands(int encode, const CELTMode *m, int start, int end,
celt_norm *X_, celt_norm *Y_, unsigned char *collapse_masks,
const celt_ener *bandE, int *pulses, int shortBlocks, int spread,
int dual_stereo, int intensity, int *tf_res, opus_int32 total_bits,
opus_int32 balance, ec_ctx *ec, int LM, int codedBands,
- opus_uint32 *seed, int complexity, int arch, int disable_inv)
+ opus_uint32 *seed, int arch)
{
int i;
opus_int32 remaining_bits;
const opus_int16 * OPUS_RESTRICT eBands = m->eBands;
celt_norm * OPUS_RESTRICT norm, * OPUS_RESTRICT norm2;
VARDECL(celt_norm, _norm);
- VARDECL(celt_norm, _lowband_scratch);
- VARDECL(celt_norm, X_save);
- VARDECL(celt_norm, Y_save);
- VARDECL(celt_norm, X_save2);
- VARDECL(celt_norm, Y_save2);
- VARDECL(celt_norm, norm_save2);
- int resynth_alloc;
celt_norm *lowband_scratch;
int B;
int M;
@@ -1420,11 +1379,10 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
int update_lowband = 1;
int C = Y_ != NULL ? 2 : 1;
int norm_offset;
- int theta_rdo = encode && Y_!=NULL && !dual_stereo && complexity>=8;
#ifdef RESYNTH
int resynth = 1;
#else
- int resynth = !encode || theta_rdo;
+ int resynth = !encode;
#endif
struct band_ctx ctx;
SAVE_STACK;
@@ -1437,24 +1395,9 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
ALLOC(_norm, C*(M*eBands[m->nbEBands-1]-norm_offset), celt_norm);
norm = _norm;
norm2 = norm + M*eBands[m->nbEBands-1]-norm_offset;
-
- /* For decoding, we can use the last band as scratch space because we don't need that
- scratch space for the last band and we don't care about the data there until we're
- decoding the last band. */
- if (encode && resynth)
- resynth_alloc = M*(eBands[m->nbEBands]-eBands[m->nbEBands-1]);
- else
- resynth_alloc = ALLOC_NONE;
- ALLOC(_lowband_scratch, resynth_alloc, celt_norm);
- if (encode && resynth)
- lowband_scratch = _lowband_scratch;
- else
- lowband_scratch = X_+M*eBands[m->nbEBands-1];
- ALLOC(X_save, resynth_alloc, celt_norm);
- ALLOC(Y_save, resynth_alloc, celt_norm);
- ALLOC(X_save2, resynth_alloc, celt_norm);
- ALLOC(Y_save2, resynth_alloc, celt_norm);
- ALLOC(norm_save2, resynth_alloc, celt_norm);
+ /* We can use the last band as scratch space because we don't need that
+ scratch space for the last band. */
+ lowband_scratch = X_+M*eBands[m->nbEBands-1];
lowband_offset = 0;
ctx.bandE = bandE;
@@ -1465,11 +1408,6 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
ctx.seed = *seed;
ctx.spread = spread;
ctx.arch = arch;
- ctx.disable_inv = disable_inv;
- ctx.resynth = resynth;
- ctx.theta_round = 0;
- /* Avoid injecting noise in the first band on transients. */
- ctx.avoid_split_noise = B > 1;
for (i=start;i<end;i++)
{
opus_int32 tell;
@@ -1492,7 +1430,6 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
else
Y = NULL;
N = M*eBands[i+1]-M*eBands[i];
- celt_assert(N > 0);
tell = ec_tell_frac(ec);
/* Compute how many bits we want to allocate to this band */
@@ -1508,15 +1445,8 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
b = 0;
}
-#ifndef DISABLE_UPDATE_DRAFT
- if (resynth && (M*eBands[i]-N >= M*eBands[start] || i==start+1) && (update_lowband || lowband_offset==0))
- lowband_offset = i;
- if (i == start+1)
- special_hybrid_folding(m, norm, norm2, start, M, dual_stereo);
-#else
if (resynth && M*eBands[i]-N >= M*eBands[start] && (update_lowband || lowband_offset==0))
lowband_offset = i;
-#endif
tf_change = tf_res[i];
ctx.tf_change = tf_change;
@@ -1527,7 +1457,7 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
Y = norm;
lowband_scratch = NULL;
}
- if (last && !theta_rdo)
+ if (i==end-1)
lowband_scratch = NULL;
/* Get a conservative estimate of the collapse_mask's for the bands we're
@@ -1542,11 +1472,7 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
fold_start = lowband_offset;
while(M*eBands[--fold_start] > effective_lowband+norm_offset);
fold_end = lowband_offset-1;
-#ifndef DISABLE_UPDATE_DRAFT
- while(++fold_end < i && M*eBands[fold_end] < effective_lowband+norm_offset+N);
-#else
while(M*eBands[++fold_end] < effective_lowband+norm_offset+N);
-#endif
x_cm = y_cm = 0;
fold_i = fold_start; do {
x_cm |= collapse_masks[fold_i*C+0];
@@ -1579,79 +1505,13 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
} else {
if (Y!=NULL)
{
- if (theta_rdo && i < intensity)
- {
- ec_ctx ec_save, ec_save2;
- struct band_ctx ctx_save, ctx_save2;
- opus_val32 dist0, dist1;
- unsigned cm, cm2;
- int nstart_bytes, nend_bytes, save_bytes;
- unsigned char *bytes_buf;
- unsigned char bytes_save[1275];
- opus_val16 w[2];
- compute_channel_weights(bandE[i], bandE[i+m->nbEBands], w);
- /* Make a copy. */
- cm = x_cm|y_cm;
- ec_save = *ec;
- ctx_save = ctx;
- OPUS_COPY(X_save, X, N);
- OPUS_COPY(Y_save, Y, N);
- /* Encode and round down. */
- ctx.theta_round = -1;
- x_cm = quant_band_stereo(&ctx, X, Y, N, b, B,
- effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
- last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, cm);
- 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));
-
- /* Save first result. */
- cm2 = x_cm;
- ec_save2 = *ec;
- ctx_save2 = ctx;
- OPUS_COPY(X_save2, X, N);
- OPUS_COPY(Y_save2, Y, N);
- if (!last)
- OPUS_COPY(norm_save2, norm+M*eBands[i]-norm_offset, N);
- nstart_bytes = ec_save.offs;
- nend_bytes = ec_save.storage;
- bytes_buf = ec_save.buf+nstart_bytes;
- save_bytes = nend_bytes-nstart_bytes;
- OPUS_COPY(bytes_save, bytes_buf, save_bytes);
-
- /* Restore */
- *ec = ec_save;
- ctx = ctx_save;
- OPUS_COPY(X, X_save, N);
- OPUS_COPY(Y, Y_save, N);
-#ifndef DISABLE_UPDATE_DRAFT
- if (i == start+1)
- special_hybrid_folding(m, norm, norm2, start, M, dual_stereo);
-#endif
- /* Encode and round up. */
- ctx.theta_round = 1;
- x_cm = quant_band_stereo(&ctx, X, Y, N, b, B,
- effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
- last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, cm);
- 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));
- if (dist0 >= dist1) {
- x_cm = cm2;
- *ec = ec_save2;
- ctx = ctx_save2;
- OPUS_COPY(X, X_save2, N);
- OPUS_COPY(Y, Y_save2, N);
- if (!last)
- OPUS_COPY(norm+M*eBands[i]-norm_offset, norm_save2, N);
- OPUS_COPY(bytes_buf, bytes_save, save_bytes);
- }
- } else {
- ctx.theta_round = 0;
- x_cm = quant_band_stereo(&ctx, X, Y, N, b, B,
- effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
- last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, x_cm|y_cm);
- }
+ x_cm = quant_band_stereo(&ctx, X, Y, N, b, B,
+ effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
+ last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, x_cm|y_cm);
} else {
x_cm = quant_band(&ctx, X, N, b, B,
effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
- last?NULL:norm+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, x_cm|y_cm);
+ last?NULL:norm+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, x_cm|y_cm);
}
y_cm = x_cm;
}
@@ -1661,9 +1521,6 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
/* Update the folding position only as long as we have 1 bit/sample depth. */
update_lowband = b>(N<<BITRES);
- /* We only need to avoid noise on a split for the first band. After that, we
- have folding. */
- ctx.avoid_split_noise = 0;
}
*seed = ctx.seed;
diff --git a/thirdparty/opus/celt/bands.h b/thirdparty/opus/celt/bands.h
index 422b32cf75..e8bef4bad0 100644
--- a/thirdparty/opus/celt/bands.h
+++ b/thirdparty/opus/celt/bands.h
@@ -36,15 +36,12 @@
#include "entdec.h"
#include "rate.h"
-opus_int16 bitexact_cos(opus_int16 x);
-int bitexact_log2tan(int isin,int icos);
-
/** Compute the amplitude (sqrt energy) in each of the bands
* @param m Mode data
* @param X Spectrum
* @param bandE Square root of the energy for each band (returned)
*/
-void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM, int arch);
+void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM);
/*void compute_noise_energies(const CELTMode *m, const celt_sig *X, const opus_val16 *tonality, celt_ener *bandE);*/
@@ -72,7 +69,7 @@ void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
int spreading_decision(const CELTMode *m, const celt_norm *X, int *average,
int last_decision, int *hf_average, int *tapset_decision, int update_hf,
- int end, int C, int M, const int *spread_weight);
+ int end, int C, int M);
#ifdef MEASURE_NORM_MSE
void measure_norm_mse(const CELTMode *m, float *X, float *X0, float *bandE, float *bandE0, int M, int N, int C);
@@ -108,7 +105,7 @@ void quant_all_bands(int encode, const CELTMode *m, int start, int end,
const celt_ener *bandE, int *pulses, int shortBlocks, int spread,
int dual_stereo, int intensity, int *tf_res, opus_int32 total_bits,
opus_int32 balance, ec_ctx *ec, int M, int codedBands, opus_uint32 *seed,
- int complexity, int arch, int disable_inv);
+ int arch);
void anti_collapse(const CELTMode *m, celt_norm *X_,
unsigned char *collapse_masks, int LM, int C, int size, int start,
diff --git a/thirdparty/opus/celt/celt.c b/thirdparty/opus/celt/celt.c
index 9ce234695c..b121c51a1f 100644
--- a/thirdparty/opus/celt/celt.c
+++ b/thirdparty/opus/celt/celt.c
@@ -111,31 +111,26 @@ void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
t = MAC16_32_Q16(x[i], g10, x2);
t = MAC16_32_Q16(t, g11, ADD32(x1,x3));
t = MAC16_32_Q16(t, g12, ADD32(x0,x4));
- t = SATURATE(t, SIG_SAT);
y[i] = t;
x4=SHL32(x[i-T+3],1);
t = MAC16_32_Q16(x[i+1], g10, x1);
t = MAC16_32_Q16(t, g11, ADD32(x0,x2));
t = MAC16_32_Q16(t, g12, ADD32(x4,x3));
- t = SATURATE(t, SIG_SAT);
y[i+1] = t;
x3=SHL32(x[i-T+4],1);
t = MAC16_32_Q16(x[i+2], g10, x0);
t = MAC16_32_Q16(t, g11, ADD32(x4,x1));
t = MAC16_32_Q16(t, g12, ADD32(x3,x2));
- t = SATURATE(t, SIG_SAT);
y[i+2] = t;
x2=SHL32(x[i-T+5],1);
t = MAC16_32_Q16(x[i+3], g10, x4);
t = MAC16_32_Q16(t, g11, ADD32(x3,x0));
t = MAC16_32_Q16(t, g12, ADD32(x2,x1));
- t = SATURATE(t, SIG_SAT);
y[i+3] = t;
x1=SHL32(x[i-T+6],1);
t = MAC16_32_Q16(x[i+4], g10, x3);
t = MAC16_32_Q16(t, g11, ADD32(x2,x4));
t = MAC16_32_Q16(t, g12, ADD32(x1,x0));
- t = SATURATE(t, SIG_SAT);
y[i+4] = t;
}
#ifdef CUSTOM_MODES
@@ -146,7 +141,6 @@ void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
t = MAC16_32_Q16(x[i], g10, x2);
t = MAC16_32_Q16(t, g11, ADD32(x1,x3));
t = MAC16_32_Q16(t, g12, ADD32(x0,x4));
- t = SATURATE(t, SIG_SAT);
y[i] = t;
x4=x3;
x3=x2;
@@ -175,7 +169,6 @@ void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
+ MULT16_32_Q15(g10,x2)
+ MULT16_32_Q15(g11,ADD32(x1,x3))
+ MULT16_32_Q15(g12,ADD32(x0,x4));
- y[i] = SATURATE(y[i], SIG_SAT);
x4=x3;
x3=x2;
x2=x1;
@@ -207,10 +200,6 @@ void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
OPUS_MOVE(y, x, N);
return;
}
- /* When the gain is zero, T0 and/or T1 is set to zero. We need
- to have then be at least 2 to avoid processing garbage data. */
- T0 = IMAX(T0, COMBFILTER_MINPERIOD);
- T1 = IMAX(T1, COMBFILTER_MINPERIOD);
g00 = MULT16_16_P15(g0, gains[tapset0][0]);
g01 = MULT16_16_P15(g0, gains[tapset0][1]);
g02 = MULT16_16_P15(g0, gains[tapset0][2]);
@@ -236,7 +225,6 @@ void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
+ MULT16_32_Q15(MULT16_16_Q15(f,g10),x2)
+ MULT16_32_Q15(MULT16_16_Q15(f,g11),ADD32(x1,x3))
+ MULT16_32_Q15(MULT16_16_Q15(f,g12),ADD32(x0,x4));
- y[i] = SATURATE(y[i], SIG_SAT);
x4=x3;
x3=x2;
x2=x1;
@@ -256,16 +244,11 @@ void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
}
#endif /* OVERRIDE_comb_filter */
-/* TF change table. Positive values mean better frequency resolution (longer
- effective window), whereas negative values mean better time resolution
- (shorter effective window). The second index is computed as:
- 4*isTransient + 2*tf_select + per_band_flag */
const signed char tf_select_table[4][8] = {
- /*isTransient=0 isTransient=1 */
- {0, -1, 0, -1, 0,-1, 0,-1}, /* 2.5 ms */
- {0, -1, 0, -2, 1, 0, 1,-1}, /* 5 ms */
- {0, -2, 0, -3, 2, 0, 1,-1}, /* 10 ms */
- {0, -2, 0, -3, 3, 0, 1,-1}, /* 20 ms */
+ {0, -1, 0, -1, 0,-1, 0,-1},
+ {0, -1, 0, -2, 1, 0, 1,-1},
+ {0, -2, 0, -3, 2, 0, 1,-1},
+ {0, -2, 0, -3, 3, 0, 1,-1},
};
diff --git a/thirdparty/opus/celt/celt.h b/thirdparty/opus/celt/celt.h
index 24b6b2b520..d1f7eb690d 100644
--- a/thirdparty/opus/celt/celt.h
+++ b/thirdparty/opus/celt/celt.h
@@ -50,8 +50,6 @@ extern "C" {
#define CELTDecoder OpusCustomDecoder
#define CELTMode OpusCustomMode
-#define LEAK_BANDS 19
-
typedef struct {
int valid;
float tonality;
@@ -59,28 +57,18 @@ typedef struct {
float noisiness;
float activity;
float music_prob;
- float music_prob_min;
- float music_prob_max;
- int bandwidth;
- float activity_probability;
- float max_pitch_ratio;
- /* Store as Q6 char to save space. */
- unsigned char leak_boost[LEAK_BANDS];
-} AnalysisInfo;
-
-typedef struct {
- int signalType;
- int offset;
-} SILKInfo;
+ int bandwidth;
+}AnalysisInfo;
#define __celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr)))
#define __celt_check_analysis_ptr(ptr) ((ptr) + ((ptr) - (const AnalysisInfo*)(ptr)))
-#define __celt_check_silkinfo_ptr(ptr) ((ptr) + ((ptr) - (const SILKInfo*)(ptr)))
-
/* Encoder/decoder Requests */
+/* Expose this option again when variable framesize actually works */
+#define OPUS_FRAMESIZE_VARIABLE 5010 /**< Optimize the frame size dynamically */
+
#define CELT_SET_PREDICTION_REQUEST 10002
/** Controls the use of interframe prediction.
@@ -128,9 +116,6 @@ typedef struct {
#define OPUS_SET_ENERGY_MASK_REQUEST 10026
#define OPUS_SET_ENERGY_MASK(x) OPUS_SET_ENERGY_MASK_REQUEST, __opus_check_val16_ptr(x)
-#define CELT_SET_SILK_INFO_REQUEST 10028
-#define CELT_SET_SILK_INFO(x) CELT_SET_SILK_INFO_REQUEST, __celt_check_silkinfo_ptr(x)
-
/* Encoder stuff */
int celt_encoder_get_size(int channels);
@@ -209,13 +194,6 @@ static OPUS_INLINE int fromOpus(unsigned char c)
extern const signed char tf_select_table[4][8];
-#if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)
-void validate_celt_decoder(CELTDecoder *st);
-#define VALIDATE_CELT_DECODER(st) validate_celt_decoder(st)
-#else
-#define VALIDATE_CELT_DECODER(st)
-#endif
-
int resampling_factor(opus_int32 rate);
void celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT inp,
diff --git a/thirdparty/opus/celt/celt_decoder.c b/thirdparty/opus/celt/celt_decoder.c
index e6efce9358..b978bb34d1 100644
--- a/thirdparty/opus/celt/celt_decoder.c
+++ b/thirdparty/opus/celt/celt_decoder.c
@@ -51,14 +51,6 @@
#include "celt_lpc.h"
#include "vq.h"
-/* The maximum pitch lag to allow in the pitch-based PLC. It's possible to save
- CPU time in the PLC pitch search by making this smaller than MAX_PERIOD. The
- current value corresponds to a pitch of 66.67 Hz. */
-#define PLC_PITCH_LAG_MAX (720)
-/* The minimum pitch lag to allow in the pitch-based PLC. This corresponds to a
- pitch of 480 Hz. */
-#define PLC_PITCH_LAG_MIN (100)
-
#if defined(SMALL_FOOTPRINT) && defined(FIXED_POINT)
#define NORM_ALIASING_HACK
#endif
@@ -81,7 +73,6 @@ struct OpusCustomDecoder {
int downsample;
int start, end;
int signalling;
- int disable_inv;
int arch;
/* Everything beyond this point gets cleared on a reset */
@@ -109,38 +100,6 @@ struct OpusCustomDecoder {
/* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */
};
-#if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)
-/* Make basic checks on the CELT state to ensure we don't end
- up writing all over memory. */
-void validate_celt_decoder(CELTDecoder *st)
-{
-#ifndef CUSTOM_MODES
- celt_assert(st->mode == opus_custom_mode_create(48000, 960, NULL));
- celt_assert(st->overlap == 120);
-#endif
- celt_assert(st->channels == 1 || st->channels == 2);
- celt_assert(st->stream_channels == 1 || st->stream_channels == 2);
- celt_assert(st->downsample > 0);
- celt_assert(st->start == 0 || st->start == 17);
- celt_assert(st->start < st->end);
- celt_assert(st->end <= 21);
-#ifdef OPUS_ARCHMASK
- celt_assert(st->arch >= 0);
- celt_assert(st->arch <= OPUS_ARCHMASK);
-#endif
- celt_assert(st->last_pitch_index <= PLC_PITCH_LAG_MAX);
- celt_assert(st->last_pitch_index >= PLC_PITCH_LAG_MIN || st->last_pitch_index == 0);
- celt_assert(st->postfilter_period < MAX_PERIOD);
- celt_assert(st->postfilter_period >= COMBFILTER_MINPERIOD || st->postfilter_period == 0);
- celt_assert(st->postfilter_period_old < MAX_PERIOD);
- celt_assert(st->postfilter_period_old >= COMBFILTER_MINPERIOD || st->postfilter_period_old == 0);
- celt_assert(st->postfilter_tapset <= 2);
- celt_assert(st->postfilter_tapset >= 0);
- celt_assert(st->postfilter_tapset_old <= 2);
- celt_assert(st->postfilter_tapset_old >= 0);
-}
-#endif
-
int celt_decoder_get_size(int channels)
{
const CELTMode *mode = opus_custom_mode_create(48000, 960, NULL);
@@ -204,11 +163,6 @@ OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_init(CELTDecoder *st, const CELTMod
st->start = 0;
st->end = st->mode->effEBands;
st->signalling = 1;
-#ifndef DISABLE_UPDATE_DRAFT
- st->disable_inv = channels == 1;
-#else
- st->disable_inv = 0;
-#endif
st->arch = opus_select_arch();
opus_custom_decoder_ctl(st, OPUS_RESET_STATE);
@@ -223,36 +177,6 @@ void opus_custom_decoder_destroy(CELTDecoder *st)
}
#endif /* CUSTOM_MODES */
-#ifndef CUSTOM_MODES
-/* Special case for stereo with no downsampling and no accumulation. This is
- quite common and we can make it faster by processing both channels in the
- same loop, reducing overhead due to the dependency loop in the IIR filter. */
-static void deemphasis_stereo_simple(celt_sig *in[], opus_val16 *pcm, int N, const opus_val16 coef0,
- celt_sig *mem)
-{
- celt_sig * OPUS_RESTRICT x0;
- celt_sig * OPUS_RESTRICT x1;
- celt_sig m0, m1;
- int j;
- x0=in[0];
- x1=in[1];
- m0 = mem[0];
- m1 = mem[1];
- for (j=0;j<N;j++)
- {
- celt_sig tmp0, tmp1;
- /* Add VERY_SMALL to x[] first to reduce dependency chain. */
- tmp0 = x0[j] + VERY_SMALL + m0;
- tmp1 = x1[j] + VERY_SMALL + m1;
- m0 = MULT16_32_Q15(coef0, tmp0);
- m1 = MULT16_32_Q15(coef0, tmp1);
- pcm[2*j ] = SCALEOUT(SIG2WORD16(tmp0));
- pcm[2*j+1] = SCALEOUT(SIG2WORD16(tmp1));
- }
- mem[0] = m0;
- mem[1] = m1;
-}
-#endif
#ifndef RESYNTH
static
@@ -266,14 +190,6 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
opus_val16 coef0;
VARDECL(celt_sig, scratch);
SAVE_STACK;
-#ifndef CUSTOM_MODES
- /* Short version for common case. */
- if (downsample == 1 && C == 2 && !accum)
- {
- deemphasis_stereo_simple(in, pcm, N, coef[0], mem);
- return;
- }
-#endif
#ifndef FIXED_POINT
(void)accum;
celt_assert(accum==0);
@@ -309,7 +225,7 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
/* Shortcut for the standard (non-custom modes) case */
for (j=0;j<N;j++)
{
- celt_sig tmp = x[j] + VERY_SMALL + m;
+ celt_sig tmp = x[j] + m + VERY_SMALL;
m = MULT16_32_Q15(coef0, tmp);
scratch[j] = tmp;
}
@@ -330,7 +246,7 @@ void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, c
{
for (j=0;j<N;j++)
{
- celt_sig tmp = x[j] + VERY_SMALL + m;
+ celt_sig tmp = x[j] + m + VERY_SMALL;
m = MULT16_32_Q15(coef0, tmp);
y[j*C] = SCALEOUT(SIG2WORD16(tmp));
}
@@ -417,7 +333,7 @@ void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
denormalise_bands(mode, X+N, freq2, oldBandE+nbEBands, start, effEnd, M,
downsample, silence);
for (i=0;i<N;i++)
- freq[i] = ADD32(HALF32(freq[i]), HALF32(freq2[i]));
+ freq[i] = HALF32(ADD32(freq[i],freq2[i]));
for (b=0;b<B;b++)
clt_mdct_backward(&mode->mdct, &freq[b], out_syn[0]+NB*b, mode->window, overlap, shift, B, arch);
} else {
@@ -429,12 +345,6 @@ void celt_synthesis(const CELTMode *mode, celt_norm *X, celt_sig * out_syn[],
clt_mdct_backward(&mode->mdct, &freq[b], out_syn[c]+NB*b, mode->window, overlap, shift, B, arch);
} while (++c<CC);
}
- /* Saturate IMDCT output so that we can't overflow in the pitch postfilter
- or in the */
- c=0; do {
- for (i=0;i<N;i++)
- out_syn[c][i] = SATURATE(out_syn[c][i], SIG_SAT);
- } while (++c<CC);
RESTORE_STACK;
}
@@ -477,6 +387,14 @@ static void tf_decode(int start, int end, int isTransient, int *tf_res, int LM,
}
}
+/* The maximum pitch lag to allow in the pitch-based PLC. It's possible to save
+ CPU time in the PLC pitch search by making this smaller than MAX_PERIOD. The
+ current value corresponds to a pitch of 66.67 Hz. */
+#define PLC_PITCH_LAG_MAX (720)
+/* The minimum pitch lag to allow in the pitch-based PLC. This corresponds to a
+ pitch of 480 Hz. */
+#define PLC_PITCH_LAG_MIN (100)
+
static int celt_plc_pitch_search(celt_sig *decode_mem[2], int C, int arch)
{
int pitch_index;
@@ -586,15 +504,12 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
celt_synthesis(mode, X, out_syn, oldBandE, start, effEnd, C, C, 0, LM, st->downsample, 0, st->arch);
} else {
- int exc_length;
/* Pitch-based PLC */
const opus_val16 *window;
- opus_val16 *exc;
opus_val16 fade = Q15ONE;
int pitch_index;
VARDECL(opus_val32, etmp);
- VARDECL(opus_val16, _exc);
- VARDECL(opus_val16, fir_tmp);
+ VARDECL(opus_val16, exc);
if (loss_count == 0)
{
@@ -604,14 +519,8 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
fade = QCONST16(.8f,15);
}
- /* We want the excitation for 2 pitch periods in order to look for a
- decaying signal, but we can't get more than MAX_PERIOD. */
- exc_length = IMIN(2*pitch_index, MAX_PERIOD);
-
ALLOC(etmp, overlap, opus_val32);
- ALLOC(_exc, MAX_PERIOD+LPC_ORDER, opus_val16);
- ALLOC(fir_tmp, exc_length, opus_val16);
- exc = _exc+LPC_ORDER;
+ ALLOC(exc, MAX_PERIOD, opus_val16);
window = mode->window;
c=0; do {
opus_val16 decay;
@@ -620,11 +529,13 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
celt_sig *buf;
int extrapolation_offset;
int extrapolation_len;
+ int exc_length;
int j;
buf = decode_mem[c];
- for (i=0;i<MAX_PERIOD+LPC_ORDER;i++)
- exc[i-LPC_ORDER] = ROUND16(buf[DECODE_BUFFER_SIZE-MAX_PERIOD-LPC_ORDER+i], SIG_SHIFT);
+ for (i=0;i<MAX_PERIOD;i++) {
+ exc[i] = ROUND16(buf[DECODE_BUFFER_SIZE-MAX_PERIOD+i], SIG_SHIFT);
+ }
if (loss_count == 0)
{
@@ -650,32 +561,22 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
#endif
}
_celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER);
-#ifdef FIXED_POINT
- /* For fixed-point, apply bandwidth expansion until we can guarantee that
- no overflow can happen in the IIR filter. This means:
- 32768*sum(abs(filter)) < 2^31 */
- while (1) {
- opus_val16 tmp=Q15ONE;
- opus_val32 sum=QCONST16(1., SIG_SHIFT);
- for (i=0;i<LPC_ORDER;i++)
- sum += ABS16(lpc[c*LPC_ORDER+i]);
- if (sum < 65535) break;
- for (i=0;i<LPC_ORDER;i++)
- {
- tmp = MULT16_16_Q15(QCONST16(.99f,15), tmp);
- lpc[c*LPC_ORDER+i] = MULT16_16_Q15(lpc[c*LPC_ORDER+i], tmp);
- }
- }
-#endif
}
+ /* We want the excitation for 2 pitch periods in order to look for a
+ decaying signal, but we can't get more than MAX_PERIOD. */
+ exc_length = IMIN(2*pitch_index, MAX_PERIOD);
/* Initialize the LPC history with the samples just before the start
of the region for which we're computing the excitation. */
{
- /* Compute the excitation for exc_length samples before the loss. We need the copy
- because celt_fir() cannot filter in-place. */
+ opus_val16 lpc_mem[LPC_ORDER];
+ for (i=0;i<LPC_ORDER;i++)
+ {
+ lpc_mem[i] =
+ ROUND16(buf[DECODE_BUFFER_SIZE-exc_length-1-i], SIG_SHIFT);
+ }
+ /* Compute the excitation for exc_length samples before the loss. */
celt_fir(exc+MAX_PERIOD-exc_length, lpc+c*LPC_ORDER,
- fir_tmp, exc_length, LPC_ORDER, st->arch);
- OPUS_COPY(exc+MAX_PERIOD-exc_length, fir_tmp, exc_length);
+ exc+MAX_PERIOD-exc_length, exc_length, LPC_ORDER, lpc_mem, st->arch);
}
/* Check if the waveform is decaying, and if so how fast.
@@ -729,8 +630,9 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
tmp = ROUND16(
buf[DECODE_BUFFER_SIZE-MAX_PERIOD-N+extrapolation_offset+j],
SIG_SHIFT);
- S1 += SHR32(MULT16_16(tmp, tmp), 10);
+ S1 += SHR32(MULT16_16(tmp, tmp), 8);
}
+
{
opus_val16 lpc_mem[LPC_ORDER];
/* Copy the last decoded samples (prior to the overlap region) to
@@ -742,10 +644,6 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
celt_iir(buf+DECODE_BUFFER_SIZE-N, lpc+c*LPC_ORDER,
buf+DECODE_BUFFER_SIZE-N, extrapolation_len, LPC_ORDER,
lpc_mem, st->arch);
-#ifdef FIXED_POINT
- for (i=0; i < extrapolation_len; i++)
- buf[DECODE_BUFFER_SIZE-N+i] = SATURATE(buf[DECODE_BUFFER_SIZE-N+i], SIG_SAT);
-#endif
}
/* Check if the synthesis energy is higher than expected, which can
@@ -756,7 +654,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
for (i=0;i<extrapolation_len;i++)
{
opus_val16 tmp = ROUND16(buf[DECODE_BUFFER_SIZE-N+i], SIG_SHIFT);
- S2 += SHR32(MULT16_16(tmp, tmp), 10);
+ S2 += SHR32(MULT16_16(tmp, tmp), 8);
}
/* This checks for an "explosion" in the synthesis. */
#ifdef FIXED_POINT
@@ -864,7 +762,6 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
const opus_int16 *eBands;
ALLOC_STACK;
- VALIDATE_CELT_DECODER(st);
mode = st->mode;
nbEBands = mode->nbEBands;
overlap = mode->overlap;
@@ -1059,7 +956,7 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
ALLOC(pulses, nbEBands, int);
ALLOC(fine_priority, nbEBands, int);
- codedBands = clt_compute_allocation(mode, start, end, offsets, cap,
+ codedBands = compute_allocation(mode, start, end, offsets, cap,
alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses,
fine_quant, fine_priority, C, LM, dec, 0, 0, 0);
@@ -1082,8 +979,7 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
quant_all_bands(0, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks,
NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res,
- len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng, 0,
- st->arch, st->disable_inv);
+ len*(8<<BITRES)-anti_collapse_rsv, balance, dec, LM, codedBands, &st->rng, st->arch);
if (anti_collapse_rsv > 0)
{
@@ -1338,26 +1234,6 @@ int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...)
*value=st->rng;
}
break;
- case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
- {
- opus_int32 value = va_arg(ap, opus_int32);
- if(value<0 || value>1)
- {
- goto bad_arg;
- }
- st->disable_inv = value;
- }
- break;
- case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
- {
- opus_int32 *value = va_arg(ap, opus_int32*);
- if (!value)
- {
- goto bad_arg;
- }
- *value = st->disable_inv;
- }
- break;
default:
goto bad_request;
}
diff --git a/thirdparty/opus/celt/celt_encoder.c b/thirdparty/opus/celt/celt_encoder.c
index 44cb0850ab..3ee7a4d3f7 100644
--- a/thirdparty/opus/celt/celt_encoder.c
+++ b/thirdparty/opus/celt/celt_encoder.c
@@ -73,8 +73,8 @@ struct OpusCustomEncoder {
int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */
int loss_rate;
int lsb_depth;
+ int variable_duration;
int lfe;
- int disable_inv;
int arch;
/* Everything beyond this point gets cleared on a reset */
@@ -98,7 +98,6 @@ struct OpusCustomEncoder {
#endif
int consec_transient;
AnalysisInfo analysis;
- SILKInfo silk_info;
opus_val32 preemph_memE[2];
opus_val32 preemph_memD[2];
@@ -124,7 +123,6 @@ struct OpusCustomEncoder {
/* opus_val16 oldBandE[], Size = channels*mode->nbEBands */
/* opus_val16 oldLogE[], Size = channels*mode->nbEBands */
/* opus_val16 oldLogE2[], Size = channels*mode->nbEBands */
- /* opus_val16 energyError[], Size = channels*mode->nbEBands */
};
int celt_encoder_get_size(int channels)
@@ -138,10 +136,9 @@ OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_get_size(const CELTMode *mode, int
int size = sizeof(struct CELTEncoder)
+ (channels*mode->overlap-1)*sizeof(celt_sig) /* celt_sig in_mem[channels*mode->overlap]; */
+ channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig) /* celt_sig prefilter_mem[channels*COMBFILTER_MAXPERIOD]; */
- + 4*channels*mode->nbEBands*sizeof(opus_val16); /* opus_val16 oldBandE[channels*mode->nbEBands]; */
+ + 3*channels*mode->nbEBands*sizeof(opus_val16); /* opus_val16 oldBandE[channels*mode->nbEBands]; */
/* opus_val16 oldLogE[channels*mode->nbEBands]; */
/* opus_val16 oldLogE2[channels*mode->nbEBands]; */
- /* opus_val16 energyError[channels*mode->nbEBands]; */
return size;
}
@@ -181,6 +178,7 @@ static int opus_custom_encoder_init_arch(CELTEncoder *st, const CELTMode *mode,
st->start = 0;
st->end = st->mode->effEBands;
st->signalling = 1;
+
st->arch = arch;
st->constrained_vbr = 1;
@@ -225,8 +223,7 @@ void opus_custom_encoder_destroy(CELTEncoder *st)
static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int C,
- opus_val16 *tf_estimate, int *tf_chan, int allow_weak_transients,
- int *weak_transient)
+ opus_val16 *tf_estimate, int *tf_chan)
{
int i;
VARDECL(opus_val16, tmp);
@@ -236,12 +233,6 @@ static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int
int c;
opus_val16 tf_max;
int len2;
- /* Forward masking: 6.7 dB/ms. */
-#ifdef FIXED_POINT
- int forward_shift = 4;
-#else
- opus_val16 forward_decay = QCONST16(.0625f,15);
-#endif
/* Table of 6*64/x, trained on real data to minimize the average error */
static const unsigned char inv_table[128] = {
255,255,156,110, 86, 70, 59, 51, 45, 40, 37, 33, 31, 28, 26, 25,
@@ -256,19 +247,6 @@ static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int
SAVE_STACK;
ALLOC(tmp, len, opus_val16);
- *weak_transient = 0;
- /* For lower bitrates, let's be more conservative and have a forward masking
- decay of 3.3 dB/ms. This avoids having to code transients at very low
- bitrate (mostly for hybrid), which can result in unstable energy and/or
- partial collapse. */
- if (allow_weak_transients)
- {
-#ifdef FIXED_POINT
- forward_shift = 5;
-#else
- forward_decay = QCONST16(.03125f,15);
-#endif
- }
len2=len/2;
for (c=0;c<C;c++)
{
@@ -291,7 +269,7 @@ static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int
mem0 = mem1 + y - 2*x;
mem1 = x - .5f*y;
#endif
- tmp[i] = SROUND16(y, 2);
+ tmp[i] = EXTRACT16(SHR32(y,2));
/*printf("%f ", tmp[i]);*/
}
/*printf("\n");*/
@@ -302,7 +280,7 @@ static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int
/* Normalize tmp to max range */
{
int shift=0;
- shift = 14-celt_ilog2(MAX16(1, celt_maxabs16(tmp, len)));
+ shift = 14-celt_ilog2(1+celt_maxabs16(tmp, len));
if (shift!=0)
{
for (i=0;i<len;i++)
@@ -321,9 +299,9 @@ static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int
mean += x2;
#ifdef FIXED_POINT
/* FIXME: Use PSHR16() instead */
- tmp[i] = mem0 + PSHR32(x2-mem0,forward_shift);
+ tmp[i] = mem0 + PSHR32(x2-mem0,4);
#else
- tmp[i] = mem0 + MULT16_16_P15(forward_decay,x2-mem0);
+ tmp[i] = mem0 + MULT16_16_P15(QCONST16(.0625f,15),x2-mem0);
#endif
mem0 = tmp[i];
}
@@ -333,7 +311,6 @@ static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int
/* Backward pass to compute the pre-echo threshold */
for (i=len2-1;i>=0;i--)
{
- /* Backward masking: 13.9 dB/ms. */
#ifdef FIXED_POINT
/* FIXME: Use PSHR16() instead */
tmp[i] = mem0 + PSHR32(tmp[i]-mem0,3);
@@ -362,12 +339,6 @@ static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int
/* Compute harmonic mean discarding the unreliable boundaries
The data is smooth, so we only take 1/4th of the samples */
unmask=0;
- /* We should never see NaNs here. If we find any, then something really bad happened and we better abort
- before it does any damage later on. If these asserts are disabled (no hardening), then the table
- lookup a few lines below (id = ...) is likely to crash dur to an out-of-bounds read. DO NOT FIX
- that crash on NaN since it could result in a worse issue later on. */
- celt_assert(!celt_isnan(tmp[0]));
- celt_assert(!celt_isnan(norm));
for (i=12;i<len2-5;i+=4)
{
int id;
@@ -388,12 +359,7 @@ static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int
}
}
is_transient = mask_metric>200;
- /* For low bitrates, define "weak transients" that need to be
- handled differently to avoid partial collapse. */
- if (allow_weak_transients && is_transient && mask_metric<600) {
- is_transient = 0;
- *weak_transient = 1;
- }
+
/* Arbitrary metric for VBR boost */
tf_max = MAX16(0,celt_sqrt(27*mask_metric)-42);
/* *tf_estimate = 1 + MIN16(1, sqrt(MAX16(0, tf_max-30))/20); */
@@ -583,7 +549,7 @@ static opus_val32 l1_metric(const celt_norm *tmp, int N, int LM, opus_val16 bias
static int tf_analysis(const CELTMode *m, int len, int isTransient,
int *tf_res, int lambda, celt_norm *X, int N0, int LM,
- opus_val16 tf_estimate, int tf_chan, int *importance)
+ int *tf_sum, opus_val16 tf_estimate, int tf_chan)
{
int i;
VARDECL(int, metric);
@@ -608,6 +574,7 @@ static int tf_analysis(const CELTMode *m, int len, int isTransient,
ALLOC(path0, len, int);
ALLOC(path1, len, int);
+ *tf_sum = 0;
for (i=0;i<len;i++)
{
int k, N;
@@ -662,26 +629,27 @@ static int tf_analysis(const CELTMode *m, int len, int isTransient,
metric[i] = 2*best_level;
else
metric[i] = -2*best_level;
+ *tf_sum += (isTransient ? LM : 0) - metric[i]/2;
/* For bands that can't be split to -1, set the metric to the half-way point to avoid
biasing the decision */
if (narrow && (metric[i]==0 || metric[i]==-2*LM))
metric[i]-=1;
- /*printf("%d ", metric[i]/2 + (!isTransient)*LM);*/
+ /*printf("%d ", metric[i]);*/
}
/*printf("\n");*/
/* Search for the optimal tf resolution, including tf_select */
tf_select = 0;
for (sel=0;sel<2;sel++)
{
- cost0 = importance[0]*abs(metric[0]-2*tf_select_table[LM][4*isTransient+2*sel+0]);
- cost1 = importance[0]*abs(metric[0]-2*tf_select_table[LM][4*isTransient+2*sel+1]) + (isTransient ? 0 : lambda);
+ cost0 = 0;
+ cost1 = isTransient ? 0 : lambda;
for (i=1;i<len;i++)
{
int curr0, curr1;
curr0 = IMIN(cost0, cost1 + lambda);
curr1 = IMIN(cost0 + lambda, cost1);
- cost0 = curr0 + importance[i]*abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*sel+0]);
- cost1 = curr1 + importance[i]*abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*sel+1]);
+ cost0 = curr0 + abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*sel+0]);
+ cost1 = curr1 + abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*sel+1]);
}
cost0 = IMIN(cost0, cost1);
selcost[sel]=cost0;
@@ -690,8 +658,8 @@ static int tf_analysis(const CELTMode *m, int len, int isTransient,
* If tests confirm it's useful for non-transients, we could allow it. */
if (selcost[1]<selcost[0] && isTransient)
tf_select=1;
- cost0 = importance[0]*abs(metric[0]-2*tf_select_table[LM][4*isTransient+2*tf_select+0]);
- cost1 = importance[0]*abs(metric[0]-2*tf_select_table[LM][4*isTransient+2*tf_select+1]) + (isTransient ? 0 : lambda);
+ cost0 = 0;
+ cost1 = isTransient ? 0 : lambda;
/* Viterbi forward pass */
for (i=1;i<len;i++)
{
@@ -719,8 +687,8 @@ static int tf_analysis(const CELTMode *m, int len, int isTransient,
curr1 = from1;
path1[i]= 1;
}
- cost0 = curr0 + importance[i]*abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*tf_select+0]);
- cost1 = curr1 + importance[i]*abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*tf_select+1]);
+ cost0 = curr0 + abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*tf_select+0]);
+ cost1 = curr1 + abs(metric[i]-2*tf_select_table[LM][4*isTransient+2*tf_select+1]);
}
tf_res[len-1] = cost0 < cost1 ? 0 : 1;
/* Viterbi backward pass to check the decisions */
@@ -786,7 +754,7 @@ static void tf_encode(int start, int end, int isTransient, int *tf_res, int LM,
static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X,
const opus_val16 *bandLogE, int end, int LM, int C, int N0,
AnalysisInfo *analysis, opus_val16 *stereo_saving, opus_val16 tf_estimate,
- int intensity, opus_val16 surround_trim, opus_int32 equiv_rate, int arch)
+ int intensity, opus_val16 surround_trim, int arch)
{
int i;
opus_val32 diff=0;
@@ -794,14 +762,6 @@ static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X,
int trim_index;
opus_val16 trim = QCONST16(5.f, 8);
opus_val16 logXC, logXC2;
- /* At low bitrate, reducing the trim seems to help. At higher bitrates, it's less
- clear what's best, so we're keeping it as it was before, at least for now. */
- if (equiv_rate < 64000) {
- trim = QCONST16(4.f, 8);
- } else if (equiv_rate < 80000) {
- opus_int32 frac = (equiv_rate-64000) >> 10;
- trim = QCONST16(4.f, 8) + QCONST16(1.f/16.f, 8)*frac;
- }
if (C==2)
{
opus_val16 sum = 0; /* Q10 */
@@ -849,7 +809,7 @@ static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X,
} while (++c<C);
diff /= C*(end-1);
/*printf("%f\n", diff);*/
- trim -= MAX32(-QCONST16(2.f, 8), MIN32(QCONST16(2.f, 8), SHR32(diff+QCONST16(1.f, DB_SHIFT),DB_SHIFT-8)/6 ));
+ trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8), SHR16(diff+QCONST16(1.f, DB_SHIFT),DB_SHIFT-8)/6 ));
trim -= SHR16(surround_trim, DB_SHIFT-8);
trim -= 2*SHR16(tf_estimate, 14-8);
#ifndef DISABLE_FLOAT_API
@@ -970,8 +930,7 @@ static opus_val16 median_of_3(const opus_val16 *x)
static opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16 *bandLogE2,
int nbEBands, int start, int end, int C, int *offsets, int lsb_depth, const opus_int16 *logN,
int isTransient, int vbr, int constrained_vbr, const opus_int16 *eBands, int LM,
- int effectiveBytes, opus_int32 *tot_boost_, int lfe, opus_val16 *surround_dynalloc,
- AnalysisInfo *analysis, int *importance, int *spread_weight)
+ int effectiveBytes, opus_int32 *tot_boost_, int lfe, opus_val16 *surround_dynalloc)
{
int i, c;
opus_int32 tot_boost=0;
@@ -997,42 +956,6 @@ static opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16
for (i=0;i<end;i++)
maxDepth = MAX16(maxDepth, bandLogE[c*nbEBands+i]-noise_floor[i]);
} while (++c<C);
- {
- /* Compute a really simple masking model to avoid taking into account completely masked
- bands when computing the spreading decision. */
- VARDECL(opus_val16, mask);
- VARDECL(opus_val16, sig);
- ALLOC(mask, nbEBands, opus_val16);
- ALLOC(sig, nbEBands, opus_val16);
- for (i=0;i<end;i++)
- mask[i] = bandLogE[i]-noise_floor[i];
- if (C==2)
- {
- for (i=0;i<end;i++)
- mask[i] = MAX16(mask[i], bandLogE[nbEBands+i]-noise_floor[i]);
- }
- OPUS_COPY(sig, mask, end);
- for (i=1;i<end;i++)
- mask[i] = MAX16(mask[i], mask[i-1] - QCONST16(2.f, DB_SHIFT));
- for (i=end-2;i>=0;i--)
- mask[i] = MAX16(mask[i], mask[i+1] - QCONST16(3.f, DB_SHIFT));
- for (i=0;i<end;i++)
- {
- /* Compute SMR: Mask is never more than 72 dB below the peak and never below the noise floor.*/
- opus_val16 smr = sig[i]-MAX16(MAX16(0, maxDepth-QCONST16(12.f, DB_SHIFT)), mask[i]);
- /* Clamp SMR to make sure we're not shifting by something negative or too large. */
-#ifdef FIXED_POINT
- /* FIXME: Use PSHR16() instead */
- int shift = -PSHR32(MAX16(-QCONST16(5.f, DB_SHIFT), MIN16(0, smr)), DB_SHIFT);
-#else
- int shift = IMIN(5, IMAX(0, -(int)floor(.5f + smr)));
-#endif
- spread_weight[i] = 32 >> shift;
- }
- /*for (i=0;i<end;i++)
- printf("%d ", spread_weight[i]);
- printf("\n");*/
- }
/* Make sure that dynamic allocation can't make us bust the budget */
if (effectiveBytes > 50 && LM>=1 && !lfe)
{
@@ -1089,14 +1012,6 @@ static opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16
}
for (i=start;i<end;i++)
follower[i] = MAX16(follower[i], surround_dynalloc[i]);
- for (i=start;i<end;i++)
- {
-#ifdef FIXED_POINT
- importance[i] = PSHR32(13*celt_exp2(MIN16(follower[i], QCONST16(4.f, DB_SHIFT))), 16);
-#else
- importance[i] = (int)floor(.5f+13*celt_exp2(MIN16(follower[i], QCONST16(4.f, DB_SHIFT))));
-#endif
- }
/* For non-transient CBR/CVBR frames, halve the dynalloc contribution */
if ((!vbr || constrained_vbr)&&!isTransient)
{
@@ -1105,26 +1020,14 @@ static opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16
}
for (i=start;i<end;i++)
{
- if (i<8)
- follower[i] *= 2;
- if (i>=12)
- follower[i] = HALF16(follower[i]);
- }
-#ifdef DISABLE_FLOAT_API
- (void)analysis;
-#else
- if (analysis->valid)
- {
- for (i=start;i<IMIN(LEAK_BANDS, end);i++)
- follower[i] = follower[i] + QCONST16(1.f/64.f, DB_SHIFT)*analysis->leak_boost[i];
- }
-#endif
- for (i=start;i<end;i++)
- {
int width;
int boost;
int boost_bits;
+ if (i<8)
+ follower[i] *= 2;
+ if (i>=12)
+ follower[i] = HALF16(follower[i]);
follower[i] = MIN16(follower[i], QCONST16(4, DB_SHIFT));
width = C*(eBands[i+1]-eBands[i])<<LM;
@@ -1139,11 +1042,11 @@ static opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16
boost = (int)SHR32(EXTEND32(follower[i])*width/6,DB_SHIFT);
boost_bits = boost*6<<BITRES;
}
- /* For CBR and non-transient CVBR frames, limit dynalloc to 2/3 of the bits */
+ /* For CBR and non-transient CVBR frames, limit dynalloc to 1/4 of the bits */
if ((!vbr || (constrained_vbr&&!isTransient))
- && (tot_boost+boost_bits)>>BITRES>>3 > 2*effectiveBytes/3)
+ && (tot_boost+boost_bits)>>BITRES>>3 > effectiveBytes/4)
{
- opus_int32 cap = ((2*effectiveBytes/3)<<BITRES<<3);
+ opus_int32 cap = ((effectiveBytes/4)<<BITRES<<3);
offsets[i] = cap-tot_boost;
tot_boost = cap;
break;
@@ -1152,9 +1055,6 @@ static opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16
tot_boost += boost_bits;
}
}
- } else {
- for (i=start;i<end;i++)
- importance[i] = 13;
}
*tot_boost_ = tot_boost;
RESTORE_STACK;
@@ -1163,7 +1063,7 @@ static opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16
static int run_prefilter(CELTEncoder *st, celt_sig *in, celt_sig *prefilter_mem, int CC, int N,
- int prefilter_tapset, int *pitch, opus_val16 *gain, int *qgain, int enabled, int nbAvailableBytes, AnalysisInfo *analysis)
+ int prefilter_tapset, int *pitch, opus_val16 *gain, int *qgain, int enabled, int nbAvailableBytes)
{
int c;
VARDECL(celt_sig, _pre);
@@ -1219,12 +1119,7 @@ static int run_prefilter(CELTEncoder *st, celt_sig *in, celt_sig *prefilter_mem,
gain1 = 0;
pitch_index = COMBFILTER_MINPERIOD;
}
-#ifndef DISABLE_FLOAT_API
- if (analysis->valid)
- gain1 = (opus_val16)(gain1 * analysis->max_pitch_ratio);
-#else
- (void)analysis;
-#endif
+
/* Gain threshold for enabling the prefilter/postfilter */
pf_threshold = QCONST16(.2f,15);
@@ -1298,7 +1193,7 @@ static int compute_vbr(const CELTMode *mode, AnalysisInfo *analysis, opus_int32
int LM, opus_int32 bitrate, int lastCodedBands, int C, int intensity,
int constrained_vbr, opus_val16 stereo_saving, int tot_boost,
opus_val16 tf_estimate, int pitch_change, opus_val16 maxDepth,
- int lfe, int has_surround_mask, opus_val16 surround_masking,
+ int variable_duration, int lfe, int has_surround_mask, opus_val16 surround_masking,
opus_val16 temporal_vbr)
{
/* The target rate in 8th bits per frame */
@@ -1340,9 +1235,10 @@ static int compute_vbr(const CELTMode *mode, AnalysisInfo *analysis, opus_int32
SHR32(MULT16_16(stereo_saving-QCONST16(0.1f,8),(coded_stereo_dof<<BITRES)),8));
}
/* Boost the rate according to dynalloc (minus the dynalloc average for calibration). */
- target += tot_boost-(19<<LM);
+ target += tot_boost-(16<<LM);
/* Apply transient boost, compensating for average boost. */
- tf_calibration = QCONST16(0.044f,14);
+ tf_calibration = variable_duration==OPUS_FRAMESIZE_VARIABLE ?
+ QCONST16(0.02f,14) : QCONST16(0.04f,14);
target += (opus_int32)SHL32(MULT16_32_Q15(tf_estimate-tf_calibration, target),1);
#ifndef DISABLE_FLOAT_API
@@ -1353,7 +1249,7 @@ static int compute_vbr(const CELTMode *mode, AnalysisInfo *analysis, opus_int32
float tonal;
/* Tonality boost (compensating for the average). */
- tonal = MAX16(0.f,analysis->tonality-.15f)-0.12f;
+ tonal = MAX16(0.f,analysis->tonality-.15f)-0.09f;
tonal_target = target + (opus_int32)((coded_bins<<BITRES)*1.2f*tonal);
if (pitch_change)
tonal_target += (opus_int32)((coded_bins<<BITRES)*.8f);
@@ -1383,11 +1279,21 @@ static int compute_vbr(const CELTMode *mode, AnalysisInfo *analysis, opus_int32
/*printf("%f %d\n", maxDepth, floor_depth);*/
}
- /* Make VBR less aggressive for constrained VBR because we can't keep a higher bitrate
- for long. Needs tuning. */
- if ((!has_surround_mask||lfe) && constrained_vbr)
+ if ((!has_surround_mask||lfe) && (constrained_vbr || bitrate<64000))
{
- target = base_target + (opus_int32)MULT16_32_Q15(QCONST16(0.67f, 15), target-base_target);
+ opus_val16 rate_factor = Q15ONE;
+ if (bitrate < 64000)
+ {
+#ifdef FIXED_POINT
+ rate_factor = MAX16(0,(bitrate-32000));
+#else
+ rate_factor = MAX16(0,(1.f/32768)*(bitrate-32000));
+#endif
+ }
+ if (constrained_vbr)
+ rate_factor = MIN16(rate_factor, QCONST16(0.67f, 15));
+ target = base_target + (opus_int32)MULT16_32_Q15(rate_factor, target-base_target);
+
}
if (!has_surround_mask && tf_estimate < QCONST16(.2f, 14))
@@ -1421,13 +1327,11 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
VARDECL(int, pulses);
VARDECL(int, cap);
VARDECL(int, offsets);
- VARDECL(int, importance);
- VARDECL(int, spread_weight);
VARDECL(int, fine_priority);
VARDECL(int, tf_res);
VARDECL(unsigned char, collapse_masks);
celt_sig *prefilter_mem;
- opus_val16 *oldBandE, *oldLogE, *oldLogE2, *energyError;
+ opus_val16 *oldBandE, *oldLogE, *oldLogE2;
int shortBlocks=0;
int isTransient=0;
const int CC = st->channels;
@@ -1439,6 +1343,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
int end;
int effEnd;
int codedBands;
+ int tf_sum;
int alloc_trim;
int pitch_index=COMBFILTER_MINPERIOD;
opus_val16 gain1 = 0;
@@ -1450,7 +1355,6 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
opus_int32 total_boost;
opus_int32 balance;
opus_int32 tell;
- opus_int32 tell0_frac;
int prefilter_tapset=0;
int pf_on;
int anti_collapse_rsv;
@@ -1472,10 +1376,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
opus_val16 surround_masking=0;
opus_val16 temporal_vbr=0;
opus_val16 surround_trim = 0;
- opus_int32 equiv_rate;
- int hybrid;
- int weak_transient = 0;
- int enable_tf_analysis;
+ opus_int32 equiv_rate = 510000;
VARDECL(opus_val16, surround_dynalloc);
ALLOC_STACK;
@@ -1485,7 +1386,6 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
eBands = mode->eBands;
start = st->start;
end = st->end;
- hybrid = start != 0;
tf_estimate = 0;
if (nbCompressedBytes<2 || pcm==NULL)
{
@@ -1509,14 +1409,12 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
oldBandE = (opus_val16*)(st->in_mem+CC*(overlap+COMBFILTER_MAXPERIOD));
oldLogE = oldBandE + CC*nbEBands;
oldLogE2 = oldLogE + CC*nbEBands;
- energyError = oldLogE2 + CC*nbEBands;
if (enc==NULL)
{
- tell0_frac=tell=1;
+ tell=1;
nbFilledBytes=0;
} else {
- tell0_frac=ec_tell_frac(enc);
tell=ec_tell(enc);
nbFilledBytes=(tell+4)>>3;
}
@@ -1569,11 +1467,10 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
if (st->bitrate!=OPUS_BITRATE_MAX)
nbCompressedBytes = IMAX(2, IMIN(nbCompressedBytes,
(tmp+4*mode->Fs)/(8*mode->Fs)-!!st->signalling));
- effectiveBytes = nbCompressedBytes - nbFilledBytes;
+ effectiveBytes = nbCompressedBytes;
}
- equiv_rate = ((opus_int32)nbCompressedBytes*8*50 >> (3-LM)) - (40*C+20)*((400>>LM) - 50);
if (st->bitrate != OPUS_BITRATE_MAX)
- equiv_rate = IMIN(equiv_rate, st->bitrate - (40*C+20)*((400>>LM) - 50));
+ equiv_rate = st->bitrate - (40*C+20)*((400>>LM) - 50);
if (enc==NULL)
{
@@ -1661,17 +1558,17 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
{
int enabled;
int qg;
- enabled = ((st->lfe&&nbAvailableBytes>3) || nbAvailableBytes>12*C) && !hybrid && !silence && !st->disable_pf
- && st->complexity >= 5;
+ enabled = ((st->lfe&&nbAvailableBytes>3) || nbAvailableBytes>12*C) && start==0 && !silence && !st->disable_pf
+ && st->complexity >= 5 && !(st->consec_transient && LM!=3 && st->variable_duration==OPUS_FRAMESIZE_VARIABLE);
prefilter_tapset = st->tapset_decision;
- pf_on = run_prefilter(st, in, prefilter_mem, CC, N, prefilter_tapset, &pitch_index, &gain1, &qg, enabled, nbAvailableBytes, &st->analysis);
+ pf_on = run_prefilter(st, in, prefilter_mem, CC, N, prefilter_tapset, &pitch_index, &gain1, &qg, enabled, nbAvailableBytes);
if ((gain1 > QCONST16(.4f,15) || st->prefilter_gain > QCONST16(.4f,15)) && (!st->analysis.valid || st->analysis.tonality > .3)
&& (pitch_index > 1.26*st->prefilter_period || pitch_index < .79*st->prefilter_period))
pitch_change = 1;
if (pf_on==0)
{
- if(!hybrid && tell+16<=total_bits)
+ if(start==0 && tell+16<=total_bits)
ec_enc_bit_logp(enc, 0, 1);
} else {
/*This block is not gated by a total bits check only because
@@ -1692,12 +1589,8 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
shortBlocks = 0;
if (st->complexity >= 1 && !st->lfe)
{
- /* Reduces the likelihood of energy instability on fricatives at low bitrate
- in hybrid mode. It seems like we still want to have real transients on vowels
- though (small SILK quantization offset value). */
- int allow_weak_transients = hybrid && effectiveBytes<15 && st->silk_info.signalType != 2;
isTransient = transient_analysis(in, N+overlap, CC,
- &tf_estimate, &tf_chan, allow_weak_transients, &weak_transient);
+ &tf_estimate, &tf_chan);
}
if (LM>0 && ec_tell(enc)+3<=total_bits)
{
@@ -1717,19 +1610,16 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
if (secondMdct)
{
compute_mdcts(mode, 0, in, freq, C, CC, LM, st->upsample, st->arch);
- compute_band_energies(mode, freq, bandE, effEnd, C, LM, st->arch);
+ compute_band_energies(mode, freq, bandE, effEnd, C, LM);
amp2Log2(mode, effEnd, end, bandE, bandLogE2, C);
for (i=0;i<C*nbEBands;i++)
bandLogE2[i] += HALF16(SHL16(LM, DB_SHIFT));
}
compute_mdcts(mode, shortBlocks, in, freq, C, CC, LM, st->upsample, st->arch);
- /* This should catch any NaN in the CELT input. Since we're not supposed to see any (they're filtered
- at the Opus layer), just abort. */
- celt_assert(!celt_isnan(freq[0]) && (C==1 || !celt_isnan(freq[N])));
if (CC==2&&C==1)
tf_chan = 0;
- compute_band_energies(mode, freq, bandE, effEnd, C, LM, st->arch);
+ compute_band_energies(mode, freq, bandE, effEnd, C, LM);
if (st->lfe)
{
@@ -1744,7 +1634,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
ALLOC(surround_dynalloc, C*nbEBands, opus_val16);
OPUS_CLEAR(surround_dynalloc, end);
/* This computes how much masking takes place between surround channels */
- if (!hybrid&&st->energy_mask&&!st->lfe)
+ if (start==0&&st->energy_mask&&!st->lfe)
{
int mask_end;
int midband;
@@ -1846,14 +1736,14 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
/* Last chance to catch any transient we might have missed in the
time-domain analysis */
- if (LM>0 && ec_tell(enc)+3<=total_bits && !isTransient && st->complexity>=5 && !st->lfe && !hybrid)
+ if (LM>0 && ec_tell(enc)+3<=total_bits && !isTransient && st->complexity>=5 && !st->lfe)
{
if (patch_transient_decision(bandLogE, oldBandE, nbEBands, start, end, C))
{
isTransient = 1;
shortBlocks = M;
compute_mdcts(mode, shortBlocks, in, freq, C, CC, LM, st->upsample, st->arch);
- compute_band_energies(mode, freq, bandE, effEnd, C, LM, st->arch);
+ compute_band_energies(mode, freq, bandE, effEnd, C, LM);
amp2Log2(mode, effEnd, end, bandE, bandLogE, C);
/* Compensate for the scaling of short vs long mdcts */
for (i=0;i<C*nbEBands;i++)
@@ -1870,59 +1760,31 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
/* Band normalisation */
normalise_bands(mode, freq, X, bandE, effEnd, C, M);
- enable_tf_analysis = effectiveBytes>=15*C && !hybrid && st->complexity>=2 && !st->lfe;
-
- ALLOC(offsets, nbEBands, int);
- ALLOC(importance, nbEBands, int);
- ALLOC(spread_weight, nbEBands, int);
-
- maxDepth = dynalloc_analysis(bandLogE, bandLogE2, nbEBands, start, end, C, offsets,
- st->lsb_depth, mode->logN, isTransient, st->vbr, st->constrained_vbr,
- eBands, LM, effectiveBytes, &tot_boost, st->lfe, surround_dynalloc, &st->analysis, importance, spread_weight);
-
ALLOC(tf_res, nbEBands, int);
/* Disable variable tf resolution for hybrid and at very low bitrate */
- if (enable_tf_analysis)
+ if (effectiveBytes>=15*C && start==0 && st->complexity>=2 && !st->lfe)
{
int lambda;
- lambda = IMAX(80, 20480/effectiveBytes + 2);
- tf_select = tf_analysis(mode, effEnd, isTransient, tf_res, lambda, X, N, LM, tf_estimate, tf_chan, importance);
+ if (effectiveBytes<40)
+ lambda = 12;
+ else if (effectiveBytes<60)
+ lambda = 6;
+ else if (effectiveBytes<100)
+ lambda = 4;
+ else
+ lambda = 3;
+ lambda*=2;
+ tf_select = tf_analysis(mode, effEnd, isTransient, tf_res, lambda, X, N, LM, &tf_sum, tf_estimate, tf_chan);
for (i=effEnd;i<end;i++)
tf_res[i] = tf_res[effEnd-1];
- } else if (hybrid && weak_transient)
- {
- /* For weak transients, we rely on the fact that improving time resolution using
- TF on a long window is imperfect and will not result in an energy collapse at
- low bitrate. */
- for (i=0;i<end;i++)
- tf_res[i] = 1;
- tf_select=0;
- } else if (hybrid && effectiveBytes<15 && st->silk_info.signalType != 2)
- {
- /* For low bitrate hybrid, we force temporal resolution to 5 ms rather than 2.5 ms. */
- for (i=0;i<end;i++)
- tf_res[i] = 0;
- tf_select=isTransient;
} else {
+ tf_sum = 0;
for (i=0;i<end;i++)
tf_res[i] = isTransient;
tf_select=0;
}
ALLOC(error, C*nbEBands, opus_val16);
- c=0;
- do {
- for (i=start;i<end;i++)
- {
- /* When the energy is stable, slightly bias energy quantization towards
- the previous error to make the gain more stable (a constant offset is
- better than fluctuations). */
- if (ABS32(SUB32(bandLogE[i+c*nbEBands], oldBandE[i+c*nbEBands])) < QCONST16(2.f, DB_SHIFT))
- {
- bandLogE[i+c*nbEBands] -= MULT16_16_Q15(energyError[i+c*nbEBands], QCONST16(0.25f, 15));
- }
- }
- } while (++c < C);
quant_coarse_energy(mode, start, end, effEnd, bandLogE,
oldBandE, total_bits, error, enc,
C, LM, nbAvailableBytes, st->force_intra,
@@ -1936,15 +1798,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
{
st->tapset_decision = 0;
st->spread_decision = SPREAD_NORMAL;
- } else if (hybrid)
- {
- if (st->complexity == 0)
- st->spread_decision = SPREAD_NONE;
- else if (isTransient)
- st->spread_decision = SPREAD_NORMAL;
- else
- st->spread_decision = SPREAD_AGGRESSIVE;
- } else if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C)
+ } else if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C || start != 0)
{
if (st->complexity == 0)
st->spread_decision = SPREAD_NONE;
@@ -1968,7 +1822,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
{
st->spread_decision = spreading_decision(mode, X,
&st->tonal_average, st->spread_decision, &st->hf_average,
- &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M, spread_weight);
+ &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M);
}
/*printf("%d %d\n", st->tapset_decision, st->spread_decision);*/
/*printf("%f %d %f %d\n\n", st->analysis.tonality, st->spread_decision, st->analysis.tonality_slope, st->tapset_decision);*/
@@ -1976,6 +1830,11 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
ec_enc_icdf(enc, st->spread_decision, spread_icdf, 5);
}
+ ALLOC(offsets, nbEBands, int);
+
+ maxDepth = dynalloc_analysis(bandLogE, bandLogE2, nbEBands, start, end, C, offsets,
+ st->lsb_depth, mode->logN, isTransient, st->vbr, st->constrained_vbr,
+ eBands, LM, effectiveBytes, &tot_boost, st->lfe, surround_dynalloc);
/* For LFE, everything interesting is in the first band */
if (st->lfe)
offsets[0] = IMIN(8, effectiveBytes/3);
@@ -2037,15 +1896,12 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
alloc_trim = 5;
if (tell+(6<<BITRES) <= total_bits - total_boost)
{
- if (start > 0 || st->lfe)
- {
- st->stereo_saving = 0;
+ if (st->lfe)
alloc_trim = 5;
- } else {
+ else
alloc_trim = alloc_trim_analysis(mode, X, bandLogE,
end, LM, C, N, &st->analysis, &st->stereo_saving, tf_estimate,
- st->intensity, surround_trim, equiv_rate, st->arch);
- }
+ st->intensity, surround_trim, st->arch);
ec_enc_icdf(enc, alloc_trim, trim_icdf, 7);
tell = ec_tell_frac(enc);
}
@@ -2063,36 +1919,17 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
/* Don't attempt to use more than 510 kb/s, even for frames smaller than 20 ms.
The CELT allocator will just not be able to use more than that anyway. */
nbCompressedBytes = IMIN(nbCompressedBytes,1275>>(3-LM));
- if (!hybrid)
- {
- base_target = vbr_rate - ((40*C+20)<<BITRES);
- } else {
- base_target = IMAX(0, vbr_rate - ((9*C+4)<<BITRES));
- }
+ base_target = vbr_rate - ((40*C+20)<<BITRES);
if (st->constrained_vbr)
base_target += (st->vbr_offset>>lm_diff);
- if (!hybrid)
- {
- target = compute_vbr(mode, &st->analysis, base_target, LM, equiv_rate,
+ target = compute_vbr(mode, &st->analysis, base_target, LM, equiv_rate,
st->lastCodedBands, C, st->intensity, st->constrained_vbr,
st->stereo_saving, tot_boost, tf_estimate, pitch_change, maxDepth,
- st->lfe, st->energy_mask!=NULL, surround_masking,
+ st->variable_duration, st->lfe, st->energy_mask!=NULL, surround_masking,
temporal_vbr);
- } else {
- target = base_target;
- /* Tonal frames (offset<100) need more bits than noisy (offset>100) ones. */
- if (st->silk_info.offset < 100) target += 12 << BITRES >> (3-LM);
- if (st->silk_info.offset > 100) target -= 18 << BITRES >> (3-LM);
- /* Boosting bitrate on transients and vowels with significant temporal
- spikes. */
- target += (opus_int32)MULT16_16_Q14(tf_estimate-QCONST16(.25f,14), (50<<BITRES));
- /* If we have a strong transient, let's make sure it has enough bits to code
- the first two bands, so that it can use folding rather than noise. */
- if (tf_estimate > QCONST16(.7f,14))
- target = IMAX(target, 50<<BITRES);
- }
+
/* The current offset is removed from the target and the space used
so far is added*/
target=target+tell;
@@ -2100,16 +1937,11 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
result in the encoder running out of bits.
The margin of 2 bytes ensures that none of the bust-prevention logic
in the decoder will have triggered so far. */
- min_allowed = ((tell+total_boost+(1<<(BITRES+3))-1)>>(BITRES+3)) + 2;
- /* Take into account the 37 bits we need to have left in the packet to
- signal a redundant frame in hybrid mode. Creating a shorter packet would
- create an entropy coder desync. */
- if (hybrid)
- min_allowed = IMAX(min_allowed, (tell0_frac+(37<<BITRES)+total_boost+(1<<(BITRES+3))-1)>>(BITRES+3));
+ min_allowed = ((tell+total_boost+(1<<(BITRES+3))-1)>>(BITRES+3)) + 2 - nbFilledBytes;
nbAvailableBytes = (target+(1<<(BITRES+2)))>>(BITRES+3);
nbAvailableBytes = IMAX(min_allowed,nbAvailableBytes);
- nbAvailableBytes = IMIN(nbCompressedBytes,nbAvailableBytes);
+ nbAvailableBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes) - nbFilledBytes;
/* By how much did we "miss" the target on that frame */
delta = target - vbr_rate;
@@ -2156,7 +1988,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
st->vbr_reservoir = 0;
/*printf ("+%d\n", adjust);*/
}
- nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes);
+ nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes);
/*printf("%d\n", nbCompressedBytes*50*8);*/
/* This moves the raw bits to take into account the new compressed size */
ec_enc_shrink(enc, nbCompressedBytes);
@@ -2191,7 +2023,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
#endif
if (st->lfe)
signalBandwidth = 1;
- codedBands = clt_compute_allocation(mode, start, end, offsets, cap,
+ codedBands = compute_allocation(mode, start, end, offsets, cap,
alloc_trim, &st->intensity, &dual_stereo, bits, &balance, pulses,
fine_quant, fine_priority, C, LM, enc, 1, st->lastCodedBands, signalBandwidth);
if (st->lastCodedBands)
@@ -2206,7 +2038,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
quant_all_bands(1, mode, start, end, X, C==2 ? X+N : NULL, collapse_masks,
bandE, pulses, shortBlocks, st->spread_decision,
dual_stereo, st->intensity, tf_res, nbCompressedBytes*(8<<BITRES)-anti_collapse_rsv,
- balance, enc, LM, codedBands, &st->rng, st->complexity, st->arch, st->disable_inv);
+ balance, enc, LM, codedBands, &st->rng, st->arch);
if (anti_collapse_rsv > 0)
{
@@ -2217,14 +2049,6 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm,
ec_enc_bits(enc, anti_collapse_on, 1);
}
quant_energy_finalise(mode, start, end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_tell(enc), enc, C);
- OPUS_CLEAR(energyError, nbEBands*CC);
- c=0;
- do {
- for (i=start;i<end;i++)
- {
- energyError[i+c*nbEBands] = MAX16(-QCONST16(0.5f, 15), MIN16(QCONST16(0.5f, 15), error[i+c*nbEBands]));
- }
- } while (++c < C);
if (silence)
{
@@ -2497,24 +2321,10 @@ int opus_custom_encoder_ctl(CELTEncoder * OPUS_RESTRICT st, int request, ...)
*value=st->lsb_depth;
}
break;
- case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
+ case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
{
opus_int32 value = va_arg(ap, opus_int32);
- if(value<0 || value>1)
- {
- goto bad_arg;
- }
- st->disable_inv = value;
- }
- break;
- case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
- {
- opus_int32 *value = va_arg(ap, opus_int32*);
- if (!value)
- {
- goto bad_arg;
- }
- *value = st->disable_inv;
+ st->variable_duration = value;
}
break;
case OPUS_RESET_STATE:
@@ -2558,13 +2368,6 @@ int opus_custom_encoder_ctl(CELTEncoder * OPUS_RESTRICT st, int request, ...)
OPUS_COPY(&st->analysis, info, 1);
}
break;
- case CELT_SET_SILK_INFO_REQUEST:
- {
- SILKInfo *info = va_arg(ap, SILKInfo *);
- if (info)
- OPUS_COPY(&st->silk_info, info, 1);
- }
- break;
case CELT_GET_MODE_REQUEST:
{
const CELTMode ** value = va_arg(ap, const CELTMode**);
diff --git a/thirdparty/opus/celt/celt_lpc.c b/thirdparty/opus/celt/celt_lpc.c
index 8ecb693ee9..b410a21c5f 100644
--- a/thirdparty/opus/celt/celt_lpc.c
+++ b/thirdparty/opus/celt/celt_lpc.c
@@ -89,40 +89,58 @@ int p
void celt_fir_c(
- const opus_val16 *x,
+ const opus_val16 *_x,
const opus_val16 *num,
- opus_val16 *y,
+ opus_val16 *_y,
int N,
int ord,
+ opus_val16 *mem,
int arch)
{
int i,j;
VARDECL(opus_val16, rnum);
+ VARDECL(opus_val16, x);
SAVE_STACK;
- celt_assert(x != y);
+
ALLOC(rnum, ord, opus_val16);
+ ALLOC(x, N+ord, opus_val16);
for(i=0;i<ord;i++)
rnum[i] = num[ord-i-1];
+ for(i=0;i<ord;i++)
+ x[i] = mem[ord-i-1];
+ for (i=0;i<N;i++)
+ x[i+ord]=_x[i];
+ for(i=0;i<ord;i++)
+ mem[i] = _x[N-i-1];
+#ifdef SMALL_FOOTPRINT
+ (void)arch;
+ for (i=0;i<N;i++)
+ {
+ opus_val32 sum = SHL32(EXTEND32(_x[i]), SIG_SHIFT);
+ for (j=0;j<ord;j++)
+ {
+ sum = MAC16_16(sum,rnum[j],x[i+j]);
+ }
+ _y[i] = SATURATE16(PSHR32(sum, SIG_SHIFT));
+ }
+#else
for (i=0;i<N-3;i+=4)
{
- opus_val32 sum[4];
- sum[0] = SHL32(EXTEND32(x[i ]), SIG_SHIFT);
- sum[1] = SHL32(EXTEND32(x[i+1]), SIG_SHIFT);
- sum[2] = SHL32(EXTEND32(x[i+2]), SIG_SHIFT);
- sum[3] = SHL32(EXTEND32(x[i+3]), SIG_SHIFT);
- xcorr_kernel(rnum, x+i-ord, sum, ord, arch);
- y[i ] = ROUND16(sum[0], SIG_SHIFT);
- y[i+1] = ROUND16(sum[1], SIG_SHIFT);
- y[i+2] = ROUND16(sum[2], SIG_SHIFT);
- y[i+3] = ROUND16(sum[3], SIG_SHIFT);
+ opus_val32 sum[4]={0,0,0,0};
+ xcorr_kernel(rnum, x+i, sum, ord, arch);
+ _y[i ] = SATURATE16(ADD32(EXTEND32(_x[i ]), PSHR32(sum[0], SIG_SHIFT)));
+ _y[i+1] = SATURATE16(ADD32(EXTEND32(_x[i+1]), PSHR32(sum[1], SIG_SHIFT)));
+ _y[i+2] = SATURATE16(ADD32(EXTEND32(_x[i+2]), PSHR32(sum[2], SIG_SHIFT)));
+ _y[i+3] = SATURATE16(ADD32(EXTEND32(_x[i+3]), PSHR32(sum[3], SIG_SHIFT)));
}
for (;i<N;i++)
{
- opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);
+ opus_val32 sum = 0;
for (j=0;j<ord;j++)
- sum = MAC16_16(sum,rnum[j],x[i+j-ord]);
- y[i] = ROUND16(sum, SIG_SHIFT);
+ sum = MAC16_16(sum,rnum[j],x[i+j]);
+ _y[i] = SATURATE16(ADD32(EXTEND32(_x[i]), PSHR32(sum, SIG_SHIFT)));
}
+#endif
RESTORE_STACK;
}
@@ -148,7 +166,7 @@ void celt_iir(const opus_val32 *_x,
{
mem[j]=mem[j-1];
}
- mem[0] = SROUND16(sum, SIG_SHIFT);
+ mem[0] = ROUND16(sum,SIG_SHIFT);
_y[i] = sum;
}
#else
@@ -177,20 +195,20 @@ void celt_iir(const opus_val32 *_x,
xcorr_kernel(rden, y+i, sum, ord, arch);
/* Patch up the result to compensate for the fact that this is an IIR */
- y[i+ord ] = -SROUND16(sum[0],SIG_SHIFT);
+ y[i+ord ] = -ROUND16(sum[0],SIG_SHIFT);
_y[i ] = sum[0];
sum[1] = MAC16_16(sum[1], y[i+ord ], den[0]);
- y[i+ord+1] = -SROUND16(sum[1],SIG_SHIFT);
+ y[i+ord+1] = -ROUND16(sum[1],SIG_SHIFT);
_y[i+1] = sum[1];
sum[2] = MAC16_16(sum[2], y[i+ord+1], den[0]);
sum[2] = MAC16_16(sum[2], y[i+ord ], den[1]);
- y[i+ord+2] = -SROUND16(sum[2],SIG_SHIFT);
+ y[i+ord+2] = -ROUND16(sum[2],SIG_SHIFT);
_y[i+2] = sum[2];
sum[3] = MAC16_16(sum[3], y[i+ord+2], den[0]);
sum[3] = MAC16_16(sum[3], y[i+ord+1], den[1]);
sum[3] = MAC16_16(sum[3], y[i+ord ], den[2]);
- y[i+ord+3] = -SROUND16(sum[3],SIG_SHIFT);
+ y[i+ord+3] = -ROUND16(sum[3],SIG_SHIFT);
_y[i+3] = sum[3];
}
for (;i<N;i++)
@@ -198,7 +216,7 @@ void celt_iir(const opus_val32 *_x,
opus_val32 sum = _x[i];
for (j=0;j<ord;j++)
sum -= MULT16_16(rden[j],y[i+j]);
- y[i+ord] = SROUND16(sum,SIG_SHIFT);
+ y[i+ord] = ROUND16(sum,SIG_SHIFT);
_y[i] = sum;
}
for(i=0;i<ord;i++)
diff --git a/thirdparty/opus/celt/celt_lpc.h b/thirdparty/opus/celt/celt_lpc.h
index a4c5fd6ea5..323459eb1a 100644
--- a/thirdparty/opus/celt/celt_lpc.h
+++ b/thirdparty/opus/celt/celt_lpc.h
@@ -45,11 +45,12 @@ void celt_fir_c(
opus_val16 *y,
int N,
int ord,
+ opus_val16 *mem,
int arch);
#if !defined(OVERRIDE_CELT_FIR)
-#define celt_fir(x, num, y, N, ord, arch) \
- (celt_fir_c(x, num, y, N, ord, arch))
+#define celt_fir(x, num, y, N, ord, mem, arch) \
+ (celt_fir_c(x, num, y, N, ord, mem, arch))
#endif
void celt_iir(const opus_val32 *x,
diff --git a/thirdparty/opus/celt/cwrs.c b/thirdparty/opus/celt/cwrs.c
index a552e4f0fb..9722f0ac86 100644
--- a/thirdparty/opus/celt/cwrs.c
+++ b/thirdparty/opus/celt/cwrs.c
@@ -482,7 +482,7 @@ static opus_val32 cwrsi(int _n,int _k,opus_uint32 _i,int *_y){
k0=_k;
q=row[_n];
if(q>_i){
- celt_sig_assert(p>q);
+ celt_assert(p>q);
_k=_n;
do p=CELT_PVQ_U_ROW[--_k][_n];
while(p>_i);
diff --git a/thirdparty/opus/celt/entcode.h b/thirdparty/opus/celt/entcode.h
index 3763e3f284..13d6c84ef0 100644
--- a/thirdparty/opus/celt/entcode.h
+++ b/thirdparty/opus/celt/entcode.h
@@ -122,7 +122,7 @@ opus_uint32 ec_tell_frac(ec_ctx *_this);
/* Tested exhaustively for all n and for 1<=d<=256 */
static OPUS_INLINE opus_uint32 celt_udiv(opus_uint32 n, opus_uint32 d) {
- celt_sig_assert(d>0);
+ celt_assert(d>0);
#ifdef USE_SMALL_DIV_TABLE
if (d>256)
return n/d;
@@ -138,7 +138,7 @@ static OPUS_INLINE opus_uint32 celt_udiv(opus_uint32 n, opus_uint32 d) {
}
static OPUS_INLINE opus_int32 celt_sudiv(opus_int32 n, opus_int32 d) {
- celt_sig_assert(d>0);
+ celt_assert(d>0);
#ifdef USE_SMALL_DIV_TABLE
if (n<0)
return -(opus_int32)celt_udiv(-n, d);
diff --git a/thirdparty/opus/celt/entdec.h b/thirdparty/opus/celt/entdec.h
index 025fc1870d..d8ab318730 100644
--- a/thirdparty/opus/celt/entdec.h
+++ b/thirdparty/opus/celt/entdec.h
@@ -85,7 +85,7 @@ int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb);
The bits must have been encoded with ec_enc_uint().
No call to ec_dec_update() is necessary after this call.
_ft: The number of integers that can be decoded (one more than the max).
- This must be at least 2, and no more than 2**32-1.
+ This must be at least one, and no more than 2**32-1.
Return: The decoded bits.*/
opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft);
diff --git a/thirdparty/opus/celt/entenc.h b/thirdparty/opus/celt/entenc.h
index f502eaf662..796bc4d572 100644
--- a/thirdparty/opus/celt/entenc.h
+++ b/thirdparty/opus/celt/entenc.h
@@ -67,7 +67,7 @@ void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb);
/*Encodes a raw unsigned integer in the stream.
_fl: The integer to encode.
_ft: The number of integers that can be encoded (one more than the max).
- This must be at least 2, and no more than 2**32-1.*/
+ This must be at least one, and no more than 2**32-1.*/
void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft);
/*Encodes a sequence of raw bits in the stream.
diff --git a/thirdparty/opus/celt/fixed_debug.h b/thirdparty/opus/celt/fixed_debug.h
index f435295234..d28227f5dc 100644
--- a/thirdparty/opus/celt/fixed_debug.h
+++ b/thirdparty/opus/celt/fixed_debug.h
@@ -59,14 +59,6 @@ extern opus_int64 celt_mips;
#define SHR(a,b) SHR32(a,b)
#define PSHR(a,b) PSHR32(a,b)
-/** Add two 32-bit values, ignore any overflows */
-#define ADD32_ovflw(a,b) (celt_mips+=2,(opus_val32)((opus_uint32)(a)+(opus_uint32)(b)))
-/** Subtract two 32-bit values, ignore any overflows */
-#define SUB32_ovflw(a,b) (celt_mips+=2,(opus_val32)((opus_uint32)(a)-(opus_uint32)(b)))
-/* Avoid MSVC warning C4146: unary minus operator applied to unsigned type */
-/** Negate 32-bit value, ignore any overflows */
-#define NEG32_ovflw(a) (celt_mips+=2,(opus_val32)(0-(opus_uint32)(a)))
-
static OPUS_INLINE short NEG16(int x)
{
int res;
@@ -235,11 +227,12 @@ static OPUS_INLINE int SHL32_(opus_int64 a, int shift, char *file, int line)
#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
#define ROUND16(x,a) (celt_mips--,EXTRACT16(PSHR32((x),(a))))
-#define SROUND16(x,a) (celt_mips--,EXTRACT16(SATURATE(PSHR32(x,a), 32767)));
-
#define HALF16(x) (SHR16(x,1))
#define HALF32(x) (SHR32(x,1))
+//#define SHR(a,shift) ((a) >> (shift))
+//#define SHL(a,shift) ((a) << (shift))
+
#define ADD16(a, b) ADD16_(a, b, __FILE__, __LINE__)
static OPUS_INLINE short ADD16_(int a, int b, char *file, int line)
{
diff --git a/thirdparty/opus/celt/fixed_generic.h b/thirdparty/opus/celt/fixed_generic.h
index 5f4abda76e..1cfd6d6989 100644
--- a/thirdparty/opus/celt/fixed_generic.h
+++ b/thirdparty/opus/celt/fixed_generic.h
@@ -104,9 +104,6 @@
/** Shift by a and round-to-neareast 32-bit value. Result is a 16-bit value */
#define ROUND16(x,a) (EXTRACT16(PSHR32((x),(a))))
-/** Shift by a and round-to-neareast 32-bit value. Result is a saturated 16-bit value */
-#define SROUND16(x,a) EXTRACT16(SATURATE(PSHR32(x,a), 32767));
-
/** Divide by two */
#define HALF16(x) (SHR16(x,1))
#define HALF32(x) (SHR32(x,1))
@@ -120,14 +117,6 @@
/** Subtract two 32-bit values */
#define SUB32(a,b) ((opus_val32)(a)-(opus_val32)(b))
-/** Add two 32-bit values, ignore any overflows */
-#define ADD32_ovflw(a,b) ((opus_val32)((opus_uint32)(a)+(opus_uint32)(b)))
-/** Subtract two 32-bit values, ignore any overflows */
-#define SUB32_ovflw(a,b) ((opus_val32)((opus_uint32)(a)-(opus_uint32)(b)))
-/* Avoid MSVC warning C4146: unary minus operator applied to unsigned type */
-/** Negate 32-bit value, ignore any overflows */
-#define NEG32_ovflw(a) ((opus_val32)(0-(opus_uint32)(a)))
-
/** 16x16 multiplication where the result fits in 16 bits */
#define MULT16_16_16(a,b) ((((opus_val16)(a))*((opus_val16)(b))))
diff --git a/thirdparty/opus/celt/float_cast.h b/thirdparty/opus/celt/float_cast.h
index 889dae965f..ed5a39b543 100644
--- a/thirdparty/opus/celt/float_cast.h
+++ b/thirdparty/opus/celt/float_cast.h
@@ -61,13 +61,7 @@
** the config.h file.
*/
-/* With GCC, when SSE is available, the fastest conversion is cvtss2si. */
-#if defined(__GNUC__) && defined(__SSE__)
-
-#include <xmmintrin.h>
-static OPUS_INLINE opus_int32 float2int(float x) {return _mm_cvt_ss2si(_mm_set_ss(x));}
-
-#elif defined(HAVE_LRINTF)
+#if (HAVE_LRINTF)
/* These defines enable functionality introduced with the 1999 ISO C
** standard. They must be defined before the inclusion of math.h to
@@ -96,10 +90,10 @@ static OPUS_INLINE opus_int32 float2int(float x) {return _mm_cvt_ss2si(_mm_set_s
#include <math.h>
#define float2int(x) lrint(x)
-#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined(_M_X64) || (defined(_M_IX86_FP) && _M_IX86_FP >= 1))
+#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && defined (_M_X64)
#include <xmmintrin.h>
- static __inline long int float2int(float value)
+ __inline long int float2int(float value)
{
return _mm_cvtss_si32(_mm_load_ss(&value));
}
@@ -110,7 +104,7 @@ static OPUS_INLINE opus_int32 float2int(float x) {return _mm_cvt_ss2si(_mm_set_s
** Therefore implement OPUS_INLINE versions of these functions here.
*/
- static __inline long int
+ __inline long int
float2int (float flt)
{ int intgr;
diff --git a/thirdparty/opus/celt/kiss_fft.c b/thirdparty/opus/celt/kiss_fft.c
index 83775165d8..1f8fd05321 100644
--- a/thirdparty/opus/celt/kiss_fft.c
+++ b/thirdparty/opus/celt/kiss_fft.c
@@ -82,8 +82,8 @@ static void kf_bfly2(
C_SUB( Fout2[0] , Fout[0] , t );
C_ADDTO( Fout[0] , t );
- t.r = S_MUL(ADD32_ovflw(Fout2[1].r, Fout2[1].i), tw);
- t.i = S_MUL(SUB32_ovflw(Fout2[1].i, Fout2[1].r), tw);
+ t.r = S_MUL(Fout2[1].r+Fout2[1].i, tw);
+ t.i = S_MUL(Fout2[1].i-Fout2[1].r, tw);
C_SUB( Fout2[1] , Fout[1] , t );
C_ADDTO( Fout[1] , t );
@@ -92,8 +92,8 @@ static void kf_bfly2(
C_SUB( Fout2[2] , Fout[2] , t );
C_ADDTO( Fout[2] , t );
- t.r = S_MUL(SUB32_ovflw(Fout2[3].i, Fout2[3].r), tw);
- t.i = S_MUL(NEG32_ovflw(ADD32_ovflw(Fout2[3].i, Fout2[3].r)), tw);
+ t.r = S_MUL(Fout2[3].i-Fout2[3].r, tw);
+ t.i = S_MUL(-Fout2[3].i-Fout2[3].r, tw);
C_SUB( Fout2[3] , Fout[3] , t );
C_ADDTO( Fout[3] , t );
Fout += 8;
@@ -126,10 +126,10 @@ static void kf_bfly4(
C_ADDTO( *Fout , scratch1 );
C_SUB( scratch1 , Fout[1] , Fout[3] );
- Fout[1].r = ADD32_ovflw(scratch0.r, scratch1.i);
- Fout[1].i = SUB32_ovflw(scratch0.i, scratch1.r);
- Fout[3].r = SUB32_ovflw(scratch0.r, scratch1.i);
- Fout[3].i = ADD32_ovflw(scratch0.i, scratch1.r);
+ Fout[1].r = scratch0.r + scratch1.i;
+ Fout[1].i = scratch0.i - scratch1.r;
+ Fout[3].r = scratch0.r - scratch1.i;
+ Fout[3].i = scratch0.i + scratch1.r;
Fout+=4;
}
} else {
@@ -160,10 +160,10 @@ static void kf_bfly4(
tw3 += fstride*3;
C_ADDTO( *Fout , scratch[3] );
- Fout[m].r = ADD32_ovflw(scratch[5].r, scratch[4].i);
- Fout[m].i = SUB32_ovflw(scratch[5].i, scratch[4].r);
- Fout[m3].r = SUB32_ovflw(scratch[5].r, scratch[4].i);
- Fout[m3].i = ADD32_ovflw(scratch[5].i, scratch[4].r);
+ Fout[m].r = scratch[5].r + scratch[4].i;
+ Fout[m].i = scratch[5].i - scratch[4].r;
+ Fout[m3].r = scratch[5].r - scratch[4].i;
+ Fout[m3].i = scratch[5].i + scratch[4].r;
++Fout;
}
}
@@ -212,18 +212,18 @@ static void kf_bfly3(
tw1 += fstride;
tw2 += fstride*2;
- Fout[m].r = SUB32_ovflw(Fout->r, HALF_OF(scratch[3].r));
- Fout[m].i = SUB32_ovflw(Fout->i, HALF_OF(scratch[3].i));
+ Fout[m].r = Fout->r - HALF_OF(scratch[3].r);
+ Fout[m].i = Fout->i - HALF_OF(scratch[3].i);
C_MULBYSCALAR( scratch[0] , epi3.i );
C_ADDTO(*Fout,scratch[3]);
- Fout[m2].r = ADD32_ovflw(Fout[m].r, scratch[0].i);
- Fout[m2].i = SUB32_ovflw(Fout[m].i, scratch[0].r);
+ Fout[m2].r = Fout[m].r + scratch[0].i;
+ Fout[m2].i = Fout[m].i - scratch[0].r;
- Fout[m].r = SUB32_ovflw(Fout[m].r, scratch[0].i);
- Fout[m].i = ADD32_ovflw(Fout[m].i, scratch[0].r);
+ Fout[m].r -= scratch[0].i;
+ Fout[m].i += scratch[0].r;
++Fout;
} while(--k);
@@ -282,22 +282,22 @@ static void kf_bfly5(
C_ADD( scratch[8],scratch[2],scratch[3]);
C_SUB( scratch[9],scratch[2],scratch[3]);
- Fout0->r = ADD32_ovflw(Fout0->r, ADD32_ovflw(scratch[7].r, scratch[8].r));
- Fout0->i = ADD32_ovflw(Fout0->i, ADD32_ovflw(scratch[7].i, scratch[8].i));
+ Fout0->r += scratch[7].r + scratch[8].r;
+ Fout0->i += scratch[7].i + scratch[8].i;
- scratch[5].r = ADD32_ovflw(scratch[0].r, ADD32_ovflw(S_MUL(scratch[7].r,ya.r), S_MUL(scratch[8].r,yb.r)));
- scratch[5].i = ADD32_ovflw(scratch[0].i, ADD32_ovflw(S_MUL(scratch[7].i,ya.r), S_MUL(scratch[8].i,yb.r)));
+ scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r);
+ scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r);
- scratch[6].r = ADD32_ovflw(S_MUL(scratch[10].i,ya.i), S_MUL(scratch[9].i,yb.i));
- scratch[6].i = NEG32_ovflw(ADD32_ovflw(S_MUL(scratch[10].r,ya.i), S_MUL(scratch[9].r,yb.i)));
+ scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i);
+ scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i);
C_SUB(*Fout1,scratch[5],scratch[6]);
C_ADD(*Fout4,scratch[5],scratch[6]);
- scratch[11].r = ADD32_ovflw(scratch[0].r, ADD32_ovflw(S_MUL(scratch[7].r,yb.r), S_MUL(scratch[8].r,ya.r)));
- scratch[11].i = ADD32_ovflw(scratch[0].i, ADD32_ovflw(S_MUL(scratch[7].i,yb.r), S_MUL(scratch[8].i,ya.r)));
- scratch[12].r = SUB32_ovflw(S_MUL(scratch[9].i,ya.i), S_MUL(scratch[10].i,yb.i));
- scratch[12].i = SUB32_ovflw(S_MUL(scratch[10].r,yb.i), S_MUL(scratch[9].r,ya.i));
+ scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r);
+ scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r);
+ scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i);
+ scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i);
C_ADD(*Fout2,scratch[11],scratch[12]);
C_SUB(*Fout3,scratch[11],scratch[12]);
diff --git a/thirdparty/opus/celt/mathops.c b/thirdparty/opus/celt/mathops.c
index 6ee9b9e101..21a01f52e4 100644
--- a/thirdparty/opus/celt/mathops.c
+++ b/thirdparty/opus/celt/mathops.c
@@ -38,8 +38,7 @@
#include "mathops.h"
/*Compute floor(sqrt(_val)) with exact arithmetic.
- _val must be greater than 0.
- This has been tested on all possible 32-bit inputs greater than 0.*/
+ This has been tested on all possible 32-bit inputs.*/
unsigned isqrt32(opus_uint32 _val){
unsigned b;
unsigned g;
@@ -183,7 +182,7 @@ opus_val32 celt_rcp(opus_val32 x)
int i;
opus_val16 n;
opus_val16 r;
- celt_sig_assert(x>0);
+ celt_assert2(x>0, "celt_rcp() only defined for positive values");
i = celt_ilog2(x);
/* n is Q15 with range [0,1). */
n = VSHR32(x,i-15)-32768;
diff --git a/thirdparty/opus/celt/mathops.h b/thirdparty/opus/celt/mathops.h
index 5e86ff0dd2..a0525a9610 100644
--- a/thirdparty/opus/celt/mathops.h
+++ b/thirdparty/opus/celt/mathops.h
@@ -38,44 +38,11 @@
#include "entcode.h"
#include "os_support.h"
-#define PI 3.141592653f
-
/* Multiplies two 16-bit fractional values. Bit-exactness of this macro is important */
#define FRAC_MUL16(a,b) ((16384+((opus_int32)(opus_int16)(a)*(opus_int16)(b)))>>15)
unsigned isqrt32(opus_uint32 _val);
-/* CELT doesn't need it for fixed-point, by analysis.c does. */
-#if !defined(FIXED_POINT) || defined(ANALYSIS_C)
-#define cA 0.43157974f
-#define cB 0.67848403f
-#define cC 0.08595542f
-#define cE ((float)PI/2)
-static OPUS_INLINE float fast_atan2f(float y, float x) {
- float x2, y2;
- x2 = x*x;
- y2 = y*y;
- /* For very small values, we don't care about the answer, so
- we can just return 0. */
- if (x2 + y2 < 1e-18f)
- {
- return 0;
- }
- if(x2<y2){
- float den = (y2 + cB*x2) * (y2 + cC*x2);
- return -x*y*(y2 + cA*x2) / den + (y<0 ? -cE : cE);
- }else{
- float den = (x2 + cB*y2) * (x2 + cC*y2);
- return x*y*(x2 + cA*y2) / den + (y<0 ? -cE : cE) - (x*y<0 ? -cE : cE);
- }
-}
-#undef cA
-#undef cB
-#undef cC
-#undef cE
-#endif
-
-
#ifndef OVERRIDE_CELT_MAXABS16
static OPUS_INLINE opus_val32 celt_maxabs16(const opus_val16 *x, int len)
{
@@ -113,6 +80,7 @@ static OPUS_INLINE opus_val32 celt_maxabs32(const opus_val32 *x, int len)
#ifndef FIXED_POINT
+#define PI 3.141592653f
#define celt_sqrt(x) ((float)sqrt(x))
#define celt_rsqrt(x) (1.f/celt_sqrt(x))
#define celt_rsqrt_norm(x) (celt_rsqrt(x))
@@ -179,7 +147,7 @@ static OPUS_INLINE float celt_exp2(float x)
/** Integer log in base2. Undefined for zero and negative numbers */
static OPUS_INLINE opus_int16 celt_ilog2(opus_int32 x)
{
- celt_sig_assert(x>0);
+ celt_assert2(x>0, "celt_ilog2() only defined for strictly positive numbers");
return EC_ILOG(x)-1;
}
#endif
diff --git a/thirdparty/opus/celt/mdct.c b/thirdparty/opus/celt/mdct.c
index 5c6dab5b75..5315ad11a3 100644
--- a/thirdparty/opus/celt/mdct.c
+++ b/thirdparty/opus/celt/mdct.c
@@ -270,8 +270,8 @@ void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_sca
int rev;
kiss_fft_scalar yr, yi;
rev = *bitrev++;
- yr = ADD32_ovflw(S_MUL(*xp2, t[i]), S_MUL(*xp1, t[N4+i]));
- yi = SUB32_ovflw(S_MUL(*xp1, t[i]), S_MUL(*xp2, t[N4+i]));
+ yr = S_MUL(*xp2, t[i]) + S_MUL(*xp1, t[N4+i]);
+ yi = S_MUL(*xp1, t[i]) - S_MUL(*xp2, t[N4+i]);
/* We swap real and imag because we use an FFT instead of an IFFT. */
yp[2*rev+1] = yr;
yp[2*rev] = yi;
@@ -301,8 +301,8 @@ void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_sca
t0 = t[i];
t1 = t[N4+i];
/* We'd scale up by 2 here, but instead it's done when mixing the windows */
- yr = ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1));
- yi = SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0));
+ yr = S_MUL(re,t0) + S_MUL(im,t1);
+ yi = S_MUL(re,t1) - S_MUL(im,t0);
/* We swap real and imag because we're using an FFT instead of an IFFT. */
re = yp1[1];
im = yp1[0];
@@ -312,8 +312,8 @@ void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_sca
t0 = t[(N4-i-1)];
t1 = t[(N2-i-1)];
/* We'd scale up by 2 here, but instead it's done when mixing the windows */
- yr = ADD32_ovflw(S_MUL(re,t0), S_MUL(im,t1));
- yi = SUB32_ovflw(S_MUL(re,t1), S_MUL(im,t0));
+ yr = S_MUL(re,t0) + S_MUL(im,t1);
+ yi = S_MUL(re,t1) - S_MUL(im,t0);
yp1[0] = yr;
yp0[1] = yi;
yp0 += 2;
@@ -333,8 +333,8 @@ void clt_mdct_backward_c(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_sca
kiss_fft_scalar x1, x2;
x1 = *xp1;
x2 = *yp1;
- *yp1++ = SUB32_ovflw(MULT16_32_Q15(*wp2, x2), MULT16_32_Q15(*wp1, x1));
- *xp1-- = ADD32_ovflw(MULT16_32_Q15(*wp1, x2), MULT16_32_Q15(*wp2, x1));
+ *yp1++ = MULT16_32_Q15(*wp2, x2) - MULT16_32_Q15(*wp1, x1);
+ *xp1-- = MULT16_32_Q15(*wp1, x2) + MULT16_32_Q15(*wp2, x1);
wp1++;
wp2--;
}
diff --git a/thirdparty/opus/celt/mips/celt_mipsr1.h b/thirdparty/opus/celt/mips/celt_mipsr1.h
index c332fe0471..e85661a661 100644
--- a/thirdparty/opus/celt/mips/celt_mipsr1.h
+++ b/thirdparty/opus/celt/mips/celt_mipsr1.h
@@ -53,7 +53,6 @@
#include "celt_lpc.h"
#include "vq.h"
-#define OVERRIDE_COMB_FILTER_CONST
#define OVERRIDE_comb_filter
void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N,
opus_val16 g0, opus_val16 g1, int tapset0, int tapset1,
diff --git a/thirdparty/opus/celt/mips/vq_mipsr1.h b/thirdparty/opus/celt/mips/vq_mipsr1.h
index f26a33e755..54cef86133 100644
--- a/thirdparty/opus/celt/mips/vq_mipsr1.h
+++ b/thirdparty/opus/celt/mips/vq_mipsr1.h
@@ -36,6 +36,11 @@
#include "mathops.h"
#include "arch.h"
+static unsigned extract_collapse_mask(int *iy, int N, int B);
+static void normalise_residual(int * OPUS_RESTRICT iy, celt_norm * OPUS_RESTRICT X, int N, opus_val32 Ryy, opus_val16 gain);
+static void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread);
+static void renormalise_vector_mips(celt_norm *X, int N, opus_val16 gain, int arch);
+
#define OVERRIDE_vq_exp_rotation1
static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_val16 s)
{
@@ -64,7 +69,11 @@ static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_
}
#define OVERRIDE_renormalise_vector
-void renormalise_vector(celt_norm *X, int N, opus_val16 gain, int arch)
+
+#define renormalise_vector(X, N, gain, arch) \
+ (renormalise_vector_mips(X, N, gain, arch))
+
+void renormalise_vector_mips(celt_norm *X, int N, opus_val16 gain, int arch)
{
int i;
#ifdef FIXED_POINT
diff --git a/thirdparty/opus/celt/modes.c b/thirdparty/opus/celt/modes.c
index 390c5e8aeb..911686e905 100644
--- a/thirdparty/opus/celt/modes.c
+++ b/thirdparty/opus/celt/modes.c
@@ -427,7 +427,7 @@ void opus_custom_mode_destroy(CELTMode *mode)
}
#endif /* CUSTOM_MODES_ONLY */
opus_free((opus_int16*)mode->eBands);
- opus_free((unsigned char*)mode->allocVectors);
+ opus_free((opus_int16*)mode->allocVectors);
opus_free((opus_val16*)mode->window);
opus_free((opus_int16*)mode->logN);
diff --git a/thirdparty/opus/celt/pitch.c b/thirdparty/opus/celt/pitch.c
index 872582a48a..bf46e7d562 100644
--- a/thirdparty/opus/celt/pitch.c
+++ b/thirdparty/opus/celt/pitch.c
@@ -102,9 +102,11 @@ static void find_best_pitch(opus_val32 *xcorr, opus_val16 *y, int len,
}
}
-static void celt_fir5(opus_val16 *x,
+static void celt_fir5(const opus_val16 *x,
const opus_val16 *num,
- int N)
+ opus_val16 *y,
+ int N,
+ opus_val16 *mem)
{
int i;
opus_val16 num0, num1, num2, num3, num4;
@@ -114,11 +116,11 @@ static void celt_fir5(opus_val16 *x,
num2=num[2];
num3=num[3];
num4=num[4];
- mem0=0;
- mem1=0;
- mem2=0;
- mem3=0;
- mem4=0;
+ mem0=mem[0];
+ mem1=mem[1];
+ mem2=mem[2];
+ mem3=mem[3];
+ mem4=mem[4];
for (i=0;i<N;i++)
{
opus_val32 sum = SHL32(EXTEND32(x[i]), SIG_SHIFT);
@@ -132,8 +134,13 @@ static void celt_fir5(opus_val16 *x,
mem2 = mem1;
mem1 = mem0;
mem0 = x[i];
- x[i] = ROUND16(sum, SIG_SHIFT);
+ y[i] = ROUND16(sum, SIG_SHIFT);
}
+ mem[0]=mem0;
+ mem[1]=mem1;
+ mem[2]=mem2;
+ mem[3]=mem3;
+ mem[4]=mem4;
}
@@ -143,7 +150,7 @@ void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x
int i;
opus_val32 ac[5];
opus_val16 tmp=Q15ONE;
- opus_val16 lpc[4];
+ opus_val16 lpc[4], mem[5]={0,0,0,0,0};
opus_val16 lpc2[5];
opus_val16 c1 = QCONST16(.8f,15);
#ifdef FIXED_POINT
@@ -204,7 +211,7 @@ void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x
lpc2[2] = lpc[2] + MULT16_16_Q15(c1,lpc[1]);
lpc2[3] = lpc[3] + MULT16_16_Q15(c1,lpc[2]);
lpc2[4] = MULT16_16_Q15(c1,lpc[3]);
- celt_fir5(x_lp, lpc2, len>>1);
+ celt_fir5(x_lp, lpc2, x_lp, len>>1, mem);
}
/* Pure C implementation. */
@@ -213,8 +220,13 @@ opus_val32
#else
void
#endif
+#if defined(OVERRIDE_PITCH_XCORR)
celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y,
+ opus_val32 *xcorr, int len, int max_pitch)
+#else
+celt_pitch_xcorr(const opus_val16 *_x, const opus_val16 *_y,
opus_val32 *xcorr, int len, int max_pitch, int arch)
+#endif
{
#if 0 /* This is a simple version of the pitch correlation that should work
@@ -249,11 +261,15 @@ celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y,
opus_val32 maxcorr=1;
#endif
celt_assert(max_pitch>0);
- celt_sig_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0);
+ celt_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0);
for (i=0;i<max_pitch-3;i+=4)
{
opus_val32 sum[4]={0,0,0,0};
+#if defined(OVERRIDE_PITCH_XCORR)
+ xcorr_kernel_c(_x, _y+i, sum, len);
+#else
xcorr_kernel(_x, _y+i, sum, len, arch);
+#endif
xcorr[i]=sum[0];
xcorr[i+1]=sum[1];
xcorr[i+2]=sum[2];
@@ -269,7 +285,11 @@ celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y,
for (;i<max_pitch;i++)
{
opus_val32 sum;
+#if defined(OVERRIDE_PITCH_XCORR)
+ sum = celt_inner_prod_c(_x, _y+i, len);
+#else
sum = celt_inner_prod(_x, _y+i, len, arch);
+#endif
xcorr[i] = sum;
#ifdef FIXED_POINT
maxcorr = MAX32(maxcorr, sum);
@@ -358,7 +378,7 @@ void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTR
for (j=0;j<len>>1;j++)
sum += SHR32(MULT16_16(x_lp[j],y[i+j]), shift);
#else
- sum = celt_inner_prod(x_lp, y+i, len>>1, arch);
+ sum = celt_inner_prod_c(x_lp, y+i, len>>1);
#endif
xcorr[i] = MAX32(-1, sum);
#ifdef FIXED_POINT
@@ -404,7 +424,7 @@ static opus_val16 compute_pitch_gain(opus_val32 xy, opus_val32 xx, opus_val32 yy
sx = celt_ilog2(xx)-14;
sy = celt_ilog2(yy)-14;
shift = sx + sy;
- x2y2 = SHR32(MULT16_16(VSHR32(xx, sx), VSHR32(yy, sy)), 14);
+ x2y2 = MULT16_16_Q14(VSHR32(xx, sx), VSHR32(yy, sy));
if (shift & 1) {
if (x2y2 < 32768)
{
diff --git a/thirdparty/opus/celt/pitch.h b/thirdparty/opus/celt/pitch.h
index e425f56aea..d3503532a0 100644
--- a/thirdparty/opus/celt/pitch.h
+++ b/thirdparty/opus/celt/pitch.h
@@ -46,7 +46,8 @@
#include "mips/pitch_mipsr1.h"
#endif
-#if (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
+#if ((defined(OPUS_ARM_ASM) && defined(FIXED_POINT)) \
+ || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
# include "arm/pitch_arm.h"
#endif
@@ -183,10 +184,17 @@ opus_val32
void
#endif
celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y,
+ opus_val32 *xcorr, int len, int max_pitch);
+
+#if !defined(OVERRIDE_PITCH_XCORR)
+#ifdef FIXED_POINT
+opus_val32
+#else
+void
+#endif
+celt_pitch_xcorr(const opus_val16 *_x, const opus_val16 *_y,
opus_val32 *xcorr, int len, int max_pitch, int arch);
-#ifndef OVERRIDE_PITCH_XCORR
-# define celt_pitch_xcorr celt_pitch_xcorr_c
#endif
#endif
diff --git a/thirdparty/opus/celt/quant_bands.c b/thirdparty/opus/celt/quant_bands.c
index 39a221eda5..95076e0af2 100644
--- a/thirdparty/opus/celt/quant_bands.c
+++ b/thirdparty/opus/celt/quant_bands.c
@@ -418,7 +418,6 @@ void quant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *ol
offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);
#endif
oldEBands[i+c*m->nbEBands] += offset;
- error[i+c*m->nbEBands] -= offset;
bits_left--;
} while (++c < C);
}
@@ -457,7 +456,7 @@ void unquant_coarse_energy(const CELTMode *m, int start, int end, opus_val16 *ol
/* It would be better to express this invariant as a
test on C at function entry, but that isn't enough
to make the static analyzer happy. */
- celt_sig_assert(c<2);
+ celt_assert(c<2);
tell = ec_tell(dec);
if(budget-tell>=15)
{
@@ -548,15 +547,9 @@ void amp2Log2(const CELTMode *m, int effEnd, int end,
c=0;
do {
for (i=0;i<effEnd;i++)
- {
bandLogE[i+c*m->nbEBands] =
- celt_log2(bandE[i+c*m->nbEBands])
+ celt_log2(SHL32(bandE[i+c*m->nbEBands],2))
- SHL16((opus_val16)eMeans[i],6);
-#ifdef FIXED_POINT
- /* Compensate for bandE[] being Q12 but celt_log2() taking a Q14 input. */
- bandLogE[i+c*m->nbEBands] += QCONST16(2.f, DB_SHIFT);
-#endif
- }
for (i=effEnd;i<end;i++)
bandLogE[c*m->nbEBands+i] = -QCONST16(14.f,DB_SHIFT);
} while (++c < C);
diff --git a/thirdparty/opus/celt/rate.c b/thirdparty/opus/celt/rate.c
index 465e1ba26c..7dfa5be8a6 100644
--- a/thirdparty/opus/celt/rate.c
+++ b/thirdparty/opus/celt/rate.c
@@ -348,17 +348,12 @@ static OPUS_INLINE int interp_bits2pulses(const CELTMode *m, int start, int end,
/*This if() block is the only part of the allocation function that
is not a mandatory part of the bitstream: any bands we choose to
skip here must be explicitly signaled.*/
- int depth_threshold;
- /*We choose a threshold with some hysteresis to keep bands from
- fluctuating in and out, but we try not to fold below a certain point. */
- if (codedBands > 17)
- depth_threshold = j<prev ? 7 : 9;
- else
- depth_threshold = 0;
+ /*Choose a threshold with some hysteresis to keep bands from
+ fluctuating in and out.*/
#ifdef FUZZING
if ((rand()&0x1) == 0)
#else
- if (codedBands<=start+2 || (band_bits > (depth_threshold*band_width<<LM<<BITRES)>>4 && j<=signalBandwidth))
+ if (codedBands<=start+2 || (band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4 && j<=signalBandwidth))
#endif
{
ec_enc_bit_logp(ec, 1, 1);
@@ -529,7 +524,7 @@ static OPUS_INLINE int interp_bits2pulses(const CELTMode *m, int start, int end,
return codedBands;
}
-int clt_compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stereo,
+int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stereo,
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)
{
int lo, hi, len, j;
diff --git a/thirdparty/opus/celt/rate.h b/thirdparty/opus/celt/rate.h
index fad5e412da..515f7687ce 100644
--- a/thirdparty/opus/celt/rate.h
+++ b/thirdparty/opus/celt/rate.h
@@ -95,7 +95,7 @@ static OPUS_INLINE int pulses2bits(const CELTMode *m, int band, int LM, int puls
@param pulses Number of pulses per band (returned)
@return Total number of bits allocated
*/
-int clt_compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stereo,
+int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stero,
opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth);
#endif
diff --git a/thirdparty/opus/celt/static_modes_fixed_arm_ne10.h b/thirdparty/opus/celt/static_modes_fixed_arm_ne10.h
index 7623092192..b8ef0cee98 100644
--- a/thirdparty/opus/celt/static_modes_fixed_arm_ne10.h
+++ b/thirdparty/opus/celt/static_modes_fixed_arm_ne10.h
@@ -1,7 +1,7 @@
/* The contents of this file was automatically generated by
* dump_mode_arm_ne10.c with arguments: 48000 960
* It contains static definitions for some pre-defined modes. */
-#include <NE10_types.h>
+#include <NE10_init.h>
#ifndef NE10_FFT_PARAMS48000_960
#define NE10_FFT_PARAMS48000_960
diff --git a/thirdparty/opus/celt/static_modes_float_arm_ne10.h b/thirdparty/opus/celt/static_modes_float_arm_ne10.h
index 66e1abb101..934a82a420 100644
--- a/thirdparty/opus/celt/static_modes_float_arm_ne10.h
+++ b/thirdparty/opus/celt/static_modes_float_arm_ne10.h
@@ -1,7 +1,7 @@
/* The contents of this file was automatically generated by
* dump_mode_arm_ne10.c with arguments: 48000 960
* It contains static definitions for some pre-defined modes. */
-#include <NE10_types.h>
+#include <NE10_init.h>
#ifndef NE10_FFT_PARAMS48000_960
#define NE10_FFT_PARAMS48000_960
diff --git a/thirdparty/opus/celt/tests/test_unit_cwrs32.c b/thirdparty/opus/celt/tests/test_unit_cwrs32.c
new file mode 100644
index 0000000000..36dd8af5f5
--- /dev/null
+++ b/thirdparty/opus/celt/tests/test_unit_cwrs32.c
@@ -0,0 +1,161 @@
+/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation,
+ Gregory Maxwell
+ Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#ifndef CUSTOM_MODES
+#define CUSTOM_MODES
+#else
+#define TEST_CUSTOM_MODES
+#endif
+
+#define CELT_C
+#include "stack_alloc.h"
+#include "entenc.c"
+#include "entdec.c"
+#include "entcode.c"
+#include "cwrs.c"
+#include "mathops.c"
+#include "rate.h"
+
+#define NMAX (240)
+#define KMAX (128)
+
+#ifdef TEST_CUSTOM_MODES
+
+#define NDIMS (44)
+static const int pn[NDIMS]={
+ 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 18, 20, 22,
+ 24, 26, 28, 30, 32, 36, 40, 44, 48,
+ 52, 56, 60, 64, 72, 80, 88, 96, 104,
+ 112, 120, 128, 144, 160, 176, 192, 208
+};
+static const int pkmax[NDIMS]={
+ 128, 128, 128, 128, 88, 52, 36, 26, 22,
+ 18, 16, 15, 13, 12, 12, 11, 10, 9,
+ 9, 8, 8, 7, 7, 7, 7, 6, 6,
+ 6, 6, 6, 5, 5, 5, 5, 5, 5,
+ 4, 4, 4, 4, 4, 4, 4, 4
+};
+
+#else /* TEST_CUSTOM_MODES */
+
+#define NDIMS (22)
+static const int pn[NDIMS]={
+ 2, 3, 4, 6, 8, 9, 11, 12, 16,
+ 18, 22, 24, 32, 36, 44, 48, 64, 72,
+ 88, 96, 144, 176
+};
+static const int pkmax[NDIMS]={
+ 128, 128, 128, 88, 36, 26, 18, 16, 12,
+ 11, 9, 9, 7, 7, 6, 6, 5, 5,
+ 5, 5, 4, 4
+};
+
+#endif
+
+int main(void){
+ int t;
+ int n;
+ ALLOC_STACK;
+ for(t=0;t<NDIMS;t++){
+ int pseudo;
+ n=pn[t];
+ for(pseudo=1;pseudo<41;pseudo++)
+ {
+ int k;
+#if defined(SMALL_FOOTPRINT)
+ opus_uint32 uu[KMAX+2U];
+#endif
+ opus_uint32 inc;
+ opus_uint32 nc;
+ opus_uint32 i;
+ k=get_pulses(pseudo);
+ if (k>pkmax[t])break;
+ printf("Testing CWRS with N=%i, K=%i...\n",n,k);
+#if defined(SMALL_FOOTPRINT)
+ nc=ncwrs_urow(n,k,uu);
+#else
+ nc=CELT_PVQ_V(n,k);
+#endif
+ inc=nc/20000;
+ if(inc<1)inc=1;
+ for(i=0;i<nc;i+=inc){
+#if defined(SMALL_FOOTPRINT)
+ opus_uint32 u[KMAX+2U];
+#endif
+ int y[NMAX];
+ int sy;
+ opus_uint32 v;
+ opus_uint32 ii;
+ int j;
+#if defined(SMALL_FOOTPRINT)
+ memcpy(u,uu,(k+2U)*sizeof(*u));
+ cwrsi(n,k,i,y,u);
+#else
+ cwrsi(n,k,i,y);
+#endif
+ sy=0;
+ for(j=0;j<n;j++)sy+=abs(y[j]);
+ if(sy!=k){
+ fprintf(stderr,"N=%d Pulse count mismatch in cwrsi (%d!=%d).\n",
+ n,sy,k);
+ return 99;
+ }
+ /*printf("%6u of %u:",i,nc);
+ for(j=0;j<n;j++)printf(" %+3i",y[j]);
+ printf(" ->");*/
+#if defined(SMALL_FOOTPRINT)
+ ii=icwrs(n,k,&v,y,u);
+#else
+ ii=icwrs(n,y);
+ v=CELT_PVQ_V(n,k);
+#endif
+ if(ii!=i){
+ fprintf(stderr,"Combination-index mismatch (%lu!=%lu).\n",
+ (long)ii,(long)i);
+ return 1;
+ }
+ if(v!=nc){
+ fprintf(stderr,"Combination count mismatch (%lu!=%lu).\n",
+ (long)v,(long)nc);
+ return 2;
+ }
+ /*printf(" %6u\n",i);*/
+ }
+ /*printf("\n");*/
+ }
+ }
+ return 0;
+}
diff --git a/thirdparty/opus/celt/tests/test_unit_dft.c b/thirdparty/opus/celt/tests/test_unit_dft.c
new file mode 100644
index 0000000000..6166eb0e4f
--- /dev/null
+++ b/thirdparty/opus/celt/tests/test_unit_dft.c
@@ -0,0 +1,189 @@
+/* Copyright (c) 2008 Xiph.Org Foundation
+ Written by Jean-Marc Valin */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define SKIP_CONFIG_H
+
+#ifndef CUSTOM_MODES
+#define CUSTOM_MODES
+#endif
+
+#include <stdio.h>
+
+#define CELT_C
+#define TEST_UNIT_DFT_C
+#include "stack_alloc.h"
+#include "kiss_fft.h"
+#include "kiss_fft.c"
+#include "mathops.c"
+#include "entcode.c"
+
+#if defined(OPUS_X86_MAY_HAVE_SSE2) || defined(OPUS_X86_MAY_HAVE_SSE4_1)
+# include "x86/x86cpu.c"
+#elif defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
+# include "arm/armcpu.c"
+# include "celt_lpc.c"
+# include "pitch.c"
+# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
+# include "arm/celt_neon_intr.c"
+# if defined(HAVE_ARM_NE10)
+# include "mdct.c"
+# include "arm/celt_ne10_fft.c"
+# include "arm/celt_ne10_mdct.c"
+# endif
+# endif
+# include "arm/arm_celt_map.c"
+#endif
+
+#ifndef M_PI
+#define M_PI 3.141592653
+#endif
+
+int ret = 0;
+
+void check(kiss_fft_cpx * in,kiss_fft_cpx * out,int nfft,int isinverse)
+{
+ int bin,k;
+ double errpow=0,sigpow=0, snr;
+
+ for (bin=0;bin<nfft;++bin) {
+ double ansr = 0;
+ double ansi = 0;
+ double difr;
+ double difi;
+
+ for (k=0;k<nfft;++k) {
+ double phase = -2*M_PI*bin*k/nfft;
+ double re = cos(phase);
+ double im = sin(phase);
+ if (isinverse)
+ im = -im;
+
+ if (!isinverse)
+ {
+ re /= nfft;
+ im /= nfft;
+ }
+
+ ansr += in[k].r * re - in[k].i * im;
+ ansi += in[k].r * im + in[k].i * re;
+ }
+ /*printf ("%d %d ", (int)ansr, (int)ansi);*/
+ difr = ansr - out[bin].r;
+ difi = ansi - out[bin].i;
+ errpow += difr*difr + difi*difi;
+ sigpow += ansr*ansr+ansi*ansi;
+ }
+ snr = 10*log10(sigpow/errpow);
+ printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
+ if (snr<60) {
+ printf( "** poor snr: %f ** \n", snr);
+ ret = 1;
+ }
+}
+
+void test1d(int nfft,int isinverse,int arch)
+{
+ size_t buflen = sizeof(kiss_fft_cpx)*nfft;
+
+ kiss_fft_cpx * in = (kiss_fft_cpx*)malloc(buflen);
+ kiss_fft_cpx * out= (kiss_fft_cpx*)malloc(buflen);
+ kiss_fft_state *cfg = opus_fft_alloc(nfft,0,0,arch);
+ int k;
+
+ for (k=0;k<nfft;++k) {
+ in[k].r = (rand() % 32767) - 16384;
+ in[k].i = (rand() % 32767) - 16384;
+ }
+
+ for (k=0;k<nfft;++k) {
+ in[k].r *= 32768;
+ in[k].i *= 32768;
+ }
+
+ if (isinverse)
+ {
+ for (k=0;k<nfft;++k) {
+ in[k].r /= nfft;
+ in[k].i /= nfft;
+ }
+ }
+
+ /*for (k=0;k<nfft;++k) printf("%d %d ", in[k].r, in[k].i);printf("\n");*/
+
+ if (isinverse)
+ opus_ifft(cfg,in,out, arch);
+ else
+ opus_fft(cfg,in,out, arch);
+
+ /*for (k=0;k<nfft;++k) printf("%d %d ", out[k].r, out[k].i);printf("\n");*/
+
+ check(in,out,nfft,isinverse);
+
+ free(in);
+ free(out);
+ opus_fft_free(cfg, arch);
+}
+
+int main(int argc,char ** argv)
+{
+ ALLOC_STACK;
+ int arch = opus_select_arch();
+
+ if (argc>1) {
+ int k;
+ for (k=1;k<argc;++k) {
+ test1d(atoi(argv[k]),0,arch);
+ test1d(atoi(argv[k]),1,arch);
+ }
+ }else{
+ test1d(32,0,arch);
+ test1d(32,1,arch);
+ test1d(128,0,arch);
+ test1d(128,1,arch);
+ test1d(256,0,arch);
+ test1d(256,1,arch);
+#ifndef RADIX_TWO_ONLY
+ test1d(36,0,arch);
+ test1d(36,1,arch);
+ test1d(50,0,arch);
+ test1d(50,1,arch);
+ test1d(60,0,arch);
+ test1d(60,1,arch);
+ test1d(120,0,arch);
+ test1d(120,1,arch);
+ test1d(240,0,arch);
+ test1d(240,1,arch);
+ test1d(480,0,arch);
+ test1d(480,1,arch);
+#endif
+ }
+ return ret;
+}
diff --git a/thirdparty/opus/celt/tests/test_unit_entropy.c b/thirdparty/opus/celt/tests/test_unit_entropy.c
new file mode 100644
index 0000000000..ff9265864c
--- /dev/null
+++ b/thirdparty/opus/celt/tests/test_unit_entropy.c
@@ -0,0 +1,382 @@
+/* Copyright (c) 2007-2011 Xiph.Org Foundation, Mozilla Corporation,
+ Gregory Maxwell
+ Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <time.h>
+#include "entcode.h"
+#include "entenc.h"
+#include "entdec.h"
+#include <string.h>
+
+#include "entenc.c"
+#include "entdec.c"
+#include "entcode.c"
+
+#ifndef M_LOG2E
+# define M_LOG2E 1.4426950408889634074
+#endif
+#define DATA_SIZE 10000000
+#define DATA_SIZE2 10000
+
+int main(int _argc,char **_argv){
+ ec_enc enc;
+ ec_dec dec;
+ long nbits;
+ long nbits2;
+ double entropy;
+ int ft;
+ int ftb;
+ int sz;
+ int i;
+ int ret;
+ unsigned int sym;
+ unsigned int seed;
+ unsigned char *ptr;
+ const char *env_seed;
+ ret=0;
+ entropy=0;
+ if (_argc > 2) {
+ fprintf(stderr, "Usage: %s [<seed>]\n", _argv[0]);
+ return 1;
+ }
+ env_seed = getenv("SEED");
+ if (_argc > 1)
+ seed = atoi(_argv[1]);
+ else if (env_seed)
+ seed = atoi(env_seed);
+ else
+ seed = time(NULL);
+ /*Testing encoding of raw bit values.*/
+ ptr = (unsigned char *)malloc(DATA_SIZE);
+ ec_enc_init(&enc,ptr, DATA_SIZE);
+ for(ft=2;ft<1024;ft++){
+ for(i=0;i<ft;i++){
+ entropy+=log(ft)*M_LOG2E;
+ ec_enc_uint(&enc,i,ft);
+ }
+ }
+ /*Testing encoding of raw bit values.*/
+ for(ftb=1;ftb<16;ftb++){
+ for(i=0;i<(1<<ftb);i++){
+ entropy+=ftb;
+ nbits=ec_tell(&enc);
+ ec_enc_bits(&enc,i,ftb);
+ nbits2=ec_tell(&enc);
+ if(nbits2-nbits!=ftb){
+ fprintf(stderr,"Used %li bits to encode %i bits directly.\n",
+ nbits2-nbits,ftb);
+ ret=-1;
+ }
+ }
+ }
+ nbits=ec_tell_frac(&enc);
+ ec_enc_done(&enc);
+ fprintf(stderr,
+ "Encoded %0.2lf bits of entropy to %0.2lf bits (%0.3lf%% wasted).\n",
+ entropy,ldexp(nbits,-3),100*(nbits-ldexp(entropy,3))/nbits);
+ fprintf(stderr,"Packed to %li bytes.\n",(long)ec_range_bytes(&enc));
+ ec_dec_init(&dec,ptr,DATA_SIZE);
+ for(ft=2;ft<1024;ft++){
+ for(i=0;i<ft;i++){
+ sym=ec_dec_uint(&dec,ft);
+ if(sym!=(unsigned)i){
+ fprintf(stderr,"Decoded %i instead of %i with ft of %i.\n",sym,i,ft);
+ ret=-1;
+ }
+ }
+ }
+ for(ftb=1;ftb<16;ftb++){
+ for(i=0;i<(1<<ftb);i++){
+ sym=ec_dec_bits(&dec,ftb);
+ if(sym!=(unsigned)i){
+ fprintf(stderr,"Decoded %i instead of %i with ftb of %i.\n",sym,i,ftb);
+ ret=-1;
+ }
+ }
+ }
+ nbits2=ec_tell_frac(&dec);
+ if(nbits!=nbits2){
+ fprintf(stderr,
+ "Reported number of bits used was %0.2lf, should be %0.2lf.\n",
+ ldexp(nbits2,-3),ldexp(nbits,-3));
+ ret=-1;
+ }
+ /*Testing an encoder bust prefers range coder data over raw bits.
+ This isn't a general guarantee, will only work for data that is buffered in
+ the encoder state and not yet stored in the user buffer, and should never
+ get used in practice.
+ It's mostly here for code coverage completeness.*/
+ /*Start with a 16-bit buffer.*/
+ ec_enc_init(&enc,ptr,2);
+ /*Write 7 raw bits.*/
+ ec_enc_bits(&enc,0x55,7);
+ /*Write 12.3 bits of range coder data.*/
+ ec_enc_uint(&enc,1,2);
+ ec_enc_uint(&enc,1,3);
+ ec_enc_uint(&enc,1,4);
+ ec_enc_uint(&enc,1,5);
+ ec_enc_uint(&enc,2,6);
+ ec_enc_uint(&enc,6,7);
+ ec_enc_done(&enc);
+ ec_dec_init(&dec,ptr,2);
+ if(!enc.error
+ /*The raw bits should have been overwritten by the range coder data.*/
+ ||ec_dec_bits(&dec,7)!=0x05
+ /*And all the range coder data should have been encoded correctly.*/
+ ||ec_dec_uint(&dec,2)!=1
+ ||ec_dec_uint(&dec,3)!=1
+ ||ec_dec_uint(&dec,4)!=1
+ ||ec_dec_uint(&dec,5)!=1
+ ||ec_dec_uint(&dec,6)!=2
+ ||ec_dec_uint(&dec,7)!=6){
+ fprintf(stderr,"Encoder bust overwrote range coder data with raw bits.\n");
+ ret=-1;
+ }
+ srand(seed);
+ fprintf(stderr,"Testing random streams... Random seed: %u (%.4X)\n", seed, rand() % 65536);
+ for(i=0;i<409600;i++){
+ unsigned *data;
+ unsigned *tell;
+ unsigned tell_bits;
+ int j;
+ int zeros;
+ ft=rand()/((RAND_MAX>>(rand()%11U))+1U)+10;
+ sz=rand()/((RAND_MAX>>(rand()%9U))+1U);
+ data=(unsigned *)malloc(sz*sizeof(*data));
+ tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
+ ec_enc_init(&enc,ptr,DATA_SIZE2);
+ zeros = rand()%13==0;
+ tell[0]=ec_tell_frac(&enc);
+ for(j=0;j<sz;j++){
+ if (zeros)
+ data[j]=0;
+ else
+ data[j]=rand()%ft;
+ ec_enc_uint(&enc,data[j],ft);
+ tell[j+1]=ec_tell_frac(&enc);
+ }
+ if (rand()%2==0)
+ while(ec_tell(&enc)%8 != 0)
+ ec_enc_uint(&enc, rand()%2, 2);
+ tell_bits = ec_tell(&enc);
+ ec_enc_done(&enc);
+ if(tell_bits!=(unsigned)ec_tell(&enc)){
+ fprintf(stderr,"ec_tell() changed after ec_enc_done(): %i instead of %i (Random seed: %u)\n",
+ ec_tell(&enc),tell_bits,seed);
+ ret=-1;
+ }
+ if ((tell_bits+7)/8 < ec_range_bytes(&enc))
+ {
+ fprintf (stderr, "ec_tell() lied, there's %i bytes instead of %d (Random seed: %u)\n",
+ ec_range_bytes(&enc), (tell_bits+7)/8,seed);
+ ret=-1;
+ }
+ ec_dec_init(&dec,ptr,DATA_SIZE2);
+ if(ec_tell_frac(&dec)!=tell[0]){
+ fprintf(stderr,
+ "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
+ 0,ec_tell_frac(&dec),tell[0],seed);
+ }
+ for(j=0;j<sz;j++){
+ sym=ec_dec_uint(&dec,ft);
+ if(sym!=data[j]){
+ fprintf(stderr,
+ "Decoded %i instead of %i with ft of %i at position %i of %i (Random seed: %u).\n",
+ sym,data[j],ft,j,sz,seed);
+ ret=-1;
+ }
+ if(ec_tell_frac(&dec)!=tell[j+1]){
+ fprintf(stderr,
+ "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
+ j+1,ec_tell_frac(&dec),tell[j+1],seed);
+ }
+ }
+ free(tell);
+ free(data);
+ }
+ /*Test compatibility between multiple different encode/decode routines.*/
+ for(i=0;i<409600;i++){
+ unsigned *logp1;
+ unsigned *data;
+ unsigned *tell;
+ unsigned *enc_method;
+ int j;
+ sz=rand()/((RAND_MAX>>(rand()%9U))+1U);
+ logp1=(unsigned *)malloc(sz*sizeof(*logp1));
+ data=(unsigned *)malloc(sz*sizeof(*data));
+ tell=(unsigned *)malloc((sz+1)*sizeof(*tell));
+ enc_method=(unsigned *)malloc(sz*sizeof(*enc_method));
+ ec_enc_init(&enc,ptr,DATA_SIZE2);
+ tell[0]=ec_tell_frac(&enc);
+ for(j=0;j<sz;j++){
+ data[j]=rand()/((RAND_MAX>>1)+1);
+ logp1[j]=(rand()%15)+1;
+ enc_method[j]=rand()/((RAND_MAX>>2)+1);
+ switch(enc_method[j]){
+ case 0:{
+ ec_encode(&enc,data[j]?(1<<logp1[j])-1:0,
+ (1<<logp1[j])-(data[j]?0:1),1<<logp1[j]);
+ }break;
+ case 1:{
+ ec_encode_bin(&enc,data[j]?(1<<logp1[j])-1:0,
+ (1<<logp1[j])-(data[j]?0:1),logp1[j]);
+ }break;
+ case 2:{
+ ec_enc_bit_logp(&enc,data[j],logp1[j]);
+ }break;
+ case 3:{
+ unsigned char icdf[2];
+ icdf[0]=1;
+ icdf[1]=0;
+ ec_enc_icdf(&enc,data[j],icdf,logp1[j]);
+ }break;
+ }
+ tell[j+1]=ec_tell_frac(&enc);
+ }
+ ec_enc_done(&enc);
+ if((ec_tell(&enc)+7U)/8U<ec_range_bytes(&enc)){
+ fprintf(stderr,"tell() lied, there's %i bytes instead of %d (Random seed: %u)\n",
+ ec_range_bytes(&enc),(ec_tell(&enc)+7)/8,seed);
+ ret=-1;
+ }
+ ec_dec_init(&dec,ptr,DATA_SIZE2);
+ if(ec_tell_frac(&dec)!=tell[0]){
+ fprintf(stderr,
+ "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
+ 0,ec_tell_frac(&dec),tell[0],seed);
+ }
+ for(j=0;j<sz;j++){
+ int fs;
+ int dec_method;
+ dec_method=rand()/((RAND_MAX>>2)+1);
+ switch(dec_method){
+ case 0:{
+ fs=ec_decode(&dec,1<<logp1[j]);
+ sym=fs>=(1<<logp1[j])-1;
+ ec_dec_update(&dec,sym?(1<<logp1[j])-1:0,
+ (1<<logp1[j])-(sym?0:1),1<<logp1[j]);
+ }break;
+ case 1:{
+ fs=ec_decode_bin(&dec,logp1[j]);
+ sym=fs>=(1<<logp1[j])-1;
+ ec_dec_update(&dec,sym?(1<<logp1[j])-1:0,
+ (1<<logp1[j])-(sym?0:1),1<<logp1[j]);
+ }break;
+ case 2:{
+ sym=ec_dec_bit_logp(&dec,logp1[j]);
+ }break;
+ case 3:{
+ unsigned char icdf[2];
+ icdf[0]=1;
+ icdf[1]=0;
+ sym=ec_dec_icdf(&dec,icdf,logp1[j]);
+ }break;
+ }
+ if(sym!=data[j]){
+ fprintf(stderr,
+ "Decoded %i instead of %i with logp1 of %i at position %i of %i (Random seed: %u).\n",
+ sym,data[j],logp1[j],j,sz,seed);
+ fprintf(stderr,"Encoding method: %i, decoding method: %i\n",
+ enc_method[j],dec_method);
+ ret=-1;
+ }
+ if(ec_tell_frac(&dec)!=tell[j+1]){
+ fprintf(stderr,
+ "Tell mismatch between encoder and decoder at symbol %i: %i instead of %i (Random seed: %u).\n",
+ j+1,ec_tell_frac(&dec),tell[j+1],seed);
+ }
+ }
+ free(enc_method);
+ free(tell);
+ free(data);
+ free(logp1);
+ }
+ ec_enc_init(&enc,ptr,DATA_SIZE2);
+ ec_enc_bit_logp(&enc,0,1);
+ ec_enc_bit_logp(&enc,0,1);
+ ec_enc_bit_logp(&enc,0,1);
+ ec_enc_bit_logp(&enc,0,1);
+ ec_enc_bit_logp(&enc,0,2);
+ ec_enc_patch_initial_bits(&enc,3,2);
+ if(enc.error){
+ fprintf(stderr,"patch_initial_bits failed");
+ ret=-1;
+ }
+ ec_enc_patch_initial_bits(&enc,0,5);
+ if(!enc.error){
+ fprintf(stderr,"patch_initial_bits didn't fail when it should have");
+ ret=-1;
+ }
+ ec_enc_done(&enc);
+ if(ec_range_bytes(&enc)!=1||ptr[0]!=192){
+ fprintf(stderr,"Got %d when expecting 192 for patch_initial_bits",ptr[0]);
+ ret=-1;
+ }
+ ec_enc_init(&enc,ptr,DATA_SIZE2);
+ ec_enc_bit_logp(&enc,0,1);
+ ec_enc_bit_logp(&enc,0,1);
+ ec_enc_bit_logp(&enc,1,6);
+ ec_enc_bit_logp(&enc,0,2);
+ ec_enc_patch_initial_bits(&enc,0,2);
+ if(enc.error){
+ fprintf(stderr,"patch_initial_bits failed");
+ ret=-1;
+ }
+ ec_enc_done(&enc);
+ if(ec_range_bytes(&enc)!=2||ptr[0]!=63){
+ fprintf(stderr,"Got %d when expecting 63 for patch_initial_bits",ptr[0]);
+ ret=-1;
+ }
+ ec_enc_init(&enc,ptr,2);
+ ec_enc_bit_logp(&enc,0,2);
+ for(i=0;i<48;i++){
+ ec_enc_bits(&enc,0,1);
+ }
+ ec_enc_done(&enc);
+ if(!enc.error){
+ fprintf(stderr,"Raw bits overfill didn't fail when it should have");
+ ret=-1;
+ }
+ ec_enc_init(&enc,ptr,2);
+ for(i=0;i<17;i++){
+ ec_enc_bits(&enc,0,1);
+ }
+ ec_enc_done(&enc);
+ if(!enc.error){
+ fprintf(stderr,"17 raw bits encoded in two bytes");
+ ret=-1;
+ }
+ free(ptr);
+ return ret;
+}
diff --git a/thirdparty/opus/celt/tests/test_unit_laplace.c b/thirdparty/opus/celt/tests/test_unit_laplace.c
new file mode 100644
index 0000000000..22951e29ee
--- /dev/null
+++ b/thirdparty/opus/celt/tests/test_unit_laplace.c
@@ -0,0 +1,93 @@
+/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation
+ Written by Jean-Marc Valin and Timothy B. Terriberry */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "laplace.h"
+#define CELT_C
+#include "stack_alloc.h"
+
+#include "entenc.c"
+#include "entdec.c"
+#include "entcode.c"
+#include "laplace.c"
+
+#define DATA_SIZE 40000
+
+int ec_laplace_get_start_freq(int decay)
+{
+ opus_uint32 ft = 32768 - LAPLACE_MINP*(2*LAPLACE_NMIN+1);
+ int fs = (ft*(16384-decay))/(16384+decay);
+ return fs+LAPLACE_MINP;
+}
+
+int main(void)
+{
+ int i;
+ int ret = 0;
+ ec_enc enc;
+ ec_dec dec;
+ unsigned char *ptr;
+ int val[10000], decay[10000];
+ ALLOC_STACK;
+ ptr = (unsigned char *)malloc(DATA_SIZE);
+ ec_enc_init(&enc,ptr,DATA_SIZE);
+
+ val[0] = 3; decay[0] = 6000;
+ val[1] = 0; decay[1] = 5800;
+ val[2] = -1; decay[2] = 5600;
+ for (i=3;i<10000;i++)
+ {
+ val[i] = rand()%15-7;
+ decay[i] = rand()%11000+5000;
+ }
+ for (i=0;i<10000;i++)
+ ec_laplace_encode(&enc, &val[i],
+ ec_laplace_get_start_freq(decay[i]), decay[i]);
+
+ ec_enc_done(&enc);
+
+ ec_dec_init(&dec,ec_get_buffer(&enc),ec_range_bytes(&enc));
+
+ for (i=0;i<10000;i++)
+ {
+ int d = ec_laplace_decode(&dec,
+ ec_laplace_get_start_freq(decay[i]), decay[i]);
+ if (d != val[i])
+ {
+ fprintf (stderr, "Got %d instead of %d\n", d, val[i]);
+ ret = 1;
+ }
+ }
+
+ free(ptr);
+ return ret;
+}
diff --git a/thirdparty/opus/celt/tests/test_unit_mathops.c b/thirdparty/opus/celt/tests/test_unit_mathops.c
new file mode 100644
index 0000000000..fd3319da91
--- /dev/null
+++ b/thirdparty/opus/celt/tests/test_unit_mathops.c
@@ -0,0 +1,304 @@
+/* Copyright (c) 2008-2011 Xiph.Org Foundation, Mozilla Corporation,
+ Gregory Maxwell
+ Written by Jean-Marc Valin, Gregory Maxwell, and Timothy B. Terriberry */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef CUSTOM_MODES
+#define CUSTOM_MODES
+#endif
+
+#define CELT_C
+
+#include <stdio.h>
+#include <math.h>
+#include "mathops.c"
+#include "entenc.c"
+#include "entdec.c"
+#include "entcode.c"
+#include "bands.c"
+#include "quant_bands.c"
+#include "laplace.c"
+#include "vq.c"
+#include "cwrs.c"
+#include "pitch.c"
+#include "celt_lpc.c"
+#include "celt.c"
+
+#if defined(OPUS_X86_MAY_HAVE_SSE) || defined(OPUS_X86_MAY_HAVE_SSE2) || defined(OPUS_X86_MAY_HAVE_SSE4_1)
+# if defined(OPUS_X86_MAY_HAVE_SSE)
+# include "x86/pitch_sse.c"
+# endif
+# if defined(OPUS_X86_MAY_HAVE_SSE2)
+# include "x86/pitch_sse2.c"
+# endif
+# if defined(OPUS_X86_MAY_HAVE_SSE4_1)
+# include "x86/pitch_sse4_1.c"
+# include "x86/celt_lpc_sse.c"
+# endif
+# include "x86/x86_celt_map.c"
+#elif defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
+# include "arm/armcpu.c"
+# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
+# include "arm/celt_neon_intr.c"
+# if defined(HAVE_ARM_NE10)
+# include "kiss_fft.c"
+# include "mdct.c"
+# include "arm/celt_ne10_fft.c"
+# include "arm/celt_ne10_mdct.c"
+# endif
+# endif
+# include "arm/arm_celt_map.c"
+#endif
+
+#ifdef FIXED_POINT
+#define WORD "%d"
+#else
+#define WORD "%f"
+#endif
+
+int ret = 0;
+
+void testdiv(void)
+{
+ opus_int32 i;
+ for (i=1;i<=327670;i++)
+ {
+ double prod;
+ opus_val32 val;
+ val = celt_rcp(i);
+#ifdef FIXED_POINT
+ prod = (1./32768./65526.)*val*i;
+#else
+ prod = val*i;
+#endif
+ if (fabs(prod-1) > .00025)
+ {
+ fprintf (stderr, "div failed: 1/%d="WORD" (product = %f)\n", i, val, prod);
+ ret = 1;
+ }
+ }
+}
+
+void testsqrt(void)
+{
+ opus_int32 i;
+ for (i=1;i<=1000000000;i++)
+ {
+ double ratio;
+ opus_val16 val;
+ val = celt_sqrt(i);
+ ratio = val/sqrt(i);
+ if (fabs(ratio - 1) > .0005 && fabs(val-sqrt(i)) > 2)
+ {
+ fprintf (stderr, "sqrt failed: sqrt(%d)="WORD" (ratio = %f)\n", i, val, ratio);
+ ret = 1;
+ }
+ i+= i>>10;
+ }
+}
+
+void testbitexactcos(void)
+{
+ int i;
+ opus_int32 min_d,max_d,last,chk;
+ chk=max_d=0;
+ last=min_d=32767;
+ for(i=64;i<=16320;i++)
+ {
+ opus_int32 d;
+ opus_int32 q=bitexact_cos(i);
+ chk ^= q*i;
+ d = last - q;
+ if (d>max_d)max_d=d;
+ if (d<min_d)min_d=d;
+ last = q;
+ }
+ if ((chk!=89408644)||(max_d!=5)||(min_d!=0)||(bitexact_cos(64)!=32767)||
+ (bitexact_cos(16320)!=200)||(bitexact_cos(8192)!=23171))
+ {
+ fprintf (stderr, "bitexact_cos failed\n");
+ ret = 1;
+ }
+}
+
+void testbitexactlog2tan(void)
+{
+ int i,fail;
+ opus_int32 min_d,max_d,last,chk;
+ fail=chk=max_d=0;
+ last=min_d=15059;
+ for(i=64;i<8193;i++)
+ {
+ opus_int32 d;
+ opus_int32 mid=bitexact_cos(i);
+ opus_int32 side=bitexact_cos(16384-i);
+ opus_int32 q=bitexact_log2tan(mid,side);
+ chk ^= q*i;
+ d = last - q;
+ if (q!=-1*bitexact_log2tan(side,mid))
+ fail = 1;
+ if (d>max_d)max_d=d;
+ if (d<min_d)min_d=d;
+ last = q;
+ }
+ if ((chk!=15821257)||(max_d!=61)||(min_d!=-2)||fail||
+ (bitexact_log2tan(32767,200)!=15059)||(bitexact_log2tan(30274,12540)!=2611)||
+ (bitexact_log2tan(23171,23171)!=0))
+ {
+ fprintf (stderr, "bitexact_log2tan failed\n");
+ ret = 1;
+ }
+}
+
+#ifndef FIXED_POINT
+void testlog2(void)
+{
+ float x;
+ for (x=0.001;x<1677700.0;x+=(x/8.0))
+ {
+ float error = fabs((1.442695040888963387*log(x))-celt_log2(x));
+ if (error>0.0009)
+ {
+ fprintf (stderr, "celt_log2 failed: fabs((1.442695040888963387*log(x))-celt_log2(x))>0.001 (x = %f, error = %f)\n", x,error);
+ ret = 1;
+ }
+ }
+}
+
+void testexp2(void)
+{
+ float x;
+ for (x=-11.0;x<24.0;x+=0.0007)
+ {
+ float error = fabs(x-(1.442695040888963387*log(celt_exp2(x))));
+ if (error>0.0002)
+ {
+ fprintf (stderr, "celt_exp2 failed: fabs(x-(1.442695040888963387*log(celt_exp2(x))))>0.0005 (x = %f, error = %f)\n", x,error);
+ ret = 1;
+ }
+ }
+}
+
+void testexp2log2(void)
+{
+ float x;
+ for (x=-11.0;x<24.0;x+=0.0007)
+ {
+ float error = fabs(x-(celt_log2(celt_exp2(x))));
+ if (error>0.001)
+ {
+ fprintf (stderr, "celt_log2/celt_exp2 failed: fabs(x-(celt_log2(celt_exp2(x))))>0.001 (x = %f, error = %f)\n", x,error);
+ ret = 1;
+ }
+ }
+}
+#else
+void testlog2(void)
+{
+ opus_val32 x;
+ for (x=8;x<1073741824;x+=(x>>3))
+ {
+ float error = fabs((1.442695040888963387*log(x/16384.0))-celt_log2(x)/1024.0);
+ if (error>0.003)
+ {
+ fprintf (stderr, "celt_log2 failed: x = %ld, error = %f\n", (long)x,error);
+ ret = 1;
+ }
+ }
+}
+
+void testexp2(void)
+{
+ opus_val16 x;
+ for (x=-32768;x<15360;x++)
+ {
+ float error1 = fabs(x/1024.0-(1.442695040888963387*log(celt_exp2(x)/65536.0)));
+ float error2 = fabs(exp(0.6931471805599453094*x/1024.0)-celt_exp2(x)/65536.0);
+ if (error1>0.0002&&error2>0.00004)
+ {
+ fprintf (stderr, "celt_exp2 failed: x = "WORD", error1 = %f, error2 = %f\n", x,error1,error2);
+ ret = 1;
+ }
+ }
+}
+
+void testexp2log2(void)
+{
+ opus_val32 x;
+ for (x=8;x<65536;x+=(x>>3))
+ {
+ float error = fabs(x-0.25*celt_exp2(celt_log2(x)))/16384;
+ if (error>0.004)
+ {
+ fprintf (stderr, "celt_log2/celt_exp2 failed: fabs(x-(celt_exp2(celt_log2(x))))>0.001 (x = %ld, error = %f)\n", (long)x,error);
+ ret = 1;
+ }
+ }
+}
+
+void testilog2(void)
+{
+ opus_val32 x;
+ for (x=1;x<=268435455;x+=127)
+ {
+ opus_val32 lg;
+ opus_val32 y;
+
+ lg = celt_ilog2(x);
+ if (lg<0 || lg>=31)
+ {
+ printf("celt_ilog2 failed: 0<=celt_ilog2(x)<31 (x = %d, celt_ilog2(x) = %d)\n",x,lg);
+ ret = 1;
+ }
+ y = 1<<lg;
+
+ if (x<y || (x>>1)>=y)
+ {
+ printf("celt_ilog2 failed: 2**celt_ilog2(x)<=x<2**(celt_ilog2(x)+1) (x = %d, 2**celt_ilog2(x) = %d)\n",x,y);
+ ret = 1;
+ }
+ }
+}
+#endif
+
+int main(void)
+{
+ testbitexactcos();
+ testbitexactlog2tan();
+ testdiv();
+ testsqrt();
+ testlog2();
+ testexp2();
+ testexp2log2();
+#ifdef FIXED_POINT
+ testilog2();
+#endif
+ return ret;
+}
diff --git a/thirdparty/opus/celt/tests/test_unit_mdct.c b/thirdparty/opus/celt/tests/test_unit_mdct.c
new file mode 100644
index 0000000000..8dbb9caa2e
--- /dev/null
+++ b/thirdparty/opus/celt/tests/test_unit_mdct.c
@@ -0,0 +1,230 @@
+/* Copyright (c) 2008-2011 Xiph.Org Foundation
+ Written by Jean-Marc Valin */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define SKIP_CONFIG_H
+
+#ifndef CUSTOM_MODES
+#define CUSTOM_MODES
+#endif
+
+#include <stdio.h>
+
+#define CELT_C
+#include "mdct.h"
+#include "stack_alloc.h"
+
+#include "kiss_fft.c"
+#include "mdct.c"
+#include "mathops.c"
+#include "entcode.c"
+
+#if defined(OPUS_X86_MAY_HAVE_SSE2) || defined(OPUS_X86_MAY_HAVE_SSE4_1)
+# include "x86/x86cpu.c"
+#elif defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
+# include "arm/armcpu.c"
+# include "pitch.c"
+# include "celt_lpc.c"
+# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
+# include "arm/celt_neon_intr.c"
+# if defined(HAVE_ARM_NE10)
+# include "arm/celt_ne10_fft.c"
+# include "arm/celt_ne10_mdct.c"
+# endif
+# endif
+# include "arm/arm_celt_map.c"
+#endif
+
+#ifndef M_PI
+#define M_PI 3.141592653
+#endif
+
+int ret = 0;
+void check(kiss_fft_scalar * in,kiss_fft_scalar * out,int nfft,int isinverse)
+{
+ int bin,k;
+ double errpow=0,sigpow=0;
+ double snr;
+ for (bin=0;bin<nfft/2;++bin) {
+ double ansr = 0;
+ double difr;
+
+ for (k=0;k<nfft;++k) {
+ double phase = 2*M_PI*(k+.5+.25*nfft)*(bin+.5)/nfft;
+ double re = cos(phase);
+
+ re /= nfft/4;
+
+ ansr += in[k] * re;
+ }
+ /*printf ("%f %f\n", ansr, out[bin]);*/
+ difr = ansr - out[bin];
+ errpow += difr*difr;
+ sigpow += ansr*ansr;
+ }
+ snr = 10*log10(sigpow/errpow);
+ printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
+ if (snr<60) {
+ printf( "** poor snr: %f **\n", snr);
+ ret = 1;
+ }
+}
+
+void check_inv(kiss_fft_scalar * in,kiss_fft_scalar * out,int nfft,int isinverse)
+{
+ int bin,k;
+ double errpow=0,sigpow=0;
+ double snr;
+ for (bin=0;bin<nfft;++bin) {
+ double ansr = 0;
+ double difr;
+
+ for (k=0;k<nfft/2;++k) {
+ double phase = 2*M_PI*(bin+.5+.25*nfft)*(k+.5)/nfft;
+ double re = cos(phase);
+
+ /*re *= 2;*/
+
+ ansr += in[k] * re;
+ }
+ /*printf ("%f %f\n", ansr, out[bin]);*/
+ difr = ansr - out[bin];
+ errpow += difr*difr;
+ sigpow += ansr*ansr;
+ }
+ snr = 10*log10(sigpow/errpow);
+ printf("nfft=%d inverse=%d,snr = %f\n",nfft,isinverse,snr );
+ if (snr<60) {
+ printf( "** poor snr: %f **\n", snr);
+ ret = 1;
+ }
+}
+
+
+void test1d(int nfft,int isinverse,int arch)
+{
+ mdct_lookup cfg;
+ size_t buflen = sizeof(kiss_fft_scalar)*nfft;
+
+ kiss_fft_scalar * in = (kiss_fft_scalar*)malloc(buflen);
+ kiss_fft_scalar * in_copy = (kiss_fft_scalar*)malloc(buflen);
+ kiss_fft_scalar * out= (kiss_fft_scalar*)malloc(buflen);
+ opus_val16 * window= (opus_val16*)malloc(sizeof(opus_val16)*nfft/2);
+ int k;
+
+ clt_mdct_init(&cfg, nfft, 0, arch);
+ for (k=0;k<nfft;++k) {
+ in[k] = (rand() % 32768) - 16384;
+ }
+
+ for (k=0;k<nfft/2;++k) {
+ window[k] = Q15ONE;
+ }
+ for (k=0;k<nfft;++k) {
+ in[k] *= 32768;
+ }
+
+ if (isinverse)
+ {
+ for (k=0;k<nfft;++k) {
+ in[k] /= nfft;
+ }
+ }
+
+ for (k=0;k<nfft;++k)
+ in_copy[k] = in[k];
+ /*for (k=0;k<nfft;++k) printf("%d %d ", in[k].r, in[k].i);printf("\n");*/
+
+ if (isinverse)
+ {
+ for (k=0;k<nfft;++k)
+ out[k] = 0;
+ clt_mdct_backward(&cfg,in,out, window, nfft/2, 0, 1, arch);
+ /* apply TDAC because clt_mdct_backward() no longer does that */
+ for (k=0;k<nfft/4;++k)
+ out[nfft-k-1] = out[nfft/2+k];
+ check_inv(in,out,nfft,isinverse);
+ } else {
+ clt_mdct_forward(&cfg,in,out,window, nfft/2, 0, 1, arch);
+ check(in_copy,out,nfft,isinverse);
+ }
+ /*for (k=0;k<nfft;++k) printf("%d %d ", out[k].r, out[k].i);printf("\n");*/
+
+
+ free(in);
+ free(in_copy);
+ free(out);
+ free(window);
+ clt_mdct_clear(&cfg, arch);
+}
+
+int main(int argc,char ** argv)
+{
+ ALLOC_STACK;
+ int arch = opus_select_arch();
+
+ if (argc>1) {
+ int k;
+ for (k=1;k<argc;++k) {
+ test1d(atoi(argv[k]),0,arch);
+ test1d(atoi(argv[k]),1,arch);
+ }
+ }else{
+ test1d(32,0,arch);
+ test1d(32,1,arch);
+ test1d(256,0,arch);
+ test1d(256,1,arch);
+ test1d(512,0,arch);
+ test1d(512,1,arch);
+ test1d(1024,0,arch);
+ test1d(1024,1,arch);
+ test1d(2048,0,arch);
+ test1d(2048,1,arch);
+#ifndef RADIX_TWO_ONLY
+ test1d(36,0,arch);
+ test1d(36,1,arch);
+ test1d(40,0,arch);
+ test1d(40,1,arch);
+ test1d(60,0,arch);
+ test1d(60,1,arch);
+ test1d(120,0,arch);
+ test1d(120,1,arch);
+ test1d(240,0,arch);
+ test1d(240,1,arch);
+ test1d(480,0,arch);
+ test1d(480,1,arch);
+ test1d(960,0,arch);
+ test1d(960,1,arch);
+ test1d(1920,0,arch);
+ test1d(1920,1,arch);
+#endif
+ }
+ return ret;
+}
diff --git a/thirdparty/opus/celt/tests/test_unit_rotation.c b/thirdparty/opus/celt/tests/test_unit_rotation.c
new file mode 100644
index 0000000000..1080c2085d
--- /dev/null
+++ b/thirdparty/opus/celt/tests/test_unit_rotation.c
@@ -0,0 +1,120 @@
+/* Copyright (c) 2008-2011 Xiph.Org Foundation
+ Written by Jean-Marc Valin */
+/*
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef CUSTOM_MODES
+#define CUSTOM_MODES
+#endif
+
+#define CELT_C
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "vq.c"
+#include "cwrs.c"
+#include "entcode.c"
+#include "entenc.c"
+#include "entdec.c"
+#include "mathops.c"
+#include "bands.h"
+#include "pitch.c"
+#include "celt_lpc.c"
+#include "celt.c"
+#include <math.h>
+
+#if defined(OPUS_X86_MAY_HAVE_SSE) || defined(OPUS_X86_MAY_HAVE_SSE2) || defined(OPUS_X86_MAY_HAVE_SSE4_1)
+# if defined(OPUS_X86_MAY_HAVE_SSE)
+# include "x86/pitch_sse.c"
+# endif
+# if defined(OPUS_X86_MAY_HAVE_SSE2)
+# include "x86/pitch_sse2.c"
+# endif
+# if defined(OPUS_X86_MAY_HAVE_SSE4_1)
+# include "x86/pitch_sse4_1.c"
+# include "x86/celt_lpc_sse.c"
+# endif
+# include "x86/x86_celt_map.c"
+#elif defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
+# include "arm/armcpu.c"
+# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
+# include "arm/celt_neon_intr.c"
+# if defined(HAVE_ARM_NE10)
+# include "kiss_fft.c"
+# include "mdct.c"
+# include "arm/celt_ne10_fft.c"
+# include "arm/celt_ne10_mdct.c"
+# endif
+# endif
+# include "arm/arm_celt_map.c"
+#endif
+
+#define MAX_SIZE 100
+
+int ret=0;
+void test_rotation(int N, int K)
+{
+ int i;
+ double err = 0, ener = 0, snr, snr0;
+ opus_val16 x0[MAX_SIZE];
+ opus_val16 x1[MAX_SIZE];
+ for (i=0;i<N;i++)
+ x1[i] = x0[i] = rand()%32767-16384;
+ exp_rotation(x1, N, 1, 1, K, SPREAD_NORMAL);
+ for (i=0;i<N;i++)
+ {
+ err += (x0[i]-(double)x1[i])*(x0[i]-(double)x1[i]);
+ ener += x0[i]*(double)x0[i];
+ }
+ snr0 = 20*log10(ener/err);
+ err = ener = 0;
+ exp_rotation(x1, N, -1, 1, K, SPREAD_NORMAL);
+ for (i=0;i<N;i++)
+ {
+ err += (x0[i]-(double)x1[i])*(x0[i]-(double)x1[i]);
+ ener += x0[i]*(double)x0[i];
+ }
+ snr = 20*log10(ener/err);
+ printf ("SNR for size %d (%d pulses) is %f (was %f without inverse)\n", N, K, snr, snr0);
+ if (snr < 60 || snr0 > 20)
+ {
+ fprintf(stderr, "FAIL!\n");
+ ret = 1;
+ }
+}
+
+int main(void)
+{
+ ALLOC_STACK;
+ test_rotation(15, 3);
+ test_rotation(23, 5);
+ test_rotation(50, 3);
+ test_rotation(80, 1);
+ return ret;
+}
diff --git a/thirdparty/opus/celt/arm/armopts.s b/thirdparty/opus/celt/tests/test_unit_types.c
index fb9196072a..67a0fb8ed3 100644
--- a/thirdparty/opus/celt/arm/armopts.s
+++ b/thirdparty/opus/celt/tests/test_unit_types.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2013 Mozilla Corporation */
+/* Copyright (c) 2008-2011 Xiph.Org Foundation
+ Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -24,14 +25,26 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-; Set the following to 1 if we have EDSP instructions
-; (LDRD/STRD, etc., ARMv5E and later).
-OPUS_ARM_MAY_HAVE_EDSP *
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
-; Set the following to 1 if we have ARMv6 media instructions.
-OPUS_ARM_MAY_HAVE_MEDIA *
+#include "opus_types.h"
+#include <stdio.h>
-; Set the following to 1 if we have NEON (some ARMv7)
-OPUS_ARM_MAY_HAVE_NEON *
-
-END
+int main(void)
+{
+ opus_int16 i = 1;
+ i <<= 14;
+ if (i>>14 != 1)
+ {
+ fprintf(stderr, "opus_int16 isn't 16 bits\n");
+ return 1;
+ }
+ if (sizeof(opus_int16)*2 != sizeof(opus_int32))
+ {
+ fprintf(stderr, "16*2 != 32\n");
+ return 1;
+ }
+ return 0;
+}
diff --git a/thirdparty/opus/celt/vq.c b/thirdparty/opus/celt/vq.c
index 8011e22548..d29f38fd8e 100644
--- a/thirdparty/opus/celt/vq.c
+++ b/thirdparty/opus/celt/vq.c
@@ -39,10 +39,6 @@
#include "rate.h"
#include "pitch.h"
-#if defined(MIPSr1_ASM)
-#include "mips/vq_mipsr1.h"
-#endif
-
#ifndef OVERRIDE_vq_exp_rotation1
static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_val16 s)
{
@@ -71,7 +67,7 @@ static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_
}
#endif /* OVERRIDE_vq_exp_rotation1 */
-void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread)
+static void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread)
{
static const int SPREAD_FACTOR[3]={15,10,5};
int i;
@@ -162,27 +158,42 @@ static unsigned extract_collapse_mask(int *iy, int N, int B)
return collapse_mask;
}
-opus_val16 op_pvq_search_c(celt_norm *X, int *iy, int K, int N, int arch)
+unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc
+#ifdef RESYNTH
+ , opus_val16 gain
+#endif
+ )
{
VARDECL(celt_norm, y);
- VARDECL(int, signx);
+ VARDECL(int, iy);
+ VARDECL(opus_val16, signx);
int i, j;
+ opus_val16 s;
int pulsesLeft;
opus_val32 sum;
opus_val32 xy;
opus_val16 yy;
+ unsigned collapse_mask;
SAVE_STACK;
- (void)arch;
+ celt_assert2(K>0, "alg_quant() needs at least one pulse");
+ celt_assert2(N>1, "alg_quant() needs at least two dimensions");
+
ALLOC(y, N, celt_norm);
- ALLOC(signx, N, int);
+ ALLOC(iy, N, int);
+ ALLOC(signx, N, opus_val16);
+
+ exp_rotation(X, N, 1, B, K, spread);
/* Get rid of the sign */
sum = 0;
j=0; do {
- signx[j] = X[j]<0;
- /* OPT: Make sure the compiler doesn't use a branch on ABS16(). */
- X[j] = ABS16(X[j]);
+ if (X[j]>0)
+ signx[j]=1;
+ else {
+ signx[j]=-1;
+ X[j]=-X[j];
+ }
iy[j] = 0;
y[j] = 0;
} while (++j<N);
@@ -214,12 +225,7 @@ opus_val16 op_pvq_search_c(celt_norm *X, int *iy, int K, int N, int arch)
while (++j<N);
sum = QCONST16(1.f,14);
}
-#ifdef FIXED_POINT
- rcp = EXTRACT16(MULT16_32_Q16(K, celt_rcp(sum)));
-#else
- /* Using K+e with e < 1 guarantees we cannot get more than K pulses. */
- rcp = EXTRACT16(MULT16_32_Q16(K+0.8f, celt_rcp(sum)));
-#endif
+ rcp = EXTRACT16(MULT16_32_Q16(K-1, celt_rcp(sum)));
j=0; do {
#ifdef FIXED_POINT
/* It's really important to round *towards zero* here */
@@ -234,12 +240,12 @@ opus_val16 op_pvq_search_c(celt_norm *X, int *iy, int K, int N, int arch)
pulsesLeft -= iy[j];
} while (++j<N);
}
- celt_sig_assert(pulsesLeft>=0);
+ celt_assert2(pulsesLeft>=1, "Allocated too many pulses in the quick pass");
/* This should never happen, but just in case it does (e.g. on silence)
we fill the first bin with pulses. */
#ifdef FIXED_POINT_DEBUG
- celt_sig_assert(pulsesLeft<=N+3);
+ celt_assert2(pulsesLeft<=N+3, "Not enough pulses in the quick pass");
#endif
if (pulsesLeft > N+3)
{
@@ -250,12 +256,12 @@ opus_val16 op_pvq_search_c(celt_norm *X, int *iy, int K, int N, int arch)
pulsesLeft=0;
}
+ s = 1;
for (i=0;i<pulsesLeft;i++)
{
- opus_val16 Rxy, Ryy;
int best_id;
- opus_val32 best_num;
- opus_val16 best_den;
+ opus_val32 best_num = -VERY_LARGE16;
+ opus_val16 best_den = 0;
#ifdef FIXED_POINT
int rshift;
#endif
@@ -266,22 +272,9 @@ opus_val16 op_pvq_search_c(celt_norm *X, int *iy, int K, int N, int arch)
/* The squared magnitude term gets added anyway, so we might as well
add it outside the loop */
yy = ADD16(yy, 1);
-
- /* Calculations for position 0 are out of the loop, in part to reduce
- mispredicted branches (since the if condition is usually false)
- in the loop. */
- /* Temporary sums of the new pulse(s) */
- Rxy = EXTRACT16(SHR32(ADD32(xy, EXTEND32(X[0])),rshift));
- /* We're multiplying y[j] by two so we don't have to do it here */
- Ryy = ADD16(yy, y[0]);
-
- /* Approximate score: we maximise Rxy/sqrt(Ryy) (we're guaranteed that
- Rxy is positive because the sign is pre-computed) */
- Rxy = MULT16_16_Q15(Rxy,Rxy);
- best_den = Ryy;
- best_num = Rxy;
- j=1;
+ j=0;
do {
+ opus_val16 Rxy, Ryy;
/* Temporary sums of the new pulse(s) */
Rxy = EXTRACT16(SHR32(ADD32(xy, EXTEND32(X[j])),rshift));
/* We're multiplying y[j] by two so we don't have to do it here */
@@ -292,11 +285,8 @@ opus_val16 op_pvq_search_c(celt_norm *X, int *iy, int K, int N, int arch)
Rxy = MULT16_16_Q15(Rxy,Rxy);
/* The idea is to check for num/den >= best_num/best_den, but that way
we can do it without any division */
- /* OPT: It's not clear whether a cmov is faster than a branch here
- since the condition is more often false than true and using
- a cmov introduces data dependencies across iterations. The optimal
- choice may be architecture-dependent. */
- if (opus_unlikely(MULT16_16(best_den, Rxy) > MULT16_16(Ryy, best_num)))
+ /* OPT: Make sure to use conditional moves here */
+ if (MULT16_16(best_den, Rxy) > MULT16_16(Ryy, best_num))
{
best_den = Ryy;
best_num = Rxy;
@@ -311,47 +301,23 @@ opus_val16 op_pvq_search_c(celt_norm *X, int *iy, int K, int N, int arch)
/* Only now that we've made the final choice, update y/iy */
/* Multiplying y[j] by 2 so we don't have to do it everywhere else */
- y[best_id] += 2;
+ y[best_id] += 2*s;
iy[best_id]++;
}
/* Put the original sign back */
j=0;
do {
- /*iy[j] = signx[j] ? -iy[j] : iy[j];*/
- /* OPT: The is more likely to be compiled without a branch than the code above
- but has the same performance otherwise. */
- iy[j] = (iy[j]^-signx[j]) + signx[j];
+ X[j] = MULT16_16(signx[j],X[j]);
+ if (signx[j] < 0)
+ iy[j] = -iy[j];
} while (++j<N);
- RESTORE_STACK;
- return yy;
-}
-
-unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc,
- opus_val16 gain, int resynth, int arch)
-{
- VARDECL(int, iy);
- opus_val16 yy;
- unsigned collapse_mask;
- SAVE_STACK;
-
- celt_assert2(K>0, "alg_quant() needs at least one pulse");
- celt_assert2(N>1, "alg_quant() needs at least two dimensions");
-
- /* Covers vectorization by up to 4. */
- ALLOC(iy, N+3, int);
-
- exp_rotation(X, N, 1, B, K, spread);
-
- yy = op_pvq_search(X, iy, K, N, arch);
-
encode_pulses(iy, N, K, enc);
- if (resynth)
- {
- normalise_residual(iy, X, N, yy, gain);
- exp_rotation(X, N, -1, B, K, spread);
- }
+#ifdef RESYNTH
+ normalise_residual(iy, X, N, yy, gain);
+ exp_rotation(X, N, -1, B, K, spread);
+#endif
collapse_mask = extract_collapse_mask(iy, N, B);
RESTORE_STACK;
@@ -435,7 +401,7 @@ int stereo_itheta(const celt_norm *X, const celt_norm *Y, int stereo, int N, int
/* 0.63662 = 2/pi */
itheta = MULT16_16_Q15(QCONST16(0.63662f,15),celt_atan2p(side, mid));
#else
- itheta = (int)floor(.5f+16384*0.63662f*fast_atan2f(side,mid));
+ itheta = (int)floor(.5f+16384*0.63662f*atan2(side,mid));
#endif
return itheta;
diff --git a/thirdparty/opus/celt/vq.h b/thirdparty/opus/celt/vq.h
index 45ec55918e..5cfcbe50ea 100644
--- a/thirdparty/opus/celt/vq.h
+++ b/thirdparty/opus/celt/vq.h
@@ -37,18 +37,10 @@
#include "entdec.h"
#include "modes.h"
-#if (defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(FIXED_POINT))
-#include "x86/vq_sse.h"
+#if defined(MIPSr1_ASM)
+#include "mips/vq_mipsr1.h"
#endif
-void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread);
-
-opus_val16 op_pvq_search_c(celt_norm *X, int *iy, int K, int N, int arch);
-
-#if !defined(OVERRIDE_OP_PVQ_SEARCH)
-#define op_pvq_search(x, iy, K, N, arch) \
- (op_pvq_search_c(x, iy, K, N, arch))
-#endif
/** Algebraic pulse-vector quantiser. The signal x is replaced by the sum of
* the pitch and a combination of pulses such that its norm is still equal
@@ -59,8 +51,12 @@ opus_val16 op_pvq_search_c(celt_norm *X, int *iy, int K, int N, int arch);
* @param enc Entropy encoder state
* @ret A mask indicating which blocks in the band received pulses
*/
-unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc,
- opus_val16 gain, int resynth, int arch);
+unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B,
+ ec_enc *enc
+#ifdef RESYNTH
+ , opus_val16 gain
+#endif
+ );
/** Algebraic pulse decoder
* @param X Decoded normalised spectrum (returned)
diff --git a/thirdparty/opus/celt/x86/celt_lpc_sse4_1.c b/thirdparty/opus/celt/x86/celt_lpc_sse.c
index 5478568849..67e5592acf 100644
--- a/thirdparty/opus/celt/x86/celt_lpc_sse4_1.c
+++ b/thirdparty/opus/celt/x86/celt_lpc_sse.c
@@ -40,23 +40,65 @@
#if defined(FIXED_POINT)
-void celt_fir_sse4_1(const opus_val16 *x,
+void celt_fir_sse4_1(const opus_val16 *_x,
const opus_val16 *num,
- opus_val16 *y,
+ opus_val16 *_y,
int N,
int ord,
+ opus_val16 *mem,
int arch)
{
int i,j;
VARDECL(opus_val16, rnum);
+ VARDECL(opus_val16, x);
__m128i vecNoA;
opus_int32 noA ;
SAVE_STACK;
ALLOC(rnum, ord, opus_val16);
+ ALLOC(x, N+ord, opus_val16);
for(i=0;i<ord;i++)
rnum[i] = num[ord-i-1];
+ for(i=0;i<ord;i++)
+ x[i] = mem[ord-i-1];
+
+ for (i=0;i<N-7;i+=8)
+ {
+ x[i+ord ]=_x[i ];
+ x[i+ord+1]=_x[i+1];
+ x[i+ord+2]=_x[i+2];
+ x[i+ord+3]=_x[i+3];
+ x[i+ord+4]=_x[i+4];
+ x[i+ord+5]=_x[i+5];
+ x[i+ord+6]=_x[i+6];
+ x[i+ord+7]=_x[i+7];
+ }
+
+ for (;i<N-3;i+=4)
+ {
+ x[i+ord ]=_x[i ];
+ x[i+ord+1]=_x[i+1];
+ x[i+ord+2]=_x[i+2];
+ x[i+ord+3]=_x[i+3];
+ }
+
+ for (;i<N;i++)
+ x[i+ord]=_x[i];
+
+ for(i=0;i<ord;i++)
+ mem[i] = _x[N-i-1];
+#ifdef SMALL_FOOTPRINT
+ for (i=0;i<N;i++)
+ {
+ opus_val32 sum = SHL32(EXTEND32(_x[i]), SIG_SHIFT);
+ for (j=0;j<ord;j++)
+ {
+ sum = MAC16_16(sum,rnum[j],x[i+j]);
+ }
+ _y[i] = SATURATE16(PSHR32(sum, SIG_SHIFT));
+ }
+#else
noA = EXTEND32(1) << SIG_SHIFT >> 1;
vecNoA = _mm_set_epi32(noA, noA, noA, noA);
@@ -65,24 +107,25 @@ void celt_fir_sse4_1(const opus_val16 *x,
opus_val32 sums[4] = {0};
__m128i vecSum, vecX;
- xcorr_kernel(rnum, x+i-ord, sums, ord, arch);
+ xcorr_kernel(rnum, x+i, sums, ord, arch);
vecSum = _mm_loadu_si128((__m128i *)sums);
vecSum = _mm_add_epi32(vecSum, vecNoA);
vecSum = _mm_srai_epi32(vecSum, SIG_SHIFT);
- vecX = OP_CVTEPI16_EPI32_M64(x + i);
+ vecX = OP_CVTEPI16_EPI32_M64(_x + i);
vecSum = _mm_add_epi32(vecSum, vecX);
vecSum = _mm_packs_epi32(vecSum, vecSum);
- _mm_storel_epi64((__m128i *)(y + i), vecSum);
+ _mm_storel_epi64((__m128i *)(_y + i), vecSum);
}
for (;i<N;i++)
{
opus_val32 sum = 0;
for (j=0;j<ord;j++)
- sum = MAC16_16(sum, rnum[j], x[i+j-ord]);
- y[i] = SATURATE16(ADD32(EXTEND32(x[i]), PSHR32(sum, SIG_SHIFT)));
+ sum = MAC16_16(sum, rnum[j], x[i + j]);
+ _y[i] = SATURATE16(ADD32(EXTEND32(_x[i]), PSHR32(sum, SIG_SHIFT)));
}
+#endif
RESTORE_STACK;
}
diff --git a/thirdparty/opus/celt/x86/celt_lpc_sse.h b/thirdparty/opus/celt/x86/celt_lpc_sse.h
index 7d1ecf7533..c5ec796ed5 100644
--- a/thirdparty/opus/celt/x86/celt_lpc_sse.h
+++ b/thirdparty/opus/celt/x86/celt_lpc_sse.h
@@ -41,11 +41,12 @@ void celt_fir_sse4_1(
opus_val16 *y,
int N,
int ord,
+ opus_val16 *mem,
int arch);
#if defined(OPUS_X86_PRESUME_SSE4_1)
-#define celt_fir(x, num, y, N, ord, arch) \
- ((void)arch, celt_fir_sse4_1(x, num, y, N, ord, arch))
+#define celt_fir(x, num, y, N, ord, mem, arch) \
+ ((void)arch, celt_fir_sse4_1(x, num, y, N, ord, mem, arch))
#else
@@ -55,10 +56,11 @@ extern void (*const CELT_FIR_IMPL[OPUS_ARCHMASK + 1])(
opus_val16 *y,
int N,
int ord,
+ opus_val16 *mem,
int arch);
-# define celt_fir(x, num, y, N, ord, arch) \
- ((*CELT_FIR_IMPL[(arch) & OPUS_ARCHMASK])(x, num, y, N, ord, arch))
+# define celt_fir(x, num, y, N, ord, mem, arch) \
+ ((*CELT_FIR_IMPL[(arch) & OPUS_ARCHMASK])(x, num, y, N, ord, mem, arch))
#endif
#endif
diff --git a/thirdparty/opus/celt/x86/vq_sse.h b/thirdparty/opus/celt/x86/vq_sse.h
deleted file mode 100644
index b4efe8f249..0000000000
--- a/thirdparty/opus/celt/x86/vq_sse.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright (c) 2016 Jean-Marc Valin */
-/*
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifndef VQ_SSE_H
-#define VQ_SSE_H
-
-#if defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(FIXED_POINT)
-#define OVERRIDE_OP_PVQ_SEARCH
-
-opus_val16 op_pvq_search_sse2(celt_norm *_X, int *iy, int K, int N, int arch);
-
-#if defined(OPUS_X86_PRESUME_SSE2)
-#define op_pvq_search(x, iy, K, N, arch) \
- (op_pvq_search_sse2(x, iy, K, N, arch))
-
-#else
-
-extern opus_val16 (*const OP_PVQ_SEARCH_IMPL[OPUS_ARCHMASK + 1])(
- celt_norm *_X, int *iy, int K, int N, int arch);
-
-# define op_pvq_search(X, iy, K, N, arch) \
- ((*OP_PVQ_SEARCH_IMPL[(arch) & OPUS_ARCHMASK])(X, iy, K, N, arch))
-
-#endif
-#endif
-
-#endif
diff --git a/thirdparty/opus/celt/x86/vq_sse2.c b/thirdparty/opus/celt/x86/vq_sse2.c
deleted file mode 100644
index 775042860d..0000000000
--- a/thirdparty/opus/celt/x86/vq_sse2.c
+++ /dev/null
@@ -1,217 +0,0 @@
-/* Copyright (c) 2007-2008 CSIRO
- Copyright (c) 2007-2009 Xiph.Org Foundation
- Copyright (c) 2007-2016 Jean-Marc Valin */
-/*
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <xmmintrin.h>
-#include <emmintrin.h>
-#include "celt_lpc.h"
-#include "stack_alloc.h"
-#include "mathops.h"
-#include "vq.h"
-#include "x86cpu.h"
-
-
-#ifndef FIXED_POINT
-
-opus_val16 op_pvq_search_sse2(celt_norm *_X, int *iy, int K, int N, int arch)
-{
- int i, j;
- int pulsesLeft;
- float xy, yy;
- VARDECL(celt_norm, y);
- VARDECL(celt_norm, X);
- VARDECL(float, signy);
- __m128 signmask;
- __m128 sums;
- __m128i fours;
- SAVE_STACK;
-
- (void)arch;
- /* All bits set to zero, except for the sign bit. */
- signmask = _mm_set_ps1(-0.f);
- fours = _mm_set_epi32(4, 4, 4, 4);
- ALLOC(y, N+3, celt_norm);
- ALLOC(X, N+3, celt_norm);
- ALLOC(signy, N+3, float);
-
- OPUS_COPY(X, _X, N);
- X[N] = X[N+1] = X[N+2] = 0;
- sums = _mm_setzero_ps();
- for (j=0;j<N;j+=4)
- {
- __m128 x4, s4;
- x4 = _mm_loadu_ps(&X[j]);
- s4 = _mm_cmplt_ps(x4, _mm_setzero_ps());
- /* Get rid of the sign */
- x4 = _mm_andnot_ps(signmask, x4);
- sums = _mm_add_ps(sums, x4);
- /* Clear y and iy in case we don't do the projection. */
- _mm_storeu_ps(&y[j], _mm_setzero_ps());
- _mm_storeu_si128((__m128i*)&iy[j], _mm_setzero_si128());
- _mm_storeu_ps(&X[j], x4);
- _mm_storeu_ps(&signy[j], s4);
- }
- sums = _mm_add_ps(sums, _mm_shuffle_ps(sums, sums, _MM_SHUFFLE(1, 0, 3, 2)));
- sums = _mm_add_ps(sums, _mm_shuffle_ps(sums, sums, _MM_SHUFFLE(2, 3, 0, 1)));
-
- xy = yy = 0;
-
- pulsesLeft = K;
-
- /* Do a pre-search by projecting on the pyramid */
- if (K > (N>>1))
- {
- __m128i pulses_sum;
- __m128 yy4, xy4;
- __m128 rcp4;
- opus_val32 sum = _mm_cvtss_f32(sums);
- /* If X is too small, just replace it with a pulse at 0 */
- /* Prevents infinities and NaNs from causing too many pulses
- to be allocated. 64 is an approximation of infinity here. */
- if (!(sum > EPSILON && sum < 64))
- {
- X[0] = QCONST16(1.f,14);
- j=1; do
- X[j]=0;
- while (++j<N);
- sums = _mm_set_ps1(1.f);
- }
- /* Using K+e with e < 1 guarantees we cannot get more than K pulses. */
- rcp4 = _mm_mul_ps(_mm_set_ps1((float)(K+.8)), _mm_rcp_ps(sums));
- xy4 = yy4 = _mm_setzero_ps();
- pulses_sum = _mm_setzero_si128();
- for (j=0;j<N;j+=4)
- {
- __m128 rx4, x4, y4;
- __m128i iy4;
- x4 = _mm_loadu_ps(&X[j]);
- rx4 = _mm_mul_ps(x4, rcp4);
- iy4 = _mm_cvttps_epi32(rx4);
- pulses_sum = _mm_add_epi32(pulses_sum, iy4);
- _mm_storeu_si128((__m128i*)&iy[j], iy4);
- y4 = _mm_cvtepi32_ps(iy4);
- xy4 = _mm_add_ps(xy4, _mm_mul_ps(x4, y4));
- yy4 = _mm_add_ps(yy4, _mm_mul_ps(y4, y4));
- /* double the y[] vector so we don't have to do it in the search loop. */
- _mm_storeu_ps(&y[j], _mm_add_ps(y4, y4));
- }
- pulses_sum = _mm_add_epi32(pulses_sum, _mm_shuffle_epi32(pulses_sum, _MM_SHUFFLE(1, 0, 3, 2)));
- pulses_sum = _mm_add_epi32(pulses_sum, _mm_shuffle_epi32(pulses_sum, _MM_SHUFFLE(2, 3, 0, 1)));
- pulsesLeft -= _mm_cvtsi128_si32(pulses_sum);
- xy4 = _mm_add_ps(xy4, _mm_shuffle_ps(xy4, xy4, _MM_SHUFFLE(1, 0, 3, 2)));
- xy4 = _mm_add_ps(xy4, _mm_shuffle_ps(xy4, xy4, _MM_SHUFFLE(2, 3, 0, 1)));
- xy = _mm_cvtss_f32(xy4);
- yy4 = _mm_add_ps(yy4, _mm_shuffle_ps(yy4, yy4, _MM_SHUFFLE(1, 0, 3, 2)));
- yy4 = _mm_add_ps(yy4, _mm_shuffle_ps(yy4, yy4, _MM_SHUFFLE(2, 3, 0, 1)));
- yy = _mm_cvtss_f32(yy4);
- }
- X[N] = X[N+1] = X[N+2] = -100;
- y[N] = y[N+1] = y[N+2] = 100;
- celt_sig_assert(pulsesLeft>=0);
-
- /* This should never happen, but just in case it does (e.g. on silence)
- we fill the first bin with pulses. */
- if (pulsesLeft > N+3)
- {
- opus_val16 tmp = (opus_val16)pulsesLeft;
- yy = MAC16_16(yy, tmp, tmp);
- yy = MAC16_16(yy, tmp, y[0]);
- iy[0] += pulsesLeft;
- pulsesLeft=0;
- }
-
- for (i=0;i<pulsesLeft;i++)
- {
- int best_id;
- __m128 xy4, yy4;
- __m128 max, max2;
- __m128i count;
- __m128i pos;
- /* The squared magnitude term gets added anyway, so we might as well
- add it outside the loop */
- yy = ADD16(yy, 1);
- xy4 = _mm_load1_ps(&xy);
- yy4 = _mm_load1_ps(&yy);
- max = _mm_setzero_ps();
- pos = _mm_setzero_si128();
- count = _mm_set_epi32(3, 2, 1, 0);
- for (j=0;j<N;j+=4)
- {
- __m128 x4, y4, r4;
- x4 = _mm_loadu_ps(&X[j]);
- y4 = _mm_loadu_ps(&y[j]);
- x4 = _mm_add_ps(x4, xy4);
- y4 = _mm_add_ps(y4, yy4);
- y4 = _mm_rsqrt_ps(y4);
- r4 = _mm_mul_ps(x4, y4);
- /* Update the index of the max. */
- pos = _mm_max_epi16(pos, _mm_and_si128(count, _mm_castps_si128(_mm_cmpgt_ps(r4, max))));
- /* Update the max. */
- max = _mm_max_ps(max, r4);
- /* Update the indices (+4) */
- count = _mm_add_epi32(count, fours);
- }
- /* Horizontal max */
- max2 = _mm_max_ps(max, _mm_shuffle_ps(max, max, _MM_SHUFFLE(1, 0, 3, 2)));
- max2 = _mm_max_ps(max2, _mm_shuffle_ps(max2, max2, _MM_SHUFFLE(2, 3, 0, 1)));
- /* Now that max2 contains the max at all positions, look at which value(s) of the
- partial max is equal to the global max. */
- pos = _mm_and_si128(pos, _mm_castps_si128(_mm_cmpeq_ps(max, max2)));
- pos = _mm_max_epi16(pos, _mm_unpackhi_epi64(pos, pos));
- pos = _mm_max_epi16(pos, _mm_shufflelo_epi16(pos, _MM_SHUFFLE(1, 0, 3, 2)));
- best_id = _mm_cvtsi128_si32(pos);
-
- /* Updating the sums of the new pulse(s) */
- xy = ADD32(xy, EXTEND32(X[best_id]));
- /* We're multiplying y[j] by two so we don't have to do it here */
- yy = ADD16(yy, y[best_id]);
-
- /* Only now that we've made the final choice, update y/iy */
- /* Multiplying y[j] by 2 so we don't have to do it everywhere else */
- y[best_id] += 2;
- iy[best_id]++;
- }
-
- /* Put the original sign back */
- for (j=0;j<N;j+=4)
- {
- __m128i y4;
- __m128i s4;
- y4 = _mm_loadu_si128((__m128i*)&iy[j]);
- s4 = _mm_castps_si128(_mm_loadu_ps(&signy[j]));
- y4 = _mm_xor_si128(_mm_add_epi32(y4, s4), s4);
- _mm_storeu_si128((__m128i*)&iy[j], y4);
- }
- RESTORE_STACK;
- return yy;
-}
-
-#endif
diff --git a/thirdparty/opus/celt/x86/x86_celt_map.c b/thirdparty/opus/celt/x86/x86_celt_map.c
index d39d88edec..47ba41b9ee 100644
--- a/thirdparty/opus/celt/x86/x86_celt_map.c
+++ b/thirdparty/opus/celt/x86/x86_celt_map.c
@@ -33,7 +33,6 @@
#include "celt_lpc.h"
#include "pitch.h"
#include "pitch_sse.h"
-#include "vq.h"
#if defined(OPUS_HAVE_RTCD)
@@ -47,6 +46,7 @@ void (*const CELT_FIR_IMPL[OPUS_ARCHMASK + 1])(
opus_val16 *y,
int N,
int ord,
+ opus_val16 *mem,
int arch
) = {
celt_fir_c, /* non-sse */
@@ -151,17 +151,5 @@ void (*const COMB_FILTER_CONST_IMPL[OPUS_ARCHMASK + 1])(
#endif
-#if defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(OPUS_X86_PRESUME_SSE2)
-opus_val16 (*const OP_PVQ_SEARCH_IMPL[OPUS_ARCHMASK + 1])(
- celt_norm *_X, int *iy, int K, int N, int arch
-) = {
- op_pvq_search_c, /* non-sse */
- op_pvq_search_c,
- MAY_HAVE_SSE2(op_pvq_search),
- MAY_HAVE_SSE2(op_pvq_search),
- MAY_HAVE_SSE2(op_pvq_search)
-};
-#endif
-
#endif
#endif
diff --git a/thirdparty/opus/celt/x86/x86cpu.h b/thirdparty/opus/celt/x86/x86cpu.h
index 1e2bf17b9b..04fd48aac4 100644
--- a/thirdparty/opus/celt/x86/x86cpu.h
+++ b/thirdparty/opus/celt/x86/x86cpu.h
@@ -82,9 +82,7 @@ int opus_select_arch(void);
(_mm_cvtepi8_epi32(*(__m128i *)(x)))
#endif
-/* similar reasoning about the instruction sequence as in the 32-bit macro above,
- */
-# if defined(__clang__) || !defined(__OPTIMIZE__)
+# if !defined(__OPTIMIZE__)
# define OP_CVTEPI16_EPI32_M64(x) \
(_mm_cvtepi16_epi32(_mm_loadl_epi64((__m128i *)(x))))
# else
diff --git a/thirdparty/opus/config.h b/thirdparty/opus/config.h
index 3ed0874d4b..7b9c92c6a8 100644
--- a/thirdparty/opus/config.h
+++ b/thirdparty/opus/config.h
@@ -1,44 +1,5 @@
-/* config.h. Generated from config.h.in by configure. */
-/* config.h.in. Generated from configure.ac by autoheader. */
-
-/* Get CPU Info by asm method */
-#define CPU_INFO_BY_ASM 1
-
-/* Get CPU Info by c method */
-/* #undef CPU_INFO_BY_C */
-
-/* Custom modes */
-/* #undef CUSTOM_MODES */
-
-/* Do not build the float API */
-/* #undef DISABLE_FLOAT_API */
-
-/* Disable bitstream fixes from RFC 8251 */
-/* #undef DISABLE_UPDATE_DRAFT */
-
-/* Assertions */
-/* #undef ENABLE_ASSERTIONS */
-
-/* Hardening */
-#define ENABLE_HARDENING 1
-
-/* Debug fixed-point implementation */
-/* #undef FIXED_DEBUG */
-
-/* Compile as fixed-point (for machines without a fast enough FPU) */
-/* #undef FIXED_POINT */
-
-/* Float approximations */
-/* #undef FLOAT_APPROX */
-
-/* Fuzzing */
-/* #undef FUZZING */
-
-/* Define to 1 if you have the <alloca.h> header file. */
-/* #undef HAVE_ALLOCA_H */
-
-/* NE10 library is installed on host. Make sure it is on target! */
-/* #undef HAVE_ARM_NE10 */
+/* Opus configuration header */
+/* Based on the output of libopus configure script */
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
@@ -46,12 +7,16 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
+#if (!defined( _MSC_VER ) || ( _MSC_VER >= 1800 ))
+
/* Define to 1 if you have the `lrint' function. */
#define HAVE_LRINT 1
/* Define to 1 if you have the `lrintf' function. */
#define HAVE_LRINTF 1
+#endif
+
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
@@ -76,10 +41,8 @@
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
-/* Define to 1 if you have the `__malloc_hook' function. */
-#define HAVE___MALLOC_HOOK 1
-
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
#define LT_OBJDIR ".libs/"
#ifdef OPUS_ARM_OPT
@@ -129,80 +92,9 @@
#endif // OPUS_ARM64_OPT
-/* Define if binary requires Aarch64 Neon Intrinsics */
-/* #undef OPUS_ARM_PRESUME_AARCH64_NEON_INTR */
-
-/* Define if binary requires EDSP instruction support */
-/* #undef OPUS_ARM_PRESUME_EDSP */
-
-/* Define if binary requires ARMv6 media instruction support */
-/* #undef OPUS_ARM_PRESUME_MEDIA */
-
-/* Define if binary requires NEON instruction support */
-/* #undef OPUS_ARM_PRESUME_NEON */
-
-/* Define if binary requires NEON intrinsics support */
-/* #undef OPUS_ARM_PRESUME_NEON_INTR */
-
/* This is a build of OPUS */
#define OPUS_BUILD /**/
-/* Run bit-exactness checks between optimized and c implementations */
-/* #undef OPUS_CHECK_ASM */
-
-#ifndef OPUS_ARM_OPT
-/* Use run-time CPU capabilities detection */
-#define OPUS_HAVE_RTCD 1
-#endif
-
-/* Compiler supports X86 AVX Intrinsics */
-/* #define OPUS_X86_MAY_HAVE_AVX */
-
-/* Compiler supports X86 SSE Intrinsics */
-/* #define OPUS_X86_MAY_HAVE_SSE */
-
-/* Compiler supports X86 SSE2 Intrinsics */
-/* #define OPUS_X86_MAY_HAVE_SSE2 */
-
-/* Compiler supports X86 SSE4.1 Intrinsics */
-/* #define OPUS_X86_MAY_HAVE_SSE4_1 */
-
-/* Define if binary requires AVX intrinsics support */
-/* #undef OPUS_X86_PRESUME_AVX */
-
-/* Define if binary requires SSE intrinsics support */
-#define OPUS_X86_PRESUME_SSE 1
-
-/* Define if binary requires SSE2 intrinsics support */
-#define OPUS_X86_PRESUME_SSE2 1
-
-/* Define if binary requires SSE4.1 intrinsics support */
-#define OPUS_X86_PRESUME_SSE4_1 1
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "opus@xiph.org"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "opus"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "opus 1.3.1"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "opus"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.3.1"
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Make use of alloca */
-/* #undef USE_ALLOCA */
-
#ifndef WIN32
/* Use C99 variable-size arrays */
#define VAR_ARRAYS 1
@@ -211,13 +103,11 @@
#define USE_ALLOCA 1
#endif
-/* Define to empty if `const' does not conform to ANSI C. */
-/* #undef const */
-
#ifndef OPUS_FIXED_POINT
#define FLOAT_APPROX 1
#endif
+
/* Define to `__inline__' or `__inline' if that's what the C compiler
calls it, or to nothing if 'inline' is not supported under any name. */
#ifndef __cplusplus
@@ -227,7 +117,11 @@
/* Define to the equivalent of the C99 'restrict' keyword, or to
nothing if this is not supported. Do not define if restrict is
supported directly. */
+#if (!defined( _MSC_VER ) || ( _MSC_VER >= 1800 ))
#define restrict __restrict
+#else
+#undef restrict
+#endif
/* Work around a bug in Sun C++: it does not support _Restrict or
__restrict__, even though the corresponding Sun C compiler ends up with
"#define restrict _Restrict" or "#define restrict __restrict__" in the
diff --git a/thirdparty/opus/info.c b/thirdparty/opus/info.c
index 3a1a5bf75b..c36f9a9ee1 100644
--- a/thirdparty/opus/info.c
+++ b/thirdparty/opus/info.c
@@ -107,32 +107,26 @@ static int op_tags_ensure_capacity(OpusTags *_tags,size_t _ncomments){
char **user_comments;
int *comment_lengths;
int cur_ncomments;
+ char *binary_suffix_data;
+ int binary_suffix_len;
size_t size;
if(OP_UNLIKELY(_ncomments>=(size_t)INT_MAX))return OP_EFAULT;
size=sizeof(*_tags->comment_lengths)*(_ncomments+1);
if(size/sizeof(*_tags->comment_lengths)!=_ncomments+1)return OP_EFAULT;
cur_ncomments=_tags->comments;
- /*We only support growing.
- Trimming requires cleaning up the allocated strings in the old space, and
- is best handled separately if it's ever needed.*/
- OP_ASSERT(_ncomments>=(size_t)cur_ncomments);
+ comment_lengths=_tags->comment_lengths;
+ binary_suffix_len=comment_lengths==NULL?0:comment_lengths[cur_ncomments];
comment_lengths=(int *)_ogg_realloc(_tags->comment_lengths,size);
if(OP_UNLIKELY(comment_lengths==NULL))return OP_EFAULT;
- if(_tags->comment_lengths==NULL){
- OP_ASSERT(cur_ncomments==0);
- comment_lengths[cur_ncomments]=0;
- }
- comment_lengths[_ncomments]=comment_lengths[cur_ncomments];
+ comment_lengths[_ncomments]=binary_suffix_len;
_tags->comment_lengths=comment_lengths;
size=sizeof(*_tags->user_comments)*(_ncomments+1);
if(size/sizeof(*_tags->user_comments)!=_ncomments+1)return OP_EFAULT;
+ user_comments=_tags->user_comments;
+ binary_suffix_data=user_comments==NULL?NULL:user_comments[cur_ncomments];
user_comments=(char **)_ogg_realloc(_tags->user_comments,size);
if(OP_UNLIKELY(user_comments==NULL))return OP_EFAULT;
- if(_tags->user_comments==NULL){
- OP_ASSERT(cur_ncomments==0);
- user_comments[cur_ncomments]=NULL;
- }
- user_comments[_ncomments]=user_comments[cur_ncomments];
+ user_comments[_ncomments]=binary_suffix_data;
_tags->user_comments=user_comments;
return 0;
}
@@ -281,30 +275,28 @@ int opus_tags_copy(OpusTags *_dst,const OpusTags *_src){
ret=opus_tags_copy_impl(&dst,_src);
if(OP_UNLIKELY(ret<0))opus_tags_clear(&dst);
else *_dst=*&dst;
- return ret;
+ return 0;
}
int opus_tags_add(OpusTags *_tags,const char *_tag,const char *_value){
- char *comment;
- size_t tag_len;
- size_t value_len;
- int ncomments;
- int ret;
+ char *comment;
+ int tag_len;
+ int value_len;
+ int ncomments;
+ int ret;
ncomments=_tags->comments;
ret=op_tags_ensure_capacity(_tags,ncomments+1);
if(OP_UNLIKELY(ret<0))return ret;
tag_len=strlen(_tag);
value_len=strlen(_value);
/*+2 for '=' and '\0'.*/
- if(tag_len+value_len<tag_len)return OP_EFAULT;
- if(tag_len+value_len>(size_t)INT_MAX-2)return OP_EFAULT;
comment=(char *)_ogg_malloc(sizeof(*comment)*(tag_len+value_len+2));
if(OP_UNLIKELY(comment==NULL))return OP_EFAULT;
memcpy(comment,_tag,sizeof(*comment)*tag_len);
comment[tag_len]='=';
memcpy(comment+tag_len+1,_value,sizeof(*comment)*(value_len+1));
_tags->user_comments[ncomments]=comment;
- _tags->comment_lengths[ncomments]=(int)(tag_len+value_len+1);
+ _tags->comment_lengths[ncomments]=tag_len+value_len+1;
_tags->comments=ncomments+1;
return 0;
}
@@ -345,10 +337,7 @@ int opus_tags_set_binary_suffix(OpusTags *_tags,
}
int opus_tagcompare(const char *_tag_name,const char *_comment){
- size_t tag_len;
- tag_len=strlen(_tag_name);
- if(OP_UNLIKELY(tag_len>(size_t)INT_MAX))return -1;
- return opus_tagncompare(_tag_name,(int)tag_len,_comment);
+ return opus_tagncompare(_tag_name,strlen(_tag_name),_comment);
}
int opus_tagncompare(const char *_tag_name,int _tag_len,const char *_comment){
@@ -359,18 +348,17 @@ int opus_tagncompare(const char *_tag_name,int _tag_len,const char *_comment){
}
const char *opus_tags_query(const OpusTags *_tags,const char *_tag,int _count){
- char **user_comments;
- size_t tag_len;
- int found;
- int ncomments;
- int ci;
+ char **user_comments;
+ int tag_len;
+ int found;
+ int ncomments;
+ int ci;
tag_len=strlen(_tag);
- if(OP_UNLIKELY(tag_len>(size_t)INT_MAX))return NULL;
ncomments=_tags->comments;
user_comments=_tags->user_comments;
found=0;
for(ci=0;ci<ncomments;ci++){
- if(!opus_tagncompare(_tag,(int)tag_len,user_comments[ci])){
+ if(!opus_tagncompare(_tag,tag_len,user_comments[ci])){
/*We return a pointer to the data, not a copy.*/
if(_count==found++)return user_comments[ci]+tag_len+1;
}
@@ -380,18 +368,17 @@ const char *opus_tags_query(const OpusTags *_tags,const char *_tag,int _count){
}
int opus_tags_query_count(const OpusTags *_tags,const char *_tag){
- char **user_comments;
- size_t tag_len;
- int found;
- int ncomments;
- int ci;
+ char **user_comments;
+ int tag_len;
+ int found;
+ int ncomments;
+ int ci;
tag_len=strlen(_tag);
- if(OP_UNLIKELY(tag_len>(size_t)INT_MAX))return 0;
ncomments=_tags->comments;
user_comments=_tags->user_comments;
found=0;
for(ci=0;ci<ncomments;ci++){
- if(!opus_tagncompare(_tag,(int)tag_len,user_comments[ci]))found++;
+ if(!opus_tagncompare(_tag,tag_len,user_comments[ci]))found++;
}
return found;
}
@@ -416,8 +403,7 @@ static int opus_tags_get_gain(const OpusTags *_tags,int *_gain_q8,
ncomments=_tags->comments;
/*Look for the first valid tag with the name _tag_name and use that.*/
for(ci=0;ci<ncomments;ci++){
- OP_ASSERT(_tag_len<=(size_t)INT_MAX);
- if(opus_tagncompare(_tag_name,(int)_tag_len,comments[ci])==0){
+ if(opus_tagncompare(_tag_name,_tag_len,comments[ci])==0){
char *p;
opus_int32 gain_q8;
int negative;
@@ -453,7 +439,8 @@ int opus_tags_get_track_gain(const OpusTags *_tags,int *_gain_q8){
}
static int op_is_jpeg(const unsigned char *_buf,size_t _buf_sz){
- return _buf_sz>=3&&memcmp(_buf,"\xFF\xD8\xFF",3)==0;
+ return _buf_sz>=11&&memcmp(_buf,"\xFF\xD8\xFF\xE0",4)==0
+ &&(_buf[4]<<8|_buf[5])>=16&&memcmp(_buf+6,"JFIF",5)==0;
}
/*Tries to extract the width, height, bits per pixel, and palette size of a
diff --git a/thirdparty/opus/internal.h b/thirdparty/opus/internal.h
index 9ac17e028f..ee48ea34c9 100644
--- a/thirdparty/opus/internal.h
+++ b/thirdparty/opus/internal.h
@@ -136,9 +136,6 @@ struct OggOpusLink{
that end-trimming calculations work properly.
This is only valid for seekable sources.*/
opus_int64 end_offset;
- /*The total duration of all prior links.
- This is always zero for non-seekable sources.*/
- ogg_int64_t pcm_file_offset;
/*The granule position of the last sample.
This is only valid for seekable sources.*/
ogg_int64_t pcm_end;
@@ -153,25 +150,23 @@ struct OggOpusLink{
};
struct OggOpusFile{
- /*The callbacks used to access the stream.*/
+ /*The callbacks used to access the data source.*/
OpusFileCallbacks callbacks;
- /*A FILE *, memory buffer, etc.*/
- void *stream;
- /*Whether or not we can seek with this stream.*/
+ /*A FILE *, memory bufer, etc.*/
+ void *source;
+ /*Whether or not we can seek with this data source.*/
int seekable;
/*The number of links in this chained Ogg Opus file.*/
int nlinks;
/*The cached information from each link in a chained Ogg Opus file.
- If stream isn't seekable (e.g., it's a pipe), only the current link
+ If source isn't seekable (e.g., it's a pipe), only the current link
appears.*/
OggOpusLink *links;
/*The number of serial numbers from a single link.*/
int nserialnos;
/*The capacity of the list of serial numbers from a single link.*/
int cserialnos;
- /*Storage for the list of serial numbers from a single link.
- This is a scratch buffer used when scanning the BOS pages at the start of
- each link.*/
+ /*Storage for the list of serial numbers from a single link.*/
ogg_uint32_t *serialnos;
/*This is the current offset of the data processed by the ogg_sync_state.
After a seek, this should be set to the target offset so that we can track
@@ -179,9 +174,9 @@ struct OggOpusFile{
After a call to op_get_next_page(), this will point to the first byte after
that page.*/
opus_int64 offset;
- /*The total size of this stream, or -1 if it's unseekable.*/
+ /*The total size of this data source, or -1 if it's unseekable.*/
opus_int64 end;
- /*Used to locate pages in the stream.*/
+ /*Used to locate pages in the data source.*/
ogg_sync_state oy;
/*One of OP_NOTOPEN, OP_PARTOPEN, OP_OPENED, OP_STREAMSET, OP_INITSET.*/
int ready_state;
@@ -232,7 +227,7 @@ struct OggOpusFile{
/*The number of valid samples in the decoded buffer.*/
int od_buffer_size;
/*The type of gain offset to apply.
- One of OP_HEADER_GAIN, OP_ALBUM_GAIN, OP_TRACK_GAIN, or OP_ABSOLUTE_GAIN.*/
+ One of OP_HEADER_GAIN, OP_TRACK_GAIN, or OP_ABSOLUTE_GAIN.*/
int gain_type;
/*The offset to apply to the gain.*/
opus_int32 gain_offset_q8;
diff --git a/thirdparty/opus/mapping_matrix.c b/thirdparty/opus/mapping_matrix.c
deleted file mode 100644
index 31298af057..0000000000
--- a/thirdparty/opus/mapping_matrix.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/* Copyright (c) 2017 Google Inc.
- Written by Andrew Allen */
-/*
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "arch.h"
-#include "float_cast.h"
-#include "opus_private.h"
-#include "opus_defines.h"
-#include "mapping_matrix.h"
-
-#define MATRIX_INDEX(nb_rows, row, col) (nb_rows * col + row)
-
-opus_int32 mapping_matrix_get_size(int rows, int cols)
-{
- opus_int32 size;
-
- /* Mapping Matrix must only support up to 255 channels in or out.
- * Additionally, the total cell count must be <= 65004 octets in order
- * for the matrix to be stored in an OGG header.
- */
- if (rows > 255 || cols > 255)
- return 0;
- size = rows * (opus_int32)cols * sizeof(opus_int16);
- if (size > 65004)
- return 0;
-
- return align(sizeof(MappingMatrix)) + align(size);
-}
-
-opus_int16 *mapping_matrix_get_data(const MappingMatrix *matrix)
-{
- /* void* cast avoids clang -Wcast-align warning */
- return (opus_int16*)(void*)((char*)matrix + align(sizeof(MappingMatrix)));
-}
-
-void mapping_matrix_init(MappingMatrix * const matrix,
- int rows, int cols, int gain, const opus_int16 *data, opus_int32 data_size)
-{
- int i;
- opus_int16 *ptr;
-
-#if !defined(ENABLE_ASSERTIONS)
- (void)data_size;
-#endif
- celt_assert(align(data_size) == align(rows * cols * sizeof(opus_int16)));
-
- matrix->rows = rows;
- matrix->cols = cols;
- matrix->gain = gain;
- ptr = mapping_matrix_get_data(matrix);
- for (i = 0; i < rows * cols; i++)
- {
- ptr[i] = data[i];
- }
-}
-
-#ifndef DISABLE_FLOAT_API
-void mapping_matrix_multiply_channel_in_float(
- const MappingMatrix *matrix,
- const float *input,
- int input_rows,
- opus_val16 *output,
- int output_row,
- int output_rows,
- int frame_size)
-{
- /* Matrix data is ordered col-wise. */
- opus_int16* matrix_data;
- int i, col;
-
- celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows);
-
- matrix_data = mapping_matrix_get_data(matrix);
-
- for (i = 0; i < frame_size; i++)
- {
- float tmp = 0;
- for (col = 0; col < input_rows; col++)
- {
- tmp +=
- matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] *
- input[MATRIX_INDEX(input_rows, col, i)];
- }
-#if defined(FIXED_POINT)
- output[output_rows * i] = FLOAT2INT16((1/32768.f)*tmp);
-#else
- output[output_rows * i] = (1/32768.f)*tmp;
-#endif
- }
-}
-
-void mapping_matrix_multiply_channel_out_float(
- const MappingMatrix *matrix,
- const opus_val16 *input,
- int input_row,
- int input_rows,
- float *output,
- int output_rows,
- int frame_size
-)
-{
- /* Matrix data is ordered col-wise. */
- opus_int16* matrix_data;
- int i, row;
- float input_sample;
-
- celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows);
-
- matrix_data = mapping_matrix_get_data(matrix);
-
- for (i = 0; i < frame_size; i++)
- {
-#if defined(FIXED_POINT)
- input_sample = (1/32768.f)*input[input_rows * i];
-#else
- input_sample = input[input_rows * i];
-#endif
- for (row = 0; row < output_rows; row++)
- {
- float tmp =
- (1/32768.f)*matrix_data[MATRIX_INDEX(matrix->rows, row, input_row)] *
- input_sample;
- output[MATRIX_INDEX(output_rows, row, i)] += tmp;
- }
- }
-}
-#endif /* DISABLE_FLOAT_API */
-
-void mapping_matrix_multiply_channel_in_short(
- const MappingMatrix *matrix,
- const opus_int16 *input,
- int input_rows,
- opus_val16 *output,
- int output_row,
- int output_rows,
- int frame_size)
-{
- /* Matrix data is ordered col-wise. */
- opus_int16* matrix_data;
- int i, col;
-
- celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows);
-
- matrix_data = mapping_matrix_get_data(matrix);
-
- for (i = 0; i < frame_size; i++)
- {
- opus_val32 tmp = 0;
- for (col = 0; col < input_rows; col++)
- {
-#if defined(FIXED_POINT)
- tmp +=
- ((opus_int32)matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] *
- (opus_int32)input[MATRIX_INDEX(input_rows, col, i)]) >> 8;
-#else
- tmp +=
- matrix_data[MATRIX_INDEX(matrix->rows, output_row, col)] *
- input[MATRIX_INDEX(input_rows, col, i)];
-#endif
- }
-#if defined(FIXED_POINT)
- output[output_rows * i] = (opus_int16)((tmp + 64) >> 7);
-#else
- output[output_rows * i] = (1/(32768.f*32768.f))*tmp;
-#endif
- }
-}
-
-void mapping_matrix_multiply_channel_out_short(
- const MappingMatrix *matrix,
- const opus_val16 *input,
- int input_row,
- int input_rows,
- opus_int16 *output,
- int output_rows,
- int frame_size)
-{
- /* Matrix data is ordered col-wise. */
- opus_int16* matrix_data;
- int i, row;
- opus_int32 input_sample;
-
- celt_assert(input_rows <= matrix->cols && output_rows <= matrix->rows);
-
- matrix_data = mapping_matrix_get_data(matrix);
-
- for (i = 0; i < frame_size; i++)
- {
-#if defined(FIXED_POINT)
- input_sample = (opus_int32)input[input_rows * i];
-#else
- input_sample = (opus_int32)FLOAT2INT16(input[input_rows * i]);
-#endif
- for (row = 0; row < output_rows; row++)
- {
- opus_int32 tmp =
- (opus_int32)matrix_data[MATRIX_INDEX(matrix->rows, row, input_row)] *
- input_sample;
- output[MATRIX_INDEX(output_rows, row, i)] += (tmp + 16384) >> 15;
- }
- }
-}
-
-const MappingMatrix mapping_matrix_foa_mixing = { 6, 6, 0 };
-const opus_int16 mapping_matrix_foa_mixing_data[36] = {
- 16384, 0, -16384, 23170, 0, 0, 16384, 23170,
- 16384, 0, 0, 0, 16384, 0, -16384, -23170,
- 0, 0, 16384, -23170, 16384, 0, 0, 0,
- 0, 0, 0, 0, 32767, 0, 0, 0,
- 0, 0, 0, 32767
-};
-
-const MappingMatrix mapping_matrix_soa_mixing = { 11, 11, 0 };
-const opus_int16 mapping_matrix_soa_mixing_data[121] = {
- 10923, 7723, 13377, -13377, 11585, 9459, 7723, -16384,
- -6689, 0, 0, 10923, 7723, 13377, 13377, -11585,
- 9459, 7723, 16384, -6689, 0, 0, 10923, -15447,
- 13377, 0, 0, -18919, 7723, 0, 13377, 0,
- 0, 10923, 7723, -13377, -13377, 11585, -9459, 7723,
- 16384, -6689, 0, 0, 10923, -7723, 0, 13377,
- -16384, 0, -15447, 0, 9459, 0, 0, 10923,
- -7723, 0, -13377, 16384, 0, -15447, 0, 9459,
- 0, 0, 10923, 15447, 0, 0, 0, 0,
- -15447, 0, -18919, 0, 0, 10923, 7723, -13377,
- 13377, -11585, -9459, 7723, -16384, -6689, 0, 0,
- 10923, -15447, -13377, 0, 0, 18919, 7723, 0,
- 13377, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 32767, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 32767
-};
-
-const MappingMatrix mapping_matrix_toa_mixing = { 18, 18, 0 };
-const opus_int16 mapping_matrix_toa_mixing_data[324] = {
- 8208, 0, -881, 14369, 0, 0, -8192, -4163,
- 13218, 0, 0, 0, 11095, -8836, -6218, 14833,
- 0, 0, 8208, -10161, 881, 10161, -13218, -2944,
- -8192, 2944, 0, -10488, -6218, 6248, -11095, -6248,
- 0, -10488, 0, 0, 8208, 10161, 881, -10161,
- -13218, 2944, -8192, -2944, 0, 10488, -6218, -6248,
- -11095, 6248, 0, 10488, 0, 0, 8176, 5566,
- -11552, 5566, 9681, -11205, 8192, -11205, 0, 4920,
- -15158, 9756, -3334, 9756, 0, -4920, 0, 0,
- 8176, 7871, 11552, 0, 0, 15846, 8192, 0,
- -9681, -6958, 0, 13797, 3334, 0, -15158, 0,
- 0, 0, 8176, 0, 11552, 7871, 0, 0,
- 8192, 15846, 9681, 0, 0, 0, 3334, 13797,
- 15158, 6958, 0, 0, 8176, 5566, -11552, -5566,
- -9681, -11205, 8192, 11205, 0, 4920, 15158, 9756,
- -3334, -9756, 0, 4920, 0, 0, 8208, 14369,
- -881, 0, 0, -4163, -8192, 0, -13218, -14833,
- 0, -8836, 11095, 0, 6218, 0, 0, 0,
- 8208, 10161, 881, 10161, 13218, 2944, -8192, 2944,
- 0, 10488, 6218, -6248, -11095, -6248, 0, -10488,
- 0, 0, 8208, -14369, -881, 0, 0, 4163,
- -8192, 0, -13218, 14833, 0, 8836, 11095, 0,
- 6218, 0, 0, 0, 8208, 0, -881, -14369,
- 0, 0, -8192, 4163, 13218, 0, 0, 0,
- 11095, 8836, -6218, -14833, 0, 0, 8176, -5566,
- -11552, 5566, -9681, 11205, 8192, -11205, 0, -4920,
- 15158, -9756, -3334, 9756, 0, -4920, 0, 0,
- 8176, 0, 11552, -7871, 0, 0, 8192, -15846,
- 9681, 0, 0, 0, 3334, -13797, 15158, -6958,
- 0, 0, 8176, -7871, 11552, 0, 0, -15846,
- 8192, 0, -9681, 6958, 0, -13797, 3334, 0,
- -15158, 0, 0, 0, 8176, -5566, -11552, -5566,
- 9681, 11205, 8192, 11205, 0, -4920, -15158, -9756,
- -3334, -9756, 0, 4920, 0, 0, 8208, -10161,
- 881, -10161, 13218, -2944, -8192, -2944, 0, -10488,
- 6218, 6248, -11095, 6248, 0, 10488, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 32767, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 32767
-};
-
-const MappingMatrix mapping_matrix_foa_demixing = { 6, 6, 0 };
-const opus_int16 mapping_matrix_foa_demixing_data[36] = {
- 16384, 16384, 16384, 16384, 0, 0, 0, 23170,
- 0, -23170, 0, 0, -16384, 16384, -16384, 16384,
- 0, 0, 23170, 0, -23170, 0, 0, 0,
- 0, 0, 0, 0, 32767, 0, 0, 0,
- 0, 0, 0, 32767
-};
-
-const MappingMatrix mapping_matrix_soa_demixing = { 11, 11, 3050 };
-const opus_int16 mapping_matrix_soa_demixing_data[121] = {
- 2771, 2771, 2771, 2771, 2771, 2771, 2771, 2771,
- 2771, 0, 0, 10033, 10033, -20066, 10033, 14189,
- 14189, -28378, 10033, -20066, 0, 0, 3393, 3393,
- 3393, -3393, 0, 0, 0, -3393, -3393, 0,
- 0, -17378, 17378, 0, -17378, -24576, 24576, 0,
- 17378, 0, 0, 0, -14189, 14189, 0, -14189,
- -28378, 28378, 0, 14189, 0, 0, 0, 2399,
- 2399, -4799, -2399, 0, 0, 0, -2399, 4799,
- 0, 0, 1959, 1959, 1959, 1959, -3918, -3918,
- -3918, 1959, 1959, 0, 0, -4156, 4156, 0,
- 4156, 0, 0, 0, -4156, 0, 0, 0,
- 8192, 8192, -16384, 8192, 16384, 16384, -32768, 8192,
- -16384, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 8312, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 8312
-};
-
-const MappingMatrix mapping_matrix_toa_demixing = { 18, 18, 0 };
-const opus_int16 mapping_matrix_toa_demixing_data[324] = {
- 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
- 8192, 8192, 8192, 8192, 8192, 8192, 8192, 8192,
- 0, 0, 0, -9779, 9779, 6263, 8857, 0,
- 6263, 13829, 9779, -13829, 0, -6263, 0, -8857,
- -6263, -9779, 0, 0, -3413, 3413, 3413, -11359,
- 11359, 11359, -11359, -3413, 3413, -3413, -3413, -11359,
- 11359, 11359, -11359, 3413, 0, 0, 13829, 9779,
- -9779, 6263, 0, 8857, -6263, 0, 9779, 0,
- -13829, 6263, -8857, 0, -6263, -9779, 0, 0,
- 0, -15617, -15617, 6406, 0, 0, -6406, 0,
- 15617, 0, 0, -6406, 0, 0, 6406, 15617,
- 0, 0, 0, -5003, 5003, -10664, 15081, 0,
- -10664, -7075, 5003, 7075, 0, 10664, 0, -15081,
- 10664, -5003, 0, 0, -8176, -8176, -8176, 8208,
- 8208, 8208, 8208, -8176, -8176, -8176, -8176, 8208,
- 8208, 8208, 8208, -8176, 0, 0, -7075, 5003,
- -5003, -10664, 0, 15081, 10664, 0, 5003, 0,
- 7075, -10664, -15081, 0, 10664, -5003, 0, 0,
- 15617, 0, 0, 0, -6406, 6406, 0, -15617,
- 0, -15617, 15617, 0, 6406, -6406, 0, 0,
- 0, 0, 0, -11393, 11393, 2993, -4233, 0,
- 2993, -16112, 11393, 16112, 0, -2993, 0, 4233,
- -2993, -11393, 0, 0, 0, -9974, -9974, -13617,
- 0, 0, 13617, 0, 9974, 0, 0, 13617,
- 0, 0, -13617, 9974, 0, 0, 0, 5579,
- -5579, 10185, 14403, 0, 10185, -7890, -5579, 7890,
- 0, -10185, 0, -14403, -10185, 5579, 0, 0,
- 11826, -11826, -11826, -901, 901, 901, -901, 11826,
- -11826, 11826, 11826, -901, 901, 901, -901, -11826,
- 0, 0, -7890, -5579, 5579, 10185, 0, 14403,
- -10185, 0, -5579, 0, 7890, 10185, -14403, 0,
- -10185, 5579, 0, 0, -9974, 0, 0, 0,
- -13617, 13617, 0, 9974, 0, 9974, -9974, 0,
- 13617, -13617, 0, 0, 0, 0, 16112, -11393,
- 11393, -2993, 0, 4233, 2993, 0, -11393, 0,
- -16112, -2993, -4233, 0, 2993, 11393, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 32767, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 32767
-};
-
diff --git a/thirdparty/opus/mapping_matrix.h b/thirdparty/opus/mapping_matrix.h
deleted file mode 100644
index 98bc82df3e..0000000000
--- a/thirdparty/opus/mapping_matrix.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/* Copyright (c) 2017 Google Inc.
- Written by Andrew Allen */
-/*
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/**
- * @file mapping_matrix.h
- * @brief Opus reference implementation mapping matrix API
- */
-
-#ifndef MAPPING_MATRIX_H
-#define MAPPING_MATRIX_H
-
-#include "opus_types.h"
-#include "opus_projection.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct MappingMatrix
-{
- int rows; /* number of channels outputted from matrix. */
- int cols; /* number of channels inputted to matrix. */
- int gain; /* in dB. S7.8-format. */
- /* Matrix cell data goes here using col-wise ordering. */
-} MappingMatrix;
-
-opus_int32 mapping_matrix_get_size(int rows, int cols);
-
-opus_int16 *mapping_matrix_get_data(const MappingMatrix *matrix);
-
-void mapping_matrix_init(
- MappingMatrix * const matrix,
- int rows,
- int cols,
- int gain,
- const opus_int16 *data,
- opus_int32 data_size
-);
-
-#ifndef DISABLE_FLOAT_API
-void mapping_matrix_multiply_channel_in_float(
- const MappingMatrix *matrix,
- const float *input,
- int input_rows,
- opus_val16 *output,
- int output_row,
- int output_rows,
- int frame_size
-);
-
-void mapping_matrix_multiply_channel_out_float(
- const MappingMatrix *matrix,
- const opus_val16 *input,
- int input_row,
- int input_rows,
- float *output,
- int output_rows,
- int frame_size
-);
-#endif /* DISABLE_FLOAT_API */
-
-void mapping_matrix_multiply_channel_in_short(
- const MappingMatrix *matrix,
- const opus_int16 *input,
- int input_rows,
- opus_val16 *output,
- int output_row,
- int output_rows,
- int frame_size
-);
-
-void mapping_matrix_multiply_channel_out_short(
- const MappingMatrix *matrix,
- const opus_val16 *input,
- int input_row,
- int input_rows,
- opus_int16 *output,
- int output_rows,
- int frame_size
-);
-
-/* Pre-computed mixing and demixing matrices for 1st to 3rd-order ambisonics.
- * foa: first-order ambisonics
- * soa: second-order ambisonics
- * toa: third-order ambisonics
- */
-extern const MappingMatrix mapping_matrix_foa_mixing;
-extern const opus_int16 mapping_matrix_foa_mixing_data[36];
-
-extern const MappingMatrix mapping_matrix_soa_mixing;
-extern const opus_int16 mapping_matrix_soa_mixing_data[121];
-
-extern const MappingMatrix mapping_matrix_toa_mixing;
-extern const opus_int16 mapping_matrix_toa_mixing_data[324];
-
-extern const MappingMatrix mapping_matrix_foa_demixing;
-extern const opus_int16 mapping_matrix_foa_demixing_data[36];
-
-extern const MappingMatrix mapping_matrix_soa_demixing;
-extern const opus_int16 mapping_matrix_soa_demixing_data[121];
-
-extern const MappingMatrix mapping_matrix_toa_demixing;
-extern const opus_int16 mapping_matrix_toa_demixing_data[324];
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* MAPPING_MATRIX_H */
diff --git a/thirdparty/opus/mlp.c b/thirdparty/opus/mlp.c
index 964c6a98f6..ff9e50df47 100644
--- a/thirdparty/opus/mlp.c
+++ b/thirdparty/opus/mlp.c
@@ -1,5 +1,5 @@
/* Copyright (c) 2008-2011 Octasic Inc.
- 2012-2017 Jean-Marc Valin */
+ Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -29,13 +29,42 @@
#include "config.h"
#endif
-#include <math.h>
#include "opus_types.h"
#include "opus_defines.h"
+
+#include <math.h>
+#include "mlp.h"
#include "arch.h"
#include "tansig_table.h"
-#include "mlp.h"
+#define MAX_NEURONS 100
+#if 0
+static OPUS_INLINE opus_val16 tansig_approx(opus_val32 _x) /* Q19 */
+{
+ int i;
+ opus_val16 xx; /* Q11 */
+ /*double x, y;*/
+ opus_val16 dy, yy; /* Q14 */
+ /*x = 1.9073e-06*_x;*/
+ if (_x>=QCONST32(8,19))
+ return QCONST32(1.,14);
+ if (_x<=-QCONST32(8,19))
+ return -QCONST32(1.,14);
+ xx = EXTRACT16(SHR32(_x, 8));
+ /*i = lrint(25*x);*/
+ i = SHR32(ADD32(1024,MULT16_16(25, xx)),11);
+ /*x -= .04*i;*/
+ xx -= EXTRACT16(SHR32(MULT16_16(20972,i),8));
+ /*x = xx*(1./2048);*/
+ /*y = tansig_table[250+i];*/
+ yy = tansig_table[250+i];
+ /*y = yy*(1./16384);*/
+ dy = 16384-MULT16_16_Q14(yy,yy);
+ yy = yy + MULT16_16_Q14(MULT16_16_Q11(xx,dy),(16384 - MULT16_16_Q11(yy,xx)));
+ return yy;
+}
+#else
+/*extern const float tansig_table[501];*/
static OPUS_INLINE float tansig_approx(float x)
{
int i;
@@ -63,82 +92,54 @@ static OPUS_INLINE float tansig_approx(float x)
y = y + x*dy*(1 - y*x);
return sign*y;
}
+#endif
-static OPUS_INLINE float sigmoid_approx(float x)
-{
- return .5f + .5f*tansig_approx(.5f*x);
-}
-
-static void gemm_accum(float *out, const opus_int8 *weights, int rows, int cols, int col_stride, const float *x)
-{
- int i, j;
- for (i=0;i<rows;i++)
- {
- for (j=0;j<cols;j++)
- out[i] += weights[j*col_stride + i]*x[j];
- }
-}
-
-void compute_dense(const DenseLayer *layer, float *output, const float *input)
+#if 0
+void mlp_process(const MLP *m, const opus_val16 *in, opus_val16 *out)
{
- int i;
- int N, M;
- int stride;
- M = layer->nb_inputs;
- N = layer->nb_neurons;
- stride = N;
- for (i=0;i<N;i++)
- output[i] = layer->bias[i];
- gemm_accum(output, layer->input_weights, N, M, stride, input);
- for (i=0;i<N;i++)
- output[i] *= WEIGHTS_SCALE;
- if (layer->sigmoid) {
- for (i=0;i<N;i++)
- output[i] = sigmoid_approx(output[i]);
- } else {
- for (i=0;i<N;i++)
- output[i] = tansig_approx(output[i]);
- }
+ int j;
+ opus_val16 hidden[MAX_NEURONS];
+ const opus_val16 *W = m->weights;
+ /* Copy to tmp_in */
+ for (j=0;j<m->topo[1];j++)
+ {
+ int k;
+ opus_val32 sum = SHL32(EXTEND32(*W++),8);
+ for (k=0;k<m->topo[0];k++)
+ sum = MAC16_16(sum, in[k],*W++);
+ hidden[j] = tansig_approx(sum);
+ }
+ for (j=0;j<m->topo[2];j++)
+ {
+ int k;
+ opus_val32 sum = SHL32(EXTEND32(*W++),14);
+ for (k=0;k<m->topo[1];k++)
+ sum = MAC16_16(sum, hidden[k], *W++);
+ out[j] = tansig_approx(EXTRACT16(PSHR32(sum,17)));
+ }
}
-
-void compute_gru(const GRULayer *gru, float *state, const float *input)
+#else
+void mlp_process(const MLP *m, const float *in, float *out)
{
- int i;
- int N, M;
- int stride;
- float tmp[MAX_NEURONS];
- float z[MAX_NEURONS];
- float r[MAX_NEURONS];
- float h[MAX_NEURONS];
- M = gru->nb_inputs;
- N = gru->nb_neurons;
- stride = 3*N;
- /* Compute update gate. */
- for (i=0;i<N;i++)
- z[i] = gru->bias[i];
- gemm_accum(z, gru->input_weights, N, M, stride, input);
- gemm_accum(z, gru->recurrent_weights, N, N, stride, state);
- for (i=0;i<N;i++)
- z[i] = sigmoid_approx(WEIGHTS_SCALE*z[i]);
-
- /* Compute reset gate. */
- for (i=0;i<N;i++)
- r[i] = gru->bias[N + i];
- gemm_accum(r, &gru->input_weights[N], N, M, stride, input);
- gemm_accum(r, &gru->recurrent_weights[N], N, N, stride, state);
- for (i=0;i<N;i++)
- r[i] = sigmoid_approx(WEIGHTS_SCALE*r[i]);
-
- /* Compute output. */
- for (i=0;i<N;i++)
- h[i] = gru->bias[2*N + i];
- for (i=0;i<N;i++)
- tmp[i] = state[i] * r[i];
- gemm_accum(h, &gru->input_weights[2*N], N, M, stride, input);
- gemm_accum(h, &gru->recurrent_weights[2*N], N, N, stride, tmp);
- for (i=0;i<N;i++)
- h[i] = z[i]*state[i] + (1-z[i])*tansig_approx(WEIGHTS_SCALE*h[i]);
- for (i=0;i<N;i++)
- state[i] = h[i];
+ int j;
+ float hidden[MAX_NEURONS];
+ const float *W = m->weights;
+ /* Copy to tmp_in */
+ for (j=0;j<m->topo[1];j++)
+ {
+ int k;
+ float sum = *W++;
+ for (k=0;k<m->topo[0];k++)
+ sum = sum + in[k]**W++;
+ hidden[j] = tansig_approx(sum);
+ }
+ for (j=0;j<m->topo[2];j++)
+ {
+ int k;
+ float sum = *W++;
+ for (k=0;k<m->topo[1];k++)
+ sum = sum + hidden[k]**W++;
+ out[j] = tansig_approx(sum);
+ }
}
-
+#endif
diff --git a/thirdparty/opus/mlp.h b/thirdparty/opus/mlp.h
index d7670550fd..618e246e2c 100644
--- a/thirdparty/opus/mlp.h
+++ b/thirdparty/opus/mlp.h
@@ -1,4 +1,5 @@
-/* Copyright (c) 2017 Jean-Marc Valin */
+/* Copyright (c) 2008-2011 Octasic Inc.
+ Written by Jean-Marc Valin */
/*
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
@@ -27,34 +28,16 @@
#ifndef _MLP_H_
#define _MLP_H_
-#include "opus_types.h"
-
-#define WEIGHTS_SCALE (1.f/128)
-
-#define MAX_NEURONS 32
+#include "arch.h"
typedef struct {
- const opus_int8 *bias;
- const opus_int8 *input_weights;
- int nb_inputs;
- int nb_neurons;
- int sigmoid;
-} DenseLayer;
-
-typedef struct {
- const opus_int8 *bias;
- const opus_int8 *input_weights;
- const opus_int8 *recurrent_weights;
- int nb_inputs;
- int nb_neurons;
-} GRULayer;
-
-extern const DenseLayer layer0;
-extern const GRULayer layer1;
-extern const DenseLayer layer2;
+ int layers;
+ const int *topo;
+ const float *weights;
+} MLP;
-void compute_dense(const DenseLayer *layer, float *output, const float *input);
+extern const MLP net;
-void compute_gru(const GRULayer *gru, float *state, const float *input);
+void mlp_process(const MLP *m, const float *in, float *out);
#endif /* _MLP_H_ */
diff --git a/thirdparty/opus/mlp_data.c b/thirdparty/opus/mlp_data.c
index ae4178df76..c2fda4e2e5 100644
--- a/thirdparty/opus/mlp_data.c
+++ b/thirdparty/opus/mlp_data.c
@@ -1,4 +1,5 @@
-/*This file is automatically generated from a Keras model*/
+/* The contents of this file was automatically generated by mlp_train.c
+ It contains multi-layer perceptron (MLP) weights. */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -6,667 +7,103 @@
#include "mlp.h"
-static const opus_int8 layer0_weights[800] = {
- -30, -9, 2, -12, 5, -1, 8, 9,
- 9, 8, -13, 18, -17, -34, -5, 17,
- -11, 0, -4, 10, 2, 10, 15, -8,
- 2, -1, 0, 5, 13, -3, -16, 1,
- -5, 3, 7, -28, -13, 6, 36, -3,
- 19, -60, -17, -28, 7, -11, -30, -7,
- 2, -42, -21, -3, 6, -22, 33, -9,
- 7, -30, 21, -14, 24, -11, -20, -18,
- -5, -12, 12, -49, -50, -49, 16, 9,
- -37, -1, 9, 34, -13, -31, -31, 12,
- 16, 44, -42, 2, -9, 8, -18, -6,
- 9, 36, 19, 11, 13, 12, -21, 3,
- -28, -12, 3, 33, 25, -14, 11, 1,
- -94, -39, 18, -12, -11, -15, -7, 49,
- 52, 10, -43, 9, 57, 8, 21, -6,
- 14, -15, 44, -8, 7, -30, -13, -2,
- -9, 25, -2, -127, 18, -11, -52, 26,
- -27, 27, 10, -10, 7, 43, 6, -24,
- 41, 10, -18, -27, 10, 17, 9, 10,
- -17, -10, 20, -6, 22, 55, 35, -80,
- 36, 25, -24, -36, 15, 9, -19, 88,
- 19, 64, -51, -35, 17, 0, -7, 41,
- -16, 27, 4, 15, -1, 18, -16, 47,
- -39, -54, -8, 13, -25, -20, 102, -18,
- -5, 44, 11, -28, 71, 2, -51, -5,
- 5, 2, -83, -9, -29, 8, 21, -53,
- 58, -37, -7, 13, 38, 9, 34, -1,
- -41, 21, 4, -24, -36, -33, -21, 32,
- 75, -2, 1, -68, -1, 47, -29, 32,
- 20, 12, -65, -87, 5, 16, -12, 24,
- 40, 15, 7, 19, -26, -17, 17, 6,
- -2, -37, -30, -9, 32, -127, -39, 0,
- -31, -27, 4, -22, 23, -6, -77, 35,
- -61, 32, -37, -24, 13, -11, -1, -40,
- -3, 17, -7, 13, 11, 59, -19, 10,
- 6, -18, 0, 13, 3, -6, -23, 19,
- 11, -17, 13, -1, -80, 40, -53, 69,
- -29, -54, 0, -4, 33, -25, -2, 38,
- 35, 36, -15, 46, 2, -13, -16, -8,
- -8, 12, -24, -9, -55, -5, -9, 32,
- 11, 7, 12, -18, -10, -86, -38, 54,
- 37, -25, 18, -43, 7, -27, -27, -54,
- 13, 9, 22, 70, 6, 35, -7, 23,
- -15, -44, -6, 7, -66, -85, 32, 40,
- -19, -9, -7, 12, -15, 7, 2, 6,
- -35, 11, 28, 0, 26, 14, 1, 1,
- 4, 12, 18, 35, 22, -18, -3, 14,
- -1, 7, 14, -8, -14, -3, 4, -3,
- -19, -7, -1, -25, -27, 25, -26, -2,
- 33, -22, -27, -25, 4, -9, 7, 21,
- 26, -30, 10, -9, -20, 11, 27, 10,
- 5, -18, 14, -4, 2, -17, -5, -7,
- -9, -13, 15, 29, 1, -10, -16, -10,
- 35, 36, -7, -22, -44, 17, 30, 22,
- 21, -1, 22, -11, 32, -8, -7, 5,
- -10, 5, 30, -20, 29, -20, -34, 12,
- -4, -6, 6, -13, 10, -5, -68, -1,
- 24, 9, 19, -24, -64, 31, 19, 27,
- -26, 75, -45, 41, 39, -42, 8, 6,
- 23, -30, 16, -25, 30, 34, 8, -38,
- -3, 18, 16, -31, 22, -4, -9, 1,
- 20, 9, 38, -32, 0, -45, 0, -6,
- -13, 11, -25, -32, -22, 31, -24, -11,
- -11, -4, -4, 20, -34, 22, 20, 9,
- -25, 27, -5, 28, -29, 29, 6, 21,
- -6, -18, 54, 4, -46, 23, 21, -14,
- -31, 36, -41, -24, 4, 22, 10, 11,
- 7, 36, -32, -13, -52, -17, 24, 28,
- -37, -36, -1, 24, 9, -38, 35, 48,
- 18, 2, -1, 45, 10, 39, 24, -38,
- 13, 8, -16, 8, 25, 11, 7, -29,
- -11, 7, 20, -30, -38, -45, 14, -18,
- -28, -9, 65, 61, 22, -53, -38, -16,
- 36, 46, 20, -39, 32, -61, -6, -6,
- -36, -33, -18, -28, 56, 101, 45, 11,
- -28, -23, -29, -61, 20, -47, 2, 48,
- 27, -17, 1, 40, 1, 3, -51, 15,
- 35, 28, 22, 35, 53, -61, -29, 12,
- -6, -21, 10, 3, -20, 2, -25, 1,
- -6, 31, 11, -3, 1, -10, -52, 6,
- 126, -105, 122, 127, -128, 127, 127, -128,
- 127, 108, 12, 127, 48, -128, -36, -128,
- 127, 127, -128, -128, 127, 89, -128, 127,
- -128, -128, -128, 127, 127, -128, -128, -93,
- -82, 20, 125, 65, -82, 127, 38, -74,
- 81, 88, -88, 79, 51, -47, -111, -26,
- 14, 83, -88, -112, 24, 35, -101, 98,
- -99, -48, -45, 46, 83, -60, -79, 45,
- -20, -41, 9, 4, 52, 54, 93, -10,
- 4, 13, 3, 123, 6, 94, -111, -69,
- -14, -31, 10, 12, 53, -79, -11, -21,
- -2, -44, -72, 92, 65, -57, 56, -38,
- 127, -56, -128, 127, 127, -128, 86, 117,
- -75, -128, 127, -19, -99, -112, 127, -128,
- 127, -48, 114, 118, -128, -128, 117, -17,
- -6, 121, -128, 127, -128, 82, 54, -106,
- 127, 127, -33, 100, -39, -23, 18, -78,
- -34, -29, -1, -30, 127, -26, 127, -128,
- 126, -128, 27, -23, -79, -120, -127, 127,
- 72, 66, 29, 7, -66, -56, -117, -128
-};
-
-static const opus_int8 layer0_bias[32] = {
- 51, -16, 1, 13, -5, -6, -16, -7,
- 11, -6, 106, 26, 28, -14, 21, -29,
- 7, 18, -18, -17, 21, -17, -9, 20,
- -25, -3, -34, 48, 11, -13, -31, -20
-};
-
-static const opus_int8 layer1_weights[2304] = {
- 22, -1, -7, 7, 29, -27, -31, -17,
- -13, 33, 44, -8, 11, 33, 24, 78,
- 15, 19, 30, -2, -24, 5, 49, 5,
- 36, 29, -14, -11, -48, -33, 21, -42,
- -38, -12, 55, -37, 54, -8, 1, 36,
- 17, 0, 51, 31, 59, 7, -12, 53,
- 4, 32, -14, 48, 5, -10, -16, -8,
- 1, -16, -56, -24, -6, 18, -2, 23,
- 6, 46, -6, -10, 20, 35, -44, -15,
- -49, 36, 16, 5, -7, -79, -67, 12,
- 70, -3, -79, -54, -85, -24, 47, -22,
- 33, 21, 69, -1, 11, 22, 14, -16,
- -16, -22, -28, -11, 11, -41, 31, -26,
- -33, -19, -4, 27, 32, -50, 5, -10,
- -38, -22, -8, 35, -31, 1, -41, -15,
- -11, 44, 28, -17, -41, -23, 17, 2,
- -23, -26, -13, -13, -17, 6, 14, -31,
- -25, 9, -19, 39, -8, 4, 31, -1,
- -45, -11, -28, -92, -46, -15, 21, 118,
- -22, 45, -51, 11, -20, -20, -15, 13,
- -21, -97, -29, -32, -23, -42, 94, 1,
- 23, -8, 63, -3, -46, 19, -26, 32,
- -40, -74, -26, 26, -4, -13, 30, -20,
- -30, -25, -14, -31, -45, -43, 4, -60,
- -48, -12, -34, 2, 2, 3, 13, 15,
- 11, 16, 5, 46, -9, -55, -16, -57,
- 29, 14, 38, -50, -2, -44, -11, -8,
- 52, -27, -38, -7, 20, 47, 17, -59,
- 0, 47, 46, -63, 35, -17, 19, 33,
- 68, -19, 2, 15, -16, 28, -16, -103,
- 26, -35, 47, -39, -60, 30, 31, -23,
- -52, -13, 116, 47, -25, 30, 40, 30,
- -22, 2, 12, -27, -18, 31, -10, 27,
- -8, -66, 12, 14, 4, -26, -28, -13,
- 3, 13, -26, -51, 37, 5, 2, -21,
- 47, 3, 13, 25, -41, -27, -8, -4,
- 5, -76, -33, 28, 10, 9, -46, -74,
- 19, 28, 25, 31, 54, -55, 68, 38,
- -24, -32, 2, 4, 68, 11, -1, 99,
- 5, 16, -2, -74, 40, 26, -26, 33,
- 31, -1, -68, 14, -6, 25, 9, 29,
- 60, 61, 7, -7, 0, -24, 7, 77,
- 4, -1, 16, -7, 13, -15, -19, 28,
- -31, -24, -16, 37, 24, 13, 30, 10,
- -30, 11, 11, -10, 22, 60, 28, 45,
- -3, -40, -62, -5, -102, 9, -32, -27,
- -54, 21, 15, -5, 37, -43, -11, 37,
- -19, 47, -64, -128, -27, -114, 21, -66,
- 59, 46, -3, -12, -87, -9, 4, 19,
- -113, -36, 78, 57, -26, -38, -77, -10,
- 6, 6, -75, 25, -97, -11, 33, -46,
- 1, 13, -21, -33, -20, 16, -6, -3,
- -11, -4, -27, 38, 8, -41, -2, -33,
- 18, 19, -26, 1, -29, -22, -4, -14,
- -55, -11, -80, -3, 11, 34, 90, 51,
- 11, 17, 43, 36, 127, -32, 29, 103,
- 9, 27, 13, 64, 56, 70, -14, 3,
- -12, 10, 37, 3, 12, -22, -10, 46,
- 28, 10, 20, 26, -24, 18, 9, 7,
- 14, 34, -5, -7, 31, -14, -56, 11,
- -18, -8, -17, -7, -10, -40, 10, -33,
- -32, -43, 5, 9, 11, -4, 10, 50,
- -12, -5, 46, 9, 7, 1, 11, 15,
- 91, -17, 7, -50, 23, 6, -30, -99,
- 0, -17, 14, 8, -10, -25, -30, -69,
- -62, 31, 127, 114, -23, 101, -5, -54,
- -6, -22, 7, -56, 39, 18, -29, 0,
- 46, 8, -79, 4, -21, 18, -32, 62,
- -12, -8, -12, -58, 31, -32, 17, 6,
- -24, 25, 24, 9, -4, -19, 45, 6,
- 17, -14, 5, -27, 16, -4, -41, 25,
- -36, 5, 15, 12, 50, 27, 25, 23,
- -44, -69, -9, -19, -48, -8, 4, 12,
- -6, 13, -19, -30, -36, 26, 37, -1,
- -3, -30, -42, -14, -10, -20, 26, -54,
- -27, -44, 4, 73, -26, 90, 32, -69,
- -29, -16, 3, 103, 15, -17, 37, 24,
- -23, -31, 33, -37, -64, 25, 13, -81,
- -28, -32, 27, 5, -35, -23, 15, -22,
- 19, -7, 9, 30, 19, -23, 27, -13,
- 43, 29, -29, -6, 9, -40, -33, -33,
- -32, 9, 11, -48, -8, -23, -52, 46,
- 17, -22, -42, 35, -15, -41, 16, 34,
- 31, -42, -19, -11, 55, 7, -39, 89,
- -11, -33, 20, -14, 22, 32, 3, -17,
- -6, 14, 34, 1, 55, -21, -90, -8,
- 18, 27, 13, -29, 21, 15, -33, -51,
- -9, -11, 4, -16, -18, 23, -4, -4,
- 48, 1, 7, 29, -14, -12, -16, 17,
- 35, 8, 0, -7, -2, 9, 8, 17,
- -6, 53, -32, -21, -50, 5, 99, -60,
- -5, -53, 10, -31, 12, -5, 7, 80,
- 36, 18, -31, 9, 98, 36, -63, -35,
- 4, -13, -28, -24, 28, -13, 18, 16,
- -1, -18, -34, 10, 20, 7, 4, 29,
- 11, 25, -7, 36, 14, 45, 24, 1,
- -16, 30, 6, 35, -6, -11, -24, 13,
- -1, 27, 39, 20, 48, -11, -4, -13,
- 28, 11, -31, -18, 31, -29, 22, -2,
- -20, -16, 5, 30, -12, -28, -3, 93,
- -16, 23, 18, -29, 6, -54, -37, 28,
- -3, -3, -47, -3, -36, -55, -3, 41,
- -10, 47, -2, 23, 42, -7, -71, -27,
- 83, -64, 7, -24, 8, 26, -17, 15,
- 12, 31, -30, -38, -13, -33, -56, 4,
- -17, 20, 18, 1, -30, -5, -6, -31,
- -14, -37, 0, 22, 10, -30, 37, -17,
- 18, 6, 5, 23, -36, -32, 14, 18,
- -13, -61, -52, -69, 44, -30, 16, 18,
- -4, -25, 14, 81, 26, -8, -23, -59,
- 52, -104, 17, 119, -32, 26, 17, 1,
- 23, 45, 29, -64, -57, -14, 73, 21,
- -13, -13, 9, -68, -7, -52, 3, 24,
- -39, 44, -15, 27, 14, 19, -9, -28,
- -11, 5, 3, -34, -2, 2, 22, -6,
- -23, 4, 3, 13, -22, -13, -10, -18,
- 29, 6, 44, -13, -24, -8, 2, 30,
- 14, 43, 6, 17, -73, -6, -7, 20,
- -80, -7, -7, -28, 15, -69, -38, -5,
- -100, -35, 15, -79, 23, 29, -18, -27,
- 21, -66, -37, 8, -22, -39, 48, 4,
- -13, 1, -9, 11, -29, 22, 6, -49,
- 32, -14, 47, -18, -4, 44, -52, -74,
- 43, 30, 23, -14, 5, 0, -27, 4,
- -7, 10, -4, 10, 1, -16, 11, -18,
- -2, -5, 2, -11, 0, -20, -4, 38,
- 74, 59, 39, 64, -10, 26, -3, -40,
- -68, 3, -30, -51, 8, -19, -27, -46,
- 51, 52, 54, 36, 90, 92, 14, 13,
- -5, 0, 16, -62, 16, 11, -47, -37,
- -6, -5, 21, 54, -57, 32, 42, -6,
- 62, -9, 16, 21, 24, 9, -10, -4,
- 33, 50, 13, -15, 1, -35, -48, 18,
- -11, -17, -67, -13, 21, 38, -44, 36,
- -16, 29, 17, 5, -10, 18, 17, -32,
- 2, 8, 22, -56, -15, -32, 40, 43,
- 19, 46, -7, -100, -96, 19, 53, 24,
- 21, -26, -48, -101, -82, 61, 38, -85,
- -28, -34, -1, 63, -5, -5, 39, 39,
- -38, 32, -12, -28, 20, 40, -8, 2,
- 31, 12, -35, -13, 20, -25, 30, 8,
- 3, -13, -9, -20, 2, -13, 24, 37,
- -10, 33, 6, 20, -16, -24, -6, -6,
- -19, -5, 22, 21, 10, 11, -4, -39,
- -1, 6, 49, 41, -15, -57, 21, -62,
- 77, -69, -13, 0, -74, 1, -7, -38,
- -8, 6, 63, 28, 4, 26, -52, 82,
- 63, 13, 45, -33, 44, -52, -65, -21,
- -46, -49, 64, -17, 32, 24, 68, -39,
- -16, -5, -26, 28, 5, -61, -28, 2,
- 24, 11, -12, -33, 9, -37, -3, -28,
- 22, -37, -12, 19, 0, -18, -2, 14,
- 1, 4, 8, -9, -2, 43, -17, -2,
- -66, -31, 56, -40, -87, -36, -2, -4,
- -42, -45, -1, 31, -43, -15, 27, 63,
- -11, 32, -10, -33, 27, -19, 4, 15,
- -26, -34, 29, -4, -39, -65, 14, -20,
- -21, -17, -36, 13, 59, 47, -38, -33,
- 13, -37, -8, -37, -7, -6, -76, -31,
- -12, -46, 7, 24, -21, -30, -14, 9,
- 15, -12, -13, 47, -27, -25, -1, -39,
- 0, 20, -9, 6, 7, 4, 3, 7,
- 39, 50, 22, -7, 14, -20, 1, 70,
- -28, 29, -41, 10, -16, -5, -28, -2,
- -37, 32, -18, 17, 62, -11, -20, -50,
- 36, 21, -62, -12, -56, 52, 50, 17,
- 3, 48, 44, -41, -25, 3, 16, -3,
- 0, 33, -6, 15, 27, 34, -25, 22,
- 9, 17, -11, 36, 16, -2, 12, 21,
- -52, 45, -2, -10, 46, 21, -18, 67,
- -28, -13, 30, 37, 42, 16, -9, 11,
- 75, 7, -64, -40, -10, 29, 57, -23,
- 5, 53, -77, 3, -17, -5, 47, -55,
- -35, -36, -13, 52, -53, -71, 52, -111,
- -23, -26, -28, 29, -43, 55, -19, 43,
- -19, 54, -12, -33, -44, -39, -19, -10,
- -31, -10, 21, 38, -57, -20, 2, -25,
- 8, -6, 50, 12, 15, 25, -25, 15,
- -30, -6, 9, 25, 37, 19, -4, 31,
- -22, 2, 4, 2, 36, 7, 3, -34,
- -80, 36, -10, -2, -5, 31, -36, 49,
- -70, 20, -36, 21, 24, 25, -46, -51,
- 36, -58, -48, -40, -10, 55, 71, 47,
- 10, -1, 1, 2, -46, -68, 16, 13,
- 0, -74, -29, 73, -52, -18, -11, 7,
- -44, -82, -32, -70, -28, -1, -39, -68,
- -6, -41, 12, -22, -16, 40, -11, -25,
- 51, -9, 21, 4, 4, -34, 7, -78,
- 16, 6, -38, -30, -2, -44, 32, 0,
- 22, 64, 5, -72, -2, -14, -10, -16,
- -8, -25, 12, 102, -58, 37, -10, -23,
- 15, 49, 7, -7, 2, -20, -32, 45,
- -6, 48, 28, 30, 33, -1, 22, -6,
- 30, 65, -17, 29, 74, 37, -26, -10,
- 15, -24, 19, -66, 22, -10, -31, -1,
- -18, -9, 11, 37, -4, 45, 5, 41,
- 17, 1, 1, 24, -58, 41, 5, -51,
- 14, 8, 43, 16, -10, -1, 45, 32,
- -64, 3, -33, -25, -3, -27, -68, 12,
- 23, -11, -13, -37, -40, 4, -21, -12,
- 32, -23, -19, 76, 41, -23, -24, -44,
- -65, -1, -15, 1, 71, 63, 5, 20,
- -3, 21, -23, 31, -32, 18, -2, 27,
- 31, 46, -5, -39, -5, -35, 18, -18,
- -40, -10, 3, 12, 2, -2, -22, 40,
- 5, -6, 60, 36, 3, 29, -27, 10,
- 25, -54, 5, 26, 39, 35, -24, -37,
- 30, -91, 28, -4, -21, -27, -39, -6,
- 5, 12, -128, 38, -16, 29, -95, -29,
- 82, -2, 35, 2, 12, 8, -22, 10,
- 80, -47, 2, -25, -73, -79, 16, -30,
- -32, -66, 48, 21, -45, -11, -47, 14,
- -27, -17, -7, 15, -44, -14, -44, -26,
- -32, 26, -23, 17, -7, -28, 26, -6,
- 28, 6, -26, 2, 13, -14, -23, -14,
- 19, 46, 16, 2, -33, -21, 28, -17,
- -42, 44, -37, 1, -39, 28, 84, -46,
- 15, 10, 13, -44, 72, -26, 26, 32,
- -28, -12, -83, 2, 10, -30, -44, -10,
- -28, 53, 45, 65, 0, -25, 57, 36,
- -33, 6, 29, 44, -53, 11, 19, -2,
- -27, 35, 32, 49, 4, 23, 38, 36,
- 24, 10, 51, -39, 4, -7, 26, 37,
- -35, 11, -47, -18, 28, 16, -35, 42,
- 17, -21, -41, 28, 14, -12, 11, -45,
- 7, -43, -15, 18, -5, 38, -40, -50,
- -30, -21, 9, -98, 13, 12, 23, 75,
- -56, -7, -3, -4, -1, -34, 12, -49,
- 11, 26, -18, -28, -17, 33, 13, -14,
- 40, 24, -72, -37, 10, 17, -6, 22,
- 16, 16, -6, -12, -30, -14, 10, 40,
- -23, 12, 15, -3, -15, 13, -56, -4,
- -30, 1, -3, -17, 27, 50, -5, 64,
- -36, -19, 7, 29, 22, 25, 9, -16,
- -58, -69, -40, -61, -71, -14, 42, 93,
- 26, 11, -6, -58, -11, 70, -52, 19,
- 9, -30, -33, 11, -37, -47, -21, -22,
- -40, 10, 47, 4, -23, 17, 48, 41,
- -48, 14, 10, 15, 34, -23, -2, -47,
- 23, -32, -13, -10, -26, -26, -4, 16,
- 38, -14, 0, -12, -7, -7, 20, 44,
- -1, -32, -27, -16, 4, -6, -18, 14,
- 5, 4, -29, 28, 7, -7, 15, -11,
- -20, -45, -36, 16, 84, 34, -59, -30,
- 22, 126, 8, 68, 79, -17, 21, -68,
- 37, 5, 15, 63, 49, 127, -90, 85,
- 43, 7, 16, 9, 6, -45, -57, -43,
- 57, 11, -23, -11, -29, 60, -26, 0,
- 7, 42, -24, 10, 23, -25, 8, -7,
- -40, 19, -17, 35, 4, 27, -39, -91,
- 27, -36, 34, 2, 16, -24, 25, 7,
- -21, 5, 17, 10, -22, -30, 9, -17,
- -61, -26, 33, 21, 58, -51, -14, 69,
- -38, 20, 7, 80, -4, -65, -6, -27,
- 53, -12, 47, -1, -15, 1, 60, 102,
- -79, -4, 12, 9, 22, 37, -8, -4,
- 37, 2, -3, -15, -16, -11, -5, 19,
- -6, -43, 20, -25, -18, 10, -27, 0,
- -28, -27, -11, 10, -18, -2, -4, -16,
- 26, 14, -6, 7, -6, 1, 53, -2,
- -29, 23, 9, -30, -6, -4, -6, 56,
- 70, 0, -33, -20, -17, -9, -24, 46,
- -5, -105, 47, -46, -51, 20, 20, -53,
- -81, -1, -7, 75, -5, -21, -65, 12,
- -52, 22, -50, -12, 49, 54, 76, -81,
- 10, 45, -41, -59, 18, -19, 25, 14,
- -31, -53, -5, 12, 31, 84, -23, 2,
- 7, 2, 10, -32, 39, -2, -12, 1,
- -9, 0, -10, -11, 9, 15, -8, -2,
- 2, -1, 10, 14, -5, -40, 19, -7,
- -7, 26, -4, 2, 1, -27, 35, 32,
- 21, -31, 26, 43, -9, 4, -32, 40,
- -62, -52, 36, 22, 38, 22, 36, -96,
- 6, -10, -23, -49, 15, -33, -18, -3,
- 0, 41, 21, -19, 21, 23, -39, -23,
- -6, 6, 47, 56, 4, 74, 0, -98,
- 29, -47, -14, -36, 21, -22, 22, 16,
- 13, 12, 16, -5, 13, 17, -13, -15,
- 1, -34, -26, 26, 12, 32, 27, 13,
- -67, 27, 2, 8, 10, 18, 16, 20,
- -17, -17, 57, -64, 5, 14, 19, 31,
- -18, -44, -46, -16, 4, -25, 17, -126,
- -24, 39, 4, 8, 55, -25, -34, 39,
- -16, 3, 9, 71, 72, -31, -55, 6,
- 10, -25, 32, -85, -21, 18, -8, 15,
- 12, -27, -7, 1, -21, -2, -5, 48,
- -16, 18, 1, -22, -26, 16, 14, -31,
- 27, -6, -15, -21, 4, -14, 18, -36
-};
-
-static const opus_int8 layer1_recur_weights[1728] = {
- 20, 67, -99, 12, 41, -25, 49, -44,
- 35, 81, 110, 47, 34, -66, -14, 14,
- -60, 34, 29, -73, 10, 41, 35, 89,
- 7, -35, 22, 7, 27, -20, -6, 56,
- 26, 66, 6, 33, -55, 53, 1, -21,
- 14, 17, 68, 55, 59, 0, 18, -9,
- 5, -41, 6, -5, -114, -12, 29, 42,
- -23, 10, 81, -27, 20, -53, -30, -62,
- 40, 95, 25, -4, 3, 18, -8, -15,
- -29, -82, 2, -57, -3, -61, -29, -29,
- 49, 2, -55, 5, -69, -99, -49, -51,
- 6, -25, 12, 89, 44, -33, 5, 41,
- 1, 23, -37, -37, -28, -48, 3, 4,
- -41, -30, -57, -35, -39, -1, -13, -56,
- -5, 50, 49, 41, -4, -4, 33, -22,
- -1, 33, 34, 18, 40, -42, 12, 1,
- -6, -2, 18, 17, 39, 44, 11, 65,
- -60, -45, 10, 91, 21, 9, -62, -11,
- 8, 69, 37, 24, -30, 21, 26, -27,
- 1, -28, 24, 66, -8, 6, -71, 34,
- 24, 44, 58, -78, -19, 57, 17, -60,
- 1, 12, -3, -1, -40, 22, 11, -5,
- 25, 12, 1, 72, 79, 7, -50, 23,
- 18, 13, 21, -11, -20, 5, 77, -94,
- 24, 15, 57, -51, 3, 36, 53, -1,
- 4, 14, 30, -31, 22, 40, 32, -11,
- -34, -36, -59, 58, 25, 21, -54, -23,
- 40, 46, 18, 0, 12, 54, -96, -99,
- -59, 5, 119, -38, 50, 55, 12, -16,
- 67, 0, 34, 35, 39, 35, -1, 69,
- 24, 27, -30, -35, -4, -70, 2, -44,
- -7, -6, 19, -9, 60, 44, -21, -10,
- 37, 43, -16, -3, 30, -15, -65, 31,
- -55, 18, -98, 76, 64, 25, 24, -18,
- -7, -68, -10, 38, 27, -60, 36, 33,
- 16, 30, 34, -39, -37, 31, 12, 53,
- -54, 14, -26, -49, -128, -13, -5, -22,
- -11, -85, 55, -8, -51, -11, -33, -10,
- -31, -76, -41, 23, 44, -40, -54, -127,
- -101, 19, -23, -15, 15, 27, 58, -60,
- 8, 14, -33, 1, 48, -9, -11, -123,
- 3, 53, 23, 4, -28, 22, 2, -29,
- -67, 36, 12, 7, 55, -21, 88, 20,
- -1, -21, -17, 3, 41, 32, -10, -14,
- -5, -57, 67, 57, 21, 23, -2, -27,
- -73, -24, 120, 21, 18, -35, 42, -7,
- 3, -45, -25, 76, -34, 50, 11, -54,
- -91, 3, -113, -20, -5, 47, 15, -47,
- 17, 27, -3, -26, -7, 10, 7, 74,
- -40, 64, -7, -5, -24, -49, -24, -3,
- -10, 27, -17, -8, -3, 14, -27, 33,
- 13, 39, 28, -7, -38, 29, 16, 44,
- 19, 55, -3, 9, -13, -57, 43, 43,
- 31, 0, -93, -17, 19, -56, 4, -12,
- -25, 37, -85, -13, -118, 33, -17, 56,
- 71, -80, -4, 6, -11, -18, 47, -52,
- 25, 9, 48, -107, 1, 21, 20, -3,
- 10, -16, -4, 24, 17, 31, -61, -18,
- -50, 24, -10, 12, 71, 26, 11, -3,
- 4, 1, 0, -7, -40, 18, 38, -34,
- 38, 17, 8, -34, 2, 21, 123, -32,
- -26, 43, 14, -34, -1, -9, 37, -16,
- 6, -17, -62, 68, 22, 17, 11, -75,
- 33, -80, 62, -9, -75, 76, 36, -41,
- -8, -40, -11, -71, 40, -39, 62, -49,
- -81, 16, -9, -52, 52, 61, 17, -103,
- -27, -10, -8, -54, -57, 21, 23, -16,
- -52, 36, 18, 10, -5, 8, 15, -29,
- 5, -19, -37, 8, -53, 6, 19, -37,
- 38, -17, 48, 10, 0, 81, 46, 70,
- -29, 101, 11, 44, -44, -3, 24, 11,
- 3, 14, -9, 11, 14, -45, 13, 46,
- -3, -57, 68, 44, 63, 98, 25, -28,
- -23, 15, 32, -10, 53, -6, -2, -9,
- -6, 16, -107, -11, -11, -28, 59, 57,
- -22, 38, 42, 83, 27, 5, 29, -30,
- 12, -21, -13, 31, 38, -21, 58, -10,
- -10, -15, -2, -5, 11, 12, -73, -28,
- -38, 22, 2, -25, 73, -52, -12, -55,
- 32, -63, 21, 51, 33, 52, -26, 55,
- -26, -26, 57, -32, -4, -52, -61, 21,
- -33, -91, -51, 69, -90, -53, -38, -44,
- 12, -76, -20, 77, -45, -7, 86, 43,
- -109, -33, -105, -40, -121, -10, 0, -72,
- 45, -51, -75, -49, -38, -1, -62, 18,
- -1, 30, -44, -14, -10, -67, 40, -10,
- -34, 46, -64, -32, 29, -13, 33, 3,
- -32, -5, 28, -27, -25, 93, 24, 68,
- -40, 57, 23, -3, -21, -58, 17, -39,
- -17, -22, -89, 11, 18, -46, 27, 24,
- 46, 127, 61, 87, 31, 127, -36, 47,
- -23, 47, 127, -24, 110, 122, 30, 100,
- 0, 96, -12, 6, 50, 44, -13, 73,
- 4, 55, -11, -15, 49, 42, -6, 20,
- -35, 58, 18, 38, 42, 72, 19, -21,
- 11, 9, -37, 7, 29, 31, 16, -17,
- 13, -50, 19, 5, -23, 51, -16, -5,
- 4, -24, 76, 10, -53, -28, -7, -65,
- 74, 40, -16, -29, 32, -16, -49, -35,
- -3, 59, -96, -50, -43, -43, -61, -15,
- -8, -36, -34, -33, -14, 11, -3, -39,
- 4, -114, -123, -11, -49, -21, 14, -56,
- 1, 43, -63, 26, 40, 18, -10, -26,
- -14, -15, -35, -35, -11, 32, -44, -67,
- 2, 22, 7, 3, -9, -30, -51, -28,
- 28, 6, -22, 16, 34, -25, -52, -54,
- -8, -6, 5, 8, 20, -16, -17, -44,
- 27, 3, 31, -5, -48, -1, -3, 116,
- 11, 71, -31, -47, 109, 50, -22, -12,
- -57, 32, 66, 8, -25, -93, -54, -10,
- 19, -76, -34, 97, 48, -36, -18, -30,
- -39, -26, -12, 28, 14, 12, -12, -31,
- 38, 2, 10, 4, -40, 20, 16, -61,
- 2, 64, 39, 5, 15, 33, 40, -61,
- -49, 93, -10, 33, 28, -11, -27, -18,
- 39, -62, -6, -6, 62, 11, -8, 38,
- -67, 12, 27, 39, -27, 123, -18, -6,
- -65, 83, -64, 20, 19, -11, 33, 24,
- 17, 56, 78, 7, -15, 54, -101, -9,
- 115, -96, 50, 51, 35, 34, 27, 37,
- -40, -11, 8, -36, 42, -45, 2, -23,
- 0, 67, -8, -9, -13, 50, -14, -27,
- 4, 0, -8, -14, 30, -9, 29, 15,
- 9, -38, 37, -8, 50, -46, 54, 41,
- -11, -8, -11, -26, 39, 45, 14, -26,
- -17, -27, 69, 38, 39, 98, 66, 0,
- 42, 123, -101, -19, -83, 117, -32, 56,
- 10, 12, -88, 79, -53, 56, 63, 95,
- -62, 9, 36, -13, -79, -16, 37, -46,
- 35, -34, 14, 17, -54, 5, 21, -7,
- 7, 63, 56, 15, 27, -76, -25, 4,
- -26, -63, 28, -67, -52, 43, -47, -70,
- 40, -12, 40, -66, -37, 0, 35, 37,
- -53, 4, -17, -51, 11, 21, 14, -34,
- -4, 24, -42, 29, 22, 7, 28, 12,
- 37, 39, -39, -19, 65, -60, -50, -2,
- 1, 82, 39, 19, -23, -43, -22, -67,
- -35, -34, 32, 102, 81, 127, 36, 67,
- -45, 1, -67, -52, -4, 35, 20, 28,
- 71, 86, -35, -9, -83, -34, 12, 9,
- -23, 2, 14, 28, -23, 7, -25, 45,
- 7, 17, -37, 0, -19, 31, 26, 40,
- -27, -16, 17, 5, -21, 23, 24, 96,
- -55, 52, -19, -14, -6, 1, 50, -34,
- 86, -53, 38, 2, -52, -36, -13, 60,
- -85, -120, 32, 7, -12, 22, 70, -7,
- -94, 38, -76, -31, -20, 15, -28, 7,
- 6, 40, 53, 88, 3, 38, 18, -8,
- -22, -23, 51, 37, -9, 13, -32, 25,
- -21, 27, 31, 20, 18, -9, -13, 1,
- 21, -24, -13, 39, 15, -11, -29, -36,
- 18, 15, 8, 27, 21, -94, -1, -22,
- 49, 66, -1, 6, -3, -40, -18, 6,
- 28, 12, 33, -59, 62, 60, -48, 90,
- -1, 108, 9, 18, -2, 27, 77, -65,
- 82, -48, -38, -19, -11, 127, 50, 66,
- 18, -13, -22, 60, -38, 40, -14, -26,
- -13, 38, 67, 57, 30, 33, 26, 36,
- 38, -17, 27, -28, 20, 12, -64, 18,
- 5, -33, -27, 13, -26, 32, 35, -5,
- -48, -14, 92, 43, -47, -14, 40, 11,
- 51, 66, 22, -63, -16, -61, 4, -28,
- 27, 20, -33, -30, -21, -29, -53, 31,
- -40, 24, 43, -4, -19, 21, 67, 20,
- 100, -16, -93, 78, -6, -18, -52, -37,
- -9, 66, -31, -8, 26, 18, 4, 24,
- -22, 17, -2, -13, 27, 0, 8, -18,
- -25, 5, -21, -24, -7, 18, -93, 21,
- 7, 2, -75, 69, 50, -5, -15, -17,
- 60, -42, 55, 1, -4, 3, 10, 46,
- 16, -13, 45, -7, -10, -44, -108, 49,
- 2, -15, -64, -12, -72, 32, -38, -45,
- 10, -54, 13, -13, -27, -36, -64, 58,
- -62, -101, 88, -86, -71, -39, -9, -128,
- 32, 15, -4, 54, -16, -39, -26, -36,
- 46, 48, -64, -10, 19, 30, -13, 34,
- -8, 50, 60, -22, -6, -11, -30, 5,
- 50, 32, 56, 0, 25, 6, 68, 11,
- -29, 45, -9, -12, 4, 1, 18, -49,
- 0, -38, -19, 90, 29, 35, 51, 8,
- -48, 96, -1, -12, -9, -32, -63, -65,
- -7, 38, 89, 28, -85, -28, -23, -25,
- -128, 56, 79, -36, 99, -6, -37, 7,
- -13, -69, -46, -29, 25, 64, -21, 17,
- 1, 42, -66, 1, 80, 26, -32, 21,
- 15, 15, 6, 6, -10, 15, 127, 5,
- 38, 27, 87, -57, -25, 11, 72, -21,
- -5, 11, -13, -66, 78, 36, -3, 41,
- -21, 8, -33, 23, 73, 28, 57, -25,
- -5, 4, -22, -47, 15, 4, -57, -72,
- 33, 1, 18, 2, 53, -71, -99, -21,
- -3, -111, 108, 71, -14, 82, 25, 61,
- -48, 5, 9, -51, -20, -25, -3, 14,
- -33, 14, -3, -34, 22, 12, -19, -38,
- -16, 2, 21, 16, 26, -31, 75, 44,
- -31, 16, 26, 66, 17, -9, -22, -22,
- 22, -44, 22, 27, 2, 58, -14, 10,
- -73, -42, 55, -25, -61, 72, -1, 30,
- -58, -25, 63, 26, -48, -40, 26, -30,
- 60, 8, -17, -1, -18, -20, 43, -20,
- -4, -28, 127, -106, 29, 70, 64, -27,
- 39, -33, -5, -88, -40, -52, 26, 44,
- -17, 23, 2, -49, 22, -9, -8, 86,
- 49, -43, -60, 1, 10, 45, 36, -53,
- -4, 33, 38, 48, -72, 1, 19, 21,
- -65, 4, -5, -62, 27, -25, 17, -6,
- 6, -45, -39, -46, 4, 26, 127, -9,
- 18, -33, -18, -3, 33, 2, -5, 15,
- -26, -22, -117, -63, -17, -59, 61, -74,
- 7, -47, -58, -128, -67, 15, -16, -128,
- 12, 2, 20, 9, -48, -40, 43, 3,
- -40, -16, -38, -6, -22, -28, -16, -59,
- -22, 6, -5, 11, -12, -66, -40, 27,
- -62, -44, -19, 38, -3, 39, -8, 40,
- -24, 13, 21, 50, -60, -22, 53, -29,
- -6, 1, 22, -59, 0, 17, -39, 115
-};
+/* RMS error was 0.138320, seed was 1361535663 */
-static const opus_int8 layer1_bias[72] = {
- -42, 20, 16, 0, 105, 60, 1, -97,
- 24, 60, 18, 13, 62, 25, 127, 34,
- 79, 55, 118, 127, 95, 31, -4, 87,
- 21, 12, 2, -14, 18, 23, 8, 17,
- -1, -8, 5, 4, 24, 37, 21, 13,
- 36, 13, 17, 18, 37, 30, 33, 1,
- 8, -16, -11, -5, -31, -3, -5, 0,
- 6, 3, 58, -7, -1, -16, 5, -13,
- 16, 10, -2, -14, 11, -4, 3, -11
-};
+static const float weights[422] = {
-static const opus_int8 layer2_weights[48] = {
- -113, -88, 31, -128, -126, -61, 85, -35,
- 118, -128, -61, 127, -128, -17, -128, 127,
- 104, -9, -128, 33, 45, 127, 5, 83,
- 84, -128, -85, -128, -45, 48, -53, -128,
- 46, 127, -17, 125, 117, -41, -117, -91,
- -127, -68, -1, -89, -80, 32, 106, 7
-};
+/* hidden layer */
+-0.0941125f, -0.302976f, -0.603555f, -0.19393f, -0.185983f,
+-0.601617f, -0.0465317f, -0.114563f, -0.103599f, -0.618938f,
+-0.317859f, -0.169949f, -0.0702885f, 0.148065f, 0.409524f,
+0.548432f, 0.367649f, -0.494393f, 0.764306f, -1.83957f,
+0.170849f, 12.786f, -1.08848f, -1.27284f, -16.2606f,
+24.1773f, -5.57454f, -0.17276f, -0.163388f, -0.224421f,
+-0.0948944f, -0.0728695f, -0.26557f, -0.100283f, -0.0515459f,
+-0.146142f, -0.120674f, -0.180655f, 0.12857f, 0.442138f,
+-0.493735f, 0.167767f, 0.206699f, -0.197567f, 0.417999f,
+1.50364f, -0.773341f, -10.0401f, 0.401872f, 2.97966f,
+15.2165f, -1.88905f, -1.19254f, 0.0285397f, -0.00405139f,
+0.0707565f, 0.00825699f, -0.0927269f, -0.010393f, -0.00428882f,
+-0.00489743f, -0.0709731f, -0.00255992f, 0.0395619f, 0.226424f,
+0.0325231f, 0.162175f, -0.100118f, 0.485789f, 0.12697f,
+0.285937f, 0.0155637f, 0.10546f, 3.05558f, 1.15059f,
+-1.00904f, -1.83088f, 3.31766f, -3.42516f, -0.119135f,
+-0.0405654f, 0.00690068f, 0.0179877f, -0.0382487f, 0.00597941f,
+-0.0183611f, 0.00190395f, -0.144322f, -0.0435671f, 0.000990594f,
+0.221087f, 0.142405f, 0.484066f, 0.404395f, 0.511955f,
+-0.237255f, 0.241742f, 0.35045f, -0.699428f, 10.3993f,
+2.6507f, -2.43459f, -4.18838f, 1.05928f, 1.71067f,
+0.00667811f, -0.0721335f, -0.0397346f, 0.0362704f, -0.11496f,
+-0.0235776f, 0.0082161f, -0.0141741f, -0.0329699f, -0.0354253f,
+0.00277404f, -0.290654f, -1.14767f, -0.319157f, -0.686544f,
+0.36897f, 0.478899f, 0.182579f, -0.411069f, 0.881104f,
+-4.60683f, 1.4697f, 0.335845f, -1.81905f, -30.1699f,
+5.55225f, 0.0019508f, -0.123576f, -0.0727332f, -0.0641597f,
+-0.0534458f, -0.108166f, -0.0937368f, -0.0697883f, -0.0275475f,
+-0.192309f, -0.110074f, 0.285375f, -0.405597f, 0.0926724f,
+-0.287881f, -0.851193f, -0.099493f, -0.233764f, -1.2852f,
+1.13611f, 3.12168f, -0.0699f, -1.86216f, 2.65292f,
+-7.31036f, 2.44776f, -0.00111802f, -0.0632786f, -0.0376296f,
+-0.149851f, 0.142963f, 0.184368f, 0.123433f, 0.0756158f,
+0.117312f, 0.0933395f, 0.0692163f, 0.0842592f, 0.0704683f,
+0.0589963f, 0.0942205f, -0.448862f, 0.0262677f, 0.270352f,
+-0.262317f, 0.172586f, 2.00227f, -0.159216f, 0.038422f,
+10.2073f, 4.15536f, -2.3407f, -0.0550265f, 0.00964792f,
+-0.141336f, 0.0274501f, 0.0343921f, -0.0487428f, 0.0950172f,
+-0.00775017f, -0.0372492f, -0.00548121f, -0.0663695f, 0.0960506f,
+-0.200008f, -0.0412827f, 0.58728f, 0.0515787f, 0.337254f,
+0.855024f, 0.668371f, -0.114904f, -3.62962f, -0.467477f,
+-0.215472f, 2.61537f, 0.406117f, -1.36373f, 0.0425394f,
+0.12208f, 0.0934502f, 0.123055f, 0.0340935f, -0.142466f,
+0.035037f, -0.0490666f, 0.0733208f, 0.0576672f, 0.123984f,
+-0.0517194f, -0.253018f, 0.590565f, 0.145849f, 0.315185f,
+0.221534f, -0.149081f, 0.216161f, -0.349575f, 24.5664f,
+-0.994196f, 0.614289f, -18.7905f, -2.83277f, -0.716801f,
+-0.347201f, 0.479515f, -0.246027f, 0.0758683f, 0.137293f,
+-0.17781f, 0.118751f, -0.00108329f, -0.237334f, 0.355732f,
+-0.12991f, -0.0547627f, -0.318576f, -0.325524f, 0.180494f,
+-0.0625604f, 0.141219f, 0.344064f, 0.37658f, -0.591772f,
+5.8427f, -0.38075f, 0.221894f, -1.41934f, -1.87943e+06f,
+1.34114f, 0.0283355f, -0.0447856f, -0.0211466f, -0.0256927f,
+0.0139618f, 0.0207934f, -0.0107666f, 0.0110969f, 0.0586069f,
+-0.0253545f, -0.0328433f, 0.11872f, -0.216943f, 0.145748f,
+0.119808f, -0.0915211f, -0.120647f, -0.0787719f, -0.143644f,
+-0.595116f, -1.152f, -1.25335f, -1.17092f, 4.34023f,
+-975268.f, -1.37033f, -0.0401123f, 0.210602f, -0.136656f,
+0.135962f, -0.0523293f, 0.0444604f, 0.0143928f, 0.00412666f,
+-0.0193003f, 0.218452f, -0.110204f, -2.02563f, 0.918238f,
+-2.45362f, 1.19542f, -0.061362f, -1.92243f, 0.308111f,
+0.49764f, 0.912356f, 0.209272f, -2.34525f, 2.19326f,
+-6.47121f, 1.69771f, -0.725123f, 0.0118929f, 0.0377944f,
+0.0554003f, 0.0226452f, -0.0704421f, -0.0300309f, 0.0122978f,
+-0.0041782f, -0.0686612f, 0.0313115f, 0.039111f, 0.364111f,
+-0.0945548f, 0.0229876f, -0.17414f, 0.329795f, 0.114714f,
+0.30022f, 0.106997f, 0.132355f, 5.79932f, 0.908058f,
+-0.905324f, -3.3561f, 0.190647f, 0.184211f, -0.673648f,
+0.231807f, -0.0586222f, 0.230752f, -0.438277f, 0.245857f,
+-0.17215f, 0.0876383f, -0.720512f, 0.162515f, 0.0170571f,
+0.101781f, 0.388477f, 1.32931f, 1.08548f, -0.936301f,
+-2.36958f, -6.71988f, -3.44376f, 2.13818f, 14.2318f,
+4.91459f, -3.09052f, -9.69191f, -0.768234f, 1.79604f,
+0.0549653f, 0.163399f, 0.0797025f, 0.0343933f, -0.0555876f,
+-0.00505673f, 0.0187258f, 0.0326628f, 0.0231486f, 0.15573f,
+0.0476223f, -0.254824f, 1.60155f, -0.801221f, 2.55496f,
+0.737629f, -1.36249f, -0.695463f, -2.44301f, -1.73188f,
+3.95279f, 1.89068f, 0.486087f, -11.3343f, 3.9416e+06f,
-static const opus_int8 layer2_bias[2] = {
- 14, 117
-};
+/* output layer */
+-0.381439f, 0.12115f, -0.906927f, 2.93878f, 1.6388f,
+0.882811f, 0.874344f, 1.21726f, -0.874545f, 0.321706f,
+0.785055f, 0.946558f, -0.575066f, -3.46553f, 0.884905f,
+0.0924047f, -9.90712f, 0.391338f, 0.160103f, -2.04954f,
+4.1455f, 0.0684029f, -0.144761f, -0.285282f, 0.379244f,
+-1.1584f, -0.0277241f, -9.85f, -4.82386f, 3.71333f,
+3.87308f, 3.52558f};
-const DenseLayer layer0 = {
- layer0_bias,
- layer0_weights,
- 25, 32, 0
-};
+static const int topo[3] = {25, 15, 2};
-const GRULayer layer1 = {
- layer1_bias,
- layer1_weights,
- layer1_recur_weights,
- 32, 24
+const MLP net = {
+ 3,
+ topo,
+ weights
};
-
-const DenseLayer layer2 = {
- layer2_bias,
- layer2_weights,
- 24, 2, 1
-};
-
diff --git a/thirdparty/opus/opus.c b/thirdparty/opus/opus.c
index 538b5ea74e..f76f125cfa 100644
--- a/thirdparty/opus/opus.c
+++ b/thirdparty/opus/opus.c
@@ -107,7 +107,7 @@ OPUS_EXPORT void opus_pcm_soft_clip(float *_x, int N, int C, float *declip_mem)
/* Slightly boost "a" by 2^-22. This is just enough to ensure -ffast-math
does not cause output values larger than +/-1, but small enough not
to matter even for 24-bit output. */
- a += a*2.4e-7f;
+ a += a*2.4e-7;
if (x[i*C]>0)
a = -a;
/* Apply soft clipping */
@@ -252,7 +252,7 @@ int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
/* Number of frames encoded in bits 0 to 5 */
ch = *data++;
count = ch&0x3F;
- if (count <= 0 || framesize*(opus_int32)count > 5760)
+ if (count <= 0 || framesize*count > 5760)
return OPUS_INVALID_PACKET;
len--;
/* Padding flag is bit 6 */
diff --git a/thirdparty/opus/opus/opus.h b/thirdparty/opus/opus/opus.h
index d282f21d25..5be73ddf4e 100644
--- a/thirdparty/opus/opus/opus.h
+++ b/thirdparty/opus/opus/opus.h
@@ -531,7 +531,7 @@ OPUS_EXPORT int opus_packet_parse(
const unsigned char *frames[48],
opus_int16 size[48],
int *payload_offset
-) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5);
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
/** Gets the bandwidth of an Opus packet.
* @param [in] data <tt>char*</tt>: Opus packet
diff --git a/thirdparty/opus/opus/opus_defines.h b/thirdparty/opus/opus/opus_defines.h
index d141418b21..315412dd1d 100644
--- a/thirdparty/opus/opus/opus_defines.h
+++ b/thirdparty/opus/opus/opus_defines.h
@@ -165,13 +165,8 @@ extern "C" {
#define OPUS_GET_EXPERT_FRAME_DURATION_REQUEST 4041
#define OPUS_SET_PREDICTION_DISABLED_REQUEST 4042
#define OPUS_GET_PREDICTION_DISABLED_REQUEST 4043
-/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */
-#define OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST 4046
-#define OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST 4047
-#define OPUS_GET_IN_DTX_REQUEST 4049
-/** Defines for the presence of extended APIs. */
-#define OPUS_HAVE_OPUS_PROJECTION_H
+/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */
/* Macros to trigger compilation errors when the wrong types are provided to a CTL */
#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x))
@@ -213,9 +208,6 @@ extern "C" {
#define OPUS_FRAMESIZE_20_MS 5004 /**< Use 20 ms frames */
#define OPUS_FRAMESIZE_40_MS 5005 /**< Use 40 ms frames */
#define OPUS_FRAMESIZE_60_MS 5006 /**< Use 60 ms frames */
-#define OPUS_FRAMESIZE_80_MS 5007 /**< Use 80 ms frames */
-#define OPUS_FRAMESIZE_100_MS 5008 /**< Use 100 ms frames */
-#define OPUS_FRAMESIZE_120_MS 5009 /**< Use 120 ms frames */
/**@}*/
@@ -574,9 +566,7 @@ extern "C" {
* <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd>
- * <dt>OPUS_FRAMESIZE_80_MS</dt><dd>Use 80 ms frames.</dd>
- * <dt>OPUS_FRAMESIZE_100_MS</dt><dd>Use 100 ms frames.</dd>
- * <dt>OPUS_FRAMESIZE_120_MS</dt><dd>Use 120 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_VARIABLE</dt><dd>Optimize the frame size dynamically.</dd>
* </dl>
* @hideinitializer */
#define OPUS_SET_EXPERT_FRAME_DURATION(x) OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int(x)
@@ -591,9 +581,7 @@ extern "C" {
* <dt>OPUS_FRAMESIZE_20_MS</dt><dd>Use 20 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_40_MS</dt><dd>Use 40 ms frames.</dd>
* <dt>OPUS_FRAMESIZE_60_MS</dt><dd>Use 60 ms frames.</dd>
- * <dt>OPUS_FRAMESIZE_80_MS</dt><dd>Use 80 ms frames.</dd>
- * <dt>OPUS_FRAMESIZE_100_MS</dt><dd>Use 100 ms frames.</dd>
- * <dt>OPUS_FRAMESIZE_120_MS</dt><dd>Use 120 ms frames.</dd>
+ * <dt>OPUS_FRAMESIZE_VARIABLE</dt><dd>Optimize the frame size dynamically.</dd>
* </dl>
* @hideinitializer */
#define OPUS_GET_EXPERT_FRAME_DURATION(x) OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int_ptr(x)
@@ -693,40 +681,6 @@ extern "C" {
*/
#define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x)
-/** If set to 1, disables the use of phase inversion for intensity stereo,
- * improving the quality of mono downmixes, but slightly reducing normal
- * stereo quality. Disabling phase inversion in the decoder does not comply
- * with RFC 6716, although it does not cause any interoperability issue and
- * is expected to become part of the Opus standard once RFC 6716 is updated
- * by draft-ietf-codec-opus-update.
- * @see OPUS_GET_PHASE_INVERSION_DISABLED
- * @param[in] x <tt>opus_int32</tt>: Allowed values:
- * <dl>
- * <dt>0</dt><dd>Enable phase inversion (default).</dd>
- * <dt>1</dt><dd>Disable phase inversion.</dd>
- * </dl>
- * @hideinitializer */
-#define OPUS_SET_PHASE_INVERSION_DISABLED(x) OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, __opus_check_int(x)
-/** Gets the encoder's configured phase inversion status.
- * @see OPUS_SET_PHASE_INVERSION_DISABLED
- * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
- * <dl>
- * <dt>0</dt><dd>Stereo phase inversion enabled (default).</dd>
- * <dt>1</dt><dd>Stereo phase inversion disabled.</dd>
- * </dl>
- * @hideinitializer */
-#define OPUS_GET_PHASE_INVERSION_DISABLED(x) OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, __opus_check_int_ptr(x)
-/** Gets the DTX state of the encoder.
- * Returns whether the last encoded frame was either a comfort noise update
- * during DTX or not encoded because of DTX.
- * @param[out] x <tt>opus_int32 *</tt>: Returns one of the following values:
- * <dl>
- * <dt>0</dt><dd>The encoder is not in DTX.</dd>
- * <dt>1</dt><dd>The encoder is in DTX.</dd>
- * </dl>
- * @hideinitializer */
-#define OPUS_GET_IN_DTX(x) OPUS_GET_IN_DTX_REQUEST, __opus_check_int_ptr(x)
-
/**@}*/
/** @defgroup opus_decoderctls Decoder related CTLs
diff --git a/thirdparty/opus/opus/opus_multistream.h b/thirdparty/opus/opus/opus_multistream.h
index babcee6905..3622e009fb 100644
--- a/thirdparty/opus/opus/opus_multistream.h
+++ b/thirdparty/opus/opus/opus_multistream.h
@@ -273,7 +273,7 @@ OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_surround_enc
unsigned char *mapping,
int application,
int *error
-) OPUS_ARG_NONNULL(4) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6);
+) OPUS_ARG_NONNULL(5);
/** Initialize a previously allocated multistream encoder state.
* The memory pointed to by \a st must be at least the size returned by
@@ -342,7 +342,7 @@ OPUS_EXPORT int opus_multistream_surround_encoder_init(
int *coupled_streams,
unsigned char *mapping,
int application
-) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6) OPUS_ARG_NONNULL(7);
+) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
/** Encodes a multistream Opus frame.
* @param st <tt>OpusMSEncoder*</tt>: Multistream encoder state.
diff --git a/thirdparty/opus/opus/opus_projection.h b/thirdparty/opus/opus/opus_projection.h
deleted file mode 100644
index 9dabf4e85c..0000000000
--- a/thirdparty/opus/opus/opus_projection.h
+++ /dev/null
@@ -1,568 +0,0 @@
-/* Copyright (c) 2017 Google Inc.
- Written by Andrew Allen */
-/*
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-/**
- * @file opus_projection.h
- * @brief Opus projection reference API
- */
-
-#ifndef OPUS_PROJECTION_H
-#define OPUS_PROJECTION_H
-
-#include "opus_multistream.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** @cond OPUS_INTERNAL_DOC */
-
-/** These are the actual encoder and decoder CTL ID numbers.
- * They should not be used directly by applications.c
- * In general, SETs should be even and GETs should be odd.*/
-/**@{*/
-#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST 6001
-#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST 6003
-#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST 6005
-/**@}*/
-
-
-/** @endcond */
-
-/** @defgroup opus_projection_ctls Projection specific encoder and decoder CTLs
- *
- * These are convenience macros that are specific to the
- * opus_projection_encoder_ctl() and opus_projection_decoder_ctl()
- * interface.
- * The CTLs from @ref opus_genericctls, @ref opus_encoderctls,
- * @ref opus_decoderctls, and @ref opus_multistream_ctls may be applied to a
- * projection encoder or decoder as well.
- */
-/**@{*/
-
-/** Gets the gain (in dB. S7.8-format) of the demixing matrix from the encoder.
- * @param[out] x <tt>opus_int32 *</tt>: Returns the gain (in dB. S7.8-format)
- * of the demixing matrix.
- * @hideinitializer
- */
-#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN(x) OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST, __opus_check_int_ptr(x)
-
-
-/** Gets the size in bytes of the demixing matrix from the encoder.
- * @param[out] x <tt>opus_int32 *</tt>: Returns the size in bytes of the
- * demixing matrix.
- * @hideinitializer
- */
-#define OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE(x) OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST, __opus_check_int_ptr(x)
-
-
-/** Copies the demixing matrix to the supplied pointer location.
- * @param[out] x <tt>unsigned char *</tt>: Returns the demixing matrix to the
- * supplied pointer location.
- * @param y <tt>opus_int32</tt>: The size in bytes of the reserved memory at the
- * pointer location.
- * @hideinitializer
- */
-#define OPUS_PROJECTION_GET_DEMIXING_MATRIX(x,y) OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST, x, __opus_check_int(y)
-
-
-/**@}*/
-
-/** Opus projection encoder state.
- * This contains the complete state of a projection Opus encoder.
- * It is position independent and can be freely copied.
- * @see opus_projection_ambisonics_encoder_create
- */
-typedef struct OpusProjectionEncoder OpusProjectionEncoder;
-
-
-/** Opus projection decoder state.
- * This contains the complete state of a projection Opus decoder.
- * It is position independent and can be freely copied.
- * @see opus_projection_decoder_create
- * @see opus_projection_decoder_init
- */
-typedef struct OpusProjectionDecoder OpusProjectionDecoder;
-
-
-/**\name Projection encoder functions */
-/**@{*/
-
-/** Gets the size of an OpusProjectionEncoder structure.
- * @param channels <tt>int</tt>: The total number of input channels to encode.
- * This must be no more than 255.
- * @param mapping_family <tt>int</tt>: The mapping family to use for selecting
- * the appropriate projection.
- * @returns The size in bytes on success, or a negative error code
- * (see @ref opus_errorcodes) on error.
- */
-OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_projection_ambisonics_encoder_get_size(
- int channels,
- int mapping_family
-);
-
-
-/** Allocates and initializes a projection encoder state.
- * Call opus_projection_encoder_destroy() to release
- * this object when finished.
- * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
- * This must be one of 8000, 12000, 16000,
- * 24000, or 48000.
- * @param channels <tt>int</tt>: Number of channels in the input signal.
- * This must be at most 255.
- * It may be greater than the number of
- * coded channels (<code>streams +
- * coupled_streams</code>).
- * @param mapping_family <tt>int</tt>: The mapping family to use for selecting
- * the appropriate projection.
- * @param[out] streams <tt>int *</tt>: The total number of streams that will
- * be encoded from the input.
- * @param[out] coupled_streams <tt>int *</tt>: Number of coupled (2 channel)
- * streams that will be encoded from the input.
- * @param application <tt>int</tt>: The target encoder application.
- * This must be one of the following:
- * <dl>
- * <dt>#OPUS_APPLICATION_VOIP</dt>
- * <dd>Process signal for improved speech intelligibility.</dd>
- * <dt>#OPUS_APPLICATION_AUDIO</dt>
- * <dd>Favor faithfulness to the original input.</dd>
- * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
- * <dd>Configure the minimum possible coding delay by disabling certain modes
- * of operation.</dd>
- * </dl>
- * @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error
- * code (see @ref opus_errorcodes) on
- * failure.
- */
-OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusProjectionEncoder *opus_projection_ambisonics_encoder_create(
- opus_int32 Fs,
- int channels,
- int mapping_family,
- int *streams,
- int *coupled_streams,
- int application,
- int *error
-) OPUS_ARG_NONNULL(4) OPUS_ARG_NONNULL(5);
-
-
-/** Initialize a previously allocated projection encoder state.
- * The memory pointed to by \a st must be at least the size returned by
- * opus_projection_ambisonics_encoder_get_size().
- * This is intended for applications which use their own allocator instead of
- * malloc.
- * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
- * @see opus_projection_ambisonics_encoder_create
- * @see opus_projection_ambisonics_encoder_get_size
- * @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state to initialize.
- * @param Fs <tt>opus_int32</tt>: Sampling rate of the input signal (in Hz).
- * This must be one of 8000, 12000, 16000,
- * 24000, or 48000.
- * @param channels <tt>int</tt>: Number of channels in the input signal.
- * This must be at most 255.
- * It may be greater than the number of
- * coded channels (<code>streams +
- * coupled_streams</code>).
- * @param streams <tt>int</tt>: The total number of streams to encode from the
- * input.
- * This must be no more than the number of channels.
- * @param coupled_streams <tt>int</tt>: Number of coupled (2 channel) streams
- * to encode.
- * This must be no larger than the total
- * number of streams.
- * Additionally, The total number of
- * encoded channels (<code>streams +
- * coupled_streams</code>) must be no
- * more than the number of input channels.
- * @param application <tt>int</tt>: The target encoder application.
- * This must be one of the following:
- * <dl>
- * <dt>#OPUS_APPLICATION_VOIP</dt>
- * <dd>Process signal for improved speech intelligibility.</dd>
- * <dt>#OPUS_APPLICATION_AUDIO</dt>
- * <dd>Favor faithfulness to the original input.</dd>
- * <dt>#OPUS_APPLICATION_RESTRICTED_LOWDELAY</dt>
- * <dd>Configure the minimum possible coding delay by disabling certain modes
- * of operation.</dd>
- * </dl>
- * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
- * on failure.
- */
-OPUS_EXPORT int opus_projection_ambisonics_encoder_init(
- OpusProjectionEncoder *st,
- opus_int32 Fs,
- int channels,
- int mapping_family,
- int *streams,
- int *coupled_streams,
- int application
-) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(5) OPUS_ARG_NONNULL(6);
-
-
-/** Encodes a projection Opus frame.
- * @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state.
- * @param[in] pcm <tt>const opus_int16*</tt>: The input signal as interleaved
- * samples.
- * This must contain
- * <code>frame_size*channels</code>
- * samples.
- * @param frame_size <tt>int</tt>: Number of samples per channel in the input
- * signal.
- * This must be an Opus frame size for the
- * encoder's sampling rate.
- * For example, at 48 kHz the permitted values
- * are 120, 240, 480, 960, 1920, and 2880.
- * Passing in a duration of less than 10 ms
- * (480 samples at 48 kHz) will prevent the
- * encoder from using the LPC or hybrid modes.
- * @param[out] data <tt>unsigned char*</tt>: Output payload.
- * This must contain storage for at
- * least \a max_data_bytes.
- * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
- * memory for the output
- * payload. This may be
- * used to impose an upper limit on
- * the instant bitrate, but should
- * not be used as the only bitrate
- * control. Use #OPUS_SET_BITRATE to
- * control the bitrate.
- * @returns The length of the encoded packet (in bytes) on success or a
- * negative error code (see @ref opus_errorcodes) on failure.
- */
-OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_encode(
- OpusProjectionEncoder *st,
- const opus_int16 *pcm,
- int frame_size,
- unsigned char *data,
- opus_int32 max_data_bytes
-) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
-
-
-/** Encodes a projection Opus frame from floating point input.
- * @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state.
- * @param[in] pcm <tt>const float*</tt>: The input signal as interleaved
- * samples with a normal range of
- * +/-1.0.
- * Samples with a range beyond +/-1.0
- * are supported but will be clipped by
- * decoders using the integer API and
- * should only be used if it is known
- * that the far end supports extended
- * dynamic range.
- * This must contain
- * <code>frame_size*channels</code>
- * samples.
- * @param frame_size <tt>int</tt>: Number of samples per channel in the input
- * signal.
- * This must be an Opus frame size for the
- * encoder's sampling rate.
- * For example, at 48 kHz the permitted values
- * are 120, 240, 480, 960, 1920, and 2880.
- * Passing in a duration of less than 10 ms
- * (480 samples at 48 kHz) will prevent the
- * encoder from using the LPC or hybrid modes.
- * @param[out] data <tt>unsigned char*</tt>: Output payload.
- * This must contain storage for at
- * least \a max_data_bytes.
- * @param [in] max_data_bytes <tt>opus_int32</tt>: Size of the allocated
- * memory for the output
- * payload. This may be
- * used to impose an upper limit on
- * the instant bitrate, but should
- * not be used as the only bitrate
- * control. Use #OPUS_SET_BITRATE to
- * control the bitrate.
- * @returns The length of the encoded packet (in bytes) on success or a
- * negative error code (see @ref opus_errorcodes) on failure.
- */
-OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_encode_float(
- OpusProjectionEncoder *st,
- const float *pcm,
- int frame_size,
- unsigned char *data,
- opus_int32 max_data_bytes
-) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4);
-
-
-/** Frees an <code>OpusProjectionEncoder</code> allocated by
- * opus_projection_ambisonics_encoder_create().
- * @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state to be freed.
- */
-OPUS_EXPORT void opus_projection_encoder_destroy(OpusProjectionEncoder *st);
-
-
-/** Perform a CTL function on a projection Opus encoder.
- *
- * Generally the request and subsequent arguments are generated by a
- * convenience macro.
- * @param st <tt>OpusProjectionEncoder*</tt>: Projection encoder state.
- * @param request This and all remaining parameters should be replaced by one
- * of the convenience macros in @ref opus_genericctls,
- * @ref opus_encoderctls, @ref opus_multistream_ctls, or
- * @ref opus_projection_ctls
- * @see opus_genericctls
- * @see opus_encoderctls
- * @see opus_multistream_ctls
- * @see opus_projection_ctls
- */
-OPUS_EXPORT int opus_projection_encoder_ctl(OpusProjectionEncoder *st, int request, ...) OPUS_ARG_NONNULL(1);
-
-
-/**@}*/
-
-/**\name Projection decoder functions */
-/**@{*/
-
-/** Gets the size of an <code>OpusProjectionDecoder</code> structure.
- * @param channels <tt>int</tt>: The total number of output channels.
- * This must be no more than 255.
- * @param streams <tt>int</tt>: The total number of streams coded in the
- * input.
- * This must be no more than 255.
- * @param coupled_streams <tt>int</tt>: Number streams to decode as coupled
- * (2 channel) streams.
- * This must be no larger than the total
- * number of streams.
- * Additionally, The total number of
- * coded channels (<code>streams +
- * coupled_streams</code>) must be no
- * more than 255.
- * @returns The size in bytes on success, or a negative error code
- * (see @ref opus_errorcodes) on error.
- */
-OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_projection_decoder_get_size(
- int channels,
- int streams,
- int coupled_streams
-);
-
-
-/** Allocates and initializes a projection decoder state.
- * Call opus_projection_decoder_destroy() to release
- * this object when finished.
- * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
- * This must be one of 8000, 12000, 16000,
- * 24000, or 48000.
- * @param channels <tt>int</tt>: Number of channels to output.
- * This must be at most 255.
- * It may be different from the number of coded
- * channels (<code>streams +
- * coupled_streams</code>).
- * @param streams <tt>int</tt>: The total number of streams coded in the
- * input.
- * This must be no more than 255.
- * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
- * (2 channel) streams.
- * This must be no larger than the total
- * number of streams.
- * Additionally, The total number of
- * coded channels (<code>streams +
- * coupled_streams</code>) must be no
- * more than 255.
- * @param[in] demixing_matrix <tt>const unsigned char[demixing_matrix_size]</tt>: Demixing matrix
- * that mapping from coded channels to output channels,
- * as described in @ref opus_projection and
- * @ref opus_projection_ctls.
- * @param demixing_matrix_size <tt>opus_int32</tt>: The size in bytes of the
- * demixing matrix, as
- * described in @ref
- * opus_projection_ctls.
- * @param[out] error <tt>int *</tt>: Returns #OPUS_OK on success, or an error
- * code (see @ref opus_errorcodes) on
- * failure.
- */
-OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusProjectionDecoder *opus_projection_decoder_create(
- opus_int32 Fs,
- int channels,
- int streams,
- int coupled_streams,
- unsigned char *demixing_matrix,
- opus_int32 demixing_matrix_size,
- int *error
-) OPUS_ARG_NONNULL(5);
-
-
-/** Intialize a previously allocated projection decoder state object.
- * The memory pointed to by \a st must be at least the size returned by
- * opus_projection_decoder_get_size().
- * This is intended for applications which use their own allocator instead of
- * malloc.
- * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL.
- * @see opus_projection_decoder_create
- * @see opus_projection_deocder_get_size
- * @param st <tt>OpusProjectionDecoder*</tt>: Projection encoder state to initialize.
- * @param Fs <tt>opus_int32</tt>: Sampling rate to decode at (in Hz).
- * This must be one of 8000, 12000, 16000,
- * 24000, or 48000.
- * @param channels <tt>int</tt>: Number of channels to output.
- * This must be at most 255.
- * It may be different from the number of coded
- * channels (<code>streams +
- * coupled_streams</code>).
- * @param streams <tt>int</tt>: The total number of streams coded in the
- * input.
- * This must be no more than 255.
- * @param coupled_streams <tt>int</tt>: Number of streams to decode as coupled
- * (2 channel) streams.
- * This must be no larger than the total
- * number of streams.
- * Additionally, The total number of
- * coded channels (<code>streams +
- * coupled_streams</code>) must be no
- * more than 255.
- * @param[in] demixing_matrix <tt>const unsigned char[demixing_matrix_size]</tt>: Demixing matrix
- * that mapping from coded channels to output channels,
- * as described in @ref opus_projection and
- * @ref opus_projection_ctls.
- * @param demixing_matrix_size <tt>opus_int32</tt>: The size in bytes of the
- * demixing matrix, as
- * described in @ref
- * opus_projection_ctls.
- * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes)
- * on failure.
- */
-OPUS_EXPORT int opus_projection_decoder_init(
- OpusProjectionDecoder *st,
- opus_int32 Fs,
- int channels,
- int streams,
- int coupled_streams,
- unsigned char *demixing_matrix,
- opus_int32 demixing_matrix_size
-) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6);
-
-
-/** Decode a projection Opus packet.
- * @param st <tt>OpusProjectionDecoder*</tt>: Projection decoder state.
- * @param[in] data <tt>const unsigned char*</tt>: Input payload.
- * Use a <code>NULL</code>
- * pointer to indicate packet
- * loss.
- * @param len <tt>opus_int32</tt>: Number of bytes in payload.
- * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
- * samples.
- * This must contain room for
- * <code>frame_size*channels</code>
- * samples.
- * @param frame_size <tt>int</tt>: The number of samples per channel of
- * available space in \a pcm.
- * If this is less than the maximum packet duration
- * (120 ms; 5760 for 48kHz), this function will not be capable
- * of decoding some packets. In the case of PLC (data==NULL)
- * or FEC (decode_fec=1), then frame_size needs to be exactly
- * the duration of audio that is missing, otherwise the
- * decoder will not be in the optimal state to decode the
- * next incoming packet. For the PLC and FEC cases, frame_size
- * <b>must</b> be a multiple of 2.5 ms.
- * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
- * forward error correction data be decoded.
- * If no such data is available, the frame is
- * decoded as if it were lost.
- * @returns Number of samples decoded on success or a negative error code
- * (see @ref opus_errorcodes) on failure.
- */
-OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_decode(
- OpusProjectionDecoder *st,
- const unsigned char *data,
- opus_int32 len,
- opus_int16 *pcm,
- int frame_size,
- int decode_fec
-) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
-
-
-/** Decode a projection Opus packet with floating point output.
- * @param st <tt>OpusProjectionDecoder*</tt>: Projection decoder state.
- * @param[in] data <tt>const unsigned char*</tt>: Input payload.
- * Use a <code>NULL</code>
- * pointer to indicate packet
- * loss.
- * @param len <tt>opus_int32</tt>: Number of bytes in payload.
- * @param[out] pcm <tt>opus_int16*</tt>: Output signal, with interleaved
- * samples.
- * This must contain room for
- * <code>frame_size*channels</code>
- * samples.
- * @param frame_size <tt>int</tt>: The number of samples per channel of
- * available space in \a pcm.
- * If this is less than the maximum packet duration
- * (120 ms; 5760 for 48kHz), this function will not be capable
- * of decoding some packets. In the case of PLC (data==NULL)
- * or FEC (decode_fec=1), then frame_size needs to be exactly
- * the duration of audio that is missing, otherwise the
- * decoder will not be in the optimal state to decode the
- * next incoming packet. For the PLC and FEC cases, frame_size
- * <b>must</b> be a multiple of 2.5 ms.
- * @param decode_fec <tt>int</tt>: Flag (0 or 1) to request that any in-band
- * forward error correction data be decoded.
- * If no such data is available, the frame is
- * decoded as if it were lost.
- * @returns Number of samples decoded on success or a negative error code
- * (see @ref opus_errorcodes) on failure.
- */
-OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_projection_decode_float(
- OpusProjectionDecoder *st,
- const unsigned char *data,
- opus_int32 len,
- float *pcm,
- int frame_size,
- int decode_fec
-) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4);
-
-
-/** Perform a CTL function on a projection Opus decoder.
- *
- * Generally the request and subsequent arguments are generated by a
- * convenience macro.
- * @param st <tt>OpusProjectionDecoder*</tt>: Projection decoder state.
- * @param request This and all remaining parameters should be replaced by one
- * of the convenience macros in @ref opus_genericctls,
- * @ref opus_decoderctls, @ref opus_multistream_ctls, or
- * @ref opus_projection_ctls.
- * @see opus_genericctls
- * @see opus_decoderctls
- * @see opus_multistream_ctls
- * @see opus_projection_ctls
- */
-OPUS_EXPORT int opus_projection_decoder_ctl(OpusProjectionDecoder *st, int request, ...) OPUS_ARG_NONNULL(1);
-
-
-/** Frees an <code>OpusProjectionDecoder</code> allocated by
- * opus_projection_decoder_create().
- * @param st <tt>OpusProjectionDecoder</tt>: Projection decoder state to be freed.
- */
-OPUS_EXPORT void opus_projection_decoder_destroy(OpusProjectionDecoder *st);
-
-
-/**@}*/
-
-/**@}*/
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* OPUS_PROJECTION_H */
diff --git a/thirdparty/opus/opus/opus_types.h b/thirdparty/opus/opus/opus_types.h
index 7cf675580f..b28e03aea2 100644
--- a/thirdparty/opus/opus/opus_types.h
+++ b/thirdparty/opus/opus/opus_types.h
@@ -33,29 +33,14 @@
#ifndef OPUS_TYPES_H
#define OPUS_TYPES_H
-#define opus_int int /* used for counters etc; at least 16 bits */
-#define opus_int64 long long
-#define opus_int8 signed char
-
-#define opus_uint unsigned int /* used for counters etc; at least 16 bits */
-#define opus_uint64 unsigned long long
-#define opus_uint8 unsigned char
-
/* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h) */
-#if (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H))
+#if (defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H))
#include <stdint.h>
-# undef opus_int64
-# undef opus_int8
-# undef opus_uint64
-# undef opus_uint8
- typedef int8_t opus_int8;
- typedef uint8_t opus_uint8;
+
typedef int16_t opus_int16;
typedef uint16_t opus_uint16;
typedef int32_t opus_int32;
typedef uint32_t opus_uint32;
- typedef int64_t opus_int64;
- typedef uint64_t opus_uint64;
#elif defined(_WIN32)
# if defined(__CYGWIN__)
@@ -163,4 +148,12 @@
#endif
+#define opus_int int /* used for counters etc; at least 16 bits */
+#define opus_int64 long long
+#define opus_int8 signed char
+
+#define opus_uint unsigned int /* used for counters etc; at least 16 bits */
+#define opus_uint64 unsigned long long
+#define opus_uint8 unsigned char
+
#endif /* OPUS_TYPES_H */
diff --git a/thirdparty/opus/opus/opusfile.h b/thirdparty/opus/opus/opusfile.h
index e3a3dc8389..4bf2fba926 100644
--- a/thirdparty/opus/opus/opusfile.h
+++ b/thirdparty/opus/opus/opusfile.h
@@ -239,8 +239,7 @@ struct OpusHead{
-32768...32767.
The <tt>libopusfile</tt> API will automatically apply this gain to the
decoded output before returning it, scaling it by
- <code>pow(10,output_gain/(20.0*256))</code>.
- You can adjust this behavior with op_set_gain_offset().*/
+ <code>pow(10,output_gain/(20.0*256))</code>.*/
int output_gain;
/**The channel mapping family, in the range 0...255.
Channel mapping family 0 covers mono or stereo in a single stream.
@@ -1155,18 +1154,16 @@ OP_WARN_UNUSED_RESULT OggOpusFile *op_open_url(const char *_url,
int *_error,...) OP_ARG_NONNULL(1);
/**Open a stream using the given set of callbacks to access it.
- \param _stream The stream to read from (e.g., a <code>FILE *</code>).
- This value will be passed verbatim as the first
- argument to all of the callbacks.
+ \param _source The stream to read from (e.g., a <code>FILE *</code>).
\param _cb The callbacks with which to access the stream.
<code><a href="#op_read_func">read()</a></code> must
be implemented.
<code><a href="#op_seek_func">seek()</a></code> and
<code><a href="#op_tell_func">tell()</a></code> may
be <code>NULL</code>, or may always return -1 to
- indicate a stream is unseekable, but if
+ indicate a source is unseekable, but if
<code><a href="#op_seek_func">seek()</a></code> is
- implemented and succeeds on a particular stream, then
+ implemented and succeeds on a particular source, then
<code><a href="#op_tell_func">tell()</a></code> must
also.
<code><a href="#op_close_func">close()</a></code> may
@@ -1229,11 +1226,11 @@ OP_WARN_UNUSED_RESULT OggOpusFile *op_open_url(const char *_url,
basic validity checks.</dd>
</dl>
\return A freshly opened \c OggOpusFile, or <code>NULL</code> on error.
- <tt>libopusfile</tt> does <em>not</em> take ownership of the stream
+ <tt>libopusfile</tt> does <em>not</em> take ownership of the source
if the call fails.
- The calling application is responsible for closing the stream if
+ The calling application is responsible for closing the source if
this call returns an error.*/
-OP_WARN_UNUSED_RESULT OggOpusFile *op_open_callbacks(void *_stream,
+OP_WARN_UNUSED_RESULT OggOpusFile *op_open_callbacks(void *_source,
const OpusFileCallbacks *_cb,const unsigned char *_initial_data,
size_t _initial_bytes,int *_error) OP_ARG_NONNULL(2);
@@ -1335,20 +1332,18 @@ OP_WARN_UNUSED_RESULT OggOpusFile *op_test_url(const char *_url,
For new code, you are likely better off using op_test() instead, which
is less resource-intensive, requires less data to succeed, and imposes a
hard limit on the amount of data it examines (important for unseekable
- streams, where all such data must be buffered until you are sure of the
+ sources, where all such data must be buffered until you are sure of the
stream type).
- \param _stream The stream to read from (e.g., a <code>FILE *</code>).
- This value will be passed verbatim as the first
- argument to all of the callbacks.
+ \param _source The stream to read from (e.g., a <code>FILE *</code>).
\param _cb The callbacks with which to access the stream.
<code><a href="#op_read_func">read()</a></code> must
be implemented.
<code><a href="#op_seek_func">seek()</a></code> and
<code><a href="#op_tell_func">tell()</a></code> may
be <code>NULL</code>, or may always return -1 to
- indicate a stream is unseekable, but if
+ indicate a source is unseekable, but if
<code><a href="#op_seek_func">seek()</a></code> is
- implemented and succeeds on a particular stream, then
+ implemented and succeeds on a particular source, then
<code><a href="#op_tell_func">tell()</a></code> must
also.
<code><a href="#op_close_func">close()</a></code> may
@@ -1378,11 +1373,11 @@ OP_WARN_UNUSED_RESULT OggOpusFile *op_test_url(const char *_url,
See op_open_callbacks() for a full list of failure
codes.
\return A partially opened \c OggOpusFile, or <code>NULL</code> on error.
- <tt>libopusfile</tt> does <em>not</em> take ownership of the stream
+ <tt>libopusfile</tt> does <em>not</em> take ownership of the source
if the call fails.
- The calling application is responsible for closing the stream if
+ The calling application is responsible for closing the source if
this call returns an error.*/
-OP_WARN_UNUSED_RESULT OggOpusFile *op_test_callbacks(void *_stream,
+OP_WARN_UNUSED_RESULT OggOpusFile *op_test_callbacks(void *_source,
const OpusFileCallbacks *_cb,const unsigned char *_initial_data,
size_t _initial_bytes,int *_error) OP_ARG_NONNULL(2);
@@ -1439,7 +1434,7 @@ void op_free(OggOpusFile *_of);
Their documention will indicate so explicitly.*/
/*@{*/
-/**Returns whether or not the stream being read is seekable.
+/**Returns whether or not the data source being read is seekable.
This is true if
<ol>
<li>The <code><a href="#op_seek_func">seek()</a></code> and
@@ -1460,9 +1455,9 @@ int op_seekable(const OggOpusFile *_of) OP_ARG_NONNULL(1);
return 1.
The actual number of links is not known until the stream is fully opened.
\param _of The \c OggOpusFile from which to retrieve the link count.
- \return For fully-open seekable streams, this returns the total number of
+ \return For fully-open seekable sources, this returns the total number of
links in the whole stream, which will be at least 1.
- For partially-open or unseekable streams, this always returns 1.*/
+ For partially-open or unseekable sources, this always returns 1.*/
int op_link_count(const OggOpusFile *_of) OP_ARG_NONNULL(1);
/**Get the serial number of the given link in a (possibly-chained) Ogg Opus
@@ -1476,7 +1471,7 @@ int op_link_count(const OggOpusFile *_of) OP_ARG_NONNULL(1);
\return The serial number of the given link.
If \a _li is greater than the total number of links, this returns
the serial number of the last link.
- If the stream is not seekable, this always returns the serial number
+ If the source is not seekable, this always returns the serial number
of the current link.*/
opus_uint32 op_serialno(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1);
@@ -1493,7 +1488,7 @@ opus_uint32 op_serialno(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1);
\return The channel count of the given link.
If \a _li is greater than the total number of links, this returns
the channel count of the last link.
- If the stream is not seekable, this always returns the channel count
+ If the source is not seekable, this always returns the channel count
of the current link.*/
int op_channel_count(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1);
@@ -1512,9 +1507,9 @@ int op_channel_count(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1);
compressed size of link \a _li if it is non-negative, or a negative
value on error.
The compressed size of the entire stream may be smaller than that
- of the underlying stream if trailing garbage was detected in the
+ of the underlying source if trailing garbage was detected in the
file.
- \retval #OP_EINVAL The stream is not seekable (so we can't know the length),
+ \retval #OP_EINVAL The source is not seekable (so we can't know the length),
\a _li wasn't less than the total number of links in
the stream, or the stream was only partially open.*/
opus_int64 op_raw_total(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1);
@@ -1532,7 +1527,7 @@ opus_int64 op_raw_total(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1);
\return The PCM length of the entire stream if \a _li is negative, the PCM
length of link \a _li if it is non-negative, or a negative value on
error.
- \retval #OP_EINVAL The stream is not seekable (so we can't know the length),
+ \retval #OP_EINVAL The source is not seekable (so we can't know the length),
\a _li wasn't less than the total number of links in
the stream, or the stream was only partially open.*/
ogg_int64_t op_pcm_total(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1);
@@ -1580,8 +1575,8 @@ const OpusTags *op_tags(const OggOpusFile *_of,int _li) OP_ARG_NONNULL(1);
\param _of The \c OggOpusFile from which to retrieve the current link index.
\return The index of the current link on success, or a negative value on
failure.
- For seekable streams, this is a number between 0 (inclusive) and the
- value returned by op_link_count() (exclusive).
+ For seekable streams, this is a number between 0 and the value
+ returned by op_link_count().
For unseekable streams, this value starts at 0 and increments by one
each time a new link is encountered (even though op_link_count()
always returns 1).
@@ -1645,10 +1640,10 @@ ogg_int64_t op_pcm_tell(const OggOpusFile *_of) OP_ARG_NONNULL(1);
/*@{*/
/**\name Functions for seeking in Opus streams
- These functions let you seek in Opus streams, if the underlying stream
+ These functions let you seek in Opus streams, if the underlying source
support it.
Seeking is implemented for all built-in stream I/O routines, though some
- individual streams may not be seekable (pipes, live HTTP streams, or HTTP
+ individual sources may not be seekable (pipes, live HTTP streams, or HTTP
streams from a server that does not support <code>Range</code> requests).
op_raw_seek() is the fastest: it is guaranteed to perform at most one
@@ -1675,8 +1670,6 @@ ogg_int64_t op_pcm_tell(const OggOpusFile *_of) OP_ARG_NONNULL(1);
packets out of the tail of the link to which it seeks.
\param _of The \c OggOpusFile in which to seek.
\param _byte_offset The byte position to seek to.
- This must be between 0 and #op_raw_total(\a _of,\c -1)
- (inclusive).
\return 0 on success, or a negative error code on failure.
\retval #OP_EREAD The underlying seek operation failed.
\retval #OP_EINVAL The stream was only partially open, or the target was
diff --git a/thirdparty/opus/opus_compare.c b/thirdparty/opus/opus_compare.c
index 1956e08fa5..06c67d752f 100644
--- a/thirdparty/opus/opus_compare.c
+++ b/thirdparty/opus/opus_compare.c
@@ -363,9 +363,6 @@ int main(int _argc,const char **_argv){
Ef*=Ef;
err+=Ef*Ef;
}
- free(xb);
- free(X);
- free(Y);
err=pow(err/nframes,1.0/16);
Q=100*(1-0.5*log(1+err)/log(1.13));
if(Q<0){
diff --git a/thirdparty/opus/opus_decoder.c b/thirdparty/opus/opus_decoder.c
index 9113638a00..080bec5072 100644
--- a/thirdparty/opus/opus_decoder.c
+++ b/thirdparty/opus/opus_decoder.c
@@ -78,26 +78,6 @@ struct OpusDecoder {
opus_uint32 rangeFinal;
};
-#if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)
-static void validate_opus_decoder(OpusDecoder *st)
-{
- celt_assert(st->channels == 1 || st->channels == 2);
- celt_assert(st->Fs == 48000 || st->Fs == 24000 || st->Fs == 16000 || st->Fs == 12000 || st->Fs == 8000);
- celt_assert(st->DecControl.API_sampleRate == st->Fs);
- celt_assert(st->DecControl.internalSampleRate == 0 || st->DecControl.internalSampleRate == 16000 || st->DecControl.internalSampleRate == 12000 || st->DecControl.internalSampleRate == 8000);
- celt_assert(st->DecControl.nChannelsAPI == st->channels);
- celt_assert(st->DecControl.nChannelsInternal == 0 || st->DecControl.nChannelsInternal == 1 || st->DecControl.nChannelsInternal == 2);
- 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);
-#ifdef OPUS_ARCHMASK
- celt_assert(st->arch >= 0);
- celt_assert(st->arch <= OPUS_ARCHMASK);
-#endif
- celt_assert(st->stream_channels == 1 || st->stream_channels == 2);
-}
-#define VALIDATE_OPUS_DECODER(st) validate_opus_decoder(st)
-#else
-#define VALIDATE_OPUS_DECODER(st)
-#endif
int opus_decoder_get_size(int channels)
{
@@ -124,7 +104,7 @@ int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels)
return OPUS_BAD_ARG;
OPUS_CLEAR((char*)st, opus_decoder_get_size(channels));
- /* Initialize SILK decoder */
+ /* Initialize SILK encoder */
ret = silk_Get_Decoder_Size(&silkDecSizeBytes);
if (ret)
return OPUS_INTERNAL_ERROR;
@@ -237,7 +217,6 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
int audiosize;
int mode;
- int bandwidth;
int transition=0;
int start_band;
int redundancy=0;
@@ -274,12 +253,10 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
{
audiosize = st->frame_size;
mode = st->mode;
- bandwidth = st->bandwidth;
ec_dec_init(&dec,(unsigned char*)data,len);
} else {
audiosize = frame_size;
mode = st->prev_mode;
- bandwidth = 0;
if (mode == 0)
{
@@ -378,15 +355,15 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
{
st->DecControl.nChannelsInternal = st->stream_channels;
if( mode == MODE_SILK_ONLY ) {
- if( bandwidth == OPUS_BANDWIDTH_NARROWBAND ) {
+ if( st->bandwidth == OPUS_BANDWIDTH_NARROWBAND ) {
st->DecControl.internalSampleRate = 8000;
- } else if( bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) {
+ } else if( st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) {
st->DecControl.internalSampleRate = 12000;
- } else if( bandwidth == OPUS_BANDWIDTH_WIDEBAND ) {
+ } else if( st->bandwidth == OPUS_BANDWIDTH_WIDEBAND ) {
st->DecControl.internalSampleRate = 16000;
} else {
st->DecControl.internalSampleRate = 16000;
- celt_assert( 0 );
+ silk_assert( 0 );
}
} else {
/* Hybrid mode */
@@ -450,26 +427,10 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
if (mode != MODE_CELT_ONLY)
start_band = 17;
- if (redundancy)
- {
- transition = 0;
- pcm_transition_silk_size=ALLOC_NONE;
- }
-
- ALLOC(pcm_transition_silk, pcm_transition_silk_size, opus_val16);
-
- if (transition && mode != MODE_CELT_ONLY)
- {
- pcm_transition = pcm_transition_silk;
- opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);
- }
-
-
- if (bandwidth)
{
int endband=21;
- switch(bandwidth)
+ switch(st->bandwidth)
{
case OPUS_BANDWIDTH_NARROWBAND:
endband = 13;
@@ -484,13 +445,24 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
case OPUS_BANDWIDTH_FULLBAND:
endband = 21;
break;
- default:
- celt_assert(0);
- break;
}
- MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_END_BAND(endband)));
+ celt_decoder_ctl(celt_dec, CELT_SET_END_BAND(endband));
+ celt_decoder_ctl(celt_dec, CELT_SET_CHANNELS(st->stream_channels));
+ }
+
+ if (redundancy)
+ {
+ transition = 0;
+ pcm_transition_silk_size=ALLOC_NONE;
+ }
+
+ ALLOC(pcm_transition_silk, pcm_transition_silk_size, opus_val16);
+
+ if (transition && mode != MODE_CELT_ONLY)
+ {
+ pcm_transition = pcm_transition_silk;
+ opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0);
}
- MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_CHANNELS(st->stream_channels)));
/* Only allocation memory for redundancy if/when needed */
redundant_audio_size = redundancy ? F5*st->channels : ALLOC_NONE;
@@ -499,21 +471,21 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
/* 5 ms redundant frame for CELT->SILK*/
if (redundancy && celt_to_silk)
{
- MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)));
+ celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
celt_decode_with_ec(celt_dec, data+len, redundancy_bytes,
redundant_audio, F5, NULL, 0);
- MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)));
+ celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));
}
/* MUST be after PLC */
- MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band)));
+ celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band));
if (mode != MODE_SILK_ONLY)
{
int celt_frame_size = IMIN(F20, frame_size);
/* Make sure to discard any previous CELT state */
if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy)
- MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_RESET_STATE));
+ celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
/* Decode CELT */
celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data,
len, pcm, celt_frame_size, &dec, celt_accum);
@@ -528,7 +500,7 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
do a fade-out by decoding a silence frame */
if (st->prev_mode == MODE_HYBRID && !(redundancy && celt_to_silk && st->prev_redundancy) )
{
- MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)));
+ celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL, celt_accum);
}
}
@@ -546,18 +518,18 @@ static int opus_decode_frame(OpusDecoder *st, const unsigned char *data,
{
const CELTMode *celt_mode;
- MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode)));
+ celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode));
window = celt_mode->window;
}
/* 5 ms redundant frame for SILK->CELT */
if (redundancy && !celt_to_silk)
{
- MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_RESET_STATE));
- MUST_SUCCEED(celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)));
+ celt_decoder_ctl(celt_dec, OPUS_RESET_STATE);
+ celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0));
celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL, 0);
- MUST_SUCCEED(celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)));
+ celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng));
smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5,
pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs);
}
@@ -633,7 +605,6 @@ int opus_decode_native(OpusDecoder *st, const unsigned char *data,
int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels;
/* 48 x 2.5 ms = 120 ms */
opus_int16 size[48];
- VALIDATE_OPUS_DECODER(st);
if (decode_fec<0 || decode_fec>1)
return OPUS_BAD_ARG;
/* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */
@@ -769,7 +740,6 @@ int opus_decode_float(OpusDecoder *st, const unsigned char *data,
else
return OPUS_INVALID_PACKET;
}
- celt_assert(st->channels == 1 || st->channels == 2);
ALLOC(out, frame_size*st->channels, opus_int16);
ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0);
@@ -807,7 +777,6 @@ int opus_decode(OpusDecoder *st, const unsigned char *data,
else
return OPUS_INVALID_PACKET;
}
- celt_assert(st->channels == 1 || st->channels == 2);
ALLOC(out, frame_size*st->channels, float);
ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 1);
@@ -895,7 +864,7 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
goto bad_arg;
}
if (st->prev_mode == MODE_CELT_ONLY)
- ret = celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value));
+ celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value));
else
*value = st->DecControl.prevPitchLag;
}
@@ -922,7 +891,7 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
break;
case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
{
- opus_int32 *value = va_arg(ap, opus_int32*);
+ opus_uint32 *value = va_arg(ap, opus_uint32*);
if (!value)
{
goto bad_arg;
@@ -930,26 +899,6 @@ int opus_decoder_ctl(OpusDecoder *st, int request, ...)
*value = st->last_packet_duration;
}
break;
- case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
- {
- opus_int32 value = va_arg(ap, opus_int32);
- if(value<0 || value>1)
- {
- goto bad_arg;
- }
- ret = celt_decoder_ctl(celt_dec, OPUS_SET_PHASE_INVERSION_DISABLED(value));
- }
- break;
- case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
- {
- opus_int32 *value = va_arg(ap, opus_int32*);
- if (!value)
- {
- goto bad_arg;
- }
- ret = celt_decoder_ctl(celt_dec, OPUS_GET_PHASE_INVERSION_DISABLED(value));
- }
- break;
default:
/*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/
ret = OPUS_UNIMPLEMENTED;
diff --git a/thirdparty/opus/opus_encoder.c b/thirdparty/opus/opus_encoder.c
index e98ac5b8d0..9a516a884a 100644
--- a/thirdparty/opus/opus_encoder.c
+++ b/thirdparty/opus/opus_encoder.c
@@ -53,10 +53,6 @@
#define MAX_ENCODER_BUFFER 480
-#ifndef DISABLE_FLOAT_API
-#define PSEUDO_SNR_THRESHOLD 316.23f /* 10^(25/10) */
-#endif
-
typedef struct {
opus_val32 XX, XY, YY;
opus_val16 smoothed_width;
@@ -86,7 +82,6 @@ struct OpusEncoder {
int encoder_buffer;
int lfe;
int arch;
- int use_dtx; /* general DTX for both SILK and CELT */
#ifndef DISABLE_FLOAT_API
TonalityAnalysisState analysis;
#endif
@@ -102,8 +97,6 @@ struct OpusEncoder {
int prev_channels;
int prev_framesize;
int bandwidth;
- /* Bandwidth determined automatically from the rate (before any other adjustment) */
- int auto_bandwidth;
int silk_bw_switch;
/* Sampling rate (at the API level) */
int first;
@@ -112,10 +105,7 @@ struct OpusEncoder {
opus_val16 delay_buffer[MAX_ENCODER_BUFFER*2];
#ifndef DISABLE_FLOAT_API
int detected_bandwidth;
- int nb_no_activity_frames;
- opus_val32 peak_signal_energy;
#endif
- int nonfinal_frame; /* current frame is not the final in a packet */
opus_uint32 rangeFinal;
};
@@ -123,46 +113,38 @@ struct OpusEncoder {
middle (memoriless) threshold. The second column is the hysteresis
(difference with the middle) */
static const opus_int32 mono_voice_bandwidth_thresholds[8] = {
- 9000, 700, /* NB<->MB */
- 9000, 700, /* MB<->WB */
- 13500, 1000, /* WB<->SWB */
- 14000, 2000, /* SWB<->FB */
+ 11000, 1000, /* NB<->MB */
+ 14000, 1000, /* MB<->WB */
+ 17000, 1000, /* WB<->SWB */
+ 21000, 2000, /* SWB<->FB */
};
static const opus_int32 mono_music_bandwidth_thresholds[8] = {
- 9000, 700, /* NB<->MB */
- 9000, 700, /* MB<->WB */
- 11000, 1000, /* WB<->SWB */
- 12000, 2000, /* SWB<->FB */
+ 12000, 1000, /* NB<->MB */
+ 15000, 1000, /* MB<->WB */
+ 18000, 2000, /* WB<->SWB */
+ 22000, 2000, /* SWB<->FB */
};
static const opus_int32 stereo_voice_bandwidth_thresholds[8] = {
- 9000, 700, /* NB<->MB */
- 9000, 700, /* MB<->WB */
- 13500, 1000, /* WB<->SWB */
- 14000, 2000, /* SWB<->FB */
+ 11000, 1000, /* NB<->MB */
+ 14000, 1000, /* MB<->WB */
+ 21000, 2000, /* WB<->SWB */
+ 28000, 2000, /* SWB<->FB */
};
static const opus_int32 stereo_music_bandwidth_thresholds[8] = {
- 9000, 700, /* NB<->MB */
- 9000, 700, /* MB<->WB */
- 11000, 1000, /* WB<->SWB */
- 12000, 2000, /* SWB<->FB */
+ 12000, 1000, /* NB<->MB */
+ 18000, 2000, /* MB<->WB */
+ 21000, 2000, /* WB<->SWB */
+ 30000, 2000, /* SWB<->FB */
};
/* Threshold bit-rates for switching between mono and stereo */
-static const opus_int32 stereo_voice_threshold = 19000;
-static const opus_int32 stereo_music_threshold = 17000;
+static const opus_int32 stereo_voice_threshold = 30000;
+static const opus_int32 stereo_music_threshold = 30000;
/* Threshold bit-rate for switching between SILK/hybrid and CELT-only */
static const opus_int32 mode_thresholds[2][2] = {
/* voice */ /* music */
- { 64000, 10000}, /* mono */
- { 44000, 10000}, /* stereo */
-};
-
-static const opus_int32 fec_thresholds[] = {
- 12000, 1000, /* NB */
- 14000, 1000, /* MB */
- 16000, 1000, /* WB */
- 20000, 1000, /* SWB */
- 22000, 1000, /* FB */
+ { 64000, 16000}, /* mono */
+ { 36000, 16000}, /* stereo */
};
int opus_encoder_get_size(int channels)
@@ -263,8 +245,7 @@ int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int applicat
st->bandwidth = OPUS_BANDWIDTH_FULLBAND;
#ifndef DISABLE_FLOAT_API
- tonality_analysis_init(&st->analysis, st->Fs);
- st->analysis.application = st->application;
+ tonality_analysis_init(&st->analysis);
#endif
return OPUS_OK;
@@ -342,11 +323,10 @@ static void silk_biquad_float(
}
#endif
-static void hp_cutoff(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs, int arch)
+static void hp_cutoff(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs)
{
opus_int32 B_Q28[ 3 ], A_Q28[ 2 ];
opus_int32 Fc_Q19, r_Q28, r_Q22;
- (void)arch;
silk_assert( cutoff_Hz <= silk_int32_MAX / SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ) );
Fc_Q19 = silk_DIV32_16( silk_SMULBB( SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ), cutoff_Hz ), Fs/1000 );
@@ -366,10 +346,9 @@ static void hp_cutoff(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *ou
A_Q28[ 1 ] = silk_SMULWW( r_Q22, r_Q22 );
#ifdef FIXED_POINT
- if( channels == 1 ) {
- silk_biquad_alt_stride1( in, B_Q28, A_Q28, hp_mem, out, len );
- } else {
- silk_biquad_alt_stride2( in, B_Q28, A_Q28, hp_mem, out, len, arch );
+ silk_biquad_alt( in, B_Q28, A_Q28, hp_mem, out, len, channels );
+ if( channels == 2 ) {
+ silk_biquad_alt( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels );
}
#else
silk_biquad_float( in, B_Q28, A_Q28, hp_mem, out, len, channels );
@@ -385,17 +364,21 @@ static void dc_reject(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *ou
int c, i;
int shift;
- /* Approximates -round(log2(6.3*cutoff_Hz/Fs)) */
- shift=celt_ilog2(Fs/(cutoff_Hz*4));
+ /* Approximates -round(log2(4.*cutoff_Hz/Fs)) */
+ shift=celt_ilog2(Fs/(cutoff_Hz*3));
for (c=0;c<channels;c++)
{
for (i=0;i<len;i++)
{
- opus_val32 x, y;
- x = SHL32(EXTEND32(in[channels*i+c]), 14);
- y = x-hp_mem[2*c];
+ opus_val32 x, tmp, y;
+ x = SHL32(EXTEND32(in[channels*i+c]), 15);
+ /* First stage */
+ tmp = x-hp_mem[2*c];
hp_mem[2*c] = hp_mem[2*c] + PSHR32(x - hp_mem[2*c], shift);
- out[channels*i+c] = EXTRACT16(SATURATE(PSHR32(y, 14), 32767));
+ /* Second stage */
+ y = tmp - hp_mem[2*c+1];
+ hp_mem[2*c+1] = hp_mem[2*c+1] + PSHR32(tmp - hp_mem[2*c+1], shift);
+ out[channels*i+c] = EXTRACT16(SATURATE(PSHR32(y, 15), 32767));
}
}
}
@@ -403,41 +386,24 @@ static void dc_reject(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *ou
#else
static void dc_reject(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs)
{
- int i;
- float coef, coef2;
- coef = 6.3f*cutoff_Hz/Fs;
- coef2 = 1-coef;
- if (channels==2)
+ int c, i;
+ float coef;
+
+ coef = 4.0f*cutoff_Hz/Fs;
+ for (c=0;c<channels;c++)
{
- float m0, m2;
- m0 = hp_mem[0];
- m2 = hp_mem[2];
for (i=0;i<len;i++)
{
- opus_val32 x0, x1, out0, out1;
- x0 = in[2*i+0];
- x1 = in[2*i+1];
- out0 = x0-m0;
- out1 = x1-m2;
- m0 = coef*x0 + VERY_SMALL + coef2*m0;
- m2 = coef*x1 + VERY_SMALL + coef2*m2;
- out[2*i+0] = out0;
- out[2*i+1] = out1;
+ opus_val32 x, tmp, y;
+ x = in[channels*i+c];
+ /* First stage */
+ tmp = x-hp_mem[2*c];
+ hp_mem[2*c] = hp_mem[2*c] + coef*(x - hp_mem[2*c]) + VERY_SMALL;
+ /* Second stage */
+ y = tmp - hp_mem[2*c+1];
+ hp_mem[2*c+1] = hp_mem[2*c+1] + coef*(tmp - hp_mem[2*c+1]) + VERY_SMALL;
+ out[channels*i+c] = y;
}
- hp_mem[0] = m0;
- hp_mem[2] = m2;
- } else {
- float m0;
- m0 = hp_mem[0];
- for (i=0;i<len;i++)
- {
- opus_val32 x, y;
- x = in[i];
- y = x-m0;
- m0 = coef*x + VERY_SMALL + coef2*m0;
- out[i] = y;
- }
- hp_mem[0] = m0;
}
}
#endif
@@ -555,57 +521,287 @@ static opus_int32 user_bitrate_to_bitrate(OpusEncoder *st, int frame_size, int m
}
#ifndef DISABLE_FLOAT_API
+/* Don't use more than 60 ms for the frame size analysis */
+#define MAX_DYNAMIC_FRAMESIZE 24
+/* Estimates how much the bitrate will be boosted based on the sub-frame energy */
+static float transient_boost(const float *E, const float *E_1, int LM, int maxM)
+{
+ int i;
+ int M;
+ float sumE=0, sumE_1=0;
+ float metric;
+
+ M = IMIN(maxM, (1<<LM)+1);
+ for (i=0;i<M;i++)
+ {
+ sumE += E[i];
+ sumE_1 += E_1[i];
+ }
+ metric = sumE*sumE_1/(M*M);
+ /*if (LM==3)
+ printf("%f\n", metric);*/
+ /*return metric>10 ? 1 : 0;*/
+ /*return MAX16(0,1-exp(-.25*(metric-2.)));*/
+ return MIN16(1,(float)sqrt(MAX16(0,.05f*(metric-2))));
+}
+
+/* Viterbi decoding trying to find the best frame size combination using look-ahead
+
+ State numbering:
+ 0: unused
+ 1: 2.5 ms
+ 2: 5 ms (#1)
+ 3: 5 ms (#2)
+ 4: 10 ms (#1)
+ 5: 10 ms (#2)
+ 6: 10 ms (#3)
+ 7: 10 ms (#4)
+ 8: 20 ms (#1)
+ 9: 20 ms (#2)
+ 10: 20 ms (#3)
+ 11: 20 ms (#4)
+ 12: 20 ms (#5)
+ 13: 20 ms (#6)
+ 14: 20 ms (#7)
+ 15: 20 ms (#8)
+*/
+static int transient_viterbi(const float *E, const float *E_1, int N, int frame_cost, int rate)
+{
+ int i;
+ float cost[MAX_DYNAMIC_FRAMESIZE][16];
+ int states[MAX_DYNAMIC_FRAMESIZE][16];
+ float best_cost;
+ int best_state;
+ float factor;
+ /* Take into account that we damp VBR in the 32 kb/s to 64 kb/s range. */
+ if (rate<80)
+ factor=0;
+ else if (rate>160)
+ factor=1;
+ else
+ factor = (rate-80.f)/80.f;
+ /* Makes variable framesize less aggressive at lower bitrates, but I can't
+ find any valid theoretical justification for this (other than it seems
+ to help) */
+ for (i=0;i<16;i++)
+ {
+ /* Impossible state */
+ states[0][i] = -1;
+ cost[0][i] = 1e10;
+ }
+ for (i=0;i<4;i++)
+ {
+ cost[0][1<<i] = (frame_cost + rate*(1<<i))*(1+factor*transient_boost(E, E_1, i, N+1));
+ states[0][1<<i] = i;
+ }
+ for (i=1;i<N;i++)
+ {
+ int j;
+
+ /* Follow continuations */
+ for (j=2;j<16;j++)
+ {
+ cost[i][j] = cost[i-1][j-1];
+ states[i][j] = j-1;
+ }
+
+ /* New frames */
+ for(j=0;j<4;j++)
+ {
+ int k;
+ float min_cost;
+ float curr_cost;
+ states[i][1<<j] = 1;
+ min_cost = cost[i-1][1];
+ for(k=1;k<4;k++)
+ {
+ float tmp = cost[i-1][(1<<(k+1))-1];
+ if (tmp < min_cost)
+ {
+ states[i][1<<j] = (1<<(k+1))-1;
+ min_cost = tmp;
+ }
+ }
+ curr_cost = (frame_cost + rate*(1<<j))*(1+factor*transient_boost(E+i, E_1+i, j, N-i+1));
+ cost[i][1<<j] = min_cost;
+ /* If part of the frame is outside the analysis window, only count part of the cost */
+ if (N-i < (1<<j))
+ cost[i][1<<j] += curr_cost*(float)(N-i)/(1<<j);
+ else
+ cost[i][1<<j] += curr_cost;
+ }
+ }
+
+ best_state=1;
+ best_cost = cost[N-1][1];
+ /* Find best end state (doesn't force a frame to end at N-1) */
+ for (i=2;i<16;i++)
+ {
+ if (cost[N-1][i]<best_cost)
+ {
+ best_cost = cost[N-1][i];
+ best_state = i;
+ }
+ }
+
+ /* Follow transitions back */
+ for (i=N-1;i>=0;i--)
+ {
+ /*printf("%d ", best_state);*/
+ best_state = states[i][best_state];
+ }
+ /*printf("%d\n", best_state);*/
+ return best_state;
+}
+
+static int optimize_framesize(const void *x, int len, int C, opus_int32 Fs,
+ int bitrate, opus_val16 tonality, float *mem, int buffering,
+ downmix_func downmix)
+{
+ int N;
+ int i;
+ float e[MAX_DYNAMIC_FRAMESIZE+4];
+ float e_1[MAX_DYNAMIC_FRAMESIZE+3];
+ opus_val32 memx;
+ int bestLM=0;
+ int subframe;
+ int pos;
+ int offset;
+ VARDECL(opus_val32, sub);
+
+ subframe = Fs/400;
+ ALLOC(sub, subframe, opus_val32);
+ e[0]=mem[0];
+ e_1[0]=1.f/(EPSILON+mem[0]);
+ if (buffering)
+ {
+ /* Consider the CELT delay when not in restricted-lowdelay */
+ /* We assume the buffering is between 2.5 and 5 ms */
+ offset = 2*subframe - buffering;
+ celt_assert(offset>=0 && offset <= subframe);
+ len -= offset;
+ e[1]=mem[1];
+ e_1[1]=1.f/(EPSILON+mem[1]);
+ e[2]=mem[2];
+ e_1[2]=1.f/(EPSILON+mem[2]);
+ pos = 3;
+ } else {
+ pos=1;
+ offset=0;
+ }
+ N=IMIN(len/subframe, MAX_DYNAMIC_FRAMESIZE);
+ /* Just silencing a warning, it's really initialized later */
+ memx = 0;
+ for (i=0;i<N;i++)
+ {
+ float tmp;
+ opus_val32 tmpx;
+ int j;
+ tmp=EPSILON;
+
+ downmix(x, sub, subframe, i*subframe+offset, 0, -2, C);
+ if (i==0)
+ memx = sub[0];
+ for (j=0;j<subframe;j++)
+ {
+ tmpx = sub[j];
+ tmp += (tmpx-memx)*(float)(tmpx-memx);
+ memx = tmpx;
+ }
+ e[i+pos] = tmp;
+ e_1[i+pos] = 1.f/tmp;
+ }
+ /* Hack to get 20 ms working with APPLICATION_AUDIO
+ The real problem is that the corresponding memory needs to use 1.5 ms
+ from this frame and 1 ms from the next frame */
+ e[i+pos] = e[i+pos-1];
+ if (buffering)
+ N=IMIN(MAX_DYNAMIC_FRAMESIZE, N+2);
+ bestLM = transient_viterbi(e, e_1, N, (int)((1.f+.5f*tonality)*(60*C+40)), bitrate/400);
+ mem[0] = e[1<<bestLM];
+ if (buffering)
+ {
+ mem[1] = e[(1<<bestLM)+1];
+ mem[2] = e[(1<<bestLM)+2];
+ }
+ return bestLM;
+}
+
+#endif
+
+#ifndef DISABLE_FLOAT_API
#ifdef FIXED_POINT
#define PCM2VAL(x) FLOAT2INT16(x)
#else
#define PCM2VAL(x) SCALEIN(x)
#endif
-
-void downmix_float(const void *_x, opus_val32 *y, int subframe, int offset, int c1, int c2, int C)
+void downmix_float(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C)
{
const float *x;
+ opus_val32 scale;
int j;
-
x = (const float *)_x;
for (j=0;j<subframe;j++)
- y[j] = PCM2VAL(x[(j+offset)*C+c1]);
+ sub[j] = PCM2VAL(x[(j+offset)*C+c1]);
if (c2>-1)
{
for (j=0;j<subframe;j++)
- y[j] += PCM2VAL(x[(j+offset)*C+c2]);
+ sub[j] += PCM2VAL(x[(j+offset)*C+c2]);
} else if (c2==-2)
{
int c;
for (c=1;c<C;c++)
{
for (j=0;j<subframe;j++)
- y[j] += PCM2VAL(x[(j+offset)*C+c]);
+ sub[j] += PCM2VAL(x[(j+offset)*C+c]);
}
}
+#ifdef FIXED_POINT
+ scale = (1<<SIG_SHIFT);
+#else
+ scale = 1.f;
+#endif
+ if (C==-2)
+ scale /= C;
+ else
+ scale /= 2;
+ for (j=0;j<subframe;j++)
+ sub[j] *= scale;
}
#endif
-void downmix_int(const void *_x, opus_val32 *y, int subframe, int offset, int c1, int c2, int C)
+void downmix_int(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C)
{
const opus_int16 *x;
+ opus_val32 scale;
int j;
-
x = (const opus_int16 *)_x;
for (j=0;j<subframe;j++)
- y[j] = x[(j+offset)*C+c1];
+ sub[j] = x[(j+offset)*C+c1];
if (c2>-1)
{
for (j=0;j<subframe;j++)
- y[j] += x[(j+offset)*C+c2];
+ sub[j] += x[(j+offset)*C+c2];
} else if (c2==-2)
{
int c;
for (c=1;c<C;c++)
{
for (j=0;j<subframe;j++)
- y[j] += x[(j+offset)*C+c];
+ sub[j] += x[(j+offset)*C+c];
}
}
+#ifdef FIXED_POINT
+ scale = (1<<SIG_SHIFT);
+#else
+ scale = 1.f/32768;
+#endif
+ if (C==-2)
+ scale /= C;
+ else
+ scale /= 2;
+ for (j=0;j<subframe;j++)
+ sub[j] *= scale;
}
opus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs)
@@ -615,24 +811,53 @@ opus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_
return -1;
if (variable_duration == OPUS_FRAMESIZE_ARG)
new_size = frame_size;
- else if (variable_duration >= OPUS_FRAMESIZE_2_5_MS && variable_duration <= OPUS_FRAMESIZE_120_MS)
- {
- if (variable_duration <= OPUS_FRAMESIZE_40_MS)
- new_size = (Fs/400)<<(variable_duration-OPUS_FRAMESIZE_2_5_MS);
- else
- new_size = (variable_duration-OPUS_FRAMESIZE_2_5_MS-2)*Fs/50;
- }
+ else if (variable_duration == OPUS_FRAMESIZE_VARIABLE)
+ new_size = Fs/50;
+ else if (variable_duration >= OPUS_FRAMESIZE_2_5_MS && variable_duration <= OPUS_FRAMESIZE_60_MS)
+ new_size = IMIN(3*Fs/50, (Fs/400)<<(variable_duration-OPUS_FRAMESIZE_2_5_MS));
else
return -1;
if (new_size>frame_size)
return -1;
- if (400*new_size!=Fs && 200*new_size!=Fs && 100*new_size!=Fs &&
- 50*new_size!=Fs && 25*new_size!=Fs && 50*new_size!=3*Fs &&
- 50*new_size!=4*Fs && 50*new_size!=5*Fs && 50*new_size!=6*Fs)
+ if (400*new_size!=Fs && 200*new_size!=Fs && 100*new_size!=Fs &&
+ 50*new_size!=Fs && 25*new_size!=Fs && 50*new_size!=3*Fs)
return -1;
return new_size;
}
+opus_int32 compute_frame_size(const void *analysis_pcm, int frame_size,
+ int variable_duration, int C, opus_int32 Fs, int bitrate_bps,
+ int delay_compensation, downmix_func downmix
+#ifndef DISABLE_FLOAT_API
+ , float *subframe_mem
+#endif
+ )
+{
+#ifndef DISABLE_FLOAT_API
+ if (variable_duration == OPUS_FRAMESIZE_VARIABLE && frame_size >= Fs/200)
+ {
+ int LM = 3;
+ LM = optimize_framesize(analysis_pcm, frame_size, C, Fs, bitrate_bps,
+ 0, subframe_mem, delay_compensation, downmix);
+ while ((Fs/400<<LM)>frame_size)
+ LM--;
+ frame_size = (Fs/400<<LM);
+ } else
+#else
+ (void)analysis_pcm;
+ (void)C;
+ (void)bitrate_bps;
+ (void)delay_compensation;
+ (void)downmix;
+#endif
+ {
+ frame_size = frame_size_select(frame_size, variable_duration, Fs);
+ }
+ if (frame_size<0)
+ return -1;
+ return frame_size;
+}
+
opus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int32 Fs, StereoWidthState *mem)
{
opus_val32 xx, xy, yy;
@@ -679,12 +904,6 @@ opus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int3
xy += SHR32(pxy, 10);
yy += SHR32(pyy, 10);
}
-#ifndef FIXED_POINT
- if (!(xx < 1e9f) || celt_isnan(xx) || !(yy < 1e9f) || celt_isnan(yy))
- {
- xy = xx = yy = 0;
- }
-#endif
mem->XX += MULT16_32_Q15(short_alpha, xx-mem->XX);
mem->XY += MULT16_32_Q15(short_alpha, xy-mem->XY);
mem->YY += MULT16_32_Q15(short_alpha, yy-mem->YY);
@@ -715,354 +934,6 @@ opus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int3
return EXTRACT16(MIN32(Q15ONE, MULT16_16(20, mem->max_follower)));
}
-static int decide_fec(int useInBandFEC, int PacketLoss_perc, int last_fec, int mode, int *bandwidth, opus_int32 rate)
-{
- int orig_bandwidth;
- if (!useInBandFEC || PacketLoss_perc == 0 || mode == MODE_CELT_ONLY)
- return 0;
- orig_bandwidth = *bandwidth;
- for (;;)
- {
- opus_int32 hysteresis;
- opus_int32 LBRR_rate_thres_bps;
- /* Compute threshold for using FEC at the current bandwidth setting */
- LBRR_rate_thres_bps = fec_thresholds[2*(*bandwidth - OPUS_BANDWIDTH_NARROWBAND)];
- hysteresis = fec_thresholds[2*(*bandwidth - OPUS_BANDWIDTH_NARROWBAND) + 1];
- if (last_fec == 1) LBRR_rate_thres_bps -= hysteresis;
- if (last_fec == 0) LBRR_rate_thres_bps += hysteresis;
- LBRR_rate_thres_bps = silk_SMULWB( silk_MUL( LBRR_rate_thres_bps,
- 125 - silk_min( PacketLoss_perc, 25 ) ), SILK_FIX_CONST( 0.01, 16 ) );
- /* If loss <= 5%, we look at whether we have enough rate to enable FEC.
- If loss > 5%, we decrease the bandwidth until we can enable FEC. */
- if (rate > LBRR_rate_thres_bps)
- return 1;
- else if (PacketLoss_perc <= 5)
- return 0;
- else if (*bandwidth > OPUS_BANDWIDTH_NARROWBAND)
- (*bandwidth)--;
- else
- break;
- }
- /* Couldn't find any bandwidth to enable FEC, keep original bandwidth. */
- *bandwidth = orig_bandwidth;
- return 0;
-}
-
-static int compute_silk_rate_for_hybrid(int rate, int bandwidth, int frame20ms, int vbr, int fec, int channels) {
- int entry;
- int i;
- int N;
- int silk_rate;
- static int rate_table[][5] = {
- /* |total| |-------- SILK------------|
- |-- No FEC -| |--- FEC ---|
- 10ms 20ms 10ms 20ms */
- { 0, 0, 0, 0, 0},
- {12000, 10000, 10000, 11000, 11000},
- {16000, 13500, 13500, 15000, 15000},
- {20000, 16000, 16000, 18000, 18000},
- {24000, 18000, 18000, 21000, 21000},
- {32000, 22000, 22000, 28000, 28000},
- {64000, 38000, 38000, 50000, 50000}
- };
- /* Do the allocation per-channel. */
- rate /= channels;
- entry = 1 + frame20ms + 2*fec;
- N = sizeof(rate_table)/sizeof(rate_table[0]);
- for (i=1;i<N;i++)
- {
- if (rate_table[i][0] > rate) break;
- }
- if (i == N)
- {
- silk_rate = rate_table[i-1][entry];
- /* For now, just give 50% of the extra bits to SILK. */
- silk_rate += (rate-rate_table[i-1][0])/2;
- } else {
- opus_int32 lo, hi, x0, x1;
- lo = rate_table[i-1][entry];
- hi = rate_table[i][entry];
- x0 = rate_table[i-1][0];
- x1 = rate_table[i][0];
- silk_rate = (lo*(x1-rate) + hi*(rate-x0))/(x1-x0);
- }
- if (!vbr)
- {
- /* Tiny boost to SILK for CBR. We should probably tune this better. */
- silk_rate += 100;
- }
- if (bandwidth==OPUS_BANDWIDTH_SUPERWIDEBAND)
- silk_rate += 300;
- silk_rate *= channels;
- /* Small adjustment for stereo (calibrated for 32 kb/s, haven't tried other bitrates). */
- if (channels == 2 && rate >= 12000)
- silk_rate -= 1000;
- return silk_rate;
-}
-
-/* Returns the equivalent bitrate corresponding to 20 ms frames,
- complexity 10 VBR operation. */
-static opus_int32 compute_equiv_rate(opus_int32 bitrate, int channels,
- int frame_rate, int vbr, int mode, int complexity, int loss)
-{
- opus_int32 equiv;
- equiv = bitrate;
- /* Take into account overhead from smaller frames. */
- if (frame_rate > 50)
- equiv -= (40*channels+20)*(frame_rate - 50);
- /* CBR is about a 8% penalty for both SILK and CELT. */
- if (!vbr)
- equiv -= equiv/12;
- /* Complexity makes about 10% difference (from 0 to 10) in general. */
- equiv = equiv * (90+complexity)/100;
- if (mode == MODE_SILK_ONLY || mode == MODE_HYBRID)
- {
- /* SILK complexity 0-1 uses the non-delayed-decision NSQ, which
- costs about 20%. */
- if (complexity<2)
- equiv = equiv*4/5;
- equiv -= equiv*loss/(6*loss + 10);
- } else if (mode == MODE_CELT_ONLY) {
- /* CELT complexity 0-4 doesn't have the pitch filter, which costs
- about 10%. */
- if (complexity<5)
- equiv = equiv*9/10;
- } else {
- /* Mode not known yet */
- /* Half the SILK loss*/
- equiv -= equiv*loss/(12*loss + 20);
- }
- return equiv;
-}
-
-#ifndef DISABLE_FLOAT_API
-
-int is_digital_silence(const opus_val16* pcm, int frame_size, int channels, int lsb_depth)
-{
- int silence = 0;
- opus_val32 sample_max = 0;
-#ifdef MLP_TRAINING
- return 0;
-#endif
- sample_max = celt_maxabs16(pcm, frame_size*channels);
-
-#ifdef FIXED_POINT
- silence = (sample_max == 0);
- (void)lsb_depth;
-#else
- silence = (sample_max <= (opus_val16) 1 / (1 << lsb_depth));
-#endif
-
- return silence;
-}
-
-#ifdef FIXED_POINT
-static opus_val32 compute_frame_energy(const opus_val16 *pcm, int frame_size, int channels, int arch)
-{
- int i;
- opus_val32 sample_max;
- int max_shift;
- int shift;
- opus_val32 energy = 0;
- int len = frame_size*channels;
- (void)arch;
- /* Max amplitude in the signal */
- sample_max = celt_maxabs16(pcm, len);
-
- /* Compute the right shift required in the MAC to avoid an overflow */
- max_shift = celt_ilog2(len);
- shift = IMAX(0, (celt_ilog2(sample_max) << 1) + max_shift - 28);
-
- /* Compute the energy */
- for (i=0; i<len; i++)
- energy += SHR32(MULT16_16(pcm[i], pcm[i]), shift);
-
- /* Normalize energy by the frame size and left-shift back to the original position */
- energy /= len;
- energy = SHL32(energy, shift);
-
- return energy;
-}
-#else
-static opus_val32 compute_frame_energy(const opus_val16 *pcm, int frame_size, int channels, int arch)
-{
- int len = frame_size*channels;
- return celt_inner_prod(pcm, pcm, len, arch)/len;
-}
-#endif
-
-/* Decides if DTX should be turned on (=1) or off (=0) */
-static int decide_dtx_mode(float activity_probability, /* probability that current frame contains speech/music */
- int *nb_no_activity_frames, /* number of consecutive frames with no activity */
- opus_val32 peak_signal_energy, /* peak energy of desired signal detected so far */
- const opus_val16 *pcm, /* input pcm signal */
- int frame_size, /* frame size */
- int channels,
- int is_silence, /* only digital silence detected in this frame */
- int arch
- )
-{
- opus_val32 noise_energy;
-
- if (!is_silence)
- {
- if (activity_probability < DTX_ACTIVITY_THRESHOLD) /* is noise */
- {
- noise_energy = compute_frame_energy(pcm, frame_size, channels, arch);
-
- /* but is sufficiently quiet */
- is_silence = peak_signal_energy >= (PSEUDO_SNR_THRESHOLD * noise_energy);
- }
- }
-
- if (is_silence)
- {
- /* The number of consecutive DTX frames should be within the allowed bounds */
- (*nb_no_activity_frames)++;
-
- if (*nb_no_activity_frames > NB_SPEECH_FRAMES_BEFORE_DTX)
- {
- if (*nb_no_activity_frames <= (NB_SPEECH_FRAMES_BEFORE_DTX + MAX_CONSECUTIVE_DTX))
- /* Valid frame for DTX! */
- return 1;
- else
- (*nb_no_activity_frames) = NB_SPEECH_FRAMES_BEFORE_DTX;
- }
- } else
- (*nb_no_activity_frames) = 0;
-
- return 0;
-}
-
-#endif
-
-static opus_int32 encode_multiframe_packet(OpusEncoder *st,
- const opus_val16 *pcm,
- int nb_frames,
- int frame_size,
- unsigned char *data,
- opus_int32 out_data_bytes,
- int to_celt,
- int lsb_depth,
- int float_api)
-{
- int i;
- int ret = 0;
- VARDECL(unsigned char, tmp_data);
- int bak_mode, bak_bandwidth, bak_channels, bak_to_mono;
- VARDECL(OpusRepacketizer, rp);
- int max_header_bytes;
- opus_int32 bytes_per_frame;
- opus_int32 cbr_bytes;
- opus_int32 repacketize_len;
- int tmp_len;
- ALLOC_STACK;
-
- /* Worst cases:
- * 2 frames: Code 2 with different compressed sizes
- * >2 frames: Code 3 VBR */
- max_header_bytes = nb_frames == 2 ? 3 : (2+(nb_frames-1)*2);
-
- if (st->use_vbr || st->user_bitrate_bps==OPUS_BITRATE_MAX)
- repacketize_len = out_data_bytes;
- else {
- cbr_bytes = 3*st->bitrate_bps/(3*8*st->Fs/(frame_size*nb_frames));
- repacketize_len = IMIN(cbr_bytes, out_data_bytes);
- }
- bytes_per_frame = IMIN(1276, 1+(repacketize_len-max_header_bytes)/nb_frames);
-
- ALLOC(tmp_data, nb_frames*bytes_per_frame, unsigned char);
- ALLOC(rp, 1, OpusRepacketizer);
- opus_repacketizer_init(rp);
-
- bak_mode = st->user_forced_mode;
- bak_bandwidth = st->user_bandwidth;
- bak_channels = st->force_channels;
-
- st->user_forced_mode = st->mode;
- st->user_bandwidth = st->bandwidth;
- st->force_channels = st->stream_channels;
-
- bak_to_mono = st->silk_mode.toMono;
- if (bak_to_mono)
- st->force_channels = 1;
- else
- st->prev_channels = st->stream_channels;
-
- for (i=0;i<nb_frames;i++)
- {
- st->silk_mode.toMono = 0;
- st->nonfinal_frame = i<(nb_frames-1);
-
- /* When switching from SILK/Hybrid to CELT, only ask for a switch at the last frame */
- if (to_celt && i==nb_frames-1)
- st->user_forced_mode = MODE_CELT_ONLY;
-
- tmp_len = opus_encode_native(st, pcm+i*(st->channels*frame_size), frame_size,
- tmp_data+i*bytes_per_frame, bytes_per_frame, lsb_depth, NULL, 0, 0, 0, 0,
- NULL, float_api);
-
- if (tmp_len<0)
- {
- RESTORE_STACK;
- return OPUS_INTERNAL_ERROR;
- }
-
- ret = opus_repacketizer_cat(rp, tmp_data+i*bytes_per_frame, tmp_len);
-
- if (ret<0)
- {
- RESTORE_STACK;
- return OPUS_INTERNAL_ERROR;
- }
- }
-
- ret = opus_repacketizer_out_range_impl(rp, 0, nb_frames, data, repacketize_len, 0, !st->use_vbr);
-
- if (ret<0)
- {
- RESTORE_STACK;
- return OPUS_INTERNAL_ERROR;
- }
-
- /* Discard configs that were forced locally for the purpose of repacketization */
- st->user_forced_mode = bak_mode;
- st->user_bandwidth = bak_bandwidth;
- st->force_channels = bak_channels;
- st->silk_mode.toMono = bak_to_mono;
-
- RESTORE_STACK;
- return ret;
-}
-
-static int compute_redundancy_bytes(opus_int32 max_data_bytes, opus_int32 bitrate_bps, int frame_rate, int channels)
-{
- int redundancy_bytes_cap;
- int redundancy_bytes;
- opus_int32 redundancy_rate;
- int base_bits;
- opus_int32 available_bits;
- base_bits = (40*channels+20);
-
- /* Equivalent rate for 5 ms frames. */
- redundancy_rate = bitrate_bps + base_bits*(200 - frame_rate);
- /* For VBR, further increase the bitrate if we can afford it. It's pretty short
- and we'll avoid artefacts. */
- redundancy_rate = 3*redundancy_rate/2;
- redundancy_bytes = redundancy_rate/1600;
-
- /* Compute the max rate we can use given CBR or VBR with cap. */
- available_bits = max_data_bytes*8 - 2*base_bits;
- redundancy_bytes_cap = (available_bits*240/(240+48000/frame_rate) + base_bits)/8;
- redundancy_bytes = IMIN(redundancy_bytes, redundancy_bytes_cap);
- /* It we can't get enough bits for redundancy to be worth it, rely on the decoder PLC. */
- if (redundancy_bytes > 4 + 8*channels)
- redundancy_bytes = IMIN(257, redundancy_bytes);
- else
- redundancy_bytes = 0;
- return redundancy_bytes;
-}
-
opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
unsigned char *data, opus_int32 out_data_bytes, int lsb_depth,
const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2,
@@ -1100,7 +971,6 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
AnalysisInfo analysis_info;
int analysis_read_pos_bak=-1;
int analysis_read_subframe_bak=-1;
- int is_silence = 0;
#endif
VARDECL(opus_val16, tmp_prefill);
@@ -1109,19 +979,15 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
max_data_bytes = IMIN(1276, out_data_bytes);
st->rangeFinal = 0;
- if (frame_size <= 0 || max_data_bytes <= 0)
+ if ((!st->variable_duration && 400*frame_size != st->Fs && 200*frame_size != st->Fs && 100*frame_size != st->Fs &&
+ 50*frame_size != st->Fs && 25*frame_size != st->Fs && 50*frame_size != 3*st->Fs)
+ || (400*frame_size < st->Fs)
+ || max_data_bytes<=0
+ )
{
RESTORE_STACK;
return OPUS_BAD_ARG;
}
-
- /* Cannot encode 100 ms in 1 byte */
- if (max_data_bytes==1 && st->Fs==(frame_size*10))
- {
- RESTORE_STACK;
- return OPUS_BUFFER_TOO_SMALL;
- }
-
silk_enc = (char*)st+st->silk_enc_offset;
celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
@@ -1135,55 +1001,31 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
#ifndef DISABLE_FLOAT_API
analysis_info.valid = 0;
#ifdef FIXED_POINT
- if (st->silk_mode.complexity >= 10 && st->Fs>=16000)
+ if (st->silk_mode.complexity >= 10 && st->Fs==48000)
#else
- if (st->silk_mode.complexity >= 7 && st->Fs>=16000)
+ if (st->silk_mode.complexity >= 7 && st->Fs==48000)
#endif
{
- is_silence = is_digital_silence(pcm, frame_size, st->channels, lsb_depth);
analysis_read_pos_bak = st->analysis.read_pos;
analysis_read_subframe_bak = st->analysis.read_subframe;
run_analysis(&st->analysis, celt_mode, analysis_pcm, analysis_size, frame_size,
c1, c2, analysis_channels, st->Fs,
lsb_depth, downmix, &analysis_info);
-
- /* Track the peak signal energy */
- if (!is_silence && analysis_info.activity_probability > DTX_ACTIVITY_THRESHOLD)
- st->peak_signal_energy = MAX32(MULT16_32_Q15(QCONST16(0.999f, 15), st->peak_signal_energy),
- compute_frame_energy(pcm, frame_size, st->channels, st->arch));
- } else if (st->analysis.initialized) {
- tonality_analysis_reset(&st->analysis);
}
#else
(void)analysis_pcm;
(void)analysis_size;
- (void)c1;
- (void)c2;
- (void)analysis_channels;
- (void)downmix;
#endif
-#ifndef DISABLE_FLOAT_API
- /* Reset voice_ratio if this frame is not silent or if analysis is disabled.
- * Otherwise, preserve voice_ratio from the last non-silent frame */
- if (!is_silence)
- st->voice_ratio = -1;
+ st->voice_ratio = -1;
+#ifndef DISABLE_FLOAT_API
st->detected_bandwidth = 0;
if (analysis_info.valid)
{
int analysis_bandwidth;
if (st->signal_type == OPUS_AUTO)
- {
- float prob;
- if (st->prev_mode == 0)
- prob = analysis_info.music_prob;
- else if (st->prev_mode == MODE_CELT_ONLY)
- prob = analysis_info.music_prob_max;
- else
- prob = analysis_info.music_prob_min;
- st->voice_ratio = (int)floor(.5+100*(1-prob));
- }
+ st->voice_ratio = (int)floor(.5+100*(1-analysis_info.music_prob));
analysis_bandwidth = analysis_info.bandwidth;
if (analysis_bandwidth<=12)
@@ -1197,8 +1039,6 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
else
st->detected_bandwidth = OPUS_BANDWIDTH_FULLBAND;
}
-#else
- st->voice_ratio = -1;
#endif
if (st->channels==2 && st->force_channels!=1)
@@ -1212,13 +1052,12 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
if (!st->use_vbr)
{
int cbrBytes;
- /* Multiply by 12 to make sure the division is exact. */
- int frame_rate12 = 12*st->Fs/frame_size;
+ /* Multiply by 3 to make sure the division is exact. */
+ int frame_rate3 = 3*st->Fs/frame_size;
/* We need to make sure that "int" values always fit in 16 bits. */
- cbrBytes = IMIN( (12*st->bitrate_bps/8 + frame_rate12/2)/frame_rate12, max_data_bytes);
- st->bitrate_bps = cbrBytes*(opus_int32)frame_rate12*8/12;
- /* Make sure we provide at least one byte to avoid failing. */
- max_data_bytes = IMAX(1, cbrBytes);
+ cbrBytes = IMIN( (3*st->bitrate_bps/8 + frame_rate3/2)/frame_rate3, max_data_bytes);
+ st->bitrate_bps = cbrBytes*(opus_int32)frame_rate3*8/3;
+ max_data_bytes = cbrBytes;
}
if (max_data_bytes<3 || st->bitrate_bps < 3*frame_rate*8
|| (frame_rate<50 && (max_data_bytes*frame_rate<300 || st->bitrate_bps < 2400)))
@@ -1226,63 +1065,25 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
/*If the space is too low to do something useful, emit 'PLC' frames.*/
int tocmode = st->mode;
int bw = st->bandwidth == 0 ? OPUS_BANDWIDTH_NARROWBAND : st->bandwidth;
- int packet_code = 0;
- int num_multiframes = 0;
-
if (tocmode==0)
tocmode = MODE_SILK_ONLY;
if (frame_rate>100)
tocmode = MODE_CELT_ONLY;
- /* 40 ms -> 2 x 20 ms if in CELT_ONLY or HYBRID mode */
- if (frame_rate==25 && tocmode!=MODE_SILK_ONLY)
- {
- frame_rate = 50;
- packet_code = 1;
- }
-
- /* >= 60 ms frames */
- if (frame_rate<=16)
- {
- /* 1 x 60 ms, 2 x 40 ms, 2 x 60 ms */
- if (out_data_bytes==1 || (tocmode==MODE_SILK_ONLY && frame_rate!=10))
- {
- tocmode = MODE_SILK_ONLY;
-
- packet_code = frame_rate <= 12;
- frame_rate = frame_rate == 12 ? 25 : 16;
- }
- else
- {
- num_multiframes = 50/frame_rate;
- frame_rate = 50;
- packet_code = 3;
- }
- }
-
+ if (frame_rate < 50)
+ tocmode = MODE_SILK_ONLY;
if(tocmode==MODE_SILK_ONLY&&bw>OPUS_BANDWIDTH_WIDEBAND)
bw=OPUS_BANDWIDTH_WIDEBAND;
else if (tocmode==MODE_CELT_ONLY&&bw==OPUS_BANDWIDTH_MEDIUMBAND)
bw=OPUS_BANDWIDTH_NARROWBAND;
else if (tocmode==MODE_HYBRID&&bw<=OPUS_BANDWIDTH_SUPERWIDEBAND)
bw=OPUS_BANDWIDTH_SUPERWIDEBAND;
-
data[0] = gen_toc(tocmode, frame_rate, bw, st->stream_channels);
- data[0] |= packet_code;
-
- ret = packet_code <= 1 ? 1 : 2;
-
- max_data_bytes = IMAX(max_data_bytes, ret);
-
- if (packet_code==3)
- data[1] = num_multiframes;
-
+ ret = 1;
if (!st->use_vbr)
{
ret = opus_packet_pad(data, ret, max_data_bytes);
if (ret == OPUS_OK)
ret = max_data_bytes;
- else
- ret = OPUS_INTERNAL_ERROR;
}
RESTORE_STACK;
return ret;
@@ -1290,8 +1091,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
max_rate = frame_rate*max_data_bytes*8;
/* Equivalent 20-ms rate for mode/channel/bandwidth decisions */
- equiv_rate = compute_equiv_rate(st->bitrate_bps, st->channels, st->Fs/frame_size,
- st->use_vbr, 0, st->silk_mode.complexity, st->silk_mode.packetLossPercentage);
+ equiv_rate = st->bitrate_bps - (40*st->channels+20)*(st->Fs/frame_size - 50);
if (st->signal_type == OPUS_SIGNAL_VOICE)
voice_est = 127;
@@ -1332,17 +1132,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
}
#endif
}
- /* Update equivalent rate for channels decision. */
- equiv_rate = compute_equiv_rate(st->bitrate_bps, st->stream_channels, st->Fs/frame_size,
- st->use_vbr, 0, st->silk_mode.complexity, st->silk_mode.packetLossPercentage);
-
- /* Allow SILK DTX if DTX is enabled but the generalized DTX cannot be used,
- e.g. because of the complexity setting or sample rate. */
-#ifndef DISABLE_FLOAT_API
- st->silk_mode.useDTX = st->use_dtx && !(analysis_info.valid || is_silence);
-#else
- st->silk_mode.useDTX = st->use_dtx;
-#endif
+ equiv_rate = st->bitrate_bps - (40*st->stream_channels+20)*(st->Fs/frame_size - 50);
/* Mode selection depending on application and signal type */
if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
@@ -1391,15 +1181,10 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
/* When FEC is enabled and there's enough packet loss, use SILK */
if (st->silk_mode.useInBandFEC && st->silk_mode.packetLossPercentage > (128-voice_est)>>4)
st->mode = MODE_SILK_ONLY;
- /* When encoding voice and DTX is enabled but the generalized DTX cannot be used,
- use SILK in order to make use of its DTX. */
+ /* When encoding voice and DTX is enabled, set the encoder to SILK mode (at least for now) */
if (st->silk_mode.useDTX && voice_est > 100)
st->mode = MODE_SILK_ONLY;
#endif
-
- /* If max_data_bytes represents less than 6 kb/s, switch to CELT-only mode */
- if (max_data_bytes < (frame_rate > 50 ? 9000 : 6000)*frame_size / (st->Fs * 8))
- st->mode = MODE_CELT_ONLY;
} else {
st->mode = st->user_forced_mode;
}
@@ -1409,6 +1194,19 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
st->mode = MODE_CELT_ONLY;
if (st->lfe)
st->mode = MODE_CELT_ONLY;
+ /* If max_data_bytes represents less than 8 kb/s, switch to CELT-only mode */
+ if (max_data_bytes < (frame_rate > 50 ? 12000 : 8000)*frame_size / (st->Fs * 8))
+ st->mode = MODE_CELT_ONLY;
+
+ if (st->stream_channels == 1 && st->prev_channels ==2 && st->silk_mode.toMono==0
+ && st->mode != MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)
+ {
+ /* Delay stereo->mono transition by two frames so that SILK can do a smooth downmix */
+ st->silk_mode.toMono = 1;
+ st->stream_channels = 2;
+ } else {
+ st->silk_mode.toMono = 0;
+ }
if (st->prev_mode > 0 &&
((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ||
@@ -1428,22 +1226,23 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
}
}
}
-
- /* When encoding multiframes, we can ask for a switch to CELT only in the last frame. This switch
- * is processed above as the requested mode shouldn't interrupt stereo->mono transition. */
- if (st->stream_channels == 1 && st->prev_channels ==2 && st->silk_mode.toMono==0
- && st->mode != MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)
+ /* For the first frame at a new SILK bandwidth */
+ if (st->silk_bw_switch)
{
- /* Delay stereo->mono transition by two frames so that SILK can do a smooth downmix */
- st->silk_mode.toMono = 1;
- st->stream_channels = 2;
- } else {
- st->silk_mode.toMono = 0;
+ redundancy = 1;
+ celt_to_silk = 1;
+ st->silk_bw_switch = 0;
+ prefill=1;
}
- /* Update equivalent rate with mode decision. */
- equiv_rate = compute_equiv_rate(st->bitrate_bps, st->stream_channels, st->Fs/frame_size,
- st->use_vbr, st->mode, st->silk_mode.complexity, st->silk_mode.packetLossPercentage);
+ if (redundancy)
+ {
+ /* Fair share of the max size allowed */
+ redundancy_bytes = IMIN(257, max_data_bytes*(opus_int32)(st->Fs/200)/(frame_size+st->Fs/200));
+ /* For VBR, target the actual bitrate (subject to the limit above) */
+ if (st->use_vbr)
+ redundancy_bytes = IMIN(redundancy_bytes, st->bitrate_bps/1600);
+ }
if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
{
@@ -1458,7 +1257,17 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
const opus_int32 *voice_bandwidth_thresholds, *music_bandwidth_thresholds;
opus_int32 bandwidth_thresholds[8];
int bandwidth = OPUS_BANDWIDTH_FULLBAND;
+ opus_int32 equiv_rate2;
+ equiv_rate2 = equiv_rate;
+ if (st->mode != MODE_CELT_ONLY)
+ {
+ /* Adjust the threshold +/- 10% depending on complexity */
+ equiv_rate2 = equiv_rate2 * (45+st->silk_mode.complexity)/50;
+ /* CBR is less efficient by ~1 kb/s */
+ if (!st->use_vbr)
+ equiv_rate2 -= 1000;
+ }
if (st->channels==2 && st->force_channels!=1)
{
voice_bandwidth_thresholds = stereo_voice_bandwidth_thresholds;
@@ -1479,19 +1288,15 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
hysteresis = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)+1];
if (!st->first)
{
- if (st->auto_bandwidth >= bandwidth)
+ if (st->bandwidth >= bandwidth)
threshold -= hysteresis;
else
threshold += hysteresis;
}
- if (equiv_rate >= threshold)
+ if (equiv_rate2 >= threshold)
break;
} while (--bandwidth>OPUS_BANDWIDTH_NARROWBAND);
- /* We don't use mediumband anymore, except when explicitly requested or during
- mode transitions. */
- if (bandwidth == OPUS_BANDWIDTH_MEDIUMBAND)
- bandwidth = OPUS_BANDWIDTH_WIDEBAND;
- st->bandwidth = st->auto_bandwidth = bandwidth;
+ st->bandwidth = bandwidth;
/* Prevents any transition to SWB/FB until the SILK layer has fully
switched to WB mode and turned the variable LP filter off */
if (!st->first && st->mode != MODE_CELT_ONLY && !st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND)
@@ -1544,8 +1349,6 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
st->bandwidth = IMIN(st->bandwidth, st->detected_bandwidth);
}
#endif
- st->silk_mode.LBRR_coded = decide_fec(st->silk_mode.useInBandFEC, st->silk_mode.packetLossPercentage,
- st->silk_mode.LBRR_coded, st->mode, &st->bandwidth, equiv_rate);
celt_encoder_ctl(celt_enc, OPUS_SET_LSB_DEPTH(lsb_depth));
/* CELT mode doesn't support mediumband, use wideband instead */
@@ -1554,34 +1357,15 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
if (st->lfe)
st->bandwidth = OPUS_BANDWIDTH_NARROWBAND;
- curr_bandwidth = st->bandwidth;
-
- /* Chooses the appropriate mode for speech
- *NEVER* switch to/from CELT-only mode here as this will invalidate some assumptions */
- if (st->mode == MODE_SILK_ONLY && curr_bandwidth > OPUS_BANDWIDTH_WIDEBAND)
- st->mode = MODE_HYBRID;
- if (st->mode == MODE_HYBRID && curr_bandwidth <= OPUS_BANDWIDTH_WIDEBAND)
- st->mode = MODE_SILK_ONLY;
-
- /* Can't support higher than >60 ms frames, and >20 ms when in Hybrid or CELT-only modes */
- if ((frame_size > st->Fs/50 && (st->mode != MODE_SILK_ONLY)) || frame_size > 3*st->Fs/50)
+ /* Can't support higher than wideband for >20 ms frames */
+ if (frame_size > st->Fs/50 && (st->mode == MODE_CELT_ONLY || st->bandwidth > OPUS_BANDWIDTH_WIDEBAND))
{
- int enc_frame_size;
+ VARDECL(unsigned char, tmp_data);
int nb_frames;
-
- if (st->mode == MODE_SILK_ONLY)
- {
- if (frame_size == 2*st->Fs/25) /* 80 ms -> 2x 40 ms */
- enc_frame_size = st->Fs/25;
- else if (frame_size == 3*st->Fs/25) /* 120 ms -> 2x 60 ms */
- enc_frame_size = 3*st->Fs/50;
- else /* 100 ms -> 5x 20 ms */
- enc_frame_size = st->Fs/50;
- }
- else
- enc_frame_size = st->Fs/50;
-
- nb_frames = frame_size/enc_frame_size;
+ int bak_mode, bak_bandwidth, bak_channels, bak_to_mono;
+ VARDECL(OpusRepacketizer, rp);
+ opus_int32 bytes_per_frame;
+ opus_int32 repacketize_len;
#ifndef DISABLE_FLOAT_API
if (analysis_read_pos_bak!= -1)
@@ -1591,34 +1375,74 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
}
#endif
- ret = encode_multiframe_packet(st, pcm, nb_frames, enc_frame_size, data,
- out_data_bytes, to_celt, lsb_depth, float_api);
+ nb_frames = frame_size > st->Fs/25 ? 3 : 2;
+ bytes_per_frame = IMIN(1276,(out_data_bytes-3)/nb_frames);
- RESTORE_STACK;
- return ret;
- }
+ ALLOC(tmp_data, nb_frames*bytes_per_frame, unsigned char);
- /* For the first frame at a new SILK bandwidth */
- if (st->silk_bw_switch)
- {
- redundancy = 1;
- celt_to_silk = 1;
- st->silk_bw_switch = 0;
- /* Do a prefill without reseting the sampling rate control. */
- prefill=2;
- }
+ ALLOC(rp, 1, OpusRepacketizer);
+ opus_repacketizer_init(rp);
- /* If we decided to go with CELT, make sure redundancy is off, no matter what
- we decided earlier. */
- if (st->mode == MODE_CELT_ONLY)
- redundancy = 0;
+ bak_mode = st->user_forced_mode;
+ bak_bandwidth = st->user_bandwidth;
+ bak_channels = st->force_channels;
- if (redundancy)
- {
- redundancy_bytes = compute_redundancy_bytes(max_data_bytes, st->bitrate_bps, frame_rate, st->stream_channels);
- if (redundancy_bytes == 0)
- redundancy = 0;
+ st->user_forced_mode = st->mode;
+ st->user_bandwidth = st->bandwidth;
+ st->force_channels = st->stream_channels;
+ bak_to_mono = st->silk_mode.toMono;
+
+ if (bak_to_mono)
+ st->force_channels = 1;
+ else
+ st->prev_channels = st->stream_channels;
+ for (i=0;i<nb_frames;i++)
+ {
+ int tmp_len;
+ st->silk_mode.toMono = 0;
+ /* When switching from SILK/Hybrid to CELT, only ask for a switch at the last frame */
+ if (to_celt && i==nb_frames-1)
+ st->user_forced_mode = MODE_CELT_ONLY;
+ tmp_len = opus_encode_native(st, pcm+i*(st->channels*st->Fs/50), st->Fs/50,
+ tmp_data+i*bytes_per_frame, bytes_per_frame, lsb_depth,
+ NULL, 0, c1, c2, analysis_channels, downmix, float_api);
+ if (tmp_len<0)
+ {
+ RESTORE_STACK;
+ return OPUS_INTERNAL_ERROR;
+ }
+ ret = opus_repacketizer_cat(rp, tmp_data+i*bytes_per_frame, tmp_len);
+ if (ret<0)
+ {
+ RESTORE_STACK;
+ return OPUS_INTERNAL_ERROR;
+ }
+ }
+ if (st->use_vbr)
+ repacketize_len = out_data_bytes;
+ else
+ repacketize_len = IMIN(3*st->bitrate_bps/(3*8*50/nb_frames), out_data_bytes);
+ ret = opus_repacketizer_out_range_impl(rp, 0, nb_frames, data, repacketize_len, 0, !st->use_vbr);
+ if (ret<0)
+ {
+ RESTORE_STACK;
+ return OPUS_INTERNAL_ERROR;
+ }
+ st->user_forced_mode = bak_mode;
+ st->user_bandwidth = bak_bandwidth;
+ st->force_channels = bak_channels;
+ st->silk_mode.toMono = bak_to_mono;
+ RESTORE_STACK;
+ return ret;
}
+ curr_bandwidth = st->bandwidth;
+
+ /* Chooses the appropriate mode for speech
+ *NEVER* switch to/from CELT-only mode here as this will invalidate some assumptions */
+ if (st->mode == MODE_SILK_ONLY && curr_bandwidth > OPUS_BANDWIDTH_WIDEBAND)
+ st->mode = MODE_HYBRID;
+ if (st->mode == MODE_HYBRID && curr_bandwidth <= OPUS_BANDWIDTH_WIDEBAND)
+ st->mode = MODE_SILK_ONLY;
/* printf("%d %d %d %d\n", st->bitrate_bps, st->stream_channels, st->mode, curr_bandwidth); */
bytes_target = IMIN(max_data_bytes-redundancy_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1;
@@ -1643,7 +1467,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
if (st->application == OPUS_APPLICATION_VOIP)
{
- hp_cutoff(pcm, cutoff_Hz, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs, st->arch);
+ hp_cutoff(pcm, cutoff_Hz, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs);
} else {
dc_reject(pcm, 3, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs);
}
@@ -1668,7 +1492,6 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
if (st->mode != MODE_CELT_ONLY)
{
opus_int32 total_bitRate, celt_rate;
- opus_int activity;
#ifdef FIXED_POINT
const opus_int16 *pcm_silk;
#else
@@ -1676,26 +1499,30 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
ALLOC(pcm_silk, st->channels*frame_size, opus_int16);
#endif
- activity = VAD_NO_DECISION;
-#ifndef DISABLE_FLOAT_API
- if( analysis_info.valid ) {
- /* Inform SILK about the Opus VAD decision */
- activity = ( analysis_info.activity_probability >= DTX_ACTIVITY_THRESHOLD );
- }
-#endif
-
/* Distribute bits between SILK and CELT */
total_bitRate = 8 * bytes_target * frame_rate;
if( st->mode == MODE_HYBRID ) {
+ int HB_gain_ref;
/* Base rate for SILK */
- st->silk_mode.bitRate = compute_silk_rate_for_hybrid(total_bitRate,
- curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded,
- st->stream_channels);
+ st->silk_mode.bitRate = st->stream_channels * ( 5000 + 1000 * ( st->Fs == 100 * frame_size ) );
+ if( curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND ) {
+ /* SILK gets 2/3 of the remaining bits */
+ st->silk_mode.bitRate += ( total_bitRate - st->silk_mode.bitRate ) * 2 / 3;
+ } else { /* FULLBAND */
+ /* SILK gets 3/5 of the remaining bits */
+ st->silk_mode.bitRate += ( total_bitRate - st->silk_mode.bitRate ) * 3 / 5;
+ }
+ /* Don't let SILK use more than 80% */
+ if( st->silk_mode.bitRate > total_bitRate * 4/5 ) {
+ st->silk_mode.bitRate = total_bitRate * 4/5;
+ }
if (!st->energy_masking)
{
/* Increasingly attenuate high band when it gets allocated fewer bits */
celt_rate = total_bitRate - st->silk_mode.bitRate;
- HB_gain = Q15ONE - SHR32(celt_exp2(-celt_rate * QCONST16(1.f/1024, 10)), 1);
+ HB_gain_ref = (curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND) ? 3000 : 3600;
+ HB_gain = SHL32((opus_val32)celt_rate, 9) / SHR32((opus_val32)celt_rate + st->stream_channels * HB_gain_ref, 6);
+ HB_gain = HB_gain < (opus_val32)Q15ONE*6/7 ? HB_gain + Q15ONE/7 : Q15ONE;
}
} else {
/* SILK gets all bits */
@@ -1742,6 +1569,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
st->silk_mode.bitRate += 3*rate_offset/5;
else
st->silk_mode.bitRate += rate_offset;
+ bytes_target += rate_offset * frame_size / (8 * st->Fs);
}
st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs;
@@ -1752,7 +1580,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
} else if (curr_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {
st->silk_mode.desiredInternalSampleRate = 12000;
} else {
- celt_assert( st->mode == MODE_HYBRID || curr_bandwidth == OPUS_BANDWIDTH_WIDEBAND );
+ silk_assert( st->mode == MODE_HYBRID || curr_bandwidth == OPUS_BANDWIDTH_WIDEBAND );
st->silk_mode.desiredInternalSampleRate = 16000;
}
if( st->mode == MODE_HYBRID ) {
@@ -1762,53 +1590,40 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
st->silk_mode.minInternalSampleRate = 8000;
}
- st->silk_mode.maxInternalSampleRate = 16000;
if (st->mode == MODE_SILK_ONLY)
{
opus_int32 effective_max_rate = max_rate;
+ st->silk_mode.maxInternalSampleRate = 16000;
if (frame_rate > 50)
effective_max_rate = effective_max_rate*2/3;
- if (effective_max_rate < 8000)
+ if (effective_max_rate < 13000)
{
st->silk_mode.maxInternalSampleRate = 12000;
st->silk_mode.desiredInternalSampleRate = IMIN(12000, st->silk_mode.desiredInternalSampleRate);
}
- if (effective_max_rate < 7000)
+ if (effective_max_rate < 9600)
{
st->silk_mode.maxInternalSampleRate = 8000;
st->silk_mode.desiredInternalSampleRate = IMIN(8000, st->silk_mode.desiredInternalSampleRate);
}
+ } else {
+ st->silk_mode.maxInternalSampleRate = 16000;
}
st->silk_mode.useCBR = !st->use_vbr;
/* Call SILK encoder for the low band */
+ nBytes = IMIN(1275, max_data_bytes-1-redundancy_bytes);
- /* Max bits for SILK, counting ToC, redundancy bytes, and optionally redundancy. */
- st->silk_mode.maxBits = (max_data_bytes-1)*8;
- if (redundancy && redundancy_bytes >= 2)
- {
- /* Counting 1 bit for redundancy position and 20 bits for flag+size (only for hybrid). */
- st->silk_mode.maxBits -= redundancy_bytes*8 + 1;
- if (st->mode == MODE_HYBRID)
- st->silk_mode.maxBits -= 20;
- }
+ st->silk_mode.maxBits = nBytes*8;
+ /* Only allow up to 90% of the bits for hybrid mode*/
+ if (st->mode == MODE_HYBRID)
+ st->silk_mode.maxBits = (opus_int32)st->silk_mode.maxBits*9/10;
if (st->silk_mode.useCBR)
{
- if (st->mode == MODE_HYBRID)
- {
- st->silk_mode.maxBits = IMIN(st->silk_mode.maxBits, st->silk_mode.bitRate * frame_size / st->Fs);
- }
- } else {
- /* Constrained VBR. */
- if (st->mode == MODE_HYBRID)
- {
- /* Compute SILK bitrate corresponding to the max total bits available */
- opus_int32 maxBitRate = compute_silk_rate_for_hybrid(st->silk_mode.maxBits*st->Fs / frame_size,
- curr_bandwidth, st->Fs == 50 * frame_size, st->use_vbr, st->silk_mode.LBRR_coded,
- st->stream_channels);
- st->silk_mode.maxBits = maxBitRate * frame_size / st->Fs;
- }
+ st->silk_mode.maxBits = (st->silk_mode.bitRate * frame_size / (st->Fs * 8))*8;
+ /* Reduce the initial target to make it easier to reach the CBR rate */
+ st->silk_mode.bitRate = IMAX(1, st->silk_mode.bitRate-2000);
}
if (prefill)
@@ -1831,9 +1646,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
for (i=0;i<st->encoder_buffer*st->channels;i++)
pcm_silk[i] = FLOAT2INT16(st->delay_buffer[i]);
#endif
- silk_Encode( silk_enc, &st->silk_mode, pcm_silk, st->encoder_buffer, NULL, &zero, prefill, activity );
- /* Prevent a second switch in the real encode call. */
- st->silk_mode.opusCanSwitch = 0;
+ silk_Encode( silk_enc, &st->silk_mode, pcm_silk, st->encoder_buffer, NULL, &zero, 1 );
}
#ifdef FIXED_POINT
@@ -1842,14 +1655,20 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
for (i=0;i<frame_size*st->channels;i++)
pcm_silk[i] = FLOAT2INT16(pcm_buf[total_buffer*st->channels + i]);
#endif
- ret = silk_Encode( silk_enc, &st->silk_mode, pcm_silk, frame_size, &enc, &nBytes, 0, activity );
+ ret = silk_Encode( silk_enc, &st->silk_mode, pcm_silk, frame_size, &enc, &nBytes, 0 );
if( ret ) {
/*fprintf (stderr, "SILK encode error: %d\n", ret);*/
/* Handle error */
RESTORE_STACK;
return OPUS_INTERNAL_ERROR;
}
-
+ if (nBytes==0)
+ {
+ st->rangeFinal = 0;
+ data[-1] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);
+ RESTORE_STACK;
+ return 1;
+ }
/* Extract SILK internal bandwidth for signaling in first byte */
if( st->mode == MODE_SILK_ONLY ) {
if( st->silk_mode.internalSampleRate == 8000 ) {
@@ -1860,24 +1679,14 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
curr_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
}
} else {
- celt_assert( st->silk_mode.internalSampleRate == 16000 );
- }
-
- st->silk_mode.opusCanSwitch = st->silk_mode.switchReady && !st->nonfinal_frame;
-
- if (nBytes==0)
- {
- st->rangeFinal = 0;
- data[-1] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);
- RESTORE_STACK;
- return 1;
+ silk_assert( st->silk_mode.internalSampleRate == 16000 );
}
+ st->silk_mode.opusCanSwitch = st->silk_mode.switchReady;
/* FIXME: How do we allocate the redundancy for CBR? */
if (st->silk_mode.opusCanSwitch)
{
- redundancy_bytes = compute_redundancy_bytes(max_data_bytes, st->bitrate_bps, frame_rate, st->stream_channels);
- redundancy = (redundancy_bytes != 0);
+ redundancy = 1;
celt_to_silk = 0;
st->silk_bw_switch = 1;
}
@@ -1918,18 +1727,40 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
if (st->mode == MODE_HYBRID)
{
+ int len;
+
+ len = (ec_tell(&enc)+7)>>3;
+ if (redundancy)
+ len += st->mode == MODE_HYBRID ? 3 : 1;
if( st->use_vbr ) {
- celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps-st->silk_mode.bitRate));
- celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(0));
+ nb_compr_bytes = len + bytes_target - (st->silk_mode.bitRate * frame_size) / (8 * st->Fs);
+ } else {
+ /* check if SILK used up too much */
+ nb_compr_bytes = len > bytes_target ? len : bytes_target;
}
} else {
if (st->use_vbr)
{
+ opus_int32 bonus=0;
+#ifndef DISABLE_FLOAT_API
+ if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != st->Fs/50)
+ {
+ bonus = (60*st->stream_channels+40)*(st->Fs/frame_size-50);
+ if (analysis_info.valid)
+ bonus = (opus_int32)(bonus*(1.f+.5f*analysis_info.tonality));
+ }
+#endif
celt_encoder_ctl(celt_enc, OPUS_SET_VBR(1));
celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(st->vbr_constraint));
- celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps));
+ celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps+bonus));
+ nb_compr_bytes = max_data_bytes-1-redundancy_bytes;
+ } else {
+ nb_compr_bytes = bytes_target;
}
}
+
+ } else {
+ nb_compr_bytes = 0;
}
ALLOC(tmp_prefill, st->channels*st->Fs/400, opus_val16);
@@ -1955,14 +1786,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
}
st->prev_HB_gain = HB_gain;
if (st->mode != MODE_HYBRID || st->stream_channels==1)
- {
- if (equiv_rate > 32000)
- st->silk_mode.stereoWidth_Q14 = 16384;
- else if (equiv_rate < 16000)
- st->silk_mode.stereoWidth_Q14 = 0;
- else
- st->silk_mode.stereoWidth_Q14 = 16384 - 2048*(opus_int32)(32000-equiv_rate)/(equiv_rate-14000);
- }
+ st->silk_mode.stereoWidth_Q14 = IMIN((1<<14),2*IMAX(0,equiv_rate-30000));
if( !st->energy_masking && st->channels == 2 ) {
/* Apply stereo width reduction (at low bitrates) */
if( st->hybrid_stereo_width_Q14 < (1 << 14) || st->silk_mode.stereoWidth_Q14 < (1 << 14) ) {
@@ -1985,23 +1809,19 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
if ( st->mode != MODE_CELT_ONLY && ec_tell(&enc)+17+20*(st->mode == MODE_HYBRID) <= 8*(max_data_bytes-1))
{
/* For SILK mode, the redundancy is inferred from the length */
- if (st->mode == MODE_HYBRID)
+ if (st->mode == MODE_HYBRID && (redundancy || ec_tell(&enc)+37 <= 8*nb_compr_bytes))
ec_enc_bit_logp(&enc, redundancy, 12);
if (redundancy)
{
int max_redundancy;
ec_enc_bit_logp(&enc, celt_to_silk, 1);
if (st->mode == MODE_HYBRID)
- {
- /* Reserve the 8 bits needed for the redundancy length,
- and at least a few bits for CELT if possible */
- max_redundancy = (max_data_bytes-1)-((ec_tell(&enc)+8+3+7)>>3);
- }
+ max_redundancy = (max_data_bytes-1)-nb_compr_bytes;
else
max_redundancy = (max_data_bytes-1)-((ec_tell(&enc)+7)>>3);
/* Target the same bit-rate for redundancy as for the rest,
up to a max of 257 bytes */
- redundancy_bytes = IMIN(max_redundancy, redundancy_bytes);
+ redundancy_bytes = IMIN(max_redundancy, st->bitrate_bps/1600);
redundancy_bytes = IMIN(257, IMAX(2, redundancy_bytes));
if (st->mode == MODE_HYBRID)
ec_enc_uint(&enc, redundancy_bytes-2, 256);
@@ -2023,7 +1843,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
ec_enc_done(&enc);
nb_compr_bytes = ret;
} else {
- nb_compr_bytes = (max_data_bytes-1)-redundancy_bytes;
+ nb_compr_bytes = IMIN((max_data_bytes-1)-redundancy_bytes, nb_compr_bytes);
ec_enc_shrink(&enc, nb_compr_bytes);
}
@@ -2031,12 +1851,6 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
if (redundancy || st->mode != MODE_SILK_ONLY)
celt_encoder_ctl(celt_enc, CELT_SET_ANALYSIS(&analysis_info));
#endif
- if (st->mode == MODE_HYBRID) {
- SILKInfo info;
- info.signalType = st->silk_mode.signalType;
- info.offset = st->silk_mode.offset;
- celt_encoder_ctl(celt_enc, CELT_SET_SILK_INFO(&info));
- }
/* 5 ms redundant frame for CELT->SILK */
if (redundancy && celt_to_silk)
@@ -2044,7 +1858,6 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
int err;
celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));
- celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX));
err = celt_encode_with_ec(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes, NULL);
if (err < 0)
{
@@ -2068,25 +1881,15 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
celt_encode_with_ec(celt_enc, tmp_prefill, st->Fs/400, dummy, 2, NULL);
celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
}
- /* If false, we already busted the budget and we'll end up with a "PLC frame" */
+ /* If false, we already busted the budget and we'll end up with a "PLC packet" */
if (ec_tell(&enc) <= 8*nb_compr_bytes)
{
- /* Set the bitrate again if it was overridden in the redundancy code above*/
- if (redundancy && celt_to_silk && st->mode==MODE_HYBRID && st->use_vbr)
- celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps-st->silk_mode.bitRate));
- celt_encoder_ctl(celt_enc, OPUS_SET_VBR(st->use_vbr));
ret = celt_encode_with_ec(celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc);
if (ret < 0)
{
RESTORE_STACK;
return OPUS_INTERNAL_ERROR;
}
- /* Put CELT->SILK redundancy data in the right place. */
- if (redundancy && celt_to_silk && st->mode==MODE_HYBRID && st->use_vbr)
- {
- OPUS_MOVE(data+ret, data+nb_compr_bytes, redundancy_bytes);
- nb_compr_bytes = nb_compr_bytes+redundancy_bytes;
- }
}
}
@@ -2102,15 +1905,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
- celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));
- celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX));
- if (st->mode == MODE_HYBRID)
- {
- /* Shrink packet to what the encoder actually used. */
- nb_compr_bytes = ret;
- ec_enc_shrink(&enc, nb_compr_bytes);
- }
/* NOTE: We could speed this up slightly (at the expense of code size) by just adding a function that prefills the buffer */
celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, dummy, 2, NULL);
@@ -2140,23 +1935,6 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
st->first = 0;
- /* DTX decision */
-#ifndef DISABLE_FLOAT_API
- if (st->use_dtx && (analysis_info.valid || is_silence))
- {
- if (decide_dtx_mode(analysis_info.activity_probability, &st->nb_no_activity_frames,
- st->peak_signal_energy, pcm, frame_size, st->channels, is_silence, st->arch))
- {
- st->rangeFinal = 0;
- data[0] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);
- RESTORE_STACK;
- return 1;
- }
- } else {
- st->nb_no_activity_frames = 0;
- }
-#endif
-
/* In the unlikely case that the SILK encoder busted its target, tell
the decoder to call the PLC */
if (ec_tell(&enc) > (max_data_bytes-1)*8)
@@ -2184,6 +1962,7 @@ opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_
if (!st->use_vbr)
{
if (opus_packet_pad(data, ret, max_data_bytes) != OPUS_OK)
+
{
RESTORE_STACK;
return OPUS_INTERNAL_ERROR;
@@ -2202,15 +1981,18 @@ opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_fra
{
int i, ret;
int frame_size;
+ int delay_compensation;
VARDECL(opus_int16, in);
ALLOC_STACK;
- frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
- if (frame_size <= 0)
- {
- RESTORE_STACK;
- return OPUS_BAD_ARG;
- }
+ if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
+ delay_compensation = 0;
+ else
+ delay_compensation = st->delay_compensation;
+ frame_size = compute_frame_size(pcm, analysis_frame_size,
+ st->variable_duration, st->channels, st->Fs, st->bitrate_bps,
+ delay_compensation, downmix_float, st->analysis.subframe_mem);
+
ALLOC(in, frame_size*st->channels, opus_int16);
for (i=0;i<frame_size*st->channels;i++)
@@ -2226,7 +2008,18 @@ opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_fram
unsigned char *data, opus_int32 out_data_bytes)
{
int frame_size;
- frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
+ int delay_compensation;
+ if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
+ delay_compensation = 0;
+ else
+ delay_compensation = st->delay_compensation;
+ frame_size = compute_frame_size(pcm, analysis_frame_size,
+ st->variable_duration, st->channels, st->Fs, st->bitrate_bps,
+ delay_compensation, downmix_int
+#ifndef DISABLE_FLOAT_API
+ , st->analysis.subframe_mem
+#endif
+ );
return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 16,
pcm, analysis_frame_size, 0, -2, st->channels, downmix_int, 0);
}
@@ -2237,15 +2030,18 @@ opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_fram
{
int i, ret;
int frame_size;
+ int delay_compensation;
VARDECL(float, in);
ALLOC_STACK;
- frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
- if (frame_size <= 0)
- {
- RESTORE_STACK;
- return OPUS_BAD_ARG;
- }
+ if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
+ delay_compensation = 0;
+ else
+ delay_compensation = st->delay_compensation;
+ frame_size = compute_frame_size(pcm, analysis_frame_size,
+ st->variable_duration, st->channels, st->Fs, st->bitrate_bps,
+ delay_compensation, downmix_int, st->analysis.subframe_mem);
+
ALLOC(in, frame_size*st->channels, float);
for (i=0;i<frame_size*st->channels;i++)
@@ -2259,7 +2055,14 @@ opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_fra
unsigned char *data, opus_int32 out_data_bytes)
{
int frame_size;
- frame_size = frame_size_select(analysis_frame_size, st->variable_duration, st->Fs);
+ int delay_compensation;
+ if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
+ delay_compensation = 0;
+ else
+ delay_compensation = st->delay_compensation;
+ frame_size = compute_frame_size(pcm, analysis_frame_size,
+ st->variable_duration, st->channels, st->Fs, st->bitrate_bps,
+ delay_compensation, downmix_float, st->analysis.subframe_mem);
return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 24,
pcm, analysis_frame_size, 0, -2, st->channels, downmix_float, 1);
}
@@ -2290,9 +2093,6 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
break;
}
st->application = value;
-#ifndef DISABLE_FLOAT_API
- st->analysis.application = value;
-#endif
}
break;
case OPUS_GET_APPLICATION_REQUEST:
@@ -2411,7 +2211,7 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
{
goto bad_arg;
}
- st->use_dtx = value;
+ st->silk_mode.useDTX = value;
}
break;
case OPUS_GET_DTX_REQUEST:
@@ -2421,7 +2221,7 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
{
goto bad_arg;
}
- *value = st->use_dtx;
+ *value = st->silk_mode.useDTX;
}
break;
case OPUS_SET_COMPLEXITY_REQUEST:
@@ -2622,15 +2422,15 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
{
opus_int32 value = va_arg(ap, opus_int32);
- if (value != OPUS_FRAMESIZE_ARG && value != OPUS_FRAMESIZE_2_5_MS &&
- value != OPUS_FRAMESIZE_5_MS && value != OPUS_FRAMESIZE_10_MS &&
- value != OPUS_FRAMESIZE_20_MS && value != OPUS_FRAMESIZE_40_MS &&
- value != OPUS_FRAMESIZE_60_MS && value != OPUS_FRAMESIZE_80_MS &&
- value != OPUS_FRAMESIZE_100_MS && value != OPUS_FRAMESIZE_120_MS)
+ if (value != OPUS_FRAMESIZE_ARG && value != OPUS_FRAMESIZE_2_5_MS &&
+ value != OPUS_FRAMESIZE_5_MS && value != OPUS_FRAMESIZE_10_MS &&
+ value != OPUS_FRAMESIZE_20_MS && value != OPUS_FRAMESIZE_40_MS &&
+ value != OPUS_FRAMESIZE_60_MS && value != OPUS_FRAMESIZE_VARIABLE)
{
goto bad_arg;
}
st->variable_duration = value;
+ celt_encoder_ctl(celt_enc, OPUS_SET_EXPERT_FRAME_DURATION(value));
}
break;
case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
@@ -2659,26 +2459,6 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
*value = st->silk_mode.reducedDependency;
}
break;
- case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
- {
- opus_int32 value = va_arg(ap, opus_int32);
- if(value<0 || value>1)
- {
- goto bad_arg;
- }
- celt_encoder_ctl(celt_enc, OPUS_SET_PHASE_INVERSION_DISABLED(value));
- }
- break;
- case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
- {
- opus_int32 *value = va_arg(ap, opus_int32*);
- if (!value)
- {
- goto bad_arg;
- }
- celt_encoder_ctl(celt_enc, OPUS_GET_PHASE_INVERSION_DISABLED(value));
- }
- break;
case OPUS_RESET_STATE:
{
void *silk_enc;
@@ -2727,33 +2507,6 @@ int opus_encoder_ctl(OpusEncoder *st, int request, ...)
ret = celt_encoder_ctl(celt_enc, OPUS_SET_ENERGY_MASK(value));
}
break;
- case OPUS_GET_IN_DTX_REQUEST:
- {
- opus_int32 *value = va_arg(ap, opus_int32*);
- if (!value)
- {
- goto bad_arg;
- }
- if (st->silk_mode.useDTX && (st->prev_mode == MODE_SILK_ONLY || st->prev_mode == MODE_HYBRID)) {
- /* DTX determined by Silk. */
- int n;
- void *silk_enc = (char*)st+st->silk_enc_offset;
- *value = 1;
- for (n=0;n<st->silk_mode.nChannelsInternal;n++) {
- *value = *value && ((silk_encoder*)silk_enc)->state_Fxx[n].sCmn.noSpeechCounter >= NB_SPEECH_FRAMES_BEFORE_DTX;
- }
- }
-#ifndef DISABLE_FLOAT_API
- else if (st->use_dtx) {
- /* DTX determined by Opus. */
- *value = st->nb_no_activity_frames >= NB_SPEECH_FRAMES_BEFORE_DTX;
- }
-#endif
- else {
- *value = 0;
- }
- }
- break;
case CELT_GET_MODE_REQUEST:
{
diff --git a/thirdparty/opus/opus_multistream_decoder.c b/thirdparty/opus/opus_multistream_decoder.c
index 0018517aeb..b95eaa6eac 100644
--- a/thirdparty/opus/opus_multistream_decoder.c
+++ b/thirdparty/opus/opus_multistream_decoder.c
@@ -37,19 +37,16 @@
#include "float_cast.h"
#include "os_support.h"
-/* DECODER */
+struct OpusMSDecoder {
+ ChannelLayout layout;
+ /* Decoder states go here */
+};
-#if defined(ENABLE_HARDENING) || defined(ENABLE_ASSERTIONS)
-static void validate_ms_decoder(OpusMSDecoder *st)
-{
- validate_layout(&st->layout);
-}
-#define VALIDATE_MS_DECODER(st) validate_ms_decoder(st)
-#else
-#define VALIDATE_MS_DECODER(st)
-#endif
+
+/* DECODER */
+
opus_int32 opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams)
{
int coupled_size;
@@ -146,6 +143,15 @@ OpusMSDecoder *opus_multistream_decoder_create(
return st;
}
+typedef void (*opus_copy_channel_out_func)(
+ void *dst,
+ int dst_stride,
+ int dst_channel,
+ const opus_val16 *src,
+ int src_stride,
+ int frame_size
+);
+
static int opus_multistream_packet_validate(const unsigned char *data,
opus_int32 len, int nb_streams, opus_int32 Fs)
{
@@ -175,7 +181,7 @@ static int opus_multistream_packet_validate(const unsigned char *data,
return samples;
}
-int opus_multistream_decode_native(
+static int opus_multistream_decode_native(
OpusMSDecoder *st,
const unsigned char *data,
opus_int32 len,
@@ -183,8 +189,7 @@ int opus_multistream_decode_native(
opus_copy_channel_out_func copy_channel_out,
int frame_size,
int decode_fec,
- int soft_clip,
- void *user_data
+ int soft_clip
)
{
opus_int32 Fs;
@@ -196,14 +201,8 @@ int opus_multistream_decode_native(
VARDECL(opus_val16, buf);
ALLOC_STACK;
- VALIDATE_MS_DECODER(st);
- if (frame_size <= 0)
- {
- RESTORE_STACK;
- return OPUS_BAD_ARG;
- }
/* Limit frame_size to avoid excessive stack allocations. */
- MUST_SUCCEED(opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs)));
+ opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs));
frame_size = IMIN(frame_size, Fs/25*3);
ALLOC(buf, 2*frame_size, opus_val16);
ptr = (char*)st + align(sizeof(OpusMSDecoder));
@@ -238,8 +237,7 @@ int opus_multistream_decode_native(
for (s=0;s<st->layout.nb_streams;s++)
{
OpusDecoder *dec;
- opus_int32 packet_offset;
- int ret;
+ int packet_offset, ret;
dec = (OpusDecoder*)ptr;
ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size);
@@ -267,7 +265,7 @@ int opus_multistream_decode_native(
while ( (chan = get_left_channel(&st->layout, s, prev)) != -1)
{
(*copy_channel_out)(pcm, st->layout.nb_channels, chan,
- buf, 2, frame_size, user_data);
+ buf, 2, frame_size);
prev = chan;
}
prev = -1;
@@ -275,7 +273,7 @@ int opus_multistream_decode_native(
while ( (chan = get_right_channel(&st->layout, s, prev)) != -1)
{
(*copy_channel_out)(pcm, st->layout.nb_channels, chan,
- buf+1, 2, frame_size, user_data);
+ buf+1, 2, frame_size);
prev = chan;
}
} else {
@@ -285,7 +283,7 @@ int opus_multistream_decode_native(
while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1)
{
(*copy_channel_out)(pcm, st->layout.nb_channels, chan,
- buf, 1, frame_size, user_data);
+ buf, 1, frame_size);
prev = chan;
}
}
@@ -296,7 +294,7 @@ int opus_multistream_decode_native(
if (st->layout.mapping[c] == 255)
{
(*copy_channel_out)(pcm, st->layout.nb_channels, c,
- NULL, 0, frame_size, user_data);
+ NULL, 0, frame_size);
}
}
RESTORE_STACK;
@@ -310,13 +308,11 @@ static void opus_copy_channel_out_float(
int dst_channel,
const opus_val16 *src,
int src_stride,
- int frame_size,
- void *user_data
+ int frame_size
)
{
float *float_dst;
opus_int32 i;
- (void)user_data;
float_dst = (float*)dst;
if (src != NULL)
{
@@ -341,13 +337,11 @@ static void opus_copy_channel_out_short(
int dst_channel,
const opus_val16 *src,
int src_stride,
- int frame_size,
- void *user_data
+ int frame_size
)
{
opus_int16 *short_dst;
opus_int32 i;
- (void)user_data;
short_dst = (opus_int16*)dst;
if (src != NULL)
{
@@ -378,7 +372,7 @@ int opus_multistream_decode(
)
{
return opus_multistream_decode_native(st, data, len,
- pcm, opus_copy_channel_out_short, frame_size, decode_fec, 0, NULL);
+ pcm, opus_copy_channel_out_short, frame_size, decode_fec, 0);
}
#ifndef DISABLE_FLOAT_API
@@ -386,7 +380,7 @@ int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data,
opus_int32 len, float *pcm, int frame_size, int decode_fec)
{
return opus_multistream_decode_native(st, data, len,
- pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0, NULL);
+ pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0);
}
#endif
@@ -396,30 +390,32 @@ int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data,
opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
{
return opus_multistream_decode_native(st, data, len,
- pcm, opus_copy_channel_out_short, frame_size, decode_fec, 1, NULL);
+ pcm, opus_copy_channel_out_short, frame_size, decode_fec, 1);
}
int opus_multistream_decode_float(
OpusMSDecoder *st,
const unsigned char *data,
opus_int32 len,
- opus_val16 *pcm,
+ float *pcm,
int frame_size,
int decode_fec
)
{
return opus_multistream_decode_native(st, data, len,
- pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0, NULL);
+ pcm, opus_copy_channel_out_float, frame_size, decode_fec, 0);
}
#endif
-int opus_multistream_decoder_ctl_va_list(OpusMSDecoder *st, int request,
- va_list ap)
+int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
{
+ va_list ap;
int coupled_size, mono_size;
char *ptr;
int ret = OPUS_OK;
+ va_start(ap, request);
+
coupled_size = opus_decoder_get_size(2);
mono_size = opus_decoder_get_size(1);
ptr = (char*)st + align(sizeof(OpusMSDecoder));
@@ -429,7 +425,6 @@ int opus_multistream_decoder_ctl_va_list(OpusMSDecoder *st, int request,
case OPUS_GET_SAMPLE_RATE_REQUEST:
case OPUS_GET_GAIN_REQUEST:
case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
- case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
{
OpusDecoder *dec;
/* For int32* GET params, just query the first stream */
@@ -487,7 +482,7 @@ int opus_multistream_decoder_ctl_va_list(OpusMSDecoder *st, int request,
OpusDecoder **value;
stream_id = va_arg(ap, opus_int32);
if (stream_id<0 || stream_id >= st->layout.nb_streams)
- goto bad_arg;
+ ret = OPUS_BAD_ARG;
value = va_arg(ap, OpusDecoder**);
if (!value)
{
@@ -504,7 +499,6 @@ int opus_multistream_decoder_ctl_va_list(OpusMSDecoder *st, int request,
}
break;
case OPUS_SET_GAIN_REQUEST:
- case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
{
int s;
/* This works for int32 params */
@@ -528,20 +522,14 @@ int opus_multistream_decoder_ctl_va_list(OpusMSDecoder *st, int request,
ret = OPUS_UNIMPLEMENTED;
break;
}
+
+ va_end(ap);
return ret;
bad_arg:
+ va_end(ap);
return OPUS_BAD_ARG;
}
-int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
-{
- int ret;
- va_list ap;
- va_start(ap, request);
- ret = opus_multistream_decoder_ctl_va_list(st, request, ap);
- va_end(ap);
- return ret;
-}
void opus_multistream_decoder_destroy(OpusMSDecoder *st)
{
diff --git a/thirdparty/opus/opus_multistream_encoder.c b/thirdparty/opus/opus_multistream_encoder.c
index 93204a14c1..1698223a16 100644
--- a/thirdparty/opus/opus_multistream_encoder.c
+++ b/thirdparty/opus/opus_multistream_encoder.c
@@ -61,6 +61,38 @@ static const VorbisLayout vorbis_mappings[8] = {
{5, 3, {0, 6, 1, 2, 3, 4, 5, 7}}, /* 8: 7.1 surround */
};
+typedef void (*opus_copy_channel_in_func)(
+ opus_val16 *dst,
+ int dst_stride,
+ const void *src,
+ int src_stride,
+ int src_channel,
+ int frame_size
+);
+
+typedef enum {
+ MAPPING_TYPE_NONE,
+ MAPPING_TYPE_SURROUND
+#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
+ , /* Do not include comma at end of enumerator list */
+ MAPPING_TYPE_AMBISONICS
+#endif
+} MappingType;
+
+struct OpusMSEncoder {
+ ChannelLayout layout;
+ int arch;
+ int lfe_stream;
+ int application;
+ int variable_duration;
+ MappingType mapping_type;
+ opus_int32 bitrate_bps;
+ float subframe_mem[3];
+ /* Encoder states go here */
+ /* then opus_val32 window_mem[channels*120]; */
+ /* then opus_val32 preemph_mem[channels]; */
+};
+
static opus_val32 *ms_get_preemph_mem(OpusMSEncoder *st)
{
int s;
@@ -101,29 +133,6 @@ static opus_val32 *ms_get_window_mem(OpusMSEncoder *st)
return (opus_val32*)(void*)ptr;
}
-static int validate_ambisonics(int nb_channels, int *nb_streams, int *nb_coupled_streams)
-{
- int order_plus_one;
- int acn_channels;
- int nondiegetic_channels;
-
- if (nb_channels < 1 || nb_channels > 227)
- return 0;
-
- order_plus_one = isqrt32(nb_channels);
- acn_channels = order_plus_one * order_plus_one;
- nondiegetic_channels = nb_channels - acn_channels;
-
- if (nondiegetic_channels != 0 && nondiegetic_channels != 2)
- return 0;
-
- if (nb_streams)
- *nb_streams = acn_channels + (nondiegetic_channels != 0);
- if (nb_coupled_streams)
- *nb_coupled_streams = nondiegetic_channels != 0;
- return 1;
-}
-
static int validate_encoder_layout(const ChannelLayout *layout)
{
int s;
@@ -231,7 +240,6 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b
int pos[8] = {0};
int upsample;
int frame_size;
- int freq_size;
opus_val16 channel_offset;
opus_val32 bandE[21];
opus_val16 maskLogE[3][21];
@@ -242,7 +250,6 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b
upsample = resampling_factor(rate);
frame_size = len*upsample;
- freq_size = IMIN(960, frame_size);
/* LM = log2(frame_size / 120) */
for (LM=0;LM<celt_mode->maxLM;LM++)
@@ -251,7 +258,7 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b
ALLOC(in, frame_size+overlap, opus_val32);
ALLOC(x, len, opus_val16);
- ALLOC(freq, freq_size, opus_val32);
+ ALLOC(freq, frame_size, opus_val32);
channel_pos(channels, pos);
@@ -261,11 +268,8 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b
for (c=0;c<channels;c++)
{
- int frame;
- int nb_frames = frame_size/freq_size;
- celt_assert(nb_frames*freq_size == frame_size);
OPUS_COPY(in, mem+c*overlap, overlap);
- (*copy_channel_in)(x, 1, pcm, channels, c, len, NULL);
+ (*copy_channel_in)(x, 1, pcm, channels, c, len);
celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0);
#ifndef FIXED_POINT
{
@@ -280,26 +284,18 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b
}
}
#endif
- OPUS_CLEAR(bandE, 21);
- for (frame=0;frame<nb_frames;frame++)
+ clt_mdct_forward(&celt_mode->mdct, in, freq, celt_mode->window,
+ overlap, celt_mode->maxLM-LM, 1, arch);
+ if (upsample != 1)
{
- opus_val32 tmpE[21];
- clt_mdct_forward(&celt_mode->mdct, in+960*frame, freq, celt_mode->window,
- overlap, celt_mode->maxLM-LM, 1, arch);
- if (upsample != 1)
- {
- int bound = freq_size/upsample;
- for (i=0;i<bound;i++)
- freq[i] *= upsample;
- for (;i<freq_size;i++)
- freq[i] = 0;
- }
-
- compute_band_energies(celt_mode, freq, tmpE, 21, 1, LM, arch);
- /* If we have multiple frames, take the max energy. */
- for (i=0;i<21;i++)
- bandE[i] = MAX32(bandE[i], tmpE[i]);
+ int bound = len;
+ for (i=0;i<bound;i++)
+ freq[i] *= upsample;
+ for (;i<frame_size;i++)
+ freq[i] = 0;
}
+
+ compute_band_energies(celt_mode, freq, bandE, 21, 1, LM);
amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1);
/* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */
for (i=1;i<21;i++)
@@ -412,10 +408,12 @@ opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_
{
nb_streams=channels;
nb_coupled_streams=0;
- } else if (mapping_family==2)
+#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
+ } else if (mapping_family==254)
{
- if (!validate_ambisonics(channels, &nb_streams, &nb_coupled_streams))
- return 0;
+ nb_streams=channels;
+ nb_coupled_streams=0;
+#endif
} else
return 0;
size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
@@ -450,6 +448,7 @@ static int opus_multistream_encoder_init_impl(
st->layout.nb_channels = channels;
st->layout.nb_streams = streams;
st->layout.nb_coupled_streams = coupled_streams;
+ st->subframe_mem[0]=st->subframe_mem[1]=st->subframe_mem[2]=0;
if (mapping_type != MAPPING_TYPE_SURROUND)
st->lfe_stream = -1;
st->bitrate_bps = OPUS_AUTO;
@@ -457,13 +456,7 @@ static int opus_multistream_encoder_init_impl(
st->variable_duration = OPUS_FRAMESIZE_ARG;
for (i=0;i<st->layout.nb_channels;i++)
st->layout.mapping[i] = mapping[i];
- if (!validate_layout(&st->layout))
- return OPUS_BAD_ARG;
- if (mapping_type == MAPPING_TYPE_SURROUND &&
- !validate_encoder_layout(&st->layout))
- return OPUS_BAD_ARG;
- if (mapping_type == MAPPING_TYPE_AMBISONICS &&
- !validate_ambisonics(st->layout.nb_channels, NULL, NULL))
+ if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout))
return OPUS_BAD_ARG;
ptr = (char*)st + align(sizeof(OpusMSEncoder));
coupled_size = opus_encoder_get_size(2);
@@ -556,23 +549,25 @@ int opus_multistream_surround_encoder_init(
*coupled_streams=0;
for(i=0;i<channels;i++)
mapping[i] = i;
- } else if (mapping_family==2)
+#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
+ } else if (mapping_family==254)
{
int i;
- if (!validate_ambisonics(channels, streams, coupled_streams))
- return OPUS_BAD_ARG;
- for(i = 0; i < (*streams - *coupled_streams); i++)
- mapping[i] = i + (*coupled_streams * 2);
- for(i = 0; i < *coupled_streams * 2; i++)
- mapping[i + (*streams - *coupled_streams)] = i;
+ *streams=channels;
+ *coupled_streams=0;
+ for(i=0;i<channels;i++)
+ mapping[i] = i;
+#endif
} else
return OPUS_UNIMPLEMENTED;
if (channels>2 && mapping_family==1) {
mapping_type = MAPPING_TYPE_SURROUND;
- } else if (mapping_family==2)
+#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
+ } else if (mapping_family==254)
{
mapping_type = MAPPING_TYPE_AMBISONICS;
+#endif
} else
{
mapping_type = MAPPING_TYPE_NONE;
@@ -677,62 +672,62 @@ static void surround_rate_allocation(
int lfe_offset;
int coupled_ratio; /* Q8 */
int lfe_ratio; /* Q8 */
- int nb_lfe;
- int nb_uncoupled;
- int nb_coupled;
- int nb_normal;
- opus_int32 channel_offset;
- opus_int32 bitrate;
- int total;
-
- nb_lfe = (st->lfe_stream!=-1);
- nb_coupled = st->layout.nb_coupled_streams;
- nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
- nb_normal = 2*nb_coupled + nb_uncoupled;
-
- /* Give each non-LFE channel enough bits per channel for coding band energy. */
- channel_offset = 40*IMAX(50, Fs/frame_size);
+ if (st->bitrate_bps > st->layout.nb_channels*40000)
+ stream_offset = 20000;
+ else
+ stream_offset = st->bitrate_bps/st->layout.nb_channels/2;
+ stream_offset += 60*(Fs/frame_size-50);
+ /* We start by giving each stream (coupled or uncoupled) the same bitrate.
+ This models the main saving of coupled channels over uncoupled. */
+ /* The LFE stream is an exception to the above and gets fewer bits. */
+ lfe_offset = 3500 + 60*(Fs/frame_size-50);
+ /* Coupled streams get twice the mono rate after the first 20 kb/s. */
+ coupled_ratio = 512;
+ /* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of mono */
+ lfe_ratio = 32;
+
+ /* Compute bitrate allocation between streams */
if (st->bitrate_bps==OPUS_AUTO)
{
- bitrate = nb_normal*(channel_offset + Fs + 10000) + 8000*nb_lfe;
+ channel_rate = Fs+60*Fs/frame_size;
} else if (st->bitrate_bps==OPUS_BITRATE_MAX)
{
- bitrate = nb_normal*300000 + nb_lfe*128000;
+ channel_rate = 300000;
} else {
- bitrate = st->bitrate_bps;
+ int nb_lfe;
+ int nb_uncoupled;
+ int nb_coupled;
+ int total;
+ nb_lfe = (st->lfe_stream!=-1);
+ nb_coupled = st->layout.nb_coupled_streams;
+ nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
+ total = (nb_uncoupled<<8) /* mono */
+ + coupled_ratio*nb_coupled /* stereo */
+ + nb_lfe*lfe_ratio;
+ channel_rate = 256*(st->bitrate_bps-lfe_offset*nb_lfe-stream_offset*(nb_coupled+nb_uncoupled))/total;
}
-
- /* Give LFE some basic stream_channel allocation but never exceed 1/20 of the
- total rate for the non-energy part to avoid problems at really low rate. */
- lfe_offset = IMIN(bitrate/20, 3000) + 15*IMAX(50, Fs/frame_size);
-
- /* We give each stream (coupled or uncoupled) a starting bitrate.
- This models the main saving of coupled channels over uncoupled. */
- stream_offset = (bitrate - channel_offset*nb_normal - lfe_offset*nb_lfe)/nb_normal/2;
- stream_offset = IMAX(0, IMIN(20000, stream_offset));
-
- /* Coupled streams get twice the mono rate after the offset is allocated. */
- coupled_ratio = 512;
- /* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of mono */
- lfe_ratio = 32;
-
- total = (nb_uncoupled<<8) /* mono */
- + coupled_ratio*nb_coupled /* stereo */
- + nb_lfe*lfe_ratio;
- channel_rate = 256*(opus_int64)(bitrate - lfe_offset*nb_lfe - stream_offset*(nb_coupled+nb_uncoupled) - channel_offset*nb_normal)/total;
+#ifndef FIXED_POINT
+ if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
+ {
+ opus_int32 bonus;
+ bonus = 60*(Fs/frame_size-50);
+ channel_rate += bonus;
+ }
+#endif
for (i=0;i<st->layout.nb_streams;i++)
{
if (i<st->layout.nb_coupled_streams)
- rate[i] = 2*channel_offset + IMAX(0, stream_offset+(channel_rate*coupled_ratio>>8));
+ rate[i] = stream_offset+(channel_rate*coupled_ratio>>8);
else if (i!=st->lfe_stream)
- rate[i] = channel_offset + IMAX(0, stream_offset + channel_rate);
+ rate[i] = stream_offset+channel_rate;
else
- rate[i] = IMAX(0, lfe_offset+(channel_rate*lfe_ratio>>8));
+ rate[i] = lfe_offset+(channel_rate*lfe_ratio>>8);
}
}
+#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
static void ambisonics_rate_allocation(
OpusMSEncoder *st,
opus_int32 *rate,
@@ -741,31 +736,50 @@ static void ambisonics_rate_allocation(
)
{
int i;
- opus_int32 total_rate;
- opus_int32 per_stream_rate;
+ int non_mono_rate;
+ int total_rate;
- const int nb_channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
+ /* The mono channel gets (rate_ratio_num / rate_ratio_den) times as many bits
+ * as all other channels */
+ const int rate_ratio_num = 4;
+ const int rate_ratio_den = 3;
+ const int num_channels = st->layout.nb_streams;
if (st->bitrate_bps==OPUS_AUTO)
{
- total_rate = (st->layout.nb_coupled_streams + st->layout.nb_streams) *
- (Fs+60*Fs/frame_size) + st->layout.nb_streams * (opus_int32)15000;
+ total_rate = num_channels * (20000 + st->layout.nb_streams*(Fs+60*Fs/frame_size));
} else if (st->bitrate_bps==OPUS_BITRATE_MAX)
{
- total_rate = nb_channels * 320000;
- } else
- {
+ total_rate = num_channels * 320000;
+ } else {
total_rate = st->bitrate_bps;
}
- /* Allocate equal number of bits to Ambisonic (uncoupled) and non-diegetic
- * (coupled) streams */
- per_stream_rate = total_rate / st->layout.nb_streams;
- for (i = 0; i < st->layout.nb_streams; i++)
+ /* Let y be the non-mono rate and let p, q be integers such that the mono
+ * channel rate is (p/q) * y.
+ * Also let T be the total bitrate to allocate. Then
+ * (n - 1) y + (p/q) y = T
+ * y = (T q) / (qn - q + p)
+ */
+ non_mono_rate =
+ total_rate * rate_ratio_den
+ / (rate_ratio_den*num_channels + rate_ratio_num - rate_ratio_den);
+
+#ifndef FIXED_POINT
+ if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
{
- rate[i] = per_stream_rate;
+ opus_int32 bonus = 60*(Fs/frame_size-50);
+ non_mono_rate += bonus;
+ }
+#endif
+
+ rate[0] = total_rate - (num_channels - 1) * non_mono_rate;
+ for (i=1;i<st->layout.nb_streams;i++)
+ {
+ rate[i] = non_mono_rate;
}
}
+#endif /* ENABLE_EXPERIMENTAL_AMBISONICS */
static opus_int32 rate_allocation(
OpusMSEncoder *st,
@@ -781,9 +795,11 @@ static opus_int32 rate_allocation(
ptr = (char*)st + align(sizeof(OpusMSEncoder));
opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
+#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
if (st->mapping_type == MAPPING_TYPE_AMBISONICS) {
ambisonics_rate_allocation(st, rate, frame_size, Fs);
} else
+#endif
{
surround_rate_allocation(st, rate, frame_size, Fs);
}
@@ -796,9 +812,9 @@ static opus_int32 rate_allocation(
return rate_sum;
}
-/* Max size in case the encoder decides to return six frames (6 x 20 ms = 120 ms) */
-#define MS_FRAME_TMP (6*1275+12)
-int opus_multistream_encode_native
+/* Max size in case the encoder decides to return three frames */
+#define MS_FRAME_TMP (3*1275+7)
+static int opus_multistream_encode_native
(
OpusMSEncoder *st,
opus_copy_channel_in_func copy_channel_in,
@@ -808,8 +824,7 @@ int opus_multistream_encode_native
opus_int32 max_data_bytes,
int lsb_depth,
downmix_func downmix,
- int float_api,
- void *user_data
+ int float_api
)
{
opus_int32 Fs;
@@ -844,8 +859,32 @@ int opus_multistream_encode_native
opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr));
opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
- frame_size = frame_size_select(analysis_frame_size, st->variable_duration, Fs);
- if (frame_size <= 0)
+ {
+ opus_int32 delay_compensation;
+ int channels;
+
+ channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
+ opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation));
+ delay_compensation -= Fs/400;
+ frame_size = compute_frame_size(pcm, analysis_frame_size,
+ st->variable_duration, channels, Fs, st->bitrate_bps,
+ delay_compensation, downmix
+#ifndef DISABLE_FLOAT_API
+ , st->subframe_mem
+#endif
+ );
+ }
+
+ if (400*frame_size < Fs)
+ {
+ RESTORE_STACK;
+ return OPUS_BAD_ARG;
+ }
+ /* Validate frame_size before using it to allocate stack space.
+ This mirrors the checks in opus_encode[_float](). */
+ if (400*frame_size != Fs && 200*frame_size != Fs &&
+ 100*frame_size != Fs && 50*frame_size != Fs &&
+ 25*frame_size != Fs && 50*frame_size != 3*Fs)
{
RESTORE_STACK;
return OPUS_BAD_ARG;
@@ -853,9 +892,6 @@ int opus_multistream_encode_native
/* Smallest packet the encoder can produce. */
smallest_packet = st->layout.nb_streams*2-1;
- /* 100 ms needs an extra byte per stream for the ToC. */
- if (Fs/frame_size == 10)
- smallest_packet += st->layout.nb_streams;
if (max_data_bytes < smallest_packet)
{
RESTORE_STACK;
@@ -916,9 +952,11 @@ int opus_multistream_encode_native
opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
}
}
+#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
else if (st->mapping_type == MAPPING_TYPE_AMBISONICS) {
opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
}
+#endif
}
ptr = (char*)st + align(sizeof(OpusMSEncoder));
@@ -941,9 +979,9 @@ int opus_multistream_encode_native
left = get_left_channel(&st->layout, s, -1);
right = get_right_channel(&st->layout, s, -1);
(*copy_channel_in)(buf, 2,
- pcm, st->layout.nb_channels, left, frame_size, user_data);
+ pcm, st->layout.nb_channels, left, frame_size);
(*copy_channel_in)(buf+1, 2,
- pcm, st->layout.nb_channels, right, frame_size, user_data);
+ pcm, st->layout.nb_channels, right, frame_size);
ptr += align(coupled_size);
if (st->mapping_type == MAPPING_TYPE_SURROUND)
{
@@ -959,7 +997,7 @@ int opus_multistream_encode_native
int i;
int chan = get_mono_channel(&st->layout, s, -1);
(*copy_channel_in)(buf, 1,
- pcm, st->layout.nb_channels, chan, frame_size, user_data);
+ pcm, st->layout.nb_channels, chan, frame_size);
ptr += align(mono_size);
if (st->mapping_type == MAPPING_TYPE_SURROUND)
{
@@ -975,9 +1013,6 @@ int opus_multistream_encode_native
curr_max = max_data_bytes - tot_size;
/* Reserve one byte for the last stream and two for the others */
curr_max -= IMAX(0,2*(st->layout.nb_streams-s-1)-1);
- /* For 100 ms, reserve an extra byte per stream for the ToC */
- if (Fs/frame_size == 10)
- curr_max -= st->layout.nb_streams-s-1;
curr_max = IMIN(curr_max,MS_FRAME_TMP);
/* Repacketizer will add one or two bytes for self-delimited frames */
if (s != st->layout.nb_streams-1) curr_max -= curr_max>253 ? 2 : 1;
@@ -1018,13 +1053,11 @@ static void opus_copy_channel_in_float(
const void *src,
int src_stride,
int src_channel,
- int frame_size,
- void *user_data
+ int frame_size
)
{
const float *float_src;
opus_int32 i;
- (void)user_data;
float_src = (const float *)src;
for (i=0;i<frame_size;i++)
#if defined(FIXED_POINT)
@@ -1041,13 +1074,11 @@ static void opus_copy_channel_in_short(
const void *src,
int src_stride,
int src_channel,
- int frame_size,
- void *user_data
+ int frame_size
)
{
const opus_int16 *short_src;
opus_int32 i;
- (void)user_data;
short_src = (const opus_int16 *)src;
for (i=0;i<frame_size;i++)
#if defined(FIXED_POINT)
@@ -1068,7 +1099,7 @@ int opus_multistream_encode(
)
{
return opus_multistream_encode_native(st, opus_copy_channel_in_short,
- pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0, NULL);
+ pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0);
}
#ifndef DISABLE_FLOAT_API
@@ -1081,7 +1112,7 @@ int opus_multistream_encode_float(
)
{
return opus_multistream_encode_native(st, opus_copy_channel_in_float,
- pcm, frame_size, data, max_data_bytes, 16, downmix_float, 1, NULL);
+ pcm, frame_size, data, max_data_bytes, 16, downmix_float, 1);
}
#endif
@@ -1097,7 +1128,7 @@ int opus_multistream_encode_float
)
{
return opus_multistream_encode_native(st, opus_copy_channel_in_float,
- pcm, frame_size, data, max_data_bytes, 24, downmix_float, 1, NULL);
+ pcm, frame_size, data, max_data_bytes, 24, downmix_float, 1);
}
int opus_multistream_encode(
@@ -1109,17 +1140,19 @@ int opus_multistream_encode(
)
{
return opus_multistream_encode_native(st, opus_copy_channel_in_short,
- pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0, NULL);
+ pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0);
}
#endif
-int opus_multistream_encoder_ctl_va_list(OpusMSEncoder *st, int request,
- va_list ap)
+int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
{
+ va_list ap;
int coupled_size, mono_size;
char *ptr;
int ret = OPUS_OK;
+ va_start(ap, request);
+
coupled_size = opus_encoder_get_size(2);
mono_size = opus_encoder_get_size(1);
ptr = (char*)st + align(sizeof(OpusMSEncoder));
@@ -1128,11 +1161,9 @@ int opus_multistream_encoder_ctl_va_list(OpusMSEncoder *st, int request,
case OPUS_SET_BITRATE_REQUEST:
{
opus_int32 value = va_arg(ap, opus_int32);
- if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX)
+ if (value<0 && value!=OPUS_AUTO && value!=OPUS_BITRATE_MAX)
{
- if (value <= 0)
- goto bad_arg;
- value = IMIN(300000*st->layout.nb_channels, IMAX(500*st->layout.nb_channels, value));
+ goto bad_arg;
}
st->bitrate_bps = value;
}
@@ -1175,7 +1206,6 @@ int opus_multistream_encoder_ctl_va_list(OpusMSEncoder *st, int request,
case OPUS_GET_INBAND_FEC_REQUEST:
case OPUS_GET_FORCE_CHANNELS_REQUEST:
case OPUS_GET_PREDICTION_DISABLED_REQUEST:
- case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
{
OpusEncoder *enc;
/* For int32* GET params, just query the first stream */
@@ -1222,7 +1252,6 @@ int opus_multistream_encoder_ctl_va_list(OpusMSEncoder *st, int request,
case OPUS_SET_FORCE_MODE_REQUEST:
case OPUS_SET_FORCE_CHANNELS_REQUEST:
case OPUS_SET_PREDICTION_DISABLED_REQUEST:
- case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
{
int s;
/* This works for int32 params */
@@ -1249,7 +1278,7 @@ int opus_multistream_encoder_ctl_va_list(OpusMSEncoder *st, int request,
OpusEncoder **value;
stream_id = va_arg(ap, opus_int32);
if (stream_id<0 || stream_id >= st->layout.nb_streams)
- goto bad_arg;
+ ret = OPUS_BAD_ARG;
value = va_arg(ap, OpusEncoder**);
if (!value)
{
@@ -1284,6 +1313,7 @@ int opus_multistream_encoder_ctl_va_list(OpusMSEncoder *st, int request,
case OPUS_RESET_STATE:
{
int s;
+ st->subframe_mem[0] = st->subframe_mem[1] = st->subframe_mem[2] = 0;
if (st->mapping_type == MAPPING_TYPE_SURROUND)
{
OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels);
@@ -1307,19 +1337,12 @@ int opus_multistream_encoder_ctl_va_list(OpusMSEncoder *st, int request,
ret = OPUS_UNIMPLEMENTED;
break;
}
- return ret;
-bad_arg:
- return OPUS_BAD_ARG;
-}
-int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
-{
- int ret;
- va_list ap;
- va_start(ap, request);
- ret = opus_multistream_encoder_ctl_va_list(st, request, ap);
va_end(ap);
return ret;
+bad_arg:
+ va_end(ap);
+ return OPUS_BAD_ARG;
}
void opus_multistream_encoder_destroy(OpusMSEncoder *st)
diff --git a/thirdparty/opus/opus_private.h b/thirdparty/opus/opus_private.h
index 5e2463f546..3b62eed096 100644
--- a/thirdparty/opus/opus_private.h
+++ b/thirdparty/opus/opus_private.h
@@ -33,7 +33,6 @@
#include "opus.h"
#include "celt.h"
-#include <stdarg.h> /* va_list */
#include <stddef.h> /* offsetof */
struct OpusRepacketizer {
@@ -51,59 +50,12 @@ typedef struct ChannelLayout {
unsigned char mapping[256];
} ChannelLayout;
-typedef enum {
- MAPPING_TYPE_NONE,
- MAPPING_TYPE_SURROUND,
- MAPPING_TYPE_AMBISONICS
-} MappingType;
-
-struct OpusMSEncoder {
- ChannelLayout layout;
- int arch;
- int lfe_stream;
- int application;
- int variable_duration;
- MappingType mapping_type;
- opus_int32 bitrate_bps;
- /* Encoder states go here */
- /* then opus_val32 window_mem[channels*120]; */
- /* then opus_val32 preemph_mem[channels]; */
-};
-
-struct OpusMSDecoder {
- ChannelLayout layout;
- /* Decoder states go here */
-};
-
-int opus_multistream_encoder_ctl_va_list(struct OpusMSEncoder *st, int request,
- va_list ap);
-int opus_multistream_decoder_ctl_va_list(struct OpusMSDecoder *st, int request,
- va_list ap);
-
int validate_layout(const ChannelLayout *layout);
int get_left_channel(const ChannelLayout *layout, int stream_id, int prev);
int get_right_channel(const ChannelLayout *layout, int stream_id, int prev);
int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev);
-typedef void (*opus_copy_channel_in_func)(
- opus_val16 *dst,
- int dst_stride,
- const void *src,
- int src_stride,
- int src_channel,
- int frame_size,
- void *user_data
-);
-
-typedef void (*opus_copy_channel_out_func)(
- void *dst,
- int dst_stride,
- int dst_channel,
- const opus_val16 *src,
- int src_stride,
- int frame_size,
- void *user_data
-);
+
#define MODE_SILK_ONLY 1000
#define MODE_HYBRID 1001
@@ -135,12 +87,19 @@ typedef void (*opus_copy_channel_out_func)(
typedef void (*downmix_func)(const void *, opus_val32 *, int, int, int, int, int);
void downmix_float(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C);
void downmix_int(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C);
-int is_digital_silence(const opus_val16* pcm, int frame_size, int channels, int lsb_depth);
int encode_size(int size, unsigned char *data);
opus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs);
+opus_int32 compute_frame_size(const void *analysis_pcm, int frame_size,
+ int variable_duration, int C, opus_int32 Fs, int bitrate_bps,
+ int delay_compensation, downmix_func downmix
+#ifndef DISABLE_FLOAT_API
+ , float *subframe_mem
+#endif
+ );
+
opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
unsigned char *data, opus_int32 out_data_bytes, int lsb_depth,
const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2,
@@ -172,30 +131,4 @@ opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int
int pad_frame(unsigned char *data, opus_int32 len, opus_int32 new_len);
-int opus_multistream_encode_native
-(
- struct OpusMSEncoder *st,
- opus_copy_channel_in_func copy_channel_in,
- const void *pcm,
- int analysis_frame_size,
- unsigned char *data,
- opus_int32 max_data_bytes,
- int lsb_depth,
- downmix_func downmix,
- int float_api,
- void *user_data
-);
-
-int opus_multistream_decode_native(
- struct OpusMSDecoder *st,
- const unsigned char *data,
- opus_int32 len,
- void *pcm,
- opus_copy_channel_out_func copy_channel_out,
- int frame_size,
- int decode_fec,
- int soft_clip,
- void *user_data
-);
-
#endif /* OPUS_PRIVATE_H */
diff --git a/thirdparty/opus/opus_projection_decoder.c b/thirdparty/opus/opus_projection_decoder.c
deleted file mode 100644
index c2e07d5bcf..0000000000
--- a/thirdparty/opus/opus_projection_decoder.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/* Copyright (c) 2017 Google Inc.
- Written by Andrew Allen */
-/*
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "mathops.h"
-#include "os_support.h"
-#include "opus_private.h"
-#include "opus_defines.h"
-#include "opus_projection.h"
-#include "opus_multistream.h"
-#include "mapping_matrix.h"
-#include "stack_alloc.h"
-
-struct OpusProjectionDecoder
-{
- opus_int32 demixing_matrix_size_in_bytes;
- /* Encoder states go here */
-};
-
-#if !defined(DISABLE_FLOAT_API)
-static void opus_projection_copy_channel_out_float(
- void *dst,
- int dst_stride,
- int dst_channel,
- const opus_val16 *src,
- int src_stride,
- int frame_size,
- void *user_data)
-{
- float *float_dst;
- const MappingMatrix *matrix;
- float_dst = (float *)dst;
- matrix = (const MappingMatrix *)user_data;
-
- if (dst_channel == 0)
- OPUS_CLEAR(float_dst, frame_size * dst_stride);
-
- if (src != NULL)
- mapping_matrix_multiply_channel_out_float(matrix, src, dst_channel,
- src_stride, float_dst, dst_stride, frame_size);
-}
-#endif
-
-static void opus_projection_copy_channel_out_short(
- void *dst,
- int dst_stride,
- int dst_channel,
- const opus_val16 *src,
- int src_stride,
- int frame_size,
- void *user_data)
-{
- opus_int16 *short_dst;
- const MappingMatrix *matrix;
- short_dst = (opus_int16 *)dst;
- matrix = (const MappingMatrix *)user_data;
- if (dst_channel == 0)
- OPUS_CLEAR(short_dst, frame_size * dst_stride);
-
- if (src != NULL)
- mapping_matrix_multiply_channel_out_short(matrix, src, dst_channel,
- src_stride, short_dst, dst_stride, frame_size);
-}
-
-static MappingMatrix *get_dec_demixing_matrix(OpusProjectionDecoder *st)
-{
- /* void* cast avoids clang -Wcast-align warning */
- return (MappingMatrix*)(void*)((char*)st +
- align(sizeof(OpusProjectionDecoder)));
-}
-
-static OpusMSDecoder *get_multistream_decoder(OpusProjectionDecoder *st)
-{
- /* void* cast avoids clang -Wcast-align warning */
- return (OpusMSDecoder*)(void*)((char*)st +
- align(sizeof(OpusProjectionDecoder) +
- st->demixing_matrix_size_in_bytes));
-}
-
-opus_int32 opus_projection_decoder_get_size(int channels, int streams,
- int coupled_streams)
-{
- opus_int32 matrix_size;
- opus_int32 decoder_size;
-
- matrix_size =
- mapping_matrix_get_size(streams + coupled_streams, channels);
- if (!matrix_size)
- return 0;
-
- decoder_size = opus_multistream_decoder_get_size(streams, coupled_streams);
- if (!decoder_size)
- return 0;
-
- return align(sizeof(OpusProjectionDecoder)) + matrix_size + decoder_size;
-}
-
-int opus_projection_decoder_init(OpusProjectionDecoder *st, opus_int32 Fs,
- int channels, int streams, int coupled_streams,
- unsigned char *demixing_matrix, opus_int32 demixing_matrix_size)
-{
- int nb_input_streams;
- opus_int32 expected_matrix_size;
- int i, ret;
- unsigned char mapping[255];
- VARDECL(opus_int16, buf);
- ALLOC_STACK;
-
- /* Verify supplied matrix size. */
- nb_input_streams = streams + coupled_streams;
- expected_matrix_size = nb_input_streams * channels * sizeof(opus_int16);
- if (expected_matrix_size != demixing_matrix_size)
- {
- RESTORE_STACK;
- return OPUS_BAD_ARG;
- }
-
- /* Convert demixing matrix input into internal format. */
- ALLOC(buf, nb_input_streams * channels, opus_int16);
- for (i = 0; i < nb_input_streams * channels; i++)
- {
- int s = demixing_matrix[2*i + 1] << 8 | demixing_matrix[2*i];
- s = ((s & 0xFFFF) ^ 0x8000) - 0x8000;
- buf[i] = (opus_int16)s;
- }
-
- /* Assign demixing matrix. */
- st->demixing_matrix_size_in_bytes =
- mapping_matrix_get_size(channels, nb_input_streams);
- if (!st->demixing_matrix_size_in_bytes)
- {
- RESTORE_STACK;
- return OPUS_BAD_ARG;
- }
-
- mapping_matrix_init(get_dec_demixing_matrix(st), channels, nb_input_streams, 0,
- buf, demixing_matrix_size);
-
- /* Set trivial mapping so each input channel pairs with a matrix column. */
- for (i = 0; i < channels; i++)
- mapping[i] = i;
-
- ret = opus_multistream_decoder_init(
- get_multistream_decoder(st), Fs, channels, streams, coupled_streams, mapping);
- RESTORE_STACK;
- return ret;
-}
-
-OpusProjectionDecoder *opus_projection_decoder_create(
- opus_int32 Fs, int channels, int streams, int coupled_streams,
- unsigned char *demixing_matrix, opus_int32 demixing_matrix_size, int *error)
-{
- int size;
- int ret;
- OpusProjectionDecoder *st;
-
- /* Allocate space for the projection decoder. */
- size = opus_projection_decoder_get_size(channels, streams, coupled_streams);
- if (!size) {
- if (error)
- *error = OPUS_ALLOC_FAIL;
- return NULL;
- }
- st = (OpusProjectionDecoder *)opus_alloc(size);
- if (!st)
- {
- if (error)
- *error = OPUS_ALLOC_FAIL;
- return NULL;
- }
-
- /* Initialize projection decoder with provided settings. */
- ret = opus_projection_decoder_init(st, Fs, channels, streams, coupled_streams,
- demixing_matrix, demixing_matrix_size);
- if (ret != OPUS_OK)
- {
- opus_free(st);
- st = NULL;
- }
- if (error)
- *error = ret;
- return st;
-}
-
-#ifdef FIXED_POINT
-int opus_projection_decode(OpusProjectionDecoder *st, const unsigned char *data,
- opus_int32 len, opus_int16 *pcm, int frame_size,
- int decode_fec)
-{
- return opus_multistream_decode_native(get_multistream_decoder(st), data, len,
- pcm, opus_projection_copy_channel_out_short, frame_size, decode_fec, 0,
- get_dec_demixing_matrix(st));
-}
-#else
-int opus_projection_decode(OpusProjectionDecoder *st, const unsigned char *data,
- opus_int32 len, opus_int16 *pcm, int frame_size,
- int decode_fec)
-{
- return opus_multistream_decode_native(get_multistream_decoder(st), data, len,
- pcm, opus_projection_copy_channel_out_short, frame_size, decode_fec, 1,
- get_dec_demixing_matrix(st));
-}
-#endif
-
-#ifndef DISABLE_FLOAT_API
-int opus_projection_decode_float(OpusProjectionDecoder *st, const unsigned char *data,
- opus_int32 len, float *pcm, int frame_size, int decode_fec)
-{
- return opus_multistream_decode_native(get_multistream_decoder(st), data, len,
- pcm, opus_projection_copy_channel_out_float, frame_size, decode_fec, 0,
- get_dec_demixing_matrix(st));
-}
-#endif
-
-int opus_projection_decoder_ctl(OpusProjectionDecoder *st, int request, ...)
-{
- va_list ap;
- int ret = OPUS_OK;
-
- va_start(ap, request);
- ret = opus_multistream_decoder_ctl_va_list(get_multistream_decoder(st),
- request, ap);
- va_end(ap);
- return ret;
-}
-
-void opus_projection_decoder_destroy(OpusProjectionDecoder *st)
-{
- opus_free(st);
-}
-
diff --git a/thirdparty/opus/opus_projection_encoder.c b/thirdparty/opus/opus_projection_encoder.c
deleted file mode 100644
index 06fb2d2526..0000000000
--- a/thirdparty/opus/opus_projection_encoder.c
+++ /dev/null
@@ -1,468 +0,0 @@
-/* Copyright (c) 2017 Google Inc.
- Written by Andrew Allen */
-/*
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "mathops.h"
-#include "os_support.h"
-#include "opus_private.h"
-#include "opus_defines.h"
-#include "opus_projection.h"
-#include "opus_multistream.h"
-#include "stack_alloc.h"
-#include "mapping_matrix.h"
-
-struct OpusProjectionEncoder
-{
- opus_int32 mixing_matrix_size_in_bytes;
- opus_int32 demixing_matrix_size_in_bytes;
- /* Encoder states go here */
-};
-
-#if !defined(DISABLE_FLOAT_API)
-static void opus_projection_copy_channel_in_float(
- opus_val16 *dst,
- int dst_stride,
- const void *src,
- int src_stride,
- int src_channel,
- int frame_size,
- void *user_data
-)
-{
- mapping_matrix_multiply_channel_in_float((const MappingMatrix*)user_data,
- (const float*)src, src_stride, dst, src_channel, dst_stride, frame_size);
-}
-#endif
-
-static void opus_projection_copy_channel_in_short(
- opus_val16 *dst,
- int dst_stride,
- const void *src,
- int src_stride,
- int src_channel,
- int frame_size,
- void *user_data
-)
-{
- mapping_matrix_multiply_channel_in_short((const MappingMatrix*)user_data,
- (const opus_int16*)src, src_stride, dst, src_channel, dst_stride, frame_size);
-}
-
-static int get_order_plus_one_from_channels(int channels, int *order_plus_one)
-{
- int order_plus_one_;
- int acn_channels;
- int nondiegetic_channels;
-
- /* Allowed numbers of channels:
- * (1 + n)^2 + 2j, for n = 0...14 and j = 0 or 1.
- */
- if (channels < 1 || channels > 227)
- return OPUS_BAD_ARG;
-
- order_plus_one_ = isqrt32(channels);
- acn_channels = order_plus_one_ * order_plus_one_;
- nondiegetic_channels = channels - acn_channels;
- if (nondiegetic_channels != 0 && nondiegetic_channels != 2)
- return OPUS_BAD_ARG;
-
- if (order_plus_one)
- *order_plus_one = order_plus_one_;
- return OPUS_OK;
-}
-
-static int get_streams_from_channels(int channels, int mapping_family,
- int *streams, int *coupled_streams,
- int *order_plus_one)
-{
- if (mapping_family == 3)
- {
- if (get_order_plus_one_from_channels(channels, order_plus_one) != OPUS_OK)
- return OPUS_BAD_ARG;
- if (streams)
- *streams = (channels + 1) / 2;
- if (coupled_streams)
- *coupled_streams = channels / 2;
- return OPUS_OK;
- }
- return OPUS_BAD_ARG;
-}
-
-static MappingMatrix *get_mixing_matrix(OpusProjectionEncoder *st)
-{
- /* void* cast avoids clang -Wcast-align warning */
- return (MappingMatrix *)(void*)((char*)st +
- align(sizeof(OpusProjectionEncoder)));
-}
-
-static MappingMatrix *get_enc_demixing_matrix(OpusProjectionEncoder *st)
-{
- /* void* cast avoids clang -Wcast-align warning */
- return (MappingMatrix *)(void*)((char*)st +
- align(sizeof(OpusProjectionEncoder) +
- st->mixing_matrix_size_in_bytes));
-}
-
-static OpusMSEncoder *get_multistream_encoder(OpusProjectionEncoder *st)
-{
- /* void* cast avoids clang -Wcast-align warning */
- return (OpusMSEncoder *)(void*)((char*)st +
- align(sizeof(OpusProjectionEncoder) +
- st->mixing_matrix_size_in_bytes +
- st->demixing_matrix_size_in_bytes));
-}
-
-opus_int32 opus_projection_ambisonics_encoder_get_size(int channels,
- int mapping_family)
-{
- int nb_streams;
- int nb_coupled_streams;
- int order_plus_one;
- int mixing_matrix_rows, mixing_matrix_cols;
- int demixing_matrix_rows, demixing_matrix_cols;
- opus_int32 mixing_matrix_size, demixing_matrix_size;
- opus_int32 encoder_size;
- int ret;
-
- ret = get_streams_from_channels(channels, mapping_family, &nb_streams,
- &nb_coupled_streams, &order_plus_one);
- if (ret != OPUS_OK)
- return 0;
-
- if (order_plus_one == 2)
- {
- mixing_matrix_rows = mapping_matrix_foa_mixing.rows;
- mixing_matrix_cols = mapping_matrix_foa_mixing.cols;
- demixing_matrix_rows = mapping_matrix_foa_demixing.rows;
- demixing_matrix_cols = mapping_matrix_foa_demixing.cols;
- }
- else if (order_plus_one == 3)
- {
- mixing_matrix_rows = mapping_matrix_soa_mixing.rows;
- mixing_matrix_cols = mapping_matrix_soa_mixing.cols;
- demixing_matrix_rows = mapping_matrix_soa_demixing.rows;
- demixing_matrix_cols = mapping_matrix_soa_demixing.cols;
- }
- else if (order_plus_one == 4)
- {
- mixing_matrix_rows = mapping_matrix_toa_mixing.rows;
- mixing_matrix_cols = mapping_matrix_toa_mixing.cols;
- demixing_matrix_rows = mapping_matrix_toa_demixing.rows;
- demixing_matrix_cols = mapping_matrix_toa_demixing.cols;
- }
- else
- return 0;
-
- mixing_matrix_size =
- mapping_matrix_get_size(mixing_matrix_rows, mixing_matrix_cols);
- if (!mixing_matrix_size)
- return 0;
-
- demixing_matrix_size =
- mapping_matrix_get_size(demixing_matrix_rows, demixing_matrix_cols);
- if (!demixing_matrix_size)
- return 0;
-
- encoder_size =
- opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
- if (!encoder_size)
- return 0;
-
- return align(sizeof(OpusProjectionEncoder)) +
- mixing_matrix_size + demixing_matrix_size + encoder_size;
-}
-
-int opus_projection_ambisonics_encoder_init(OpusProjectionEncoder *st, opus_int32 Fs,
- int channels, int mapping_family,
- int *streams, int *coupled_streams,
- int application)
-{
- MappingMatrix *mixing_matrix;
- MappingMatrix *demixing_matrix;
- OpusMSEncoder *ms_encoder;
- int i;
- int ret;
- int order_plus_one;
- unsigned char mapping[255];
-
- if (streams == NULL || coupled_streams == NULL) {
- return OPUS_BAD_ARG;
- }
-
- if (get_streams_from_channels(channels, mapping_family, streams,
- coupled_streams, &order_plus_one) != OPUS_OK)
- return OPUS_BAD_ARG;
-
- if (mapping_family == 3)
- {
- /* Assign mixing matrix based on available pre-computed matrices. */
- mixing_matrix = get_mixing_matrix(st);
- if (order_plus_one == 2)
- {
- mapping_matrix_init(mixing_matrix, mapping_matrix_foa_mixing.rows,
- mapping_matrix_foa_mixing.cols, mapping_matrix_foa_mixing.gain,
- mapping_matrix_foa_mixing_data,
- sizeof(mapping_matrix_foa_mixing_data));
- }
- else if (order_plus_one == 3)
- {
- mapping_matrix_init(mixing_matrix, mapping_matrix_soa_mixing.rows,
- mapping_matrix_soa_mixing.cols, mapping_matrix_soa_mixing.gain,
- mapping_matrix_soa_mixing_data,
- sizeof(mapping_matrix_soa_mixing_data));
- }
- else if (order_plus_one == 4)
- {
- mapping_matrix_init(mixing_matrix, mapping_matrix_toa_mixing.rows,
- mapping_matrix_toa_mixing.cols, mapping_matrix_toa_mixing.gain,
- mapping_matrix_toa_mixing_data,
- sizeof(mapping_matrix_toa_mixing_data));
- }
- else
- return OPUS_BAD_ARG;
-
- st->mixing_matrix_size_in_bytes = mapping_matrix_get_size(
- mixing_matrix->rows, mixing_matrix->cols);
- if (!st->mixing_matrix_size_in_bytes)
- return OPUS_BAD_ARG;
-
- /* Assign demixing matrix based on available pre-computed matrices. */
- demixing_matrix = get_enc_demixing_matrix(st);
- if (order_plus_one == 2)
- {
- mapping_matrix_init(demixing_matrix, mapping_matrix_foa_demixing.rows,
- mapping_matrix_foa_demixing.cols, mapping_matrix_foa_demixing.gain,
- mapping_matrix_foa_demixing_data,
- sizeof(mapping_matrix_foa_demixing_data));
- }
- else if (order_plus_one == 3)
- {
- mapping_matrix_init(demixing_matrix, mapping_matrix_soa_demixing.rows,
- mapping_matrix_soa_demixing.cols, mapping_matrix_soa_demixing.gain,
- mapping_matrix_soa_demixing_data,
- sizeof(mapping_matrix_soa_demixing_data));
- }
- else if (order_plus_one == 4)
- {
- mapping_matrix_init(demixing_matrix, mapping_matrix_toa_demixing.rows,
- mapping_matrix_toa_demixing.cols, mapping_matrix_toa_demixing.gain,
- mapping_matrix_toa_demixing_data,
- sizeof(mapping_matrix_toa_demixing_data));
- }
- else
- return OPUS_BAD_ARG;
-
- st->demixing_matrix_size_in_bytes = mapping_matrix_get_size(
- demixing_matrix->rows, demixing_matrix->cols);
- if (!st->demixing_matrix_size_in_bytes)
- return OPUS_BAD_ARG;
- }
- else
- return OPUS_UNIMPLEMENTED;
-
- /* Ensure matrices are large enough for desired coding scheme. */
- if (*streams + *coupled_streams > mixing_matrix->rows ||
- channels > mixing_matrix->cols ||
- channels > demixing_matrix->rows ||
- *streams + *coupled_streams > demixing_matrix->cols)
- return OPUS_BAD_ARG;
-
- /* Set trivial mapping so each input channel pairs with a matrix column. */
- for (i = 0; i < channels; i++)
- mapping[i] = i;
-
- /* Initialize multistream encoder with provided settings. */
- ms_encoder = get_multistream_encoder(st);
- ret = opus_multistream_encoder_init(ms_encoder, Fs, channels, *streams,
- *coupled_streams, mapping, application);
- return ret;
-}
-
-OpusProjectionEncoder *opus_projection_ambisonics_encoder_create(
- opus_int32 Fs, int channels, int mapping_family, int *streams,
- int *coupled_streams, int application, int *error)
-{
- int size;
- int ret;
- OpusProjectionEncoder *st;
-
- /* Allocate space for the projection encoder. */
- size = opus_projection_ambisonics_encoder_get_size(channels, mapping_family);
- if (!size) {
- if (error)
- *error = OPUS_ALLOC_FAIL;
- return NULL;
- }
- st = (OpusProjectionEncoder *)opus_alloc(size);
- if (!st)
- {
- if (error)
- *error = OPUS_ALLOC_FAIL;
- return NULL;
- }
-
- /* Initialize projection encoder with provided settings. */
- ret = opus_projection_ambisonics_encoder_init(st, Fs, channels,
- mapping_family, streams, coupled_streams, application);
- if (ret != OPUS_OK)
- {
- opus_free(st);
- st = NULL;
- }
- if (error)
- *error = ret;
- return st;
-}
-
-int opus_projection_encode(OpusProjectionEncoder *st, const opus_int16 *pcm,
- int frame_size, unsigned char *data,
- opus_int32 max_data_bytes)
-{
- return opus_multistream_encode_native(get_multistream_encoder(st),
- opus_projection_copy_channel_in_short, pcm, frame_size, data,
- max_data_bytes, 16, downmix_int, 0, get_mixing_matrix(st));
-}
-
-#ifndef DISABLE_FLOAT_API
-#ifdef FIXED_POINT
-int opus_projection_encode_float(OpusProjectionEncoder *st, const float *pcm,
- int frame_size, unsigned char *data,
- opus_int32 max_data_bytes)
-{
- return opus_multistream_encode_native(get_multistream_encoder(st),
- opus_projection_copy_channel_in_float, pcm, frame_size, data,
- max_data_bytes, 16, downmix_float, 1, get_mixing_matrix(st));
-}
-#else
-int opus_projection_encode_float(OpusProjectionEncoder *st, const float *pcm,
- int frame_size, unsigned char *data,
- opus_int32 max_data_bytes)
-{
- return opus_multistream_encode_native(get_multistream_encoder(st),
- opus_projection_copy_channel_in_float, pcm, frame_size, data,
- max_data_bytes, 24, downmix_float, 1, get_mixing_matrix(st));
-}
-#endif
-#endif
-
-void opus_projection_encoder_destroy(OpusProjectionEncoder *st)
-{
- opus_free(st);
-}
-
-int opus_projection_encoder_ctl(OpusProjectionEncoder *st, int request, ...)
-{
- va_list ap;
- MappingMatrix *demixing_matrix;
- OpusMSEncoder *ms_encoder;
- int ret = OPUS_OK;
-
- ms_encoder = get_multistream_encoder(st);
- demixing_matrix = get_enc_demixing_matrix(st);
-
- va_start(ap, request);
- switch(request)
- {
- case OPUS_PROJECTION_GET_DEMIXING_MATRIX_SIZE_REQUEST:
- {
- opus_int32 *value = va_arg(ap, opus_int32*);
- if (!value)
- {
- goto bad_arg;
- }
- *value =
- ms_encoder->layout.nb_channels * (ms_encoder->layout.nb_streams
- + ms_encoder->layout.nb_coupled_streams) * sizeof(opus_int16);
- }
- break;
- case OPUS_PROJECTION_GET_DEMIXING_MATRIX_GAIN_REQUEST:
- {
- opus_int32 *value = va_arg(ap, opus_int32*);
- if (!value)
- {
- goto bad_arg;
- }
- *value = demixing_matrix->gain;
- }
- break;
- case OPUS_PROJECTION_GET_DEMIXING_MATRIX_REQUEST:
- {
- int i, j, k, l;
- int nb_input_streams;
- int nb_output_streams;
- unsigned char *external_char;
- opus_int16 *internal_short;
- opus_int32 external_size;
- opus_int32 internal_size;
-
- /* (I/O is in relation to the decoder's perspective). */
- nb_input_streams = ms_encoder->layout.nb_streams +
- ms_encoder->layout.nb_coupled_streams;
- nb_output_streams = ms_encoder->layout.nb_channels;
-
- external_char = va_arg(ap, unsigned char *);
- external_size = va_arg(ap, opus_int32);
- if (!external_char)
- {
- goto bad_arg;
- }
- internal_short = mapping_matrix_get_data(demixing_matrix);
- internal_size = nb_input_streams * nb_output_streams * sizeof(opus_int16);
- if (external_size != internal_size)
- {
- goto bad_arg;
- }
-
- /* Copy demixing matrix subset to output destination. */
- l = 0;
- for (i = 0; i < nb_input_streams; i++) {
- for (j = 0; j < nb_output_streams; j++) {
- k = demixing_matrix->rows * i + j;
- external_char[2*l] = (unsigned char)internal_short[k];
- external_char[2*l+1] = (unsigned char)(internal_short[k] >> 8);
- l++;
- }
- }
- }
- break;
- default:
- {
- ret = opus_multistream_encoder_ctl_va_list(ms_encoder, request, ap);
- }
- break;
- }
- va_end(ap);
- return ret;
-
-bad_arg:
- va_end(ap);
- return OPUS_BAD_ARG;
-}
-
diff --git a/thirdparty/opus/opusfile.c b/thirdparty/opus/opusfile.c
index 8b000a2c58..b8b3a354cf 100644
--- a/thirdparty/opus/opusfile.c
+++ b/thirdparty/opus/opusfile.c
@@ -86,15 +86,14 @@ int op_test(OpusHead *_head,
This is to prevent us spending a lot of time allocating memory and looking
for Ogg pages in non-Ogg files.*/
if(memcmp(_initial_data,"OggS",4)!=0)return OP_ENOTFORMAT;
- if(OP_UNLIKELY(_initial_bytes>(size_t)LONG_MAX))return OP_EFAULT;
ogg_sync_init(&oy);
- data=ogg_sync_buffer(&oy,(long)_initial_bytes);
+ data=ogg_sync_buffer(&oy,_initial_bytes);
if(data!=NULL){
ogg_stream_state os;
ogg_page og;
int ret;
memcpy(data,_initial_data,_initial_bytes);
- ogg_sync_wrote(&oy,(long)_initial_bytes);
+ ogg_sync_wrote(&oy,_initial_bytes);
ogg_stream_init(&os,-1);
err=OP_FALSE;
do{
@@ -148,7 +147,7 @@ static int op_get_data(OggOpusFile *_of,int _nbytes){
int nbytes;
OP_ASSERT(_nbytes>0);
buffer=(unsigned char *)ogg_sync_buffer(&_of->oy,_nbytes);
- nbytes=(int)(*_of->callbacks.read)(_of->stream,buffer,_nbytes);
+ nbytes=(int)(*_of->callbacks.read)(_of->source,buffer,_nbytes);
OP_ASSERT(nbytes<=_nbytes);
if(OP_LIKELY(nbytes>0))ogg_sync_wrote(&_of->oy,nbytes);
return nbytes;
@@ -158,7 +157,7 @@ static int op_get_data(OggOpusFile *_of,int _nbytes){
static int op_seek_helper(OggOpusFile *_of,opus_int64 _offset){
if(_offset==_of->offset)return 0;
if(_of->callbacks.seek==NULL
- ||(*_of->callbacks.seek)(_of->stream,_offset,SEEK_SET)){
+ ||(*_of->callbacks.seek)(_of->source,_offset,SEEK_SET)){
return OP_EREAD;
}
_of->offset=_offset;
@@ -166,7 +165,7 @@ static int op_seek_helper(OggOpusFile *_of,opus_int64 _offset){
return 0;
}
-/*Get the current position indicator of the underlying stream.
+/*Get the current position indicator of the underlying source.
This should be the same as the value reported by tell().*/
static opus_int64 op_position(const OggOpusFile *_of){
/*The current position indicator is _not_ simply offset.
@@ -370,7 +369,7 @@ static int op_get_prev_page_serial(OggOpusFile *_of,OpusSeekRecord *_sr,
search_start=llret+1;
}
/*We started from the beginning of the stream and found nothing.
- This should be impossible unless the contents of the stream changed out
+ This should be impossible unless the contents of the source changed out
from under us after we read from it.*/
if(OP_UNLIKELY(!begin)&&OP_UNLIKELY(_offset<0))return OP_EBADLINK;
/*Bump up the chunk size.
@@ -456,7 +455,7 @@ static opus_int64 op_get_last_page(OggOpusFile *_of,ogg_int64_t *_gp,
}
}
/*We started from at or before the beginning of the link and found nothing.
- This should be impossible unless the contents of the stream changed out
+ This should be impossible unless the contents of the source changed out
from under us after we read from it.*/
if((OP_UNLIKELY(left_link)||OP_UNLIKELY(!begin))&&OP_UNLIKELY(_offset<0)){
return OP_EBADLINK;
@@ -856,7 +855,6 @@ static int op_find_initial_pcm_offset(OggOpusFile *_of,
/*Fail if the pre-skip is non-zero, since it's asking us to skip more
samples than exist.*/
if(_link->head.pre_skip>0)return OP_EBADTIMESTAMP;
- _link->pcm_file_offset=0;
/*Set pcm_end and end_offset so we can skip the call to
op_find_final_pcm_offset().*/
_link->pcm_start=_link->pcm_end=0;
@@ -868,8 +866,7 @@ static int op_find_initial_pcm_offset(OggOpusFile *_of,
if(_link->head.pre_skip>0)return OP_EBADTIMESTAMP;
/*Set pcm_end and end_offset so we can skip the call to
op_find_final_pcm_offset().*/
- _link->pcm_file_offset=0;
- _link->pcm_start=_link->pcm_end=0;
+ _link->pcm_end=_link->pcm_start=0;
_link->end_offset=_link->data_offset;
/*Tell the caller we've got a buffered page for them.*/
return 1;
@@ -954,7 +951,6 @@ static int op_find_initial_pcm_offset(OggOpusFile *_of,
/*Update the packet count after end-trimming.*/
_of->op_count=pi;
_of->cur_discard_count=_link->head.pre_skip;
- _link->pcm_file_offset=0;
_of->prev_packet_gp=_link->pcm_start=pcm_start;
_of->prev_page_offset=page_offset;
return 0;
@@ -1275,7 +1271,6 @@ static int op_bisect_forward_serialno(OggOpusFile *_of,
always starts with a seek.*/
ret=op_find_initial_pcm_offset(_of,links+nlinks,NULL);
if(OP_UNLIKELY(ret<0))return ret;
- links[nlinks].pcm_file_offset=total_duration;
_searched=_of->offset;
/*Mark the current link count so it can be cleaned up on error.*/
_of->nlinks=++nlinks;
@@ -1395,8 +1390,8 @@ static int op_open_seekable2_impl(OggOpusFile *_of){
opus_int64 data_offset;
int ret;
/*We can seek, so set out learning all about this file.*/
- (*_of->callbacks.seek)(_of->stream,0,SEEK_END);
- _of->offset=_of->end=(*_of->callbacks.tell)(_of->stream);
+ (*_of->callbacks.seek)(_of->source,0,SEEK_END);
+ _of->offset=_of->end=(*_of->callbacks.tell)(_of->source);
if(OP_UNLIKELY(_of->end<0))return OP_EREAD;
data_offset=_of->links[0].data_offset;
if(OP_UNLIKELY(_of->end<data_offset))return OP_EBADLINK;
@@ -1441,7 +1436,7 @@ static int op_open_seekable2(OggOpusFile *_of){
prev_page_offset=_of->prev_page_offset;
start_offset=_of->offset;
memcpy(op_start,_of->op,sizeof(*op_start)*start_op_count);
- OP_ASSERT((*_of->callbacks.tell)(_of->stream)==op_position(_of));
+ OP_ASSERT((*_of->callbacks.tell)(_of->source)==op_position(_of));
ogg_sync_init(&_of->oy);
ogg_stream_init(&_of->os,-1);
ret=op_open_seekable2_impl(_of);
@@ -1459,7 +1454,7 @@ static int op_open_seekable2(OggOpusFile *_of){
_of->cur_discard_count=_of->links[0].head.pre_skip;
if(OP_UNLIKELY(ret<0))return ret;
/*And restore the position indicator.*/
- ret=(*_of->callbacks.seek)(_of->stream,op_position(_of),SEEK_SET);
+ ret=(*_of->callbacks.seek)(_of->source,op_position(_of),SEEK_SET);
return OP_UNLIKELY(ret<0)?OP_EREAD:0;
}
@@ -1498,20 +1493,19 @@ static void op_clear(OggOpusFile *_of){
_ogg_free(_of->serialnos);
ogg_stream_clear(&_of->os);
ogg_sync_clear(&_of->oy);
- if(_of->callbacks.close!=NULL)(*_of->callbacks.close)(_of->stream);
+ if(_of->callbacks.close!=NULL)(*_of->callbacks.close)(_of->source);
}
static int op_open1(OggOpusFile *_of,
- void *_stream,const OpusFileCallbacks *_cb,
+ void *_source,const OpusFileCallbacks *_cb,
const unsigned char *_initial_data,size_t _initial_bytes){
ogg_page og;
ogg_page *pog;
int seekable;
int ret;
memset(_of,0,sizeof(*_of));
- if(OP_UNLIKELY(_initial_bytes>(size_t)LONG_MAX))return OP_EFAULT;
_of->end=-1;
- _of->stream=_stream;
+ _of->source=_source;
*&_of->callbacks=*_cb;
/*At a minimum, we need to be able to read data.*/
if(OP_UNLIKELY(_of->callbacks.read==NULL))return OP_EREAD;
@@ -1526,18 +1520,18 @@ static int op_open1(OggOpusFile *_of,
decoding entire files from RAM.*/
if(_initial_bytes>0){
char *buffer;
- buffer=ogg_sync_buffer(&_of->oy,(long)_initial_bytes);
+ buffer=ogg_sync_buffer(&_of->oy,_initial_bytes);
memcpy(buffer,_initial_data,_initial_bytes*sizeof(*buffer));
- ogg_sync_wrote(&_of->oy,(long)_initial_bytes);
+ ogg_sync_wrote(&_of->oy,_initial_bytes);
}
/*Can we seek?
Stevens suggests the seek test is portable.*/
- seekable=_cb->seek!=NULL&&(*_cb->seek)(_stream,0,SEEK_CUR)!=-1;
+ seekable=_cb->seek!=NULL&&(*_cb->seek)(_source,0,SEEK_CUR)!=-1;
/*If seek is implemented, tell must also be implemented.*/
if(seekable){
opus_int64 pos;
if(OP_UNLIKELY(_of->callbacks.tell==NULL))return OP_EINVAL;
- pos=(*_of->callbacks.tell)(_of->stream);
+ pos=(*_of->callbacks.tell)(_of->source);
/*If the current position is not equal to the initial bytes consumed,
absolute seeking will not work.*/
if(OP_UNLIKELY(pos!=(opus_int64)_initial_bytes))return OP_EINVAL;
@@ -1596,14 +1590,14 @@ static int op_open2(OggOpusFile *_of){
return ret;
}
-OggOpusFile *op_test_callbacks(void *_stream,const OpusFileCallbacks *_cb,
+OggOpusFile *op_test_callbacks(void *_source,const OpusFileCallbacks *_cb,
const unsigned char *_initial_data,size_t _initial_bytes,int *_error){
OggOpusFile *of;
int ret;
of=(OggOpusFile *)_ogg_malloc(sizeof(*of));
ret=OP_EFAULT;
if(OP_LIKELY(of!=NULL)){
- ret=op_open1(of,_stream,_cb,_initial_data,_initial_bytes);
+ ret=op_open1(of,_source,_cb,_initial_data,_initial_bytes);
if(OP_LIKELY(ret>=0)){
if(_error!=NULL)*_error=0;
return of;
@@ -1617,10 +1611,10 @@ OggOpusFile *op_test_callbacks(void *_stream,const OpusFileCallbacks *_cb,
return NULL;
}
-OggOpusFile *op_open_callbacks(void *_stream,const OpusFileCallbacks *_cb,
+OggOpusFile *op_open_callbacks(void *_source,const OpusFileCallbacks *_cb,
const unsigned char *_initial_data,size_t _initial_bytes,int *_error){
OggOpusFile *of;
- of=op_test_callbacks(_stream,_cb,_initial_data,_initial_bytes,_error);
+ of=op_test_callbacks(_source,_cb,_initial_data,_initial_bytes,_error);
if(OP_LIKELY(of!=NULL)){
int ret;
ret=op_open2(of);
@@ -1633,15 +1627,15 @@ OggOpusFile *op_open_callbacks(void *_stream,const OpusFileCallbacks *_cb,
/*Convenience routine to clean up from failure for the open functions that
create their own streams.*/
-static OggOpusFile *op_open_close_on_failure(void *_stream,
+static OggOpusFile *op_open_close_on_failure(void *_source,
const OpusFileCallbacks *_cb,int *_error){
OggOpusFile *of;
- if(OP_UNLIKELY(_stream==NULL)){
+ if(OP_UNLIKELY(_source==NULL)){
if(_error!=NULL)*_error=OP_EFAULT;
return NULL;
}
- of=op_open_callbacks(_stream,_cb,NULL,0,_error);
- if(OP_UNLIKELY(of==NULL))(*_cb->close)(_stream);
+ of=op_open_callbacks(_source,_cb,NULL,0,_error);
+ if(OP_UNLIKELY(of==NULL))(*_cb->close)(_source);
return of;
}
@@ -1659,15 +1653,15 @@ OggOpusFile *op_open_memory(const unsigned char *_data,size_t _size,
/*Convenience routine to clean up from failure for the open functions that
create their own streams.*/
-static OggOpusFile *op_test_close_on_failure(void *_stream,
+static OggOpusFile *op_test_close_on_failure(void *_source,
const OpusFileCallbacks *_cb,int *_error){
OggOpusFile *of;
- if(OP_UNLIKELY(_stream==NULL)){
+ if(OP_UNLIKELY(_source==NULL)){
if(_error!=NULL)*_error=OP_EFAULT;
return NULL;
}
- of=op_test_callbacks(_stream,_cb,NULL,0,_error);
- if(OP_UNLIKELY(of==NULL))(*_cb->close)(_stream);
+ of=op_test_callbacks(_source,_cb,NULL,0,_error);
+ if(OP_UNLIKELY(of==NULL))(*_cb->close)(_source);
return of;
}
@@ -1708,7 +1702,7 @@ int op_link_count(const OggOpusFile *_of){
return _of->nlinks;
}
-opus_uint32 op_serialno(const OggOpusFile *_of,int _li){
+ogg_uint32_t op_serialno(const OggOpusFile *_of,int _li){
if(OP_UNLIKELY(_li>=_of->nlinks))_li=_of->nlinks-1;
if(!_of->seekable)_li=0;
return _of->links[_li<0?_of->cur_link:_li].serialno;
@@ -1724,14 +1718,13 @@ opus_int64 op_raw_total(const OggOpusFile *_of,int _li){
||OP_UNLIKELY(_li>=_of->nlinks)){
return OP_EINVAL;
}
- if(_li<0)return _of->end;
+ if(_li<0)return _of->end-_of->links[0].offset;
return (_li+1>=_of->nlinks?_of->end:_of->links[_li+1].offset)
- -(_li>0?_of->links[_li].offset:0);
+ -_of->links[_li].offset;
}
ogg_int64_t op_pcm_total(const OggOpusFile *_of,int _li){
OggOpusLink *links;
- ogg_int64_t pcm_total;
ogg_int64_t diff;
int nlinks;
nlinks=_of->nlinks;
@@ -1744,14 +1737,20 @@ ogg_int64_t op_pcm_total(const OggOpusFile *_of,int _li){
/*We verify that the granule position differences are larger than the
pre-skip and that the total duration does not overflow during link
enumeration, so we don't have to check here.*/
- pcm_total=0;
if(_li<0){
- pcm_total=links[nlinks-1].pcm_file_offset;
- _li=nlinks-1;
+ ogg_int64_t pcm_total;
+ int li;
+ pcm_total=0;
+ for(li=0;li<nlinks;li++){
+ OP_ALWAYS_TRUE(!op_granpos_diff(&diff,
+ links[li].pcm_end,links[li].pcm_start));
+ pcm_total+=diff-links[li].head.pre_skip;
+ }
+ return pcm_total;
}
OP_ALWAYS_TRUE(!op_granpos_diff(&diff,
links[_li].pcm_end,links[_li].pcm_start));
- return pcm_total+diff-links[_li].head.pre_skip;
+ return diff-links[_li].head.pre_skip;
}
const OpusHead *op_head(const OggOpusFile *_of,int _li){
@@ -1821,34 +1820,6 @@ opus_int32 op_bitrate_instant(OggOpusFile *_of){
return ret;
}
-/*Given a serialno, find a link with a corresponding Opus stream, if it exists.
- Return: The index of the link to which the page belongs, or a negative number
- if it was not a desired Opus bitstream section.*/
-static int op_get_link_from_serialno(const OggOpusFile *_of,int _cur_link,
- opus_int64 _page_offset,ogg_uint32_t _serialno){
- const OggOpusLink *links;
- int nlinks;
- int li_lo;
- int li_hi;
- OP_ASSERT(_of->seekable);
- links=_of->links;
- nlinks=_of->nlinks;
- li_lo=0;
- /*Start off by guessing we're just a multiplexed page in the current link.*/
- li_hi=_cur_link+1<nlinks&&_page_offset<links[_cur_link+1].offset?
- _cur_link+1:nlinks;
- do{
- if(_page_offset>=links[_cur_link].offset)li_lo=_cur_link;
- else li_hi=_cur_link;
- _cur_link=li_lo+(li_hi-li_lo>>1);
- }
- while(li_hi-li_lo>1);
- /*We've identified the link that should contain this page.
- Make sure it's a page we care about.*/
- if(links[_cur_link].serialno!=_serialno)return OP_FALSE;
- return _cur_link;
-}
-
/*Fetch and process a page.
This handles the case where we're at a bitstream boundary and dumps the
decoding machine.
@@ -1905,28 +1876,19 @@ static int op_fetch_and_process_page(OggOpusFile *_of,
if(OP_UNLIKELY(_of->ready_state<OP_STREAMSET)){
if(seekable){
ogg_uint32_t serialno;
+ int nlinks;
+ int li;
serialno=ogg_page_serialno(&og);
- /*Match the serialno to bitstream section.*/
- OP_ASSERT(cur_link>=0&&cur_link<_of->nlinks);
- if(links[cur_link].serialno!=serialno){
- /*It wasn't a page from the current link.
- Is it from the next one?*/
- if(OP_LIKELY(cur_link+1<_of->nlinks&&links[cur_link+1].serialno==
- serialno)){
- cur_link++;
- }
- else{
- int new_link;
- new_link=
- op_get_link_from_serialno(_of,cur_link,_page_offset,serialno);
- /*Not a desired Opus bitstream section.
- Keep trying.*/
- if(new_link<0)continue;
- cur_link=new_link;
- }
- }
+ /*Match the serialno to bitstream section.
+ We use this rather than offset positions to avoid problems near
+ logical bitstream boundaries.*/
+ nlinks=_of->nlinks;
+ for(li=0;li<nlinks&&links[li].serialno!=serialno;li++);
+ /*Not a desired Opus bitstream section.
+ Keep trying.*/
+ if(li>=nlinks)continue;
cur_serialno=serialno;
- _of->cur_link=cur_link;
+ _of->cur_link=cur_link=li;
ogg_stream_reset_serialno(&_of->os,serialno);
_of->ready_state=OP_STREAMSET;
/*If we're at the start of this link, initialize the granule position
@@ -1980,32 +1942,13 @@ static int op_fetch_and_process_page(OggOpusFile *_of,
opus_int32 total_duration;
int durations[255];
int op_count;
- int report_hole;
- report_hole=0;
total_duration=op_collect_audio_packets(_of,durations);
if(OP_UNLIKELY(total_duration<0)){
- /*libogg reported a hole (a gap in the page sequence numbers).
- Drain the packets from the page anyway.
- If we don't, they'll still be there when we fetch the next page.
- Then, when we go to pull out packets, we might get more than 255,
- which would overrun our packet buffer.*/
+ /*Drain the packets from the page anyway.*/
total_duration=op_collect_audio_packets(_of,durations);
OP_ASSERT(total_duration>=0);
- if(!_ignore_holes){
- /*Report the hole to the caller after we finish timestamping the
- packets.*/
- report_hole=1;
- /*We had lost or damaged pages, so reset our granule position
- tracking.
- This makes holes behave the same as a small raw seek.
- If the next page is the EOS page, we'll discard it (because we
- can't perform end trimming properly), and we'll always discard at
- least 80 ms of audio (to allow decoder state to re-converge).
- We could try to fill in the gap with PLC by looking at timestamps
- in the non-EOS case, but that's complicated and error prone and we
- can't rely on the timestamps being valid.*/
- _of->prev_packet_gp=-1;
- }
+ /*Report holes to the caller.*/
+ if(!_ignore_holes)return OP_HOLE;
}
op_count=_of->op_count;
/*If we found at least one audio data packet, compute per-packet granule
@@ -2032,7 +1975,6 @@ static int op_fetch_and_process_page(OggOpusFile *_of,
Proceed to the next link, rather than risk playing back some
samples that shouldn't have been played.*/
_of->op_count=0;
- if(report_hole)return OP_HOLE;
continue;
}
/*By default discard 80 ms of data after a seek, unless we seek
@@ -2078,11 +2020,7 @@ static int op_fetch_and_process_page(OggOpusFile *_of,
&&OP_LIKELY(diff<total_duration)){
cur_packet_gp=prev_packet_gp;
for(pi=0;pi<op_count;pi++){
- /*Check for overflow.*/
- if(diff<0&&OP_UNLIKELY(OP_INT64_MAX+diff<durations[pi])){
- diff=durations[pi]+1;
- }
- else diff=durations[pi]-diff;
+ diff=durations[pi]-diff;
/*If we have samples to trim...*/
if(diff>0){
/*If we trimmed the entire packet, stop (the spec says encoders
@@ -2138,11 +2076,10 @@ static int op_fetch_and_process_page(OggOpusFile *_of,
}
_of->prev_packet_gp=prev_packet_gp;
_of->prev_page_offset=_page_offset;
- _of->op_count=op_count=pi;
+ _of->op_count=pi;
+ /*If end-trimming didn't trim all the packets, we're done.*/
+ if(OP_LIKELY(pi>0))return 0;
}
- if(report_hole)return OP_HOLE;
- /*If end-trimming didn't trim all the packets, we're done.*/
- if(op_count>0)return 0;
}
}
}
@@ -2180,41 +2117,35 @@ static ogg_int64_t op_get_granulepos(const OggOpusFile *_of,
ogg_int64_t _pcm_offset,int *_li){
const OggOpusLink *links;
ogg_int64_t duration;
- ogg_int64_t pcm_start;
- opus_int32 pre_skip;
int nlinks;
- int li_lo;
- int li_hi;
+ int li;
OP_ASSERT(_pcm_offset>=0);
nlinks=_of->nlinks;
links=_of->links;
- li_lo=0;
- li_hi=nlinks;
- do{
- int li;
- li=li_lo+(li_hi-li_lo>>1);
- if(links[li].pcm_file_offset<=_pcm_offset)li_lo=li;
- else li_hi=li;
- }
- while(li_hi-li_lo>1);
- _pcm_offset-=links[li_lo].pcm_file_offset;
- pcm_start=links[li_lo].pcm_start;
- pre_skip=links[li_lo].head.pre_skip;
- OP_ALWAYS_TRUE(!op_granpos_diff(&duration,links[li_lo].pcm_end,pcm_start));
- duration-=pre_skip;
- if(_pcm_offset>=duration)return -1;
- _pcm_offset+=pre_skip;
- if(OP_UNLIKELY(pcm_start>OP_INT64_MAX-_pcm_offset)){
- /*Adding this amount to the granule position would overflow the positive
- half of its 64-bit range.
- Since signed overflow is undefined in C, do it in a way the compiler
- isn't allowed to screw up.*/
- _pcm_offset-=OP_INT64_MAX-pcm_start+1;
- pcm_start=OP_INT64_MIN;
- }
- pcm_start+=_pcm_offset;
- *_li=li_lo;
- return pcm_start;
+ for(li=0;OP_LIKELY(li<nlinks);li++){
+ ogg_int64_t pcm_start;
+ opus_int32 pre_skip;
+ pcm_start=links[li].pcm_start;
+ pre_skip=links[li].head.pre_skip;
+ OP_ALWAYS_TRUE(!op_granpos_diff(&duration,links[li].pcm_end,pcm_start));
+ duration-=pre_skip;
+ if(_pcm_offset<duration){
+ _pcm_offset+=pre_skip;
+ if(OP_UNLIKELY(pcm_start>OP_INT64_MAX-_pcm_offset)){
+ /*Adding this amount to the granule position would overflow the positive
+ half of its 64-bit range.
+ Since signed overflow is undefined in C, do it in a way the compiler
+ isn't allowed to screw up.*/
+ _pcm_offset-=OP_INT64_MAX-pcm_start+1;
+ pcm_start=OP_INT64_MIN;
+ }
+ pcm_start+=_pcm_offset;
+ *_li=li;
+ return pcm_start;
+ }
+ _pcm_offset-=duration;
+ }
+ return -1;
}
/*A small helper to determine if an Ogg page contains data that continues onto
@@ -2601,14 +2532,15 @@ int op_pcm_seek(OggOpusFile *_of,ogg_int64_t _pcm_offset){
ogg_int64_t gp;
gp=_of->prev_packet_gp;
if(OP_LIKELY(gp!=-1)){
- ogg_int64_t discard_count;
- int nbuffered;
+ int nbuffered;
nbuffered=OP_MAX(_of->od_buffer_size-_of->od_buffer_pos,0);
OP_ALWAYS_TRUE(!op_granpos_add(&gp,gp,-nbuffered));
/*We do _not_ add cur_discard_count to gp.
Otherwise the total amount to discard could grow without bound, and it
would be better just to do a full seek.*/
- if(OP_LIKELY(!op_granpos_diff(&discard_count,target_gp,gp))){
+ if(OP_LIKELY(!op_granpos_diff(&diff,gp,pcm_start))){
+ ogg_int64_t discard_count;
+ discard_count=_pcm_offset-diff;
/*We use a threshold of 90 ms instead of 80, since 80 ms is the
_minimum_ we would have discarded after a full seek.
Assuming 20 ms frames (the default), we'd discard 90 ms on average.*/
@@ -2674,14 +2606,22 @@ static ogg_int64_t op_get_pcm_offset(const OggOpusFile *_of,
ogg_int64_t _gp,int _li){
const OggOpusLink *links;
ogg_int64_t pcm_offset;
+ ogg_int64_t delta;
+ int li;
links=_of->links;
- OP_ASSERT(_li>=0&&_li<_of->nlinks);
- pcm_offset=links[_li].pcm_file_offset;
+ pcm_offset=0;
+ OP_ASSERT(_li<_of->nlinks);
+ for(li=0;li<_li;li++){
+ OP_ALWAYS_TRUE(!op_granpos_diff(&delta,
+ links[li].pcm_end,links[li].pcm_start));
+ delta-=links[li].head.pre_skip;
+ pcm_offset+=delta;
+ }
+ OP_ASSERT(_li>=0);
if(_of->seekable&&OP_UNLIKELY(op_granpos_cmp(_gp,links[_li].pcm_end)>0)){
_gp=links[_li].pcm_end;
}
if(OP_LIKELY(op_granpos_cmp(_gp,links[_li].pcm_start)>0)){
- ogg_int64_t delta;
if(OP_UNLIKELY(op_granpos_diff(&delta,_gp,links[_li].pcm_start)<0)){
/*This means an unseekable stream claimed to have a page from more than
2 billion days after we joined.*/
diff --git a/thirdparty/opus/repacketizer.c b/thirdparty/opus/repacketizer.c
index bda44a148a..c80ee7f001 100644
--- a/thirdparty/opus/repacketizer.c
+++ b/thirdparty/opus/repacketizer.c
@@ -213,8 +213,7 @@ opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int
{
/* Using OPUS_MOVE() instead of OPUS_COPY() in case we're doing in-place
padding from opus_packet_pad or opus_packet_unpad(). */
- /* assert disabled because it's not valid in C. */
- /* celt_assert(frames[i] + len[i] <= data || ptr <= frames[i]); */
+ celt_assert(frames[i] + len[i] <= data || ptr <= frames[i]);
OPUS_MOVE(ptr, frames[i], len[i]);
ptr += len[i];
}
diff --git a/thirdparty/opus/silk/A2NLSF.c b/thirdparty/opus/silk/A2NLSF.c
index b487686ff9..b6e9e5ffcc 100644
--- a/thirdparty/opus/silk/A2NLSF.c
+++ b/thirdparty/opus/silk/A2NLSF.c
@@ -40,7 +40,7 @@ POSSIBILITY OF SUCH DAMAGE.
/* Number of binary divisions, when not in low complexity mode */
#define BIN_DIV_STEPS_A2NLSF_FIX 3 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */
-#define MAX_ITERATIONS_A2NLSF_FIX 16
+#define MAX_ITERATIONS_A2NLSF_FIX 30
/* Helper function for A2NLSF(..) */
/* Transforms polynomials from cos(n*f) to cos(f)^n */
@@ -130,7 +130,7 @@ void silk_A2NLSF(
const opus_int d /* I Filter order (must be even) */
)
{
- opus_int i, k, m, dd, root_ix, ffrac;
+ opus_int i, k, m, dd, root_ix, ffrac;
opus_int32 xlo, xhi, xmid;
opus_int32 ylo, yhi, ymid, thr;
opus_int32 nom, den;
@@ -239,13 +239,13 @@ void silk_A2NLSF(
/* Set NLSFs to white spectrum and exit */
NLSF[ 0 ] = (opus_int16)silk_DIV32_16( 1 << 15, d + 1 );
for( k = 1; k < d; k++ ) {
- NLSF[ k ] = (opus_int16)silk_ADD16( NLSF[ k-1 ], NLSF[ 0 ] );
+ NLSF[ k ] = (opus_int16)silk_SMULBB( k + 1, NLSF[ 0 ] );
}
return;
}
/* Error: Apply progressively more bandwidth expansion and run again */
- silk_bwexpander_32( a_Q16, d, 65536 - silk_LSHIFT( 1, i ) );
+ silk_bwexpander_32( a_Q16, d, 65536 - silk_SMULBB( 10 + i, i ) ); /* 10_Q16 = 0.00015*/
silk_A2NLSF_init( a_Q16, P, Q, dd );
p = P; /* Pointer to polynomial */
diff --git a/thirdparty/opus/silk/API.h b/thirdparty/opus/silk/API.h
index 4d90ff9aa3..0131acbb08 100644
--- a/thirdparty/opus/silk/API.h
+++ b/thirdparty/opus/silk/API.h
@@ -80,8 +80,7 @@ opus_int silk_Encode( /* O Returns error co
opus_int nSamplesIn, /* I Number of samples in input vector */
ec_enc *psRangeEnc, /* I/O Compressor data structure */
opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */
- const opus_int prefillFlag, /* I Flag to indicate prefilling buffers no coding */
- int activity /* I Decision of Opus voice activity detector */
+ const opus_int prefillFlag /* I Flag to indicate prefilling buffers no coding */
);
/****************************************/
diff --git a/thirdparty/opus/silk/CNG.c b/thirdparty/opus/silk/CNG.c
index ef8e38df9f..8443ad63bb 100644
--- a/thirdparty/opus/silk/CNG.c
+++ b/thirdparty/opus/silk/CNG.c
@@ -138,16 +138,16 @@ void silk_CNG(
gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 8 );
}
gain_Q10 = silk_RSHIFT( gain_Q16, 6 );
-
+
silk_CNG_exc( CNG_sig_Q14 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, length, &psCNG->rand_seed );
/* Convert CNG NLSF to filter representation */
- silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order, psDec->arch );
+ silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order );
/* Generate CNG signal, by synthesis filtering */
silk_memcpy( CNG_sig_Q14, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( opus_int32 ) );
- celt_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
for( i = 0; i < length; i++ ) {
+ silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
/* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 );
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] );
@@ -170,11 +170,11 @@ void silk_CNG(
}
/* Update states */
- CNG_sig_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_SAT32( CNG_sig_Q14[ MAX_LPC_ORDER + i ], silk_LSHIFT_SAT32( LPC_pred_Q10, 4 ) );
-
+ CNG_sig_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT( CNG_sig_Q14[ MAX_LPC_ORDER + i ], LPC_pred_Q10, 4 );
+
/* Scale with Gain and add to input signal */
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 ) ) );
-
+
}
silk_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q14[ length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );
} else {
diff --git a/thirdparty/opus/silk/LPC_analysis_filter.c b/thirdparty/opus/silk/LPC_analysis_filter.c
index d34b5eb709..20906673ff 100644
--- a/thirdparty/opus/silk/LPC_analysis_filter.c
+++ b/thirdparty/opus/silk/LPC_analysis_filter.c
@@ -39,13 +39,6 @@ POSSIBILITY OF SUCH DAMAGE.
/* first d output samples are set to zero */
/*******************************************/
-/* OPT: Using celt_fir() for this function should be faster, but it may cause
- integer overflows in intermediate values (not final results), which the
- current implementation silences by casting to unsigned. Enabling
- this should be safe in pretty much all cases, even though it is not technically
- C89-compliant. */
-#define USE_CELT_FIR 0
-
void silk_LPC_analysis_filter(
opus_int16 *out, /* O Output signal */
const opus_int16 *in, /* I Input signal */
@@ -56,7 +49,8 @@ void silk_LPC_analysis_filter(
)
{
opus_int j;
-#if defined(FIXED_POINT) && USE_CELT_FIR
+#ifdef FIXED_POINT
+ opus_int16 mem[SILK_MAX_ORDER_LPC];
opus_int16 num[SILK_MAX_ORDER_LPC];
#else
int ix;
@@ -64,16 +58,19 @@ void silk_LPC_analysis_filter(
const opus_int16 *in_ptr;
#endif
- celt_assert( d >= 6 );
- celt_assert( (d & 1) == 0 );
- celt_assert( d <= len );
+ silk_assert( d >= 6 );
+ silk_assert( (d & 1) == 0 );
+ silk_assert( d <= len );
-#if defined(FIXED_POINT) && USE_CELT_FIR
- celt_assert( d <= SILK_MAX_ORDER_LPC );
+#ifdef FIXED_POINT
+ silk_assert( d <= SILK_MAX_ORDER_LPC );
for ( j = 0; j < d; j++ ) {
num[ j ] = -B[ j ];
}
- celt_fir( in + d, num, out + d, len - d, d, arch );
+ for (j=0;j<d;j++) {
+ mem[ j ] = in[ d - j - 1 ];
+ }
+ celt_fir( in + d, num, out + d, len - d, d, mem, arch );
for ( j = 0; j < d; j++ ) {
out[ j ] = 0;
}
diff --git a/thirdparty/opus/silk/LPC_fit.c b/thirdparty/opus/silk/LPC_fit.c
deleted file mode 100644
index cdea4f3abc..0000000000
--- a/thirdparty/opus/silk/LPC_fit.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/***********************************************************************
-Copyright (c) 2013, Koen Vos. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-- Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-- Neither the name of Internet Society, IETF or IETF Trust, nor the
-names of specific contributors, may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "SigProc_FIX.h"
-
-/* Convert int32 coefficients to int16 coefs and make sure there's no wrap-around */
-void silk_LPC_fit(
- opus_int16 *a_QOUT, /* O Output signal */
- opus_int32 *a_QIN, /* I/O Input signal */
- const opus_int QOUT, /* I Input Q domain */
- const opus_int QIN, /* I Input Q domain */
- const opus_int d /* I Filter order */
-)
-{
- opus_int i, k, idx = 0;
- opus_int32 maxabs, absval, chirp_Q16;
-
- /* Limit the maximum absolute value of the prediction coefficients, so that they'll fit in int16 */
- for( i = 0; i < 10; i++ ) {
- /* Find maximum absolute value and its index */
- maxabs = 0;
- for( k = 0; k < d; k++ ) {
- absval = silk_abs( a_QIN[k] );
- if( absval > maxabs ) {
- maxabs = absval;
- idx = k;
- }
- }
- maxabs = silk_RSHIFT_ROUND( maxabs, QIN - QOUT );
-
- if( maxabs > silk_int16_MAX ) {
- /* Reduce magnitude of prediction coefficients */
- maxabs = silk_min( maxabs, 163838 ); /* ( silk_int32_MAX >> 14 ) + silk_int16_MAX = 163838 */
- chirp_Q16 = SILK_FIX_CONST( 0.999, 16 ) - silk_DIV32( silk_LSHIFT( maxabs - silk_int16_MAX, 14 ),
- silk_RSHIFT32( silk_MUL( maxabs, idx + 1), 2 ) );
- silk_bwexpander_32( a_QIN, d, chirp_Q16 );
- } else {
- break;
- }
- }
-
- if( i == 10 ) {
- /* Reached the last iteration, clip the coefficients */
- for( k = 0; k < d; k++ ) {
- a_QOUT[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a_QIN[ k ], QIN - QOUT ) );
- a_QIN[ k ] = silk_LSHIFT( (opus_int32)a_QOUT[ k ], QIN - QOUT );
- }
- } else {
- for( k = 0; k < d; k++ ) {
- a_QOUT[ k ] = (opus_int16)silk_RSHIFT_ROUND( a_QIN[ k ], QIN - QOUT );
- }
- }
-}
diff --git a/thirdparty/opus/silk/LPC_inv_pred_gain.c b/thirdparty/opus/silk/LPC_inv_pred_gain.c
index a3746a6ef9..4af89aa5fa 100644
--- a/thirdparty/opus/silk/LPC_inv_pred_gain.c
+++ b/thirdparty/opus/silk/LPC_inv_pred_gain.c
@@ -30,7 +30,6 @@ POSSIBILITY OF SUCH DAMAGE.
#endif
#include "SigProc_FIX.h"
-#include "define.h"
#define QA 24
#define A_LIMIT SILK_FIX_CONST( 0.99975, QA )
@@ -39,103 +38,117 @@ POSSIBILITY OF SUCH DAMAGE.
/* Compute inverse of LPC prediction gain, and */
/* test if LPC coefficients are stable (all poles within unit circle) */
-static opus_int32 LPC_inverse_pred_gain_QA_c( /* O Returns inverse prediction gain in energy domain, Q30 */
- opus_int32 A_QA[ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */
+static opus_int32 LPC_inverse_pred_gain_QA( /* O Returns inverse prediction gain in energy domain, Q30 */
+ opus_int32 A_QA[ 2 ][ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */
const opus_int order /* I Prediction order */
)
{
opus_int k, n, mult2Q;
- opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp1, tmp2;
+ opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp_QA;
+ opus_int32 *Aold_QA, *Anew_QA;
- invGain_Q30 = SILK_FIX_CONST( 1, 30 );
+ Anew_QA = A_QA[ order & 1 ];
+
+ invGain_Q30 = (opus_int32)1 << 30;
for( k = order - 1; k > 0; k-- ) {
/* Check for stability */
- if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) {
+ if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) {
return 0;
}
/* Set RC equal to negated AR coef */
- rc_Q31 = -silk_LSHIFT( A_QA[ k ], 31 - QA );
+ rc_Q31 = -silk_LSHIFT( Anew_QA[ k ], 31 - QA );
/* rc_mult1_Q30 range: [ 1 : 2^30 ] */
- rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) );
+ rc_mult1_Q30 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );
silk_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */
silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) );
+ /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */
+ mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) );
+ rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 );
+
/* Update inverse gain */
/* invGain_Q30 range: [ 0 : 2^30 ] */
invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
silk_assert( invGain_Q30 >= 0 );
silk_assert( invGain_Q30 <= ( 1 << 30 ) );
- if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
- return 0;
- }
- /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */
- mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) );
- rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 );
+ /* Swap pointers */
+ Aold_QA = Anew_QA;
+ Anew_QA = A_QA[ k & 1 ];
/* Update AR coefficient */
- for( n = 0; n < (k + 1) >> 1; n++ ) {
- opus_int64 tmp64;
- tmp1 = A_QA[ n ];
- tmp2 = A_QA[ k - n - 1 ];
- tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp1,
- MUL32_FRAC_Q( tmp2, rc_Q31, 31 ) ), rc_mult2 ), mult2Q);
- if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
- return 0;
- }
- A_QA[ n ] = ( opus_int32 )tmp64;
- tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp2,
- MUL32_FRAC_Q( tmp1, rc_Q31, 31 ) ), rc_mult2), mult2Q);
- if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
- return 0;
- }
- A_QA[ k - n - 1 ] = ( opus_int32 )tmp64;
+ for( n = 0; n < k; n++ ) {
+ tmp_QA = Aold_QA[ n ] - MUL32_FRAC_Q( Aold_QA[ k - n - 1 ], rc_Q31, 31 );
+ Anew_QA[ n ] = MUL32_FRAC_Q( tmp_QA, rc_mult2 , mult2Q );
}
}
/* Check for stability */
- if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) {
+ if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) {
return 0;
}
/* Set RC equal to negated AR coef */
- rc_Q31 = -silk_LSHIFT( A_QA[ 0 ], 31 - QA );
+ rc_Q31 = -silk_LSHIFT( Anew_QA[ 0 ], 31 - QA );
/* Range: [ 1 : 2^30 ] */
- rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) );
+ rc_mult1_Q30 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 );
/* Update inverse gain */
/* Range: [ 0 : 2^30 ] */
invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
- silk_assert( invGain_Q30 >= 0 );
- silk_assert( invGain_Q30 <= ( 1 << 30 ) );
- if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
- return 0;
- }
+ silk_assert( invGain_Q30 >= 0 );
+ silk_assert( invGain_Q30 <= 1<<30 );
return invGain_Q30;
}
/* For input in Q12 domain */
-opus_int32 silk_LPC_inverse_pred_gain_c( /* O Returns inverse prediction gain in energy domain, Q30 */
+opus_int32 silk_LPC_inverse_pred_gain( /* O Returns inverse prediction gain in energy domain, Q30 */
const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
const opus_int order /* I Prediction order */
)
{
opus_int k;
- opus_int32 Atmp_QA[ SILK_MAX_ORDER_LPC ];
+ opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ];
+ opus_int32 *Anew_QA;
opus_int32 DC_resp = 0;
+ Anew_QA = Atmp_QA[ order & 1 ];
+
/* Increase Q domain of the AR coefficients */
for( k = 0; k < order; k++ ) {
DC_resp += (opus_int32)A_Q12[ k ];
- Atmp_QA[ k ] = silk_LSHIFT32( (opus_int32)A_Q12[ k ], QA - 12 );
+ Anew_QA[ k ] = silk_LSHIFT32( (opus_int32)A_Q12[ k ], QA - 12 );
}
/* If the DC is unstable, we don't even need to do the full calculations */
if( DC_resp >= 4096 ) {
return 0;
}
- return LPC_inverse_pred_gain_QA_c( Atmp_QA, order );
+ return LPC_inverse_pred_gain_QA( Atmp_QA, order );
}
+
+#ifdef FIXED_POINT
+
+/* For input in Q24 domain */
+opus_int32 silk_LPC_inverse_pred_gain_Q24( /* O Returns inverse prediction gain in energy domain, Q30 */
+ const opus_int32 *A_Q24, /* I Prediction coefficients [order] */
+ const opus_int order /* I Prediction order */
+)
+{
+ opus_int k;
+ opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ];
+ opus_int32 *Anew_QA;
+
+ Anew_QA = Atmp_QA[ order & 1 ];
+
+ /* Increase Q domain of the AR coefficients */
+ for( k = 0; k < order; k++ ) {
+ Anew_QA[ k ] = silk_RSHIFT32( A_Q24[ k ], 24 - QA );
+ }
+
+ return LPC_inverse_pred_gain_QA( Atmp_QA, order );
+}
+#endif
diff --git a/thirdparty/opus/silk/LP_variable_cutoff.c b/thirdparty/opus/silk/LP_variable_cutoff.c
index 79112ad354..f639e1f899 100644
--- a/thirdparty/opus/silk/LP_variable_cutoff.c
+++ b/thirdparty/opus/silk/LP_variable_cutoff.c
@@ -130,6 +130,6 @@ void silk_LP_variable_cutoff(
/* ARMA low-pass filtering */
silk_assert( TRANSITION_NB == 3 && TRANSITION_NA == 2 );
- silk_biquad_alt_stride1( frame, B_Q28, A_Q28, psLP->In_LP_State, frame, frame_length);
+ silk_biquad_alt( frame, B_Q28, A_Q28, psLP->In_LP_State, frame, frame_length, 1);
}
}
diff --git a/thirdparty/opus/silk/MacroCount.h b/thirdparty/opus/silk/MacroCount.h
index 78100ffede..834817d058 100644
--- a/thirdparty/opus/silk/MacroCount.h
+++ b/thirdparty/opus/silk/MacroCount.h
@@ -319,6 +319,14 @@ static OPUS_INLINE opus_int32 silk_ADD_POS_SAT32(opus_int64 a, opus_int64 b){
return(tmp);
}
+#undef silk_ADD_POS_SAT64
+static OPUS_INLINE opus_int64 silk_ADD_POS_SAT64(opus_int64 a, opus_int64 b){
+ opus_int64 tmp;
+ ops_count += 1;
+ tmp = ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b)));
+ return(tmp);
+}
+
#undef silk_LSHIFT8
static OPUS_INLINE opus_int8 silk_LSHIFT8(opus_int8 a, opus_int32 shift){
opus_int8 ret;
@@ -691,7 +699,7 @@ return(ret);
#undef silk_LIMIT_32
-static OPUS_INLINE opus_int32 silk_LIMIT_32(opus_int32 a, opus_int32 limit1, opus_int32 limit2)
+static OPUS_INLINE opus_int silk_LIMIT_32(opus_int32 a, opus_int32 limit1, opus_int32 limit2)
{
opus_int32 ret;
ops_count += 6;
diff --git a/thirdparty/opus/silk/MacroDebug.h b/thirdparty/opus/silk/MacroDebug.h
index 8dd4ce2ee2..35aedc5c5f 100644
--- a/thirdparty/opus/silk/MacroDebug.h
+++ b/thirdparty/opus/silk/MacroDebug.h
@@ -539,7 +539,8 @@ static OPUS_INLINE opus_int32 silk_DIV32_16_(opus_int32 a32, opus_int32 b32, cha
no checking needed for silk_POS_SAT32
no checking needed for silk_ADD_POS_SAT8
no checking needed for silk_ADD_POS_SAT16
- no checking needed for silk_ADD_POS_SAT32 */
+ no checking needed for silk_ADD_POS_SAT32
+ no checking needed for silk_ADD_POS_SAT64 */
#undef silk_LSHIFT8
#define silk_LSHIFT8(a,b) silk_LSHIFT8_((a), (b), __FILE__, __LINE__)
diff --git a/thirdparty/opus/silk/NLSF2A.c b/thirdparty/opus/silk/NLSF2A.c
index d5b7730638..b1c559ea68 100644
--- a/thirdparty/opus/silk/NLSF2A.c
+++ b/thirdparty/opus/silk/NLSF2A.c
@@ -66,8 +66,7 @@ static OPUS_INLINE void silk_NLSF2A_find_poly(
void silk_NLSF2A(
opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */
const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */
- const opus_int d, /* I filter order (should be even) */
- int arch /* I Run-time architecture */
+ const opus_int d /* I filter order (should be even) */
)
{
/* This ordering was found to maximize quality. It improves numerical accuracy of
@@ -84,14 +83,15 @@ void silk_NLSF2A(
opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ];
opus_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta;
opus_int32 a32_QA1[ SILK_MAX_ORDER_LPC ];
+ opus_int32 maxabs, absval, idx=0, sc_Q16;
silk_assert( LSF_COS_TAB_SZ_FIX == 128 );
- celt_assert( d==10 || d==16 );
+ silk_assert( d==10||d==16 );
/* convert LSFs to 2*cos(LSF), using piecewise linear curve from table */
ordering = d == 16 ? ordering16 : ordering10;
for( k = 0; k < d; k++ ) {
- silk_assert( NLSF[k] >= 0 );
+ silk_assert(NLSF[k] >= 0 );
/* f_int on a scale 0-127 (rounded down) */
f_int = silk_RSHIFT( NLSF[k], 15 - 7 );
@@ -126,15 +126,52 @@ void silk_NLSF2A(
a32_QA1[ d-k-1 ] = Qtmp - Ptmp; /* QA+1 */
}
- /* Convert int32 coefficients to Q12 int16 coefs */
- silk_LPC_fit( a_Q12, a32_QA1, 12, QA + 1, d );
+ /* Limit the maximum absolute value of the prediction coefficients, so that they'll fit in int16 */
+ for( i = 0; i < 10; i++ ) {
+ /* Find maximum absolute value and its index */
+ maxabs = 0;
+ for( k = 0; k < d; k++ ) {
+ absval = silk_abs( a32_QA1[k] );
+ if( absval > maxabs ) {
+ maxabs = absval;
+ idx = k;
+ }
+ }
+ maxabs = silk_RSHIFT_ROUND( maxabs, QA + 1 - 12 ); /* QA+1 -> Q12 */
+
+ if( maxabs > silk_int16_MAX ) {
+ /* Reduce magnitude of prediction coefficients */
+ maxabs = silk_min( maxabs, 163838 ); /* ( silk_int32_MAX >> 14 ) + silk_int16_MAX = 163838 */
+ sc_Q16 = SILK_FIX_CONST( 0.999, 16 ) - silk_DIV32( silk_LSHIFT( maxabs - silk_int16_MAX, 14 ),
+ silk_RSHIFT32( silk_MUL( maxabs, idx + 1), 2 ) );
+ silk_bwexpander_32( a32_QA1, d, sc_Q16 );
+ } else {
+ break;
+ }
+ }
- for( i = 0; silk_LPC_inverse_pred_gain( a_Q12, d, arch ) == 0 && i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
- /* Prediction coefficients are (too close to) unstable; apply bandwidth expansion */
- /* on the unscaled coefficients, convert to Q12 and measure again */
- silk_bwexpander_32( a32_QA1, d, 65536 - silk_LSHIFT( 2, i ) );
+ if( i == 10 ) {
+ /* Reached the last iteration, clip the coefficients */
for( k = 0; k < d; k++ ) {
- a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */
+ a_Q12[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ) ); /* QA+1 -> Q12 */
+ a32_QA1[ k ] = silk_LSHIFT( (opus_int32)a_Q12[ k ], QA + 1 - 12 );
+ }
+ } else {
+ for( k = 0; k < d; k++ ) {
+ a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */
+ }
+ }
+
+ for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
+ if( silk_LPC_inverse_pred_gain( a_Q12, d ) < SILK_FIX_CONST( 1.0 / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
+ /* Prediction coefficients are (too close to) unstable; apply bandwidth expansion */
+ /* on the unscaled coefficients, convert to Q12 and measure again */
+ silk_bwexpander_32( a32_QA1, d, 65536 - silk_LSHIFT( 2, i ) );
+ for( k = 0; k < d; k++ ) {
+ a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */
+ }
+ } else {
+ break;
}
}
}
diff --git a/thirdparty/opus/silk/NLSF_VQ.c b/thirdparty/opus/silk/NLSF_VQ.c
index b83182a79c..69b6e22e18 100644
--- a/thirdparty/opus/silk/NLSF_VQ.c
+++ b/thirdparty/opus/silk/NLSF_VQ.c
@@ -33,44 +33,36 @@ POSSIBILITY OF SUCH DAMAGE.
/* Compute quantization errors for an LPC_order element input vector for a VQ codebook */
void silk_NLSF_VQ(
- opus_int32 err_Q24[], /* O Quantization errors [K] */
+ opus_int32 err_Q26[], /* O Quantization errors [K] */
const opus_int16 in_Q15[], /* I Input vectors to be quantized [LPC_order] */
const opus_uint8 pCB_Q8[], /* I Codebook vectors [K*LPC_order] */
- const opus_int16 pWght_Q9[], /* I Codebook weights [K*LPC_order] */
const opus_int K, /* I Number of codebook vectors */
const opus_int LPC_order /* I Number of LPCs */
)
{
- opus_int i, m;
- opus_int32 diff_Q15, diffw_Q24, sum_error_Q24, pred_Q24;
- const opus_int16 *w_Q9_ptr;
- const opus_uint8 *cb_Q8_ptr;
+ opus_int i, m;
+ opus_int32 diff_Q15, sum_error_Q30, sum_error_Q26;
- celt_assert( ( LPC_order & 1 ) == 0 );
+ silk_assert( LPC_order <= 16 );
+ silk_assert( ( LPC_order & 1 ) == 0 );
/* Loop over codebook */
- cb_Q8_ptr = pCB_Q8;
- w_Q9_ptr = pWght_Q9;
for( i = 0; i < K; i++ ) {
- sum_error_Q24 = 0;
- pred_Q24 = 0;
- for( m = LPC_order-2; m >= 0; m -= 2 ) {
- /* Compute weighted absolute predictive quantization error for index m + 1 */
- diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m + 1 ], (opus_int32)cb_Q8_ptr[ m + 1 ], 7 ); /* range: [ -32767 : 32767 ]*/
- diffw_Q24 = silk_SMULBB( diff_Q15, w_Q9_ptr[ m + 1 ] );
- sum_error_Q24 = silk_ADD32( sum_error_Q24, silk_abs( silk_SUB_RSHIFT32( diffw_Q24, pred_Q24, 1 ) ) );
- pred_Q24 = diffw_Q24;
+ sum_error_Q26 = 0;
+ for( m = 0; m < LPC_order; m += 2 ) {
+ /* Compute weighted squared quantization error for index m */
+ diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m ], (opus_int32)*pCB_Q8++, 7 ); /* range: [ -32767 : 32767 ]*/
+ sum_error_Q30 = silk_SMULBB( diff_Q15, diff_Q15 );
- /* Compute weighted absolute predictive quantization error for index m */
- diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m ], (opus_int32)cb_Q8_ptr[ m ], 7 ); /* range: [ -32767 : 32767 ]*/
- diffw_Q24 = silk_SMULBB( diff_Q15, w_Q9_ptr[ m ] );
- sum_error_Q24 = silk_ADD32( sum_error_Q24, silk_abs( silk_SUB_RSHIFT32( diffw_Q24, pred_Q24, 1 ) ) );
- pred_Q24 = diffw_Q24;
+ /* Compute weighted squared quantization error for index m + 1 */
+ diff_Q15 = silk_SUB_LSHIFT32( in_Q15[m + 1], (opus_int32)*pCB_Q8++, 7 ); /* range: [ -32767 : 32767 ]*/
+ sum_error_Q30 = silk_SMLABB( sum_error_Q30, diff_Q15, diff_Q15 );
- silk_assert( sum_error_Q24 >= 0 );
+ sum_error_Q26 = silk_ADD_RSHIFT32( sum_error_Q26, sum_error_Q30, 4 );
+
+ silk_assert( sum_error_Q26 >= 0 );
+ silk_assert( sum_error_Q30 >= 0 );
}
- err_Q24[ i ] = sum_error_Q24;
- cb_Q8_ptr += LPC_order;
- w_Q9_ptr += LPC_order;
+ err_Q26[ i ] = sum_error_Q26;
}
}
diff --git a/thirdparty/opus/silk/NLSF_VQ_weights_laroia.c b/thirdparty/opus/silk/NLSF_VQ_weights_laroia.c
index 9873bcde10..04894c59ab 100644
--- a/thirdparty/opus/silk/NLSF_VQ_weights_laroia.c
+++ b/thirdparty/opus/silk/NLSF_VQ_weights_laroia.c
@@ -48,8 +48,8 @@ void silk_NLSF_VQ_weights_laroia(
opus_int k;
opus_int32 tmp1_int, tmp2_int;
- celt_assert( D > 0 );
- celt_assert( ( D & 1 ) == 0 );
+ silk_assert( D > 0 );
+ silk_assert( ( D & 1 ) == 0 );
/* First value */
tmp1_int = silk_max_int( pNLSF_Q15[ 0 ], 1 );
diff --git a/thirdparty/opus/silk/NLSF_decode.c b/thirdparty/opus/silk/NLSF_decode.c
index eeb0ba8c92..9f715060b8 100644
--- a/thirdparty/opus/silk/NLSF_decode.c
+++ b/thirdparty/opus/silk/NLSF_decode.c
@@ -32,7 +32,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "main.h"
/* Predictive dequantizer for NLSF residuals */
-static OPUS_INLINE void silk_NLSF_residual_dequant( /* O Returns RD value in Q30 */
+static OPUS_INLINE void silk_NLSF_residual_dequant( /* O Returns RD value in Q30 */
opus_int16 x_Q10[], /* O Output [ order ] */
const opus_int8 indices[], /* I Quantization indices [ order ] */
const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */
@@ -70,9 +70,15 @@ void silk_NLSF_decode(
opus_uint8 pred_Q8[ MAX_LPC_ORDER ];
opus_int16 ec_ix[ MAX_LPC_ORDER ];
opus_int16 res_Q10[ MAX_LPC_ORDER ];
- opus_int32 NLSF_Q15_tmp;
+ opus_int16 W_tmp_QW[ MAX_LPC_ORDER ];
+ opus_int32 W_tmp_Q9, NLSF_Q15_tmp;
const opus_uint8 *pCB_element;
- const opus_int16 *pCB_Wght_Q9;
+
+ /* Decode first stage */
+ pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ];
+ for( i = 0; i < psNLSF_CB->order; i++ ) {
+ pNLSF_Q15[ i ] = silk_LSHIFT( (opus_int16)pCB_element[ i ], 7 );
+ }
/* Unpack entropy table indices and predictor for current CB1 index */
silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, NLSFIndices[ 0 ] );
@@ -80,11 +86,13 @@ void silk_NLSF_decode(
/* Predictive residual dequantizer */
silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order );
- /* Apply inverse square-rooted weights to first stage and add to output */
- pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ];
- pCB_Wght_Q9 = &psNLSF_CB->CB1_Wght_Q9[ NLSFIndices[ 0 ] * psNLSF_CB->order ];
+ /* Weights from codebook vector */
+ silk_NLSF_VQ_weights_laroia( W_tmp_QW, pNLSF_Q15, psNLSF_CB->order );
+
+ /* Apply inverse square-rooted weights and add to output */
for( i = 0; i < psNLSF_CB->order; i++ ) {
- 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 );
+ W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( (opus_int32)W_tmp_QW[ i ], 18 - NLSF_W_Q ) );
+ NLSF_Q15_tmp = silk_ADD32( pNLSF_Q15[ i ], silk_DIV32_16( silk_LSHIFT( (opus_int32)res_Q10[ i ], 14 ), W_tmp_Q9 ) );
pNLSF_Q15[ i ] = (opus_int16)silk_LIMIT( NLSF_Q15_tmp, 0, 32767 );
}
diff --git a/thirdparty/opus/silk/NLSF_del_dec_quant.c b/thirdparty/opus/silk/NLSF_del_dec_quant.c
index 44a16acd0b..de88fee060 100644
--- a/thirdparty/opus/silk/NLSF_del_dec_quant.c
+++ b/thirdparty/opus/silk/NLSF_del_dec_quant.c
@@ -84,7 +84,7 @@ opus_int32 silk_NLSF_del_dec_quant( /* O Returns
nStates = 1;
RD_Q25[ 0 ] = 0;
prev_out_Q10[ 0 ] = 0;
- for( i = order - 1; i >= 0; i-- ) {
+ for( i = order - 1; ; i-- ) {
rates_Q5 = &ec_rates_Q5[ ec_ix[ i ] ];
in_Q10 = x_Q10[ i ];
for( j = 0; j < nStates; j++ ) {
@@ -131,7 +131,7 @@ opus_int32 silk_NLSF_del_dec_quant( /* O Returns
RD_Q25[ j + nStates ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate1_Q5 );
}
- if( nStates <= NLSF_QUANT_DEL_DEC_STATES/2 ) {
+ if( nStates <= ( NLSF_QUANT_DEL_DEC_STATES >> 1 ) ) {
/* double number of states and copy */
for( j = 0; j < nStates; j++ ) {
ind[ j + nStates ][ i ] = ind[ j ][ i ] + 1;
@@ -140,7 +140,7 @@ opus_int32 silk_NLSF_del_dec_quant( /* O Returns
for( j = nStates; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
ind[ j ][ i ] = ind[ j - nStates ][ i ];
}
- } else {
+ } else if( i > 0 ) {
/* sort lower and upper half of RD_Q25, pairwise */
for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
if( RD_Q25[ j ] > RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] ) {
@@ -191,6 +191,8 @@ opus_int32 silk_NLSF_del_dec_quant( /* O Returns
for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) {
ind[ j ][ i ] += silk_RSHIFT( ind_sort[ j ], NLSF_QUANT_DEL_DEC_STATES_LOG2 );
}
+ } else { /* i == 0 */
+ break;
}
}
diff --git a/thirdparty/opus/silk/NLSF_encode.c b/thirdparty/opus/silk/NLSF_encode.c
index 01ac7db78c..f03c3f1c35 100644
--- a/thirdparty/opus/silk/NLSF_encode.c
+++ b/thirdparty/opus/silk/NLSF_encode.c
@@ -37,9 +37,9 @@ POSSIBILITY OF SUCH DAMAGE.
/***********************/
opus_int32 silk_NLSF_encode( /* O Returns RD value in Q25 */
opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */
- opus_int16 *pNLSF_Q15, /* I/O (Un)quantized NLSF vector [ LPC_ORDER ] */
+ opus_int16 *pNLSF_Q15, /* I/O Quantized NLSF vector [ LPC_ORDER ] */
const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */
- const opus_int16 *pW_Q2, /* I NLSF weight vector [ LPC_ORDER ] */
+ const opus_int16 *pW_QW, /* I NLSF weight vector [ LPC_ORDER ] */
const opus_int NLSF_mu_Q20, /* I Rate weight for the RD optimization */
const opus_int nSurvivors, /* I Max survivors after first stage */
const opus_int signalType /* I Signal type: 0/1/2 */
@@ -47,32 +47,34 @@ opus_int32 silk_NLSF_encode( /* O Returns
{
opus_int i, s, ind1, bestIndex, prob_Q8, bits_q7;
opus_int32 W_tmp_Q9, ret;
- VARDECL( opus_int32, err_Q24 );
+ VARDECL( opus_int32, err_Q26 );
VARDECL( opus_int32, RD_Q25 );
VARDECL( opus_int, tempIndices1 );
VARDECL( opus_int8, tempIndices2 );
+ opus_int16 res_Q15[ MAX_LPC_ORDER ];
opus_int16 res_Q10[ MAX_LPC_ORDER ];
opus_int16 NLSF_tmp_Q15[ MAX_LPC_ORDER ];
+ opus_int16 W_tmp_QW[ MAX_LPC_ORDER ];
opus_int16 W_adj_Q5[ MAX_LPC_ORDER ];
opus_uint8 pred_Q8[ MAX_LPC_ORDER ];
opus_int16 ec_ix[ MAX_LPC_ORDER ];
const opus_uint8 *pCB_element, *iCDF_ptr;
- const opus_int16 *pCB_Wght_Q9;
SAVE_STACK;
- celt_assert( signalType >= 0 && signalType <= 2 );
+ silk_assert( nSurvivors <= NLSF_VQ_MAX_SURVIVORS );
+ silk_assert( signalType >= 0 && signalType <= 2 );
silk_assert( NLSF_mu_Q20 <= 32767 && NLSF_mu_Q20 >= 0 );
/* NLSF stabilization */
silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order );
/* First stage: VQ */
- ALLOC( err_Q24, psNLSF_CB->nVectors, opus_int32 );
- silk_NLSF_VQ( err_Q24, pNLSF_Q15, psNLSF_CB->CB1_NLSF_Q8, psNLSF_CB->CB1_Wght_Q9, psNLSF_CB->nVectors, psNLSF_CB->order );
+ ALLOC( err_Q26, psNLSF_CB->nVectors, opus_int32 );
+ silk_NLSF_VQ( err_Q26, pNLSF_Q15, psNLSF_CB->CB1_NLSF_Q8, psNLSF_CB->nVectors, psNLSF_CB->order );
/* Sort the quantization errors */
ALLOC( tempIndices1, nSurvivors, opus_int );
- silk_insertion_sort_increasing( err_Q24, tempIndices1, psNLSF_CB->nVectors, nSurvivors );
+ silk_insertion_sort_increasing( err_Q26, tempIndices1, psNLSF_CB->nVectors, nSurvivors );
ALLOC( RD_Q25, nSurvivors, opus_int32 );
ALLOC( tempIndices2, nSurvivors * MAX_LPC_ORDER, opus_int8 );
@@ -83,12 +85,23 @@ opus_int32 silk_NLSF_encode( /* O Returns
/* Residual after first stage */
pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ ind1 * psNLSF_CB->order ];
- pCB_Wght_Q9 = &psNLSF_CB->CB1_Wght_Q9[ ind1 * psNLSF_CB->order ];
for( i = 0; i < psNLSF_CB->order; i++ ) {
NLSF_tmp_Q15[ i ] = silk_LSHIFT16( (opus_int16)pCB_element[ i ], 7 );
- W_tmp_Q9 = pCB_Wght_Q9[ i ];
- res_Q10[ i ] = (opus_int16)silk_RSHIFT( silk_SMULBB( pNLSF_Q15[ i ] - NLSF_tmp_Q15[ i ], W_tmp_Q9 ), 14 );
- W_adj_Q5[ i ] = silk_DIV32_varQ( (opus_int32)pW_Q2[ i ], silk_SMULBB( W_tmp_Q9, W_tmp_Q9 ), 21 );
+ res_Q15[ i ] = pNLSF_Q15[ i ] - NLSF_tmp_Q15[ i ];
+ }
+
+ /* Weights from codebook vector */
+ silk_NLSF_VQ_weights_laroia( W_tmp_QW, NLSF_tmp_Q15, psNLSF_CB->order );
+
+ /* Apply square-rooted weights */
+ for( i = 0; i < psNLSF_CB->order; i++ ) {
+ W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( (opus_int32)W_tmp_QW[ i ], 18 - NLSF_W_Q ) );
+ res_Q10[ i ] = (opus_int16)silk_RSHIFT( silk_SMULBB( res_Q15[ i ], W_tmp_Q9 ), 14 );
+ }
+
+ /* Modify input weights accordingly */
+ for( i = 0; i < psNLSF_CB->order; i++ ) {
+ W_adj_Q5[ i ] = silk_DIV32_16( silk_LSHIFT( (opus_int32)pW_QW[ i ], 5 ), W_tmp_QW[ i ] );
}
/* Unpack entropy table indices and predictor for current CB1 index */
diff --git a/thirdparty/opus/silk/NSQ.c b/thirdparty/opus/silk/NSQ.c
index 1d64d8e257..43e3fee7e0 100644
--- a/thirdparty/opus/silk/NSQ.c
+++ b/thirdparty/opus/silk/NSQ.c
@@ -37,7 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
static OPUS_INLINE void silk_nsq_scale_states(
const silk_encoder_state *psEncC, /* I Encoder State */
silk_nsq_state *NSQ, /* I/O NSQ state */
- const opus_int16 x16[], /* I input */
+ const opus_int32 x_Q3[], /* I input in Q3 */
opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */
opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
@@ -75,14 +75,14 @@ static OPUS_INLINE void silk_noise_shape_quantizer(
void silk_NSQ_c
(
- const silk_encoder_state *psEncC, /* I Encoder State */
+ const silk_encoder_state *psEncC, /* I/O Encoder State */
silk_nsq_state *NSQ, /* I/O NSQ state */
SideInfoIndices *psIndices, /* I/O Quantization Indices */
- const opus_int16 x16[], /* I Input */
+ const opus_int32 x_Q3[], /* I Prefiltered input signal */
opus_int8 pulses[], /* O Quantized pulse signal */
const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
- const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
+ const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
@@ -117,7 +117,8 @@ void silk_NSQ_c
LSF_interpolation_flag = 1;
}
- ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
+ ALLOC( sLTP_Q15,
+ psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
/* Set up pointers to start of sub frame */
@@ -127,7 +128,7 @@ void silk_NSQ_c
for( k = 0; k < psEncC->nb_subfr; k++ ) {
A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ];
B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
- AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ];
+ AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ];
/* Noise shape parameters */
silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
@@ -143,7 +144,7 @@ void silk_NSQ_c
if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
/* Rewhiten with new A coefs */
start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
- celt_assert( start_idx > 0 );
+ silk_assert( start_idx > 0 );
silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
@@ -153,13 +154,13 @@ void silk_NSQ_c
}
}
- silk_nsq_scale_states( psEncC, NSQ, x16, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType );
+ silk_nsq_scale_states( psEncC, NSQ, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType );
silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14,
AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,
offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->arch );
- x16 += psEncC->subfr_length;
+ x_Q3 += psEncC->subfr_length;
pulses += psEncC->subfr_length;
pxq += psEncC->subfr_length;
}
@@ -168,6 +169,7 @@ void silk_NSQ_c
NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
/* Save quantized speech and noise shaping signals */
+ /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[ psEncC->ltp_mem_length ], psEncC->frame_length * sizeof( opus_int16 ) ) */
silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
RESTORE_STACK;
@@ -247,15 +249,15 @@ void silk_noise_shape_quantizer(
}
/* Noise shape feedback */
- celt_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
- n_AR_Q12 = silk_NSQ_noise_shape_feedback_loop(&NSQ->sDiff_shp_Q14, NSQ->sAR2_Q14, AR_shp_Q13, shapingLPCOrder, arch);
+ silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
+ n_AR_Q12 = silk_NSQ_noise_shape_feedback_loop(psLPC_Q14, NSQ->sAR2_Q14, AR_shp_Q13, shapingLPCOrder, arch);
n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sLF_AR_shp_Q14, Tilt_Q14 );
n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 );
n_LF_Q12 = silk_SMLAWT( n_LF_Q12, NSQ->sLF_AR_shp_Q14, LF_shp_Q14 );
- celt_assert( lag > 0 || signalType != TYPE_VOICED );
+ silk_assert( lag > 0 || signalType != TYPE_VOICED );
/* Combine prediction and noise shaping signals */
tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 ); /* Q12 */
@@ -277,27 +279,14 @@ void silk_noise_shape_quantizer(
r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 ); /* residual error Q10 */
/* Flip sign depending on dither */
- if( NSQ->rand_seed < 0 ) {
- r_Q10 = -r_Q10;
+ if ( NSQ->rand_seed < 0 ) {
+ r_Q10 = -r_Q10;
}
r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 );
/* Find two quantization level candidates and measure their rate-distortion */
q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
- if (Lambda_Q10 > 2048) {
- /* For aggressive RDO, the bias becomes more than one pulse. */
- int rdo_offset = Lambda_Q10/2 - 512;
- if (q1_Q10 > rdo_offset) {
- q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 );
- } else if (q1_Q10 < -rdo_offset) {
- q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 );
- } else if (q1_Q10 < 0) {
- q1_Q0 = -1;
- } else {
- q1_Q0 = 0;
- }
- }
if( q1_Q0 > 0 ) {
q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
@@ -348,8 +337,7 @@ void silk_noise_shape_quantizer(
/* Update states */
psLPC_Q14++;
*psLPC_Q14 = xq_Q14;
- NSQ->sDiff_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_sc_Q10[ i ], 4 );
- sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( NSQ->sDiff_shp_Q14, n_AR_Q12, 2 );
+ sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, n_AR_Q12, 2 );
NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14;
NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 );
@@ -368,7 +356,7 @@ void silk_noise_shape_quantizer(
static OPUS_INLINE void silk_nsq_scale_states(
const silk_encoder_state *psEncC, /* I Encoder State */
silk_nsq_state *NSQ, /* I/O NSQ state */
- const opus_int16 x16[], /* I input */
+ const opus_int32 x_Q3[], /* I input in Q3 */
opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */
const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */
opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
@@ -380,18 +368,28 @@ static OPUS_INLINE void silk_nsq_scale_states(
)
{
opus_int i, lag;
- opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26;
+ opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23;
lag = pitchL[ subfr ];
inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
silk_assert( inv_gain_Q31 != 0 );
+ /* Calculate gain adjustment factor */
+ if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
+ gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
+ } else {
+ gain_adj_Q16 = (opus_int32)1 << 16;
+ }
+
/* Scale input */
- inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 );
+ inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 );
for( i = 0; i < psEncC->subfr_length; i++ ) {
- x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 );
+ x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 );
}
+ /* Save inverse gain */
+ NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
+
/* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
if( NSQ->rewhite_flag ) {
if( subfr == 0 ) {
@@ -405,9 +403,7 @@ static OPUS_INLINE void silk_nsq_scale_states(
}
/* Adjust for changing gain */
- if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
- gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
-
+ if( gain_adj_Q16 != (opus_int32)1 << 16 ) {
/* Scale long-term shaping state */
for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {
NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
@@ -421,7 +417,6 @@ static OPUS_INLINE void silk_nsq_scale_states(
}
NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 );
- NSQ->sDiff_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sDiff_shp_Q14 );
/* Scale short-term prediction and shaping states */
for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
@@ -430,8 +425,5 @@ static OPUS_INLINE void silk_nsq_scale_states(
for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] );
}
-
- /* Save inverse gain */
- NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
}
}
diff --git a/thirdparty/opus/silk/NSQ_del_dec.c b/thirdparty/opus/silk/NSQ_del_dec.c
index 3fd9fa0d5b..ab6feeac98 100644
--- a/thirdparty/opus/silk/NSQ_del_dec.c
+++ b/thirdparty/opus/silk/NSQ_del_dec.c
@@ -43,7 +43,6 @@ typedef struct {
opus_int32 Shape_Q14[ DECISION_DELAY ];
opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];
opus_int32 LF_AR_Q14;
- opus_int32 Diff_Q14;
opus_int32 Seed;
opus_int32 SeedInit;
opus_int32 RD_Q10;
@@ -54,7 +53,6 @@ typedef struct {
opus_int32 RD_Q10;
opus_int32 xq_Q14;
opus_int32 LF_AR_Q14;
- opus_int32 Diff_Q14;
opus_int32 sLTP_shp_Q14;
opus_int32 LPC_exc_Q14;
} NSQ_sample_struct;
@@ -68,7 +66,7 @@ static OPUS_INLINE void silk_nsq_del_dec_scale_states(
const silk_encoder_state *psEncC, /* I Encoder State */
silk_nsq_state *NSQ, /* I/O NSQ state */
NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
- const opus_int16 x16[], /* I Input */
+ const opus_int32 x_Q3[], /* I Input in Q3 */
opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
@@ -109,20 +107,20 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
opus_int predictLPCOrder, /* I Prediction filter order */
opus_int warping_Q16, /* I */
opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
- opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
+ opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */
opus_int decisionDelay, /* I */
int arch /* I */
);
void silk_NSQ_del_dec_c(
- const silk_encoder_state *psEncC, /* I Encoder State */
+ const silk_encoder_state *psEncC, /* I/O Encoder State */
silk_nsq_state *NSQ, /* I/O NSQ state */
SideInfoIndices *psIndices, /* I/O Quantization Indices */
- const opus_int16 x16[], /* I Input */
+ const opus_int32 x_Q3[], /* I Prefiltered input signal */
opus_int8 pulses[], /* O Quantized pulse signal */
const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
- const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
+ const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
@@ -161,7 +159,6 @@ void silk_NSQ_del_dec_c(
psDD->SeedInit = psDD->Seed;
psDD->RD_Q10 = 0;
psDD->LF_AR_Q14 = NSQ->sLF_AR_shp_Q14;
- psDD->Diff_Q14 = NSQ->sDiff_shp_Q14;
psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ];
silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) );
@@ -189,7 +186,8 @@ void silk_NSQ_del_dec_c(
LSF_interpolation_flag = 1;
}
- ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
+ ALLOC( sLTP_Q15,
+ psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 );
@@ -201,7 +199,7 @@ void silk_NSQ_del_dec_c(
for( k = 0; k < psEncC->nb_subfr; k++ ) {
A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];
B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
- AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ];
+ AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ];
/* Noise shape parameters */
silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
@@ -237,8 +235,7 @@ void silk_NSQ_del_dec_c(
psDD = &psDelDec[ Winner_ind ];
last_smple_idx = smpl_buf_idx + decisionDelay;
for( i = 0; i < decisionDelay; i++ ) {
- last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY;
- if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY;
+ last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) );
@@ -250,7 +247,7 @@ void silk_NSQ_del_dec_c(
/* Rewhiten with new A coefs */
start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
- celt_assert( start_idx > 0 );
+ silk_assert( start_idx > 0 );
silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
@@ -260,7 +257,7 @@ void silk_NSQ_del_dec_c(
}
}
- silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x16, x_sc_Q10, sLTP, sLTP_Q15, k,
+ silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k,
psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );
silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,
@@ -268,7 +265,7 @@ void silk_NSQ_del_dec_c(
Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,
psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay, psEncC->arch );
- x16 += psEncC->subfr_length;
+ x_Q3 += psEncC->subfr_length;
pulses += psEncC->subfr_length;
pxq += psEncC->subfr_length;
}
@@ -289,9 +286,7 @@ void silk_NSQ_del_dec_c(
last_smple_idx = smpl_buf_idx + decisionDelay;
Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 );
for( i = 0; i < decisionDelay; i++ ) {
- last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY;
- if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY;
-
+ last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) );
@@ -302,10 +297,10 @@ void silk_NSQ_del_dec_c(
/* Update states */
NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14;
- NSQ->sDiff_shp_Q14 = psDD->Diff_Q14;
NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
/* Save quantized speech signal */
+ /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[psEncC->ltp_mem_length], psEncC->frame_length * sizeof( opus_int16 ) ) */
silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
RESTORE_STACK;
@@ -340,7 +335,7 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
opus_int predictLPCOrder, /* I Prediction filter order */
opus_int warping_Q16, /* I */
opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
- opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
+ opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */
opus_int decisionDelay, /* I */
int arch /* I */
)
@@ -361,7 +356,7 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
NSQ_sample_struct *psSS;
SAVE_STACK;
- celt_assert( nStatesDelayedDecision > 0 );
+ silk_assert( nStatesDelayedDecision > 0 );
ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair );
shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
@@ -419,9 +414,9 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */
/* Noise shape feedback */
- celt_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
+ silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
/* Output of lowpass section */
- tmp2 = silk_SMLAWB( psDD->Diff_Q14, psDD->sAR2_Q14[ 0 ], warping_Q16 );
+ tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 );
/* Output of allpass section */
tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 );
psDD->sAR2_Q14[ 0 ] = tmp2;
@@ -467,19 +462,6 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
/* Find two quantization level candidates and measure their rate-distortion */
q1_Q10 = silk_SUB32( r_Q10, offset_Q10 );
q1_Q0 = silk_RSHIFT( q1_Q10, 10 );
- if (Lambda_Q10 > 2048) {
- /* For aggressive RDO, the bias becomes more than one pulse. */
- int rdo_offset = Lambda_Q10/2 - 512;
- if (q1_Q10 > rdo_offset) {
- q1_Q0 = silk_RSHIFT( q1_Q10 - rdo_offset, 10 );
- } else if (q1_Q10 < -rdo_offset) {
- q1_Q0 = silk_RSHIFT( q1_Q10 + rdo_offset, 10 );
- } else if (q1_Q10 < 0) {
- q1_Q0 = -1;
- } else {
- q1_Q0 = 0;
- }
- }
if( q1_Q0 > 0 ) {
q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 );
q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 );
@@ -533,8 +515,7 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
/* Update states */
- psSS[ 0 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 );
- sLF_AR_shp_Q14 = silk_SUB32( psSS[ 0 ].Diff_Q14, n_AR_Q14 );
+ sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 );
psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14;
psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14;
@@ -548,22 +529,21 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
exc_Q14 = -exc_Q14;
}
+
/* Add predictions */
LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 );
xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 );
/* Update states */
- psSS[ 1 ].Diff_Q14 = silk_SUB_LSHIFT32( xq_Q14, x_Q10[ i ], 4 );
- sLF_AR_shp_Q14 = silk_SUB32( psSS[ 1 ].Diff_Q14, n_AR_Q14 );
+ sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 );
psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 );
psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14;
psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14;
psSS[ 1 ].xq_Q14 = xq_Q14;
}
- *smpl_buf_idx = ( *smpl_buf_idx - 1 ) % DECISION_DELAY;
- if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY;
- last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY;
+ *smpl_buf_idx = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK; /* Index to newest samples */
+ last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK; /* Index to decisionDelay old samples */
/* Find winner */
RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
@@ -627,7 +607,6 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
psDD = &psDelDec[ k ];
psSS = &psSampleState[ k ][ 0 ];
psDD->LF_AR_Q14 = psSS->LF_AR_Q14;
- psDD->Diff_Q14 = psSS->Diff_Q14;
psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14;
psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14;
psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10;
@@ -652,7 +631,7 @@ static OPUS_INLINE void silk_nsq_del_dec_scale_states(
const silk_encoder_state *psEncC, /* I Encoder State */
silk_nsq_state *NSQ, /* I/O NSQ state */
NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */
- const opus_int16 x16[], /* I Input */
+ const opus_int32 x_Q3[], /* I Input in Q3 */
opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
@@ -666,19 +645,29 @@ static OPUS_INLINE void silk_nsq_del_dec_scale_states(
)
{
opus_int i, k, lag;
- opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26;
+ opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23;
NSQ_del_dec_struct *psDD;
lag = pitchL[ subfr ];
inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
silk_assert( inv_gain_Q31 != 0 );
+ /* Calculate gain adjustment factor */
+ if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
+ gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
+ } else {
+ gain_adj_Q16 = (opus_int32)1 << 16;
+ }
+
/* Scale input */
- inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 );
+ inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 );
for( i = 0; i < psEncC->subfr_length; i++ ) {
- x_sc_Q10[ i ] = silk_SMULWW( x16[ i ], inv_gain_Q26 );
+ x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 );
}
+ /* Save inverse gain */
+ NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
+
/* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
if( NSQ->rewhite_flag ) {
if( subfr == 0 ) {
@@ -692,9 +681,7 @@ static OPUS_INLINE void silk_nsq_del_dec_scale_states(
}
/* Adjust for changing gain */
- if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
- gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
-
+ if( gain_adj_Q16 != (opus_int32)1 << 16 ) {
/* Scale long-term shaping state */
for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) {
NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
@@ -712,7 +699,6 @@ static OPUS_INLINE void silk_nsq_del_dec_scale_states(
/* Scale scalar states */
psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 );
- psDD->Diff_Q14 = silk_SMULWW( gain_adj_Q16, psDD->Diff_Q14 );
/* Scale short-term prediction and shaping states */
for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
@@ -726,8 +712,5 @@ static OPUS_INLINE void silk_nsq_del_dec_scale_states(
psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] );
}
}
-
- /* Save inverse gain */
- NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
}
}
diff --git a/thirdparty/opus/silk/PLC.c b/thirdparty/opus/silk/PLC.c
index f89391651c..fb6ea887b7 100644
--- a/thirdparty/opus/silk/PLC.c
+++ b/thirdparty/opus/silk/PLC.c
@@ -275,7 +275,7 @@ static OPUS_INLINE void silk_PLC_conceal(
/* Reduce random noise for unvoiced frames with high LPC gain */
opus_int32 invGain_Q30, down_scale_Q30;
- invGain_Q30 = silk_LPC_inverse_pred_gain( psPLC->prevLPC_Q12, psDec->LPC_order, arch );
+ invGain_Q30 = silk_LPC_inverse_pred_gain( psPLC->prevLPC_Q12, psDec->LPC_order );
down_scale_Q30 = silk_min_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 );
down_scale_Q30 = silk_max_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 );
@@ -291,7 +291,7 @@ static OPUS_INLINE void silk_PLC_conceal(
/* Rewhiten LTP state */
idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2;
- celt_assert( idx > 0 );
+ silk_assert( idx > 0 );
silk_LPC_analysis_filter( &sLTP[ idx ], &psDec->outBuf[ idx ], A_Q12, psDec->ltp_mem_length - idx, psDec->LPC_order, arch );
/* Scale LTP state */
inv_gain_Q30 = silk_INVERSE32_varQ( psPLC->prevGain_Q16[ 1 ], 46 );
@@ -328,10 +328,8 @@ static OPUS_INLINE void silk_PLC_conceal(
for( j = 0; j < LTP_ORDER; j++ ) {
B_Q14[ j ] = silk_RSHIFT( silk_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 );
}
- if ( psDec->indices.signalType != TYPE_NO_VOICE_ACTIVITY ) {
- /* Gradually reduce excitation gain */
- rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 );
- }
+ /* Gradually reduce excitation gain */
+ rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 );
/* Slowly increase pitch lag */
psPLC->pitchL_Q8 = silk_SMLAWB( psPLC->pitchL_Q8, psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 );
@@ -347,7 +345,7 @@ static OPUS_INLINE void silk_PLC_conceal(
/* Copy LPC state */
silk_memcpy( sLPC_Q14_ptr, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) );
- celt_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */
+ silk_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */
for( i = 0; i < psDec->frame_length; i++ ) {
/* partly unrolled */
/* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
diff --git a/thirdparty/opus/silk/SigProc_FIX.h b/thirdparty/opus/silk/SigProc_FIX.h
index f9ae326326..b63299441e 100644
--- a/thirdparty/opus/silk/SigProc_FIX.h
+++ b/thirdparty/opus/silk/SigProc_FIX.h
@@ -35,7 +35,7 @@ extern "C"
/*#define silk_MACRO_COUNT */ /* Used to enable WMOPS counting */
-#define SILK_MAX_ORDER_LPC 24 /* max order of the LPC analysis in schur() and k2a() */
+#define SILK_MAX_ORDER_LPC 16 /* max order of the LPC analysis in schur() and k2a() */
#include <string.h> /* for memset(), memcpy(), memmove() */
#include "typedef.h"
@@ -47,11 +47,6 @@ extern "C"
#include "x86/SigProc_FIX_sse.h"
#endif
-#if (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
-#include "arm/biquad_alt_arm.h"
-#include "arm/LPC_inv_pred_gain_arm.h"
-#endif
-
/********************************************************************/
/* SIGNAL PROCESSING FUNCTIONS */
/********************************************************************/
@@ -101,22 +96,14 @@ void silk_resampler_down2_3(
* slower than biquad() but uses more precise coefficients
* can handle (slowly) varying coefficients
*/
-void silk_biquad_alt_stride1(
+void silk_biquad_alt(
const opus_int16 *in, /* I input signal */
const opus_int32 *B_Q28, /* I MA coefficients [3] */
const opus_int32 *A_Q28, /* I AR coefficients [2] */
opus_int32 *S, /* I/O State vector [2] */
opus_int16 *out, /* O output signal */
- const opus_int32 len /* I signal length (must be even) */
-);
-
-void silk_biquad_alt_stride2_c(
- const opus_int16 *in, /* I input signal */
- const opus_int32 *B_Q28, /* I MA coefficients [3] */
- const opus_int32 *A_Q28, /* I AR coefficients [2] */
- opus_int32 *S, /* I/O State vector [4] */
- opus_int16 *out, /* O output signal */
- const opus_int32 len /* I signal length (must be even) */
+ const opus_int32 len, /* I signal length (must be even) */
+ opus_int stride /* I Operate on interleaved signal if > 1 */
);
/* Variable order MA prediction error filter. */
@@ -145,11 +132,17 @@ void silk_bwexpander_32(
/* Compute inverse of LPC prediction gain, and */
/* test if LPC coefficients are stable (all poles within unit circle) */
-opus_int32 silk_LPC_inverse_pred_gain_c( /* O Returns inverse prediction gain in energy domain, Q30 */
+opus_int32 silk_LPC_inverse_pred_gain( /* O Returns inverse prediction gain in energy domain, Q30 */
const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
const opus_int order /* I Prediction order */
);
+/* For input in Q24 domain */
+opus_int32 silk_LPC_inverse_pred_gain_Q24( /* O Returns inverse prediction gain in energy domain, Q30 */
+ const opus_int32 *A_Q24, /* I Prediction coefficients [order] */
+ const opus_int order /* I Prediction order */
+);
+
/* Split signal in two decimated bands using first-order allpass filters */
void silk_ana_filt_bank_1(
const opus_int16 *in, /* I Input signal [N] */
@@ -159,14 +152,6 @@ void silk_ana_filt_bank_1(
const opus_int32 N /* I Number of input samples */
);
-#if !defined(OVERRIDE_silk_biquad_alt_stride2)
-#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))
-#endif
-
-#if !defined(OVERRIDE_silk_LPC_inverse_pred_gain)
-#define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((void)(arch), silk_LPC_inverse_pred_gain_c(A_Q12, order))
-#endif
-
/********************************************************************/
/* SCALAR FUNCTIONS */
/********************************************************************/
@@ -286,17 +271,7 @@ void silk_A2NLSF(
void silk_NLSF2A(
opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */
const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */
- const opus_int d, /* I filter order (should be even) */
- int arch /* I Run-time architecture */
-);
-
-/* Convert int32 coefficients to int16 coefs and make sure there's no wrap-around */
-void silk_LPC_fit(
- opus_int16 *a_QOUT, /* O Output signal */
- opus_int32 *a_QIN, /* I/O Input signal */
- const opus_int QOUT, /* I Input Q domain */
- const opus_int QIN, /* I Input Q domain */
- const opus_int d /* I Filter order */
+ const opus_int d /* I filter order (should be even) */
);
void silk_insertion_sort_increasing(
@@ -496,7 +471,8 @@ static OPUS_INLINE opus_int32 silk_ROR32( opus_int32 a32, opus_int rot )
/* Add with saturation for positive input values */
#define silk_ADD_POS_SAT8(a, b) ((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b)))
#define silk_ADD_POS_SAT16(a, b) ((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b)))
-#define silk_ADD_POS_SAT32(a, b) ((((opus_uint32)(a)+(opus_uint32)(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b)))
+#define silk_ADD_POS_SAT32(a, b) ((((a)+(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b)))
+#define silk_ADD_POS_SAT64(a, b) ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b)))
#define silk_LSHIFT8(a, shift) ((opus_int8)((opus_uint8)(a)<<(shift))) /* shift >= 0, shift < 8 */
#define silk_LSHIFT16(a, shift) ((opus_int16)((opus_uint16)(a)<<(shift))) /* shift >= 0, shift < 16 */
@@ -596,9 +572,7 @@ static OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b)
/* Make sure to store the result as the seed for the next call (also in between */
/* frames), otherwise result won't be random at all. When only using some of the */
/* bits, take the most significant bits by right-shifting. */
-#define RAND_MULTIPLIER 196314165
-#define RAND_INCREMENT 907633515
-#define silk_RAND(seed) (silk_MLA_ovflw((RAND_INCREMENT), (seed), (RAND_MULTIPLIER)))
+#define silk_RAND(seed) (silk_MLA_ovflw(907633515, (seed), 196314165))
/* Add some multiplication functions that can be easily mapped to ARM. */
diff --git a/thirdparty/opus/silk/VAD.c b/thirdparty/opus/silk/VAD.c
index d0cda52162..0a782af2f1 100644
--- a/thirdparty/opus/silk/VAD.c
+++ b/thirdparty/opus/silk/VAD.c
@@ -101,9 +101,9 @@ opus_int silk_VAD_GetSA_Q8_c( /* O Return v
/* Safety checks */
silk_assert( VAD_N_BANDS == 4 );
- celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
- celt_assert( psEncC->frame_length <= 512 );
- celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
+ silk_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
+ silk_assert( psEncC->frame_length <= 512 );
+ silk_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
/***********************/
/* Filter and Decimate */
@@ -252,14 +252,15 @@ opus_int silk_VAD_GetSA_Q8_c( /* O Return v
speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );
}
- if( psEncC->frame_length == 20 * psEncC->fs_kHz ) {
- speech_nrg = silk_RSHIFT32( speech_nrg, 1 );
- }
/* Power scaling */
if( speech_nrg <= 0 ) {
SA_Q15 = silk_RSHIFT( SA_Q15, 1 );
- } else if( speech_nrg < 16384 ) {
- speech_nrg = silk_LSHIFT32( speech_nrg, 16 );
+ } else if( speech_nrg < 32768 ) {
+ if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {
+ speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 16 );
+ } else {
+ speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 15 );
+ }
/* square-root */
speech_nrg = silk_SQRT_APPROX( speech_nrg );
@@ -312,8 +313,6 @@ void silk_VAD_GetNoiseLevels(
/* Initially faster smoothing */
if( psSilk_VAD->counter < 1000 ) { /* 1000 = 20 sec */
min_coef = silk_DIV32_16( silk_int16_MAX, silk_RSHIFT( psSilk_VAD->counter, 4 ) + 1 );
- /* Increment frame counter */
- psSilk_VAD->counter++;
} else {
min_coef = 0;
}
@@ -357,4 +356,7 @@ void silk_VAD_GetNoiseLevels(
/* Store as part of state */
psSilk_VAD->NL[ k ] = nl;
}
+
+ /* Increment frame counter */
+ psSilk_VAD->counter++;
}
diff --git a/thirdparty/opus/silk/VQ_WMat_EC.c b/thirdparty/opus/silk/VQ_WMat_EC.c
index 0f3d545c4e..7983f1db80 100644
--- a/thirdparty/opus/silk/VQ_WMat_EC.c
+++ b/thirdparty/opus/silk/VQ_WMat_EC.c
@@ -34,95 +34,84 @@ POSSIBILITY OF SUCH DAMAGE.
/* Entropy constrained matrix-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */
void silk_VQ_WMat_EC_c(
opus_int8 *ind, /* O index of best codebook vector */
- opus_int32 *res_nrg_Q15, /* O best residual energy */
- opus_int32 *rate_dist_Q8, /* O best total bitrate */
+ opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */
opus_int *gain_Q7, /* O sum of absolute LTP coefficients */
- const opus_int32 *XX_Q17, /* I correlation matrix */
- const opus_int32 *xX_Q17, /* I correlation vector */
+ const opus_int16 *in_Q14, /* I input vector to be quantized */
+ const opus_int32 *W_Q18, /* I weighting matrix */
const opus_int8 *cb_Q7, /* I codebook */
const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */
const opus_uint8 *cl_Q5, /* I code length for each codebook vector */
- const opus_int subfr_len, /* I number of samples per subframe */
+ const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */
const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
- const opus_int L /* I number of vectors in codebook */
+ opus_int L /* I number of vectors in codebook */
)
{
opus_int k, gain_tmp_Q7;
const opus_int8 *cb_row_Q7;
- opus_int32 neg_xX_Q24[ 5 ];
- opus_int32 sum1_Q15, sum2_Q24;
- opus_int32 bits_res_Q8, bits_tot_Q8;
-
- /* Negate and convert to new Q domain */
- neg_xX_Q24[ 0 ] = -silk_LSHIFT32( xX_Q17[ 0 ], 7 );
- neg_xX_Q24[ 1 ] = -silk_LSHIFT32( xX_Q17[ 1 ], 7 );
- neg_xX_Q24[ 2 ] = -silk_LSHIFT32( xX_Q17[ 2 ], 7 );
- neg_xX_Q24[ 3 ] = -silk_LSHIFT32( xX_Q17[ 3 ], 7 );
- neg_xX_Q24[ 4 ] = -silk_LSHIFT32( xX_Q17[ 4 ], 7 );
+ opus_int16 diff_Q14[ 5 ];
+ opus_int32 sum1_Q14, sum2_Q16;
/* Loop over codebook */
- *rate_dist_Q8 = silk_int32_MAX;
- *res_nrg_Q15 = silk_int32_MAX;
+ *rate_dist_Q14 = silk_int32_MAX;
cb_row_Q7 = cb_Q7;
- /* In things go really bad, at least *ind is set to something safe. */
- *ind = 0;
for( k = 0; k < L; k++ ) {
- opus_int32 penalty;
gain_tmp_Q7 = cb_gain_Q7[k];
+
+ diff_Q14[ 0 ] = in_Q14[ 0 ] - silk_LSHIFT( cb_row_Q7[ 0 ], 7 );
+ diff_Q14[ 1 ] = in_Q14[ 1 ] - silk_LSHIFT( cb_row_Q7[ 1 ], 7 );
+ diff_Q14[ 2 ] = in_Q14[ 2 ] - silk_LSHIFT( cb_row_Q7[ 2 ], 7 );
+ diff_Q14[ 3 ] = in_Q14[ 3 ] - silk_LSHIFT( cb_row_Q7[ 3 ], 7 );
+ diff_Q14[ 4 ] = in_Q14[ 4 ] - silk_LSHIFT( cb_row_Q7[ 4 ], 7 );
+
/* Weighted rate */
- /* Quantization error: 1 - 2 * xX * cb + cb' * XX * cb */
- sum1_Q15 = SILK_FIX_CONST( 1.001, 15 );
+ sum1_Q14 = silk_SMULBB( mu_Q9, cl_Q5[ k ] );
/* Penalty for too large gain */
- penalty = silk_LSHIFT32( silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 11 );
-
- /* first row of XX_Q17 */
- sum2_Q24 = silk_MLA( neg_xX_Q24[ 0 ], XX_Q17[ 1 ], cb_row_Q7[ 1 ] );
- sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 2 ], cb_row_Q7[ 2 ] );
- sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 3 ], cb_row_Q7[ 3 ] );
- sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 4 ], cb_row_Q7[ 4 ] );
- sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 );
- sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 0 ], cb_row_Q7[ 0 ] );
- sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 0 ] );
-
- /* second row of XX_Q17 */
- sum2_Q24 = silk_MLA( neg_xX_Q24[ 1 ], XX_Q17[ 7 ], cb_row_Q7[ 2 ] );
- sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 8 ], cb_row_Q7[ 3 ] );
- sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 9 ], cb_row_Q7[ 4 ] );
- sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 );
- sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 6 ], cb_row_Q7[ 1 ] );
- sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 1 ] );
-
- /* third row of XX_Q17 */
- sum2_Q24 = silk_MLA( neg_xX_Q24[ 2 ], XX_Q17[ 13 ], cb_row_Q7[ 3 ] );
- sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 14 ], cb_row_Q7[ 4 ] );
- sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 );
- sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 12 ], cb_row_Q7[ 2 ] );
- sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 2 ] );
-
- /* fourth row of XX_Q17 */
- sum2_Q24 = silk_MLA( neg_xX_Q24[ 3 ], XX_Q17[ 19 ], cb_row_Q7[ 4 ] );
- sum2_Q24 = silk_LSHIFT32( sum2_Q24, 1 );
- sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 18 ], cb_row_Q7[ 3 ] );
- sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 3 ] );
-
- /* last row of XX_Q17 */
- sum2_Q24 = silk_LSHIFT32( neg_xX_Q24[ 4 ], 1 );
- sum2_Q24 = silk_MLA( sum2_Q24, XX_Q17[ 24 ], cb_row_Q7[ 4 ] );
- sum1_Q15 = silk_SMLAWB( sum1_Q15, sum2_Q24, cb_row_Q7[ 4 ] );
+ sum1_Q14 = silk_ADD_LSHIFT32( sum1_Q14, silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 10 );
+
+ silk_assert( sum1_Q14 >= 0 );
+
+ /* first row of W_Q18 */
+ sum2_Q16 = silk_SMULWB( W_Q18[ 1 ], diff_Q14[ 1 ] );
+ sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 2 ], diff_Q14[ 2 ] );
+ sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 3 ], diff_Q14[ 3 ] );
+ sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 4 ], diff_Q14[ 4 ] );
+ sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );
+ sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 0 ], diff_Q14[ 0 ] );
+ sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 0 ] );
+
+ /* second row of W_Q18 */
+ sum2_Q16 = silk_SMULWB( W_Q18[ 7 ], diff_Q14[ 2 ] );
+ sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 8 ], diff_Q14[ 3 ] );
+ sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 9 ], diff_Q14[ 4 ] );
+ sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );
+ sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 6 ], diff_Q14[ 1 ] );
+ sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 1 ] );
+
+ /* third row of W_Q18 */
+ sum2_Q16 = silk_SMULWB( W_Q18[ 13 ], diff_Q14[ 3 ] );
+ sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 14 ], diff_Q14[ 4 ] );
+ sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );
+ sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 12 ], diff_Q14[ 2 ] );
+ sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 2 ] );
+
+ /* fourth row of W_Q18 */
+ sum2_Q16 = silk_SMULWB( W_Q18[ 19 ], diff_Q14[ 4 ] );
+ sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 );
+ sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 18 ], diff_Q14[ 3 ] );
+ sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 3 ] );
+
+ /* last row of W_Q18 */
+ sum2_Q16 = silk_SMULWB( W_Q18[ 24 ], diff_Q14[ 4 ] );
+ sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 4 ] );
+
+ silk_assert( sum1_Q14 >= 0 );
/* find best */
- if( sum1_Q15 >= 0 ) {
- /* Translate residual energy to bits using high-rate assumption (6 dB ==> 1 bit/sample) */
- bits_res_Q8 = silk_SMULBB( subfr_len, silk_lin2log( sum1_Q15 + penalty) - (15 << 7) );
- /* In the following line we reduce the codelength component by half ("-1"); seems to slghtly improve quality */
- bits_tot_Q8 = silk_ADD_LSHIFT32( bits_res_Q8, cl_Q5[ k ], 3-1 );
- if( bits_tot_Q8 <= *rate_dist_Q8 ) {
- *rate_dist_Q8 = bits_tot_Q8;
- *res_nrg_Q15 = sum1_Q15 + penalty;
- *ind = (opus_int8)k;
- *gain_Q7 = gain_tmp_Q7;
- }
+ if( sum1_Q14 < *rate_dist_Q14 ) {
+ *rate_dist_Q14 = sum1_Q14;
+ *ind = (opus_int8)k;
+ *gain_Q7 = gain_tmp_Q7;
}
/* Go to next cbk vector */
diff --git a/thirdparty/opus/silk/arm/LPC_inv_pred_gain_arm.h b/thirdparty/opus/silk/arm/LPC_inv_pred_gain_arm.h
deleted file mode 100644
index 9895b555c8..0000000000
--- a/thirdparty/opus/silk/arm/LPC_inv_pred_gain_arm.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/***********************************************************************
-Copyright (c) 2017 Google Inc.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-- Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-- Neither the name of Internet Society, IETF or IETF Trust, nor the
-names of specific contributors, may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-***********************************************************************/
-
-#ifndef SILK_LPC_INV_PRED_GAIN_ARM_H
-# define SILK_LPC_INV_PRED_GAIN_ARM_H
-
-# include "celt/arm/armcpu.h"
-
-# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
-opus_int32 silk_LPC_inverse_pred_gain_neon( /* O Returns inverse prediction gain in energy domain, Q30 */
- const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
- const opus_int order /* I Prediction order */
-);
-
-# if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON)
-# define OVERRIDE_silk_LPC_inverse_pred_gain (1)
-# define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((void)(arch), PRESUME_NEON(silk_LPC_inverse_pred_gain)(A_Q12, order))
-# endif
-# endif
-
-# if !defined(OVERRIDE_silk_LPC_inverse_pred_gain)
-/*Is run-time CPU detection enabled on this platform?*/
-# if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
-extern opus_int32 (*const SILK_LPC_INVERSE_PRED_GAIN_IMPL[OPUS_ARCHMASK+1])(const opus_int16 *A_Q12, const opus_int order);
-# define OVERRIDE_silk_LPC_inverse_pred_gain (1)
-# define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((*SILK_LPC_INVERSE_PRED_GAIN_IMPL[(arch)&OPUS_ARCHMASK])(A_Q12, order))
-# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
-# define OVERRIDE_silk_LPC_inverse_pred_gain (1)
-# define silk_LPC_inverse_pred_gain(A_Q12, order, arch) ((void)(arch), silk_LPC_inverse_pred_gain_neon(A_Q12, order))
-# endif
-# endif
-
-#endif /* end SILK_LPC_INV_PRED_GAIN_ARM_H */
diff --git a/thirdparty/opus/silk/arm/LPC_inv_pred_gain_neon_intr.c b/thirdparty/opus/silk/arm/LPC_inv_pred_gain_neon_intr.c
deleted file mode 100644
index ab426bcd66..0000000000
--- a/thirdparty/opus/silk/arm/LPC_inv_pred_gain_neon_intr.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/***********************************************************************
-Copyright (c) 2017 Google Inc.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-- Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-- Neither the name of Internet Society, IETF or IETF Trust, nor the
-names of specific contributors, may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <arm_neon.h>
-#include "SigProc_FIX.h"
-#include "define.h"
-
-#define QA 24
-#define A_LIMIT SILK_FIX_CONST( 0.99975, QA )
-
-#define MUL32_FRAC_Q(a32, b32, Q) ((opus_int32)(silk_RSHIFT_ROUND64(silk_SMULL(a32, b32), Q)))
-
-/* The difficulty is how to judge a 64-bit signed integer tmp64 is 32-bit overflowed,
- * since NEON has no 64-bit min, max or comparison instructions.
- * A failed idea is to compare the results of vmovn(tmp64) and vqmovn(tmp64) whether they are equal or not.
- * However, this idea fails when the tmp64 is something like 0xFFFFFFF980000000.
- * Here we know that mult2Q >= 1, so the highest bit (bit 63, sign bit) of tmp64 must equal to bit 62.
- * tmp64 was shifted left by 1 and we got tmp64'. If high_half(tmp64') != 0 and high_half(tmp64') != -1,
- * 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.
- * That is, we judge if tmp64' > 0x00000000FFFFFFFF, or tmp64' <= 0xFFFFFFFF00000000.
- * We use narrowing shift right 31 bits to tmp32' to save data bandwidth and instructions.
- * That is, we judge if tmp32' > 0x00000000, or tmp32' <= 0xFFFFFFFF.
- */
-
-/* Compute inverse of LPC prediction gain, and */
-/* test if LPC coefficients are stable (all poles within unit circle) */
-static OPUS_INLINE opus_int32 LPC_inverse_pred_gain_QA_neon( /* O Returns inverse prediction gain in energy domain, Q30 */
- opus_int32 A_QA[ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */
- const opus_int order /* I Prediction order */
-)
-{
- opus_int k, n, mult2Q;
- opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp1, tmp2;
- opus_int32 max, min;
- int32x4_t max_s32x4, min_s32x4;
- int32x2_t max_s32x2, min_s32x2;
-
- max_s32x4 = vdupq_n_s32( silk_int32_MIN );
- min_s32x4 = vdupq_n_s32( silk_int32_MAX );
- invGain_Q30 = SILK_FIX_CONST( 1, 30 );
- for( k = order - 1; k > 0; k-- ) {
- int32x2_t rc_Q31_s32x2, rc_mult2_s32x2;
- int64x2_t mult2Q_s64x2;
-
- /* Check for stability */
- if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) {
- return 0;
- }
-
- /* Set RC equal to negated AR coef */
- rc_Q31 = -silk_LSHIFT( A_QA[ k ], 31 - QA );
-
- /* rc_mult1_Q30 range: [ 1 : 2^30 ] */
- rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) );
- silk_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */
- silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) );
-
- /* Update inverse gain */
- /* invGain_Q30 range: [ 0 : 2^30 ] */
- invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
- silk_assert( invGain_Q30 >= 0 );
- silk_assert( invGain_Q30 <= ( 1 << 30 ) );
- if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
- return 0;
- }
-
- /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */
- mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) );
- rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 );
-
- /* Update AR coefficient */
- rc_Q31_s32x2 = vdup_n_s32( rc_Q31 );
- mult2Q_s64x2 = vdupq_n_s64( -mult2Q );
- rc_mult2_s32x2 = vdup_n_s32( rc_mult2 );
-
- for( n = 0; n < ( ( k + 1 ) >> 1 ) - 3; n += 4 ) {
- /* We always calculate extra elements of A_QA buffer when ( k % 4 ) != 0, to take the advantage of SIMD parallelization. */
- int32x4_t tmp1_s32x4, tmp2_s32x4, t0_s32x4, t1_s32x4, s0_s32x4, s1_s32x4, t_QA0_s32x4, t_QA1_s32x4;
- int64x2_t t0_s64x2, t1_s64x2, t2_s64x2, t3_s64x2;
- tmp1_s32x4 = vld1q_s32( A_QA + n );
- tmp2_s32x4 = vld1q_s32( A_QA + k - n - 4 );
- tmp2_s32x4 = vrev64q_s32( tmp2_s32x4 );
- tmp2_s32x4 = vcombine_s32( vget_high_s32( tmp2_s32x4 ), vget_low_s32( tmp2_s32x4 ) );
- t0_s32x4 = vqrdmulhq_lane_s32( tmp2_s32x4, rc_Q31_s32x2, 0 );
- t1_s32x4 = vqrdmulhq_lane_s32( tmp1_s32x4, rc_Q31_s32x2, 0 );
- t_QA0_s32x4 = vqsubq_s32( tmp1_s32x4, t0_s32x4 );
- t_QA1_s32x4 = vqsubq_s32( tmp2_s32x4, t1_s32x4 );
- t0_s64x2 = vmull_s32( vget_low_s32 ( t_QA0_s32x4 ), rc_mult2_s32x2 );
- t1_s64x2 = vmull_s32( vget_high_s32( t_QA0_s32x4 ), rc_mult2_s32x2 );
- t2_s64x2 = vmull_s32( vget_low_s32 ( t_QA1_s32x4 ), rc_mult2_s32x2 );
- t3_s64x2 = vmull_s32( vget_high_s32( t_QA1_s32x4 ), rc_mult2_s32x2 );
- t0_s64x2 = vrshlq_s64( t0_s64x2, mult2Q_s64x2 );
- t1_s64x2 = vrshlq_s64( t1_s64x2, mult2Q_s64x2 );
- t2_s64x2 = vrshlq_s64( t2_s64x2, mult2Q_s64x2 );
- t3_s64x2 = vrshlq_s64( t3_s64x2, mult2Q_s64x2 );
- t0_s32x4 = vcombine_s32( vmovn_s64( t0_s64x2 ), vmovn_s64( t1_s64x2 ) );
- t1_s32x4 = vcombine_s32( vmovn_s64( t2_s64x2 ), vmovn_s64( t3_s64x2 ) );
- s0_s32x4 = vcombine_s32( vshrn_n_s64( t0_s64x2, 31 ), vshrn_n_s64( t1_s64x2, 31 ) );
- s1_s32x4 = vcombine_s32( vshrn_n_s64( t2_s64x2, 31 ), vshrn_n_s64( t3_s64x2, 31 ) );
- max_s32x4 = vmaxq_s32( max_s32x4, s0_s32x4 );
- min_s32x4 = vminq_s32( min_s32x4, s0_s32x4 );
- max_s32x4 = vmaxq_s32( max_s32x4, s1_s32x4 );
- min_s32x4 = vminq_s32( min_s32x4, s1_s32x4 );
- t1_s32x4 = vrev64q_s32( t1_s32x4 );
- t1_s32x4 = vcombine_s32( vget_high_s32( t1_s32x4 ), vget_low_s32( t1_s32x4 ) );
- vst1q_s32( A_QA + n, t0_s32x4 );
- vst1q_s32( A_QA + k - n - 4, t1_s32x4 );
- }
- for( ; n < (k + 1) >> 1; n++ ) {
- opus_int64 tmp64;
- tmp1 = A_QA[ n ];
- tmp2 = A_QA[ k - n - 1 ];
- tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp1,
- MUL32_FRAC_Q( tmp2, rc_Q31, 31 ) ), rc_mult2 ), mult2Q);
- if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
- return 0;
- }
- A_QA[ n ] = ( opus_int32 )tmp64;
- tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp2,
- MUL32_FRAC_Q( tmp1, rc_Q31, 31 ) ), rc_mult2), mult2Q);
- if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
- return 0;
- }
- A_QA[ k - n - 1 ] = ( opus_int32 )tmp64;
- }
- }
-
- /* Check for stability */
- if( ( A_QA[ k ] > A_LIMIT ) || ( A_QA[ k ] < -A_LIMIT ) ) {
- return 0;
- }
-
- max_s32x2 = vmax_s32( vget_low_s32( max_s32x4 ), vget_high_s32( max_s32x4 ) );
- min_s32x2 = vmin_s32( vget_low_s32( min_s32x4 ), vget_high_s32( min_s32x4 ) );
- max_s32x2 = vmax_s32( max_s32x2, vreinterpret_s32_s64( vshr_n_s64( vreinterpret_s64_s32( max_s32x2 ), 32 ) ) );
- min_s32x2 = vmin_s32( min_s32x2, vreinterpret_s32_s64( vshr_n_s64( vreinterpret_s64_s32( min_s32x2 ), 32 ) ) );
- max = vget_lane_s32( max_s32x2, 0 );
- min = vget_lane_s32( min_s32x2, 0 );
- if( ( max > 0 ) || ( min < -1 ) ) {
- return 0;
- }
-
- /* Set RC equal to negated AR coef */
- rc_Q31 = -silk_LSHIFT( A_QA[ 0 ], 31 - QA );
-
- /* Range: [ 1 : 2^30 ] */
- rc_mult1_Q30 = silk_SUB32( SILK_FIX_CONST( 1, 30 ), silk_SMMUL( rc_Q31, rc_Q31 ) );
-
- /* Update inverse gain */
- /* Range: [ 0 : 2^30 ] */
- invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 );
- silk_assert( invGain_Q30 >= 0 );
- silk_assert( invGain_Q30 <= ( 1 << 30 ) );
- if( invGain_Q30 < SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN, 30 ) ) {
- return 0;
- }
-
- return invGain_Q30;
-}
-
-/* For input in Q12 domain */
-opus_int32 silk_LPC_inverse_pred_gain_neon( /* O Returns inverse prediction gain in energy domain, Q30 */
- const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
- const opus_int order /* I Prediction order */
-)
-{
-#ifdef OPUS_CHECK_ASM
- const opus_int32 invGain_Q30_c = silk_LPC_inverse_pred_gain_c( A_Q12, order );
-#endif
-
- opus_int32 invGain_Q30;
- if( ( SILK_MAX_ORDER_LPC != 24 ) || ( order & 1 )) {
- invGain_Q30 = silk_LPC_inverse_pred_gain_c( A_Q12, order );
- }
- else {
- opus_int32 Atmp_QA[ SILK_MAX_ORDER_LPC ];
- opus_int32 DC_resp;
- int16x8_t t0_s16x8, t1_s16x8, t2_s16x8;
- int32x4_t t0_s32x4;
- const opus_int leftover = order & 7;
-
- /* Increase Q domain of the AR coefficients */
- t0_s16x8 = vld1q_s16( A_Q12 + 0 );
- t1_s16x8 = vld1q_s16( A_Q12 + 8 );
- t2_s16x8 = vld1q_s16( A_Q12 + 16 );
- t0_s32x4 = vpaddlq_s16( t0_s16x8 );
-
- switch( order - leftover )
- {
- case 24:
- t0_s32x4 = vpadalq_s16( t0_s32x4, t2_s16x8 );
- /* FALLTHROUGH */
-
- case 16:
- t0_s32x4 = vpadalq_s16( t0_s32x4, t1_s16x8 );
- vst1q_s32( Atmp_QA + 16, vshll_n_s16( vget_low_s16 ( t2_s16x8 ), QA - 12 ) );
- vst1q_s32( Atmp_QA + 20, vshll_n_s16( vget_high_s16( t2_s16x8 ), QA - 12 ) );
- /* FALLTHROUGH */
-
- case 8:
- {
- const int32x2_t t_s32x2 = vpadd_s32( vget_low_s32( t0_s32x4 ), vget_high_s32( t0_s32x4 ) );
- const int64x1_t t_s64x1 = vpaddl_s32( t_s32x2 );
- DC_resp = vget_lane_s32( vreinterpret_s32_s64( t_s64x1 ), 0 );
- vst1q_s32( Atmp_QA + 8, vshll_n_s16( vget_low_s16 ( t1_s16x8 ), QA - 12 ) );
- vst1q_s32( Atmp_QA + 12, vshll_n_s16( vget_high_s16( t1_s16x8 ), QA - 12 ) );
- }
- break;
-
- default:
- DC_resp = 0;
- break;
- }
- A_Q12 += order - leftover;
-
- switch( leftover )
- {
- case 6:
- DC_resp += (opus_int32)A_Q12[ 5 ];
- DC_resp += (opus_int32)A_Q12[ 4 ];
- /* FALLTHROUGH */
-
- case 4:
- DC_resp += (opus_int32)A_Q12[ 3 ];
- DC_resp += (opus_int32)A_Q12[ 2 ];
- /* FALLTHROUGH */
-
- case 2:
- DC_resp += (opus_int32)A_Q12[ 1 ];
- DC_resp += (opus_int32)A_Q12[ 0 ];
- /* FALLTHROUGH */
-
- default:
- break;
- }
-
- /* If the DC is unstable, we don't even need to do the full calculations */
- if( DC_resp >= 4096 ) {
- invGain_Q30 = 0;
- } else {
- vst1q_s32( Atmp_QA + 0, vshll_n_s16( vget_low_s16 ( t0_s16x8 ), QA - 12 ) );
- vst1q_s32( Atmp_QA + 4, vshll_n_s16( vget_high_s16( t0_s16x8 ), QA - 12 ) );
- invGain_Q30 = LPC_inverse_pred_gain_QA_neon( Atmp_QA, order );
- }
- }
-
-#ifdef OPUS_CHECK_ASM
- silk_assert( invGain_Q30_c == invGain_Q30 );
-#endif
-
- return invGain_Q30;
-}
diff --git a/thirdparty/opus/silk/arm/NSQ_del_dec_arm.h b/thirdparty/opus/silk/arm/NSQ_del_dec_arm.h
deleted file mode 100644
index 9e76e16927..0000000000
--- a/thirdparty/opus/silk/arm/NSQ_del_dec_arm.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/***********************************************************************
-Copyright (c) 2017 Google Inc.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-- Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-- Neither the name of Internet Society, IETF or IETF Trust, nor the
-names of specific contributors, may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-***********************************************************************/
-
-#ifndef SILK_NSQ_DEL_DEC_ARM_H
-#define SILK_NSQ_DEL_DEC_ARM_H
-
-#include "celt/arm/armcpu.h"
-
-#if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
-void silk_NSQ_del_dec_neon(
- const silk_encoder_state *psEncC, silk_nsq_state *NSQ,
- SideInfoIndices *psIndices, const opus_int16 x16[], opus_int8 pulses[],
- const opus_int16 PredCoef_Q12[2 * MAX_LPC_ORDER],
- const opus_int16 LTPCoef_Q14[LTP_ORDER * MAX_NB_SUBFR],
- const opus_int16 AR_Q13[MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER],
- const opus_int HarmShapeGain_Q14[MAX_NB_SUBFR],
- const opus_int Tilt_Q14[MAX_NB_SUBFR],
- const opus_int32 LF_shp_Q14[MAX_NB_SUBFR],
- const opus_int32 Gains_Q16[MAX_NB_SUBFR],
- const opus_int pitchL[MAX_NB_SUBFR], const opus_int Lambda_Q10,
- const opus_int LTP_scale_Q14);
-
-#if !defined(OPUS_HAVE_RTCD)
-#define OVERRIDE_silk_NSQ_del_dec (1)
-#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \
- LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \
- LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \
- LTP_scale_Q14, arch) \
- ((void)(arch), \
- PRESUME_NEON(silk_NSQ_del_dec)( \
- psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, \
- AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, \
- Lambda_Q10, LTP_scale_Q14))
-#endif
-#endif
-
-#if !defined(OVERRIDE_silk_NSQ_del_dec)
-/*Is run-time CPU detection enabled on this platform?*/
-#if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && \
- !defined(OPUS_ARM_PRESUME_NEON_INTR))
-extern void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])(
- const silk_encoder_state *psEncC, silk_nsq_state *NSQ,
- SideInfoIndices *psIndices, const opus_int16 x16[], opus_int8 pulses[],
- const opus_int16 PredCoef_Q12[2 * MAX_LPC_ORDER],
- const opus_int16 LTPCoef_Q14[LTP_ORDER * MAX_NB_SUBFR],
- const opus_int16 AR_Q13[MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER],
- const opus_int HarmShapeGain_Q14[MAX_NB_SUBFR],
- const opus_int Tilt_Q14[MAX_NB_SUBFR],
- const opus_int32 LF_shp_Q14[MAX_NB_SUBFR],
- const opus_int32 Gains_Q16[MAX_NB_SUBFR],
- const opus_int pitchL[MAX_NB_SUBFR], const opus_int Lambda_Q10,
- const opus_int LTP_scale_Q14);
-#define OVERRIDE_silk_NSQ_del_dec (1)
-#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \
- LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \
- LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \
- LTP_scale_Q14, arch) \
- ((*SILK_NSQ_DEL_DEC_IMPL[(arch)&OPUS_ARCHMASK])( \
- psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, \
- AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, \
- Lambda_Q10, LTP_scale_Q14))
-#elif defined(OPUS_ARM_PRESUME_NEON_INTR)
-#define OVERRIDE_silk_NSQ_del_dec (1)
-#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \
- LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \
- LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \
- LTP_scale_Q14, arch) \
- ((void)(arch), \
- silk_NSQ_del_dec_neon(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, \
- LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14, Tilt_Q14, \
- LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, \
- LTP_scale_Q14))
-#endif
-#endif
-
-#endif /* end SILK_NSQ_DEL_DEC_ARM_H */
diff --git a/thirdparty/opus/silk/arm/NSQ_del_dec_neon_intr.c b/thirdparty/opus/silk/arm/NSQ_del_dec_neon_intr.c
deleted file mode 100644
index 212410f362..0000000000
--- a/thirdparty/opus/silk/arm/NSQ_del_dec_neon_intr.c
+++ /dev/null
@@ -1,1124 +0,0 @@
-/***********************************************************************
-Copyright (c) 2017 Google Inc.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-- Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-- Neither the name of Internet Society, IETF or IETF Trust, nor the
-names of specific contributors, may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <arm_neon.h>
-#ifdef OPUS_CHECK_ASM
-# include <string.h>
-#endif
-#include "main.h"
-#include "stack_alloc.h"
-
-/* NEON intrinsics optimization now can only parallelize up to 4 delay decision states. */
-/* If there are more states, C function is called, and this optimization must be expanded. */
-#define NEON_MAX_DEL_DEC_STATES 4
-
-typedef struct {
- opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ][ NEON_MAX_DEL_DEC_STATES ];
- opus_int32 RandState[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ];
- opus_int32 Q_Q10[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ];
- opus_int32 Xq_Q14[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ];
- opus_int32 Pred_Q15[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ];
- opus_int32 Shape_Q14[ DECISION_DELAY ][ NEON_MAX_DEL_DEC_STATES ];
- opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ][ NEON_MAX_DEL_DEC_STATES ];
- opus_int32 LF_AR_Q14[ NEON_MAX_DEL_DEC_STATES ];
- opus_int32 Diff_Q14[ NEON_MAX_DEL_DEC_STATES ];
- opus_int32 Seed[ NEON_MAX_DEL_DEC_STATES ];
- opus_int32 SeedInit[ NEON_MAX_DEL_DEC_STATES ];
- opus_int32 RD_Q10[ NEON_MAX_DEL_DEC_STATES ];
-} NSQ_del_decs_struct;
-
-typedef struct {
- opus_int32 Q_Q10[ NEON_MAX_DEL_DEC_STATES ];
- opus_int32 RD_Q10[ NEON_MAX_DEL_DEC_STATES ];
- opus_int32 xq_Q14[ NEON_MAX_DEL_DEC_STATES ];
- opus_int32 LF_AR_Q14[ NEON_MAX_DEL_DEC_STATES ];
- opus_int32 Diff_Q14[ NEON_MAX_DEL_DEC_STATES ];
- opus_int32 sLTP_shp_Q14[ NEON_MAX_DEL_DEC_STATES ];
- opus_int32 LPC_exc_Q14[ NEON_MAX_DEL_DEC_STATES ];
-} NSQ_samples_struct;
-
-static OPUS_INLINE void silk_nsq_del_dec_scale_states_neon(
- const silk_encoder_state *psEncC, /* I Encoder State */
- silk_nsq_state *NSQ, /* I/O NSQ state */
- NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */
- const opus_int16 x16[], /* I Input */
- opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
- const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
- opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
- opus_int subfr, /* I Subframe number */
- const opus_int LTP_scale_Q14, /* I LTP state scaling */
- const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
- const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
- const opus_int signal_type, /* I Signal type */
- const opus_int decisionDelay /* I Decision delay */
-);
-
-/******************************************/
-/* Noise shape quantizer for one subframe */
-/******************************************/
-static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_neon(
- silk_nsq_state *NSQ, /* I/O NSQ state */
- NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */
- opus_int signalType, /* I Signal type */
- const opus_int32 x_Q10[], /* I */
- opus_int8 pulses[], /* O */
- opus_int16 xq[], /* O */
- opus_int32 sLTP_Q15[], /* I/O LTP filter state */
- opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
- const opus_int16 a_Q12[], /* I Short term prediction coefs */
- const opus_int16 b_Q14[], /* I Long term prediction coefs */
- const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
- opus_int lag, /* I Pitch lag */
- opus_int32 HarmShapeFIRPacked_Q14, /* I */
- opus_int Tilt_Q14, /* I Spectral tilt */
- opus_int32 LF_shp_Q14, /* I */
- opus_int32 Gain_Q16, /* I */
- opus_int Lambda_Q10, /* I */
- opus_int offset_Q10, /* I */
- opus_int length, /* I Input length */
- opus_int subfr, /* I Subframe number */
- opus_int shapingLPCOrder, /* I Shaping LPC filter order */
- opus_int predictLPCOrder, /* I Prediction filter order */
- opus_int warping_Q16, /* I */
- opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
- opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
- opus_int decisionDelay /* I */
-);
-
-static OPUS_INLINE void copy_winner_state_kernel(
- const NSQ_del_decs_struct *psDelDec,
- const opus_int offset,
- const opus_int last_smple_idx,
- const opus_int Winner_ind,
- const int32x2_t gain_lo_s32x2,
- const int32x2_t gain_hi_s32x2,
- const int32x4_t shift_s32x4,
- int32x4_t t0_s32x4,
- int32x4_t t1_s32x4,
- opus_int8 *const pulses,
- opus_int16 *pxq,
- silk_nsq_state *NSQ
-)
-{
- int16x8_t t_s16x8;
- int32x4_t o0_s32x4, o1_s32x4;
-
- t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 0 ][ Winner_ind ], t0_s32x4, 0 );
- t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 1 ][ Winner_ind ], t0_s32x4, 1 );
- t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 2 ][ Winner_ind ], t0_s32x4, 2 );
- t0_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 3 ][ Winner_ind ], t0_s32x4, 3 );
- t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 4 ][ Winner_ind ], t1_s32x4, 0 );
- t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 5 ][ Winner_ind ], t1_s32x4, 1 );
- t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 6 ][ Winner_ind ], t1_s32x4, 2 );
- t1_s32x4 = vld1q_lane_s32( &psDelDec->Q_Q10[ last_smple_idx - 7 ][ Winner_ind ], t1_s32x4, 3 );
- t_s16x8 = vcombine_s16( vrshrn_n_s32( t0_s32x4, 10 ), vrshrn_n_s32( t1_s32x4, 10 ) );
- vst1_s8( &pulses[ offset ], vmovn_s16( t_s16x8 ) );
-
- t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 0 ][ Winner_ind ], t0_s32x4, 0 );
- t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 1 ][ Winner_ind ], t0_s32x4, 1 );
- t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 2 ][ Winner_ind ], t0_s32x4, 2 );
- t0_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 3 ][ Winner_ind ], t0_s32x4, 3 );
- t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 4 ][ Winner_ind ], t1_s32x4, 0 );
- t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 5 ][ Winner_ind ], t1_s32x4, 1 );
- t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 6 ][ Winner_ind ], t1_s32x4, 2 );
- t1_s32x4 = vld1q_lane_s32( &psDelDec->Xq_Q14[ last_smple_idx - 7 ][ Winner_ind ], t1_s32x4, 3 );
- o0_s32x4 = vqdmulhq_lane_s32( t0_s32x4, gain_lo_s32x2, 0 );
- o1_s32x4 = vqdmulhq_lane_s32( t1_s32x4, gain_lo_s32x2, 0 );
- o0_s32x4 = vmlaq_lane_s32( o0_s32x4, t0_s32x4, gain_hi_s32x2, 0 );
- o1_s32x4 = vmlaq_lane_s32( o1_s32x4, t1_s32x4, gain_hi_s32x2, 0 );
- o0_s32x4 = vrshlq_s32( o0_s32x4, shift_s32x4 );
- o1_s32x4 = vrshlq_s32( o1_s32x4, shift_s32x4 );
- vst1_s16( &pxq[ offset + 0 ], vqmovn_s32( o0_s32x4 ) );
- vst1_s16( &pxq[ offset + 4 ], vqmovn_s32( o1_s32x4 ) );
-
- t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 0 ][ Winner_ind ], t0_s32x4, 0 );
- t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 1 ][ Winner_ind ], t0_s32x4, 1 );
- t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 2 ][ Winner_ind ], t0_s32x4, 2 );
- t0_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 3 ][ Winner_ind ], t0_s32x4, 3 );
- t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 4 ][ Winner_ind ], t1_s32x4, 0 );
- t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 5 ][ Winner_ind ], t1_s32x4, 1 );
- t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 6 ][ Winner_ind ], t1_s32x4, 2 );
- t1_s32x4 = vld1q_lane_s32( &psDelDec->Shape_Q14[ last_smple_idx - 7 ][ Winner_ind ], t1_s32x4, 3 );
- vst1q_s32( &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx + offset + 0 ], t0_s32x4 );
- vst1q_s32( &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx + offset + 4 ], t1_s32x4 );
-}
-
-static OPUS_INLINE void copy_winner_state(
- const NSQ_del_decs_struct *psDelDec,
- const opus_int decisionDelay,
- const opus_int smpl_buf_idx,
- const opus_int Winner_ind,
- const opus_int32 gain,
- const opus_int32 shift,
- opus_int8 *const pulses,
- opus_int16 *pxq,
- silk_nsq_state *NSQ
-)
-{
- opus_int i, last_smple_idx;
- const int32x2_t gain_lo_s32x2 = vdup_n_s32( silk_LSHIFT32( gain & 0x0000FFFF, 15 ) );
- const int32x2_t gain_hi_s32x2 = vdup_n_s32( gain >> 16 );
- const int32x4_t shift_s32x4 = vdupq_n_s32( -shift );
- int32x4_t t0_s32x4, t1_s32x4;
-
- t0_s32x4 = t1_s32x4 = vdupq_n_s32( 0 ); /* initialization */
- last_smple_idx = smpl_buf_idx + decisionDelay - 1 + DECISION_DELAY;
- if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY;
- if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY;
-
- for( i = 0; ( i < ( decisionDelay - 7 ) ) && ( last_smple_idx >= 7 ); i += 8, last_smple_idx -= 8 ) {
- 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 );
- }
- for( ; ( i < decisionDelay ) && ( last_smple_idx >= 0 ); i++, last_smple_idx-- ) {
- pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDelDec->Q_Q10[ last_smple_idx ][ Winner_ind ], 10 );
- pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDelDec->Xq_Q14[ last_smple_idx ][ Winner_ind ], gain ), shift ) );
- NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDelDec->Shape_Q14[ last_smple_idx ][ Winner_ind ];
- }
-
- last_smple_idx += DECISION_DELAY;
- for( ; i < ( decisionDelay - 7 ); i++, last_smple_idx-- ) {
- 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 );
- }
- for( ; i < decisionDelay; i++, last_smple_idx-- ) {
- pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDelDec->Q_Q10[ last_smple_idx ][ Winner_ind ], 10 );
- pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( psDelDec->Xq_Q14[ last_smple_idx ][ Winner_ind ], gain ), shift ) );
- NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDelDec->Shape_Q14[ last_smple_idx ][ Winner_ind ];
- }
-}
-
-void silk_NSQ_del_dec_neon(
- const silk_encoder_state *psEncC, /* I Encoder State */
- silk_nsq_state *NSQ, /* I/O NSQ state */
- SideInfoIndices *psIndices, /* I/O Quantization Indices */
- const opus_int16 x16[], /* I Input */
- opus_int8 pulses[], /* O Quantized pulse signal */
- const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
- const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
- const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
- const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
- const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
- const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
- const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
- const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
- const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
- const opus_int LTP_scale_Q14 /* I LTP state scaling */
-)
-{
-#ifdef OPUS_CHECK_ASM
- silk_nsq_state NSQ_c;
- SideInfoIndices psIndices_c;
- opus_int8 pulses_c[ MAX_FRAME_LENGTH ];
- const opus_int8 *const pulses_a = pulses;
-
- ( void )pulses_a;
- silk_memcpy( &NSQ_c, NSQ, sizeof( NSQ_c ) );
- silk_memcpy( &psIndices_c, psIndices, sizeof( psIndices_c ) );
- silk_memcpy( pulses_c, pulses, sizeof( pulses_c ) );
- 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,
- pitchL, Lambda_Q10, LTP_scale_Q14 );
-#endif
-
- /* The optimization parallelizes the different delay decision states. */
- if(( psEncC->nStatesDelayedDecision > NEON_MAX_DEL_DEC_STATES ) || ( psEncC->nStatesDelayedDecision <= 2 )) {
- /* NEON intrinsics optimization now can only parallelize up to 4 delay decision states. */
- /* If there are more states, C function is called, and this optimization must be expanded. */
- /* When the number of delay decision states is less than 3, there are penalties using this */
- /* optimization, and C function is called. */
- /* When the number of delay decision states is 2, it's better to specialize another */
- /* structure NSQ_del_dec2_struct and optimize with shorter NEON registers. (Low priority) */
- silk_NSQ_del_dec_c( psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, HarmShapeGain_Q14,
- Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14 );
- } else {
- opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr;
- opus_int smpl_buf_idx, decisionDelay;
- const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13;
- opus_int16 *pxq;
- VARDECL( opus_int32, sLTP_Q15 );
- VARDECL( opus_int16, sLTP );
- opus_int32 HarmShapeFIRPacked_Q14;
- opus_int offset_Q10;
- opus_int32 RDmin_Q10, Gain_Q10;
- VARDECL( opus_int32, x_sc_Q10 );
- VARDECL( opus_int32, delayedGain_Q10 );
- VARDECL( NSQ_del_decs_struct, psDelDec );
- int32x4_t t_s32x4;
- SAVE_STACK;
-
- /* Set unvoiced lag to the previous one, overwrite later for voiced */
- lag = NSQ->lagPrev;
-
- silk_assert( NSQ->prev_gain_Q16 != 0 );
-
- /* Initialize delayed decision states */
- ALLOC( psDelDec, 1, NSQ_del_decs_struct );
- /* Only RandState and RD_Q10 need to be initialized to 0. */
- silk_memset( psDelDec->RandState, 0, sizeof( psDelDec->RandState ) );
- vst1q_s32( psDelDec->RD_Q10, vdupq_n_s32( 0 ) );
-
- for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) {
- psDelDec->SeedInit[ k ] = psDelDec->Seed[ k ] = ( k + psIndices->Seed ) & 3;
- }
- vst1q_s32( psDelDec->LF_AR_Q14, vld1q_dup_s32( &NSQ->sLF_AR_shp_Q14 ) );
- vst1q_s32( psDelDec->Diff_Q14, vld1q_dup_s32( &NSQ->sDiff_shp_Q14 ) );
- vst1q_s32( psDelDec->Shape_Q14[ 0 ], vld1q_dup_s32( &NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ] ) );
- for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
- vst1q_s32( psDelDec->sLPC_Q14[ i ], vld1q_dup_s32( &NSQ->sLPC_Q14[ i ] ) );
- }
- for( i = 0; i < (opus_int)( sizeof( NSQ->sAR2_Q14 ) / sizeof( NSQ->sAR2_Q14[ 0 ] ) ); i++ ) {
- vst1q_s32( psDelDec->sAR2_Q14[ i ], vld1q_dup_s32( &NSQ->sAR2_Q14[ i ] ) );
- }
-
- offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ];
- smpl_buf_idx = 0; /* index of oldest samples */
-
- decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length );
-
- /* For voiced frames limit the decision delay to lower than the pitch lag */
- if( psIndices->signalType == TYPE_VOICED ) {
- opus_int pitch_min = pitchL[ 0 ];
- for( k = 1; k < psEncC->nb_subfr; k++ ) {
- pitch_min = silk_min_int( pitch_min, pitchL[ k ] );
- }
- decisionDelay = silk_min_int( decisionDelay, pitch_min - LTP_ORDER / 2 - 1 );
- } else {
- if( lag > 0 ) {
- decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 );
- }
- }
-
- if( psIndices->NLSFInterpCoef_Q2 == 4 ) {
- LSF_interpolation_flag = 0;
- } else {
- LSF_interpolation_flag = 1;
- }
-
- ALLOC( sLTP_Q15, psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 );
- ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 );
- ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 );
- ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 );
- /* Set up pointers to start of sub frame */
- pxq = &NSQ->xq[ psEncC->ltp_mem_length ];
- NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length;
- NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
- subfr = 0;
- for( k = 0; k < psEncC->nb_subfr; k++ ) {
- A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ];
- B_Q14 = &LTPCoef_Q14[ k * LTP_ORDER ];
- AR_shp_Q13 = &AR_Q13[ k * MAX_SHAPE_LPC_ORDER ];
-
- /* Noise shape parameters */
- silk_assert( HarmShapeGain_Q14[ k ] >= 0 );
- HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 );
- HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 );
-
- NSQ->rewhite_flag = 0;
- if( psIndices->signalType == TYPE_VOICED ) {
- /* Voiced */
- lag = pitchL[ k ];
-
- /* Re-whitening */
- if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
- if( k == 2 ) {
- /* RESET DELAYED DECISIONS */
- /* Find winner */
- int32x4_t RD_Q10_s32x4;
- RDmin_Q10 = psDelDec->RD_Q10[ 0 ];
- Winner_ind = 0;
- for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) {
- if( psDelDec->RD_Q10[ i ] < RDmin_Q10 ) {
- RDmin_Q10 = psDelDec->RD_Q10[ i ];
- Winner_ind = i;
- }
- }
- psDelDec->RD_Q10[ Winner_ind ] -= ( silk_int32_MAX >> 4 );
- RD_Q10_s32x4 = vld1q_s32( psDelDec->RD_Q10 );
- RD_Q10_s32x4 = vaddq_s32( RD_Q10_s32x4, vdupq_n_s32( silk_int32_MAX >> 4 ) );
- vst1q_s32( psDelDec->RD_Q10, RD_Q10_s32x4 );
-
- /* Copy final part of signals from winner state to output and long-term filter states */
- copy_winner_state( psDelDec, decisionDelay, smpl_buf_idx, Winner_ind, Gains_Q16[ 1 ], 14, pulses, pxq, NSQ );
-
- subfr = 0;
- }
-
- /* Rewhiten with new A coefs */
- start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
- silk_assert( start_idx > 0 );
-
- silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
- A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
-
- NSQ->sLTP_buf_idx = psEncC->ltp_mem_length;
- NSQ->rewhite_flag = 1;
- }
- }
-
- silk_nsq_del_dec_scale_states_neon( psEncC, NSQ, psDelDec, x16, x_sc_Q10, sLTP, sLTP_Q15, k,
- LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay );
-
- silk_noise_shape_quantizer_del_dec_neon( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,
- delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ],
- Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,
- psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay );
-
- x16 += psEncC->subfr_length;
- pulses += psEncC->subfr_length;
- pxq += psEncC->subfr_length;
- }
-
- /* Find winner */
- RDmin_Q10 = psDelDec->RD_Q10[ 0 ];
- Winner_ind = 0;
- for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) {
- if( psDelDec->RD_Q10[ k ] < RDmin_Q10 ) {
- RDmin_Q10 = psDelDec->RD_Q10[ k ];
- Winner_ind = k;
- }
- }
-
- /* Copy final part of signals from winner state to output and long-term filter states */
- psIndices->Seed = psDelDec->SeedInit[ Winner_ind ];
- Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 );
- copy_winner_state( psDelDec, decisionDelay, smpl_buf_idx, Winner_ind, Gain_Q10, 8, pulses, pxq, NSQ );
-
- t_s32x4 = vdupq_n_s32( 0 ); /* initialization */
- for( i = 0; i < ( NSQ_LPC_BUF_LENGTH - 3 ); i += 4 ) {
- t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 0 ][ Winner_ind ], t_s32x4, 0 );
- t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 1 ][ Winner_ind ], t_s32x4, 1 );
- t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 2 ][ Winner_ind ], t_s32x4, 2 );
- t_s32x4 = vld1q_lane_s32( &psDelDec->sLPC_Q14[ i + 3 ][ Winner_ind ], t_s32x4, 3 );
- vst1q_s32( &NSQ->sLPC_Q14[ i ], t_s32x4 );
- }
-
- for( ; i < NSQ_LPC_BUF_LENGTH; i++ ) {
- NSQ->sLPC_Q14[ i ] = psDelDec->sLPC_Q14[ i ][ Winner_ind ];
- }
-
- for( i = 0; i < (opus_int)( sizeof( NSQ->sAR2_Q14 ) / sizeof( NSQ->sAR2_Q14[ 0 ] ) - 3 ); i += 4 ) {
- t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 0 ][ Winner_ind ], t_s32x4, 0 );
- t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 1 ][ Winner_ind ], t_s32x4, 1 );
- t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 2 ][ Winner_ind ], t_s32x4, 2 );
- t_s32x4 = vld1q_lane_s32( &psDelDec->sAR2_Q14[ i + 3 ][ Winner_ind ], t_s32x4, 3 );
- vst1q_s32( &NSQ->sAR2_Q14[ i ], t_s32x4 );
- }
-
- for( ; i < (opus_int)( sizeof( NSQ->sAR2_Q14 ) / sizeof( NSQ->sAR2_Q14[ 0 ] ) ); i++ ) {
- NSQ->sAR2_Q14[ i ] = psDelDec->sAR2_Q14[ i ][ Winner_ind ];
- }
-
- /* Update states */
- NSQ->sLF_AR_shp_Q14 = psDelDec->LF_AR_Q14[ Winner_ind ];
- NSQ->sDiff_shp_Q14 = psDelDec->Diff_Q14[ Winner_ind ];
- NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
-
- /* Save quantized speech signal */
- silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
- silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
- RESTORE_STACK;
- }
-
-#ifdef OPUS_CHECK_ASM
- silk_assert( !memcmp( &NSQ_c, NSQ, sizeof( NSQ_c ) ) );
- silk_assert( !memcmp( &psIndices_c, psIndices, sizeof( psIndices_c ) ) );
- silk_assert( !memcmp( pulses_c, pulses_a, sizeof( pulses_c ) ) );
-#endif
-}
-
-/******************************************/
-/* Noise shape quantizer for one subframe */
-/******************************************/
-/* Note: Function silk_short_prediction_create_arch_coef_neon() defined in NSQ_neon.h is actually a hacking C function. */
-/* Therefore here we append "_local" to the NEON function name to avoid confusion. */
-static OPUS_INLINE void silk_short_prediction_create_arch_coef_neon_local(opus_int32 *out, const opus_int16 *in, opus_int order)
-{
- int16x8_t t_s16x8;
- int32x4_t t0_s32x4, t1_s32x4, t2_s32x4, t3_s32x4;
- silk_assert( order == 10 || order == 16 );
-
- t_s16x8 = vld1q_s16( in + 0 ); /* 7 6 5 4 3 2 1 0 */
- t_s16x8 = vrev64q_s16( t_s16x8 ); /* 4 5 6 7 0 1 2 3 */
- t2_s32x4 = vshll_n_s16( vget_high_s16( t_s16x8 ), 15 ); /* 4 5 6 7 */
- t3_s32x4 = vshll_n_s16( vget_low_s16( t_s16x8 ), 15 ); /* 0 1 2 3 */
-
- if( order == 16 ) {
- t_s16x8 = vld1q_s16( in + 8 ); /* F E D C B A 9 8 */
- t_s16x8 = vrev64q_s16( t_s16x8 ); /* C D E F 8 9 A B */
- t0_s32x4 = vshll_n_s16( vget_high_s16( t_s16x8 ), 15 ); /* C D E F */
- t1_s32x4 = vshll_n_s16( vget_low_s16( t_s16x8 ), 15 ); /* 8 9 A B */
- } else {
- int16x4_t t_s16x4;
-
- t0_s32x4 = vdupq_n_s32( 0 ); /* zero zero zero zero */
- t_s16x4 = vld1_s16( in + 6 ); /* 9 8 7 6 */
- t_s16x4 = vrev64_s16( t_s16x4 ); /* 6 7 8 9 */
- t1_s32x4 = vshll_n_s16( t_s16x4, 15 );
- t1_s32x4 = vcombine_s32( vget_low_s32(t0_s32x4), vget_low_s32( t1_s32x4 ) ); /* 8 9 zero zero */
- }
- vst1q_s32( out + 0, t0_s32x4 );
- vst1q_s32( out + 4, t1_s32x4 );
- vst1q_s32( out + 8, t2_s32x4 );
- vst1q_s32( out + 12, t3_s32x4 );
-}
-
-static OPUS_INLINE int32x4_t silk_SMLAWB_lane0_neon(
- const int32x4_t out_s32x4,
- const int32x4_t in_s32x4,
- const int32x2_t coef_s32x2
-)
-{
- return vaddq_s32( out_s32x4, vqdmulhq_lane_s32( in_s32x4, coef_s32x2, 0 ) );
-}
-
-static OPUS_INLINE int32x4_t silk_SMLAWB_lane1_neon(
- const int32x4_t out_s32x4,
- const int32x4_t in_s32x4,
- const int32x2_t coef_s32x2
-)
-{
- return vaddq_s32( out_s32x4, vqdmulhq_lane_s32( in_s32x4, coef_s32x2, 1 ) );
-}
-
-/* Note: This function has different return value than silk_noise_shape_quantizer_short_prediction_neon(). */
-/* Therefore here we append "_local" to the function name to avoid confusion. */
-static 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)
-{
- const int32x4_t a_Q12_arch0_s32x4 = vld1q_s32( a_Q12_arch + 0 );
- const int32x4_t a_Q12_arch1_s32x4 = vld1q_s32( a_Q12_arch + 4 );
- const int32x4_t a_Q12_arch2_s32x4 = vld1q_s32( a_Q12_arch + 8 );
- const int32x4_t a_Q12_arch3_s32x4 = vld1q_s32( a_Q12_arch + 12 );
- int32x4_t LPC_pred_Q14_s32x4;
-
- silk_assert( order == 10 || order == 16 );
- /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
- LPC_pred_Q14_s32x4 = vdupq_n_s32( silk_RSHIFT( order, 1 ) );
- 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 ) );
- 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 ) );
- 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 ) );
- 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 ) );
- 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 ) );
- 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 ) );
- 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 ) );
- 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 ) );
- 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 ) );
- 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 ) );
- 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 ) );
- 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 ) );
- 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 ) );
- 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 ) );
- 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 ) );
- 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 ) );
-
- return LPC_pred_Q14_s32x4;
-}
-
-static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_neon(
- silk_nsq_state *NSQ, /* I/O NSQ state */
- NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */
- opus_int signalType, /* I Signal type */
- const opus_int32 x_Q10[], /* I */
- opus_int8 pulses[], /* O */
- opus_int16 xq[], /* O */
- opus_int32 sLTP_Q15[], /* I/O LTP filter state */
- opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */
- const opus_int16 a_Q12[], /* I Short term prediction coefs */
- const opus_int16 b_Q14[], /* I Long term prediction coefs */
- const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */
- opus_int lag, /* I Pitch lag */
- opus_int32 HarmShapeFIRPacked_Q14, /* I */
- opus_int Tilt_Q14, /* I Spectral tilt */
- opus_int32 LF_shp_Q14, /* I */
- opus_int32 Gain_Q16, /* I */
- opus_int Lambda_Q10, /* I */
- opus_int offset_Q10, /* I */
- opus_int length, /* I Input length */
- opus_int subfr, /* I Subframe number */
- opus_int shapingLPCOrder, /* I Shaping LPC filter order */
- opus_int predictLPCOrder, /* I Prediction filter order */
- opus_int warping_Q16, /* I */
- opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
- opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
- opus_int decisionDelay /* I */
-)
-{
- opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
- opus_int32 Winner_rand_state;
- opus_int32 LTP_pred_Q14, n_LTP_Q14;
- opus_int32 RDmin_Q10, RDmax_Q10;
- opus_int32 Gain_Q10;
- opus_int32 *pred_lag_ptr, *shp_lag_ptr;
- opus_int32 a_Q12_arch[MAX_LPC_ORDER];
- const int32x2_t warping_Q16_s32x2 = vdup_n_s32( silk_LSHIFT32( warping_Q16, 16 ) >> 1 );
- const opus_int32 LF_shp_Q29 = silk_LSHIFT32( LF_shp_Q14, 16 ) >> 1;
- opus_int32 AR_shp_Q28[ MAX_SHAPE_LPC_ORDER ];
- const uint32x4_t rand_multiplier_u32x4 = vdupq_n_u32( RAND_MULTIPLIER );
- const uint32x4_t rand_increment_u32x4 = vdupq_n_u32( RAND_INCREMENT );
-
- VARDECL( NSQ_samples_struct, psSampleState );
- SAVE_STACK;
-
- silk_assert( nStatesDelayedDecision > 0 );
- silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
- ALLOC( psSampleState, 2, NSQ_samples_struct );
-
- shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
- pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
- Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
-
- for( i = 0; i < ( MAX_SHAPE_LPC_ORDER - 7 ); i += 8 ) {
- const int16x8_t t_s16x8 = vld1q_s16( AR_shp_Q13 + i );
- vst1q_s32( AR_shp_Q28 + i + 0, vshll_n_s16( vget_low_s16( t_s16x8 ), 15 ) );
- vst1q_s32( AR_shp_Q28 + i + 4, vshll_n_s16( vget_high_s16( t_s16x8 ), 15 ) );
- }
-
- for( ; i < MAX_SHAPE_LPC_ORDER; i++ ) {
- AR_shp_Q28[i] = silk_LSHIFT32( AR_shp_Q13[i], 15 );
- }
-
- silk_short_prediction_create_arch_coef_neon_local( a_Q12_arch, a_Q12, predictLPCOrder );
-
- for( i = 0; i < length; i++ ) {
- int32x4_t Seed_s32x4, LPC_pred_Q14_s32x4;
- int32x4_t sign_s32x4, tmp1_s32x4, tmp2_s32x4;
- int32x4_t n_AR_Q14_s32x4, n_LF_Q14_s32x4;
- int32x2_t AR_shp_Q28_s32x2;
- int16x4_t r_Q10_s16x4, rr_Q10_s16x4;
-
- /* Perform common calculations used in all states */
-
- /* Long-term prediction */
- if( signalType == TYPE_VOICED ) {
- /* Unrolled loop */
- /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
- LTP_pred_Q14 = 2;
- LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ 0 ], b_Q14[ 0 ] );
- LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] );
- LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] );
- LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] );
- LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] );
- LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */
- pred_lag_ptr++;
- } else {
- LTP_pred_Q14 = 0;
- }
-
- /* Long-term shaping */
- if( lag > 0 ) {
- /* Symmetric, packed FIR coefficients */
- n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 );
- n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 );
- n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */
- shp_lag_ptr++;
- } else {
- n_LTP_Q14 = 0;
- }
-
- /* Generate dither */
- Seed_s32x4 = vld1q_s32( psDelDec->Seed );
- Seed_s32x4 = vreinterpretq_s32_u32( vmlaq_u32( rand_increment_u32x4, vreinterpretq_u32_s32( Seed_s32x4 ), rand_multiplier_u32x4 ) );
- vst1q_s32( psDelDec->Seed, Seed_s32x4 );
-
- /* Short-term prediction */
- 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);
- LPC_pred_Q14_s32x4 = vshlq_n_s32( LPC_pred_Q14_s32x4, 4 ); /* Q10 -> Q14 */
-
- /* Noise shape feedback */
- /* Output of lowpass section */
- tmp2_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->Diff_Q14 ), vld1q_s32( psDelDec->sAR2_Q14[ 0 ] ), warping_Q16_s32x2 );
- /* Output of allpass section */
- tmp1_s32x4 = vsubq_s32( vld1q_s32( psDelDec->sAR2_Q14[ 1 ] ), tmp2_s32x4 );
- tmp1_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->sAR2_Q14[ 0 ] ), tmp1_s32x4, warping_Q16_s32x2 );
- vst1q_s32( psDelDec->sAR2_Q14[ 0 ], tmp2_s32x4 );
- AR_shp_Q28_s32x2 = vld1_s32( AR_shp_Q28 );
- n_AR_Q14_s32x4 = vaddq_s32( vdupq_n_s32( silk_RSHIFT( shapingLPCOrder, 1 ) ), vqdmulhq_lane_s32( tmp2_s32x4, AR_shp_Q28_s32x2, 0 ) );
-
- /* Loop over allpass sections */
- for( j = 2; j < shapingLPCOrder; j += 2 ) {
- /* Output of allpass section */
- tmp2_s32x4 = vsubq_s32( vld1q_s32( psDelDec->sAR2_Q14[ j + 0 ] ), tmp1_s32x4 );
- tmp2_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->sAR2_Q14[ j - 1 ] ), tmp2_s32x4, warping_Q16_s32x2 );
- vst1q_s32( psDelDec->sAR2_Q14[ j - 1 ], tmp1_s32x4 );
- n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_lane_s32( tmp1_s32x4, AR_shp_Q28_s32x2, 1 ) );
- /* Output of allpass section */
- tmp1_s32x4 = vsubq_s32( vld1q_s32( psDelDec->sAR2_Q14[ j + 1 ] ), tmp2_s32x4 );
- tmp1_s32x4 = silk_SMLAWB_lane0_neon( vld1q_s32( psDelDec->sAR2_Q14[ j + 0 ] ), tmp1_s32x4, warping_Q16_s32x2 );
- vst1q_s32( psDelDec->sAR2_Q14[ j + 0 ], tmp2_s32x4 );
- AR_shp_Q28_s32x2 = vld1_s32( &AR_shp_Q28[ j ] );
- n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_lane_s32( tmp2_s32x4, AR_shp_Q28_s32x2, 0 ) );
- }
- vst1q_s32( psDelDec->sAR2_Q14[ shapingLPCOrder - 1 ], tmp1_s32x4 );
- n_AR_Q14_s32x4 = vaddq_s32( n_AR_Q14_s32x4, vqdmulhq_lane_s32( tmp1_s32x4, AR_shp_Q28_s32x2, 1 ) );
- n_AR_Q14_s32x4 = vshlq_n_s32( n_AR_Q14_s32x4, 1 ); /* Q11 -> Q12 */
- 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 */
- n_AR_Q14_s32x4 = vshlq_n_s32( n_AR_Q14_s32x4, 2 ); /* Q12 -> Q14 */
- n_LF_Q14_s32x4 = vqdmulhq_n_s32( vld1q_s32( psDelDec->Shape_Q14[ *smpl_buf_idx ] ), LF_shp_Q29 ); /* Q12 */
- 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 */
- n_LF_Q14_s32x4 = vshlq_n_s32( n_LF_Q14_s32x4, 2 ); /* Q12 -> Q14 */
-
- /* Input minus prediction plus noise feedback */
- /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */
- tmp1_s32x4 = vaddq_s32( n_AR_Q14_s32x4, n_LF_Q14_s32x4 ); /* Q14 */
- tmp2_s32x4 = vaddq_s32( vdupq_n_s32( n_LTP_Q14 ), LPC_pred_Q14_s32x4 ); /* Q13 */
- tmp1_s32x4 = vsubq_s32( tmp2_s32x4, tmp1_s32x4 ); /* Q13 */
- tmp1_s32x4 = vrshrq_n_s32( tmp1_s32x4, 4 ); /* Q10 */
- tmp1_s32x4 = vsubq_s32( vdupq_n_s32( x_Q10[ i ] ), tmp1_s32x4 ); /* residual error Q10 */
-
- /* Flip sign depending on dither */
- sign_s32x4 = vreinterpretq_s32_u32( vcltq_s32( Seed_s32x4, vdupq_n_s32( 0 ) ) );
- tmp1_s32x4 = veorq_s32( tmp1_s32x4, sign_s32x4 );
- tmp1_s32x4 = vsubq_s32( tmp1_s32x4, sign_s32x4 );
- tmp1_s32x4 = vmaxq_s32( tmp1_s32x4, vdupq_n_s32( -( 31 << 10 ) ) );
- tmp1_s32x4 = vminq_s32( tmp1_s32x4, vdupq_n_s32( 30 << 10 ) );
- r_Q10_s16x4 = vmovn_s32( tmp1_s32x4 );
-
- /* Find two quantization level candidates and measure their rate-distortion */
- {
- int16x4_t q1_Q10_s16x4 = vsub_s16( r_Q10_s16x4, vdup_n_s16( offset_Q10 ) );
- int16x4_t q1_Q0_s16x4 = vshr_n_s16( q1_Q10_s16x4, 10 );
- int16x4_t q2_Q10_s16x4;
- int32x4_t rd1_Q10_s32x4, rd2_Q10_s32x4;
- uint32x4_t t_u32x4;
-
- if( Lambda_Q10 > 2048 ) {
- /* For aggressive RDO, the bias becomes more than one pulse. */
- const int rdo_offset = Lambda_Q10/2 - 512;
- const uint16x4_t greaterThanRdo = vcgt_s16( q1_Q10_s16x4, vdup_n_s16( rdo_offset ) );
- const uint16x4_t lessThanMinusRdo = vclt_s16( q1_Q10_s16x4, vdup_n_s16( -rdo_offset ) );
- /* If Lambda_Q10 > 32767, then q1_Q0, q1_Q10 and q2_Q10 must change to 32-bit. */
- silk_assert( Lambda_Q10 <= 32767 );
-
- q1_Q0_s16x4 = vreinterpret_s16_u16( vclt_s16( q1_Q10_s16x4, vdup_n_s16( 0 ) ) );
- q1_Q0_s16x4 = vbsl_s16( greaterThanRdo, vsub_s16( q1_Q10_s16x4, vdup_n_s16( rdo_offset ) ), q1_Q0_s16x4 );
- q1_Q0_s16x4 = vbsl_s16( lessThanMinusRdo, vadd_s16( q1_Q10_s16x4, vdup_n_s16( rdo_offset ) ), q1_Q0_s16x4 );
- q1_Q0_s16x4 = vshr_n_s16( q1_Q0_s16x4, 10 );
- }
- {
- const uint16x4_t equal0_u16x4 = vceq_s16( q1_Q0_s16x4, vdup_n_s16( 0 ) );
- const uint16x4_t equalMinus1_u16x4 = vceq_s16( q1_Q0_s16x4, vdup_n_s16( -1 ) );
- const uint16x4_t lessThanMinus1_u16x4 = vclt_s16( q1_Q0_s16x4, vdup_n_s16( -1 ) );
- int16x4_t tmp1_s16x4, tmp2_s16x4;
-
- q1_Q10_s16x4 = vshl_n_s16( q1_Q0_s16x4, 10 );
- tmp1_s16x4 = vadd_s16( q1_Q10_s16x4, vdup_n_s16( offset_Q10 - QUANT_LEVEL_ADJUST_Q10 ) );
- q1_Q10_s16x4 = vadd_s16( q1_Q10_s16x4, vdup_n_s16( offset_Q10 + QUANT_LEVEL_ADJUST_Q10 ) );
- q1_Q10_s16x4 = vbsl_s16( lessThanMinus1_u16x4, q1_Q10_s16x4, tmp1_s16x4 );
- q1_Q10_s16x4 = vbsl_s16( equal0_u16x4, vdup_n_s16( offset_Q10 ), q1_Q10_s16x4 );
- q1_Q10_s16x4 = vbsl_s16( equalMinus1_u16x4, vdup_n_s16( offset_Q10 - ( 1024 - QUANT_LEVEL_ADJUST_Q10 ) ), q1_Q10_s16x4 );
- q2_Q10_s16x4 = vadd_s16( q1_Q10_s16x4, vdup_n_s16( 1024 ) );
- q2_Q10_s16x4 = vbsl_s16( equal0_u16x4, vdup_n_s16( offset_Q10 + 1024 - QUANT_LEVEL_ADJUST_Q10 ), q2_Q10_s16x4 );
- q2_Q10_s16x4 = vbsl_s16( equalMinus1_u16x4, vdup_n_s16( offset_Q10 ), q2_Q10_s16x4 );
- tmp1_s16x4 = q1_Q10_s16x4;
- tmp2_s16x4 = q2_Q10_s16x4;
- tmp1_s16x4 = vbsl_s16( vorr_u16( equalMinus1_u16x4, lessThanMinus1_u16x4 ), vneg_s16( tmp1_s16x4 ), tmp1_s16x4 );
- tmp2_s16x4 = vbsl_s16( lessThanMinus1_u16x4, vneg_s16( tmp2_s16x4 ), tmp2_s16x4 );
- rd1_Q10_s32x4 = vmull_s16( tmp1_s16x4, vdup_n_s16( Lambda_Q10 ) );
- rd2_Q10_s32x4 = vmull_s16( tmp2_s16x4, vdup_n_s16( Lambda_Q10 ) );
- }
-
- rr_Q10_s16x4 = vsub_s16( r_Q10_s16x4, q1_Q10_s16x4 );
- rd1_Q10_s32x4 = vmlal_s16( rd1_Q10_s32x4, rr_Q10_s16x4, rr_Q10_s16x4 );
- rd1_Q10_s32x4 = vshrq_n_s32( rd1_Q10_s32x4, 10 );
-
- rr_Q10_s16x4 = vsub_s16( r_Q10_s16x4, q2_Q10_s16x4 );
- rd2_Q10_s32x4 = vmlal_s16( rd2_Q10_s32x4, rr_Q10_s16x4, rr_Q10_s16x4 );
- rd2_Q10_s32x4 = vshrq_n_s32( rd2_Q10_s32x4, 10 );
-
- tmp2_s32x4 = vld1q_s32( psDelDec->RD_Q10 );
- tmp1_s32x4 = vaddq_s32( tmp2_s32x4, vminq_s32( rd1_Q10_s32x4, rd2_Q10_s32x4 ) );
- tmp2_s32x4 = vaddq_s32( tmp2_s32x4, vmaxq_s32( rd1_Q10_s32x4, rd2_Q10_s32x4 ) );
- vst1q_s32( psSampleState[ 0 ].RD_Q10, tmp1_s32x4 );
- vst1q_s32( psSampleState[ 1 ].RD_Q10, tmp2_s32x4 );
- t_u32x4 = vcltq_s32( rd1_Q10_s32x4, rd2_Q10_s32x4 );
- tmp1_s32x4 = vbslq_s32( t_u32x4, vmovl_s16( q1_Q10_s16x4 ), vmovl_s16( q2_Q10_s16x4 ) );
- tmp2_s32x4 = vbslq_s32( t_u32x4, vmovl_s16( q2_Q10_s16x4 ), vmovl_s16( q1_Q10_s16x4 ) );
- vst1q_s32( psSampleState[ 0 ].Q_Q10, tmp1_s32x4 );
- vst1q_s32( psSampleState[ 1 ].Q_Q10, tmp2_s32x4 );
- }
-
- {
- /* Update states for best quantization */
- int32x4_t exc_Q14_s32x4, LPC_exc_Q14_s32x4, xq_Q14_s32x4, sLF_AR_shp_Q14_s32x4;
-
- /* Quantized excitation */
- exc_Q14_s32x4 = vshlq_n_s32( tmp1_s32x4, 4 );
- exc_Q14_s32x4 = veorq_s32( exc_Q14_s32x4, sign_s32x4 );
- exc_Q14_s32x4 = vsubq_s32( exc_Q14_s32x4, sign_s32x4 );
-
- /* Add predictions */
- LPC_exc_Q14_s32x4 = vaddq_s32( exc_Q14_s32x4, vdupq_n_s32( LTP_pred_Q14 ) );
- xq_Q14_s32x4 = vaddq_s32( LPC_exc_Q14_s32x4, LPC_pred_Q14_s32x4 );
-
- /* Update states */
- tmp1_s32x4 = vsubq_s32( xq_Q14_s32x4, vshlq_n_s32( vdupq_n_s32( x_Q10[ i ] ), 4 ) );
- vst1q_s32( psSampleState[ 0 ].Diff_Q14, tmp1_s32x4 );
- sLF_AR_shp_Q14_s32x4 = vsubq_s32( tmp1_s32x4, n_AR_Q14_s32x4 );
- vst1q_s32( psSampleState[ 0 ].sLTP_shp_Q14, vsubq_s32( sLF_AR_shp_Q14_s32x4, n_LF_Q14_s32x4 ) );
- vst1q_s32( psSampleState[ 0 ].LF_AR_Q14, sLF_AR_shp_Q14_s32x4 );
- vst1q_s32( psSampleState[ 0 ].LPC_exc_Q14, LPC_exc_Q14_s32x4 );
- vst1q_s32( psSampleState[ 0 ].xq_Q14, xq_Q14_s32x4 );
-
- /* Quantized excitation */
- exc_Q14_s32x4 = vshlq_n_s32( tmp2_s32x4, 4 );
- exc_Q14_s32x4 = veorq_s32( exc_Q14_s32x4, sign_s32x4 );
- exc_Q14_s32x4 = vsubq_s32( exc_Q14_s32x4, sign_s32x4 );
-
- /* Add predictions */
- LPC_exc_Q14_s32x4 = vaddq_s32( exc_Q14_s32x4, vdupq_n_s32( LTP_pred_Q14 ) );
- xq_Q14_s32x4 = vaddq_s32( LPC_exc_Q14_s32x4, LPC_pred_Q14_s32x4 );
-
- /* Update states */
- tmp1_s32x4 = vsubq_s32( xq_Q14_s32x4, vshlq_n_s32( vdupq_n_s32( x_Q10[ i ] ), 4 ) );
- vst1q_s32( psSampleState[ 1 ].Diff_Q14, tmp1_s32x4 );
- sLF_AR_shp_Q14_s32x4 = vsubq_s32( tmp1_s32x4, n_AR_Q14_s32x4 );
- vst1q_s32( psSampleState[ 1 ].sLTP_shp_Q14, vsubq_s32( sLF_AR_shp_Q14_s32x4, n_LF_Q14_s32x4 ) );
- vst1q_s32( psSampleState[ 1 ].LF_AR_Q14, sLF_AR_shp_Q14_s32x4 );
- vst1q_s32( psSampleState[ 1 ].LPC_exc_Q14, LPC_exc_Q14_s32x4 );
- vst1q_s32( psSampleState[ 1 ].xq_Q14, xq_Q14_s32x4 );
- }
-
- *smpl_buf_idx = *smpl_buf_idx ? ( *smpl_buf_idx - 1 ) : ( DECISION_DELAY - 1);
- last_smple_idx = *smpl_buf_idx + decisionDelay + DECISION_DELAY;
- if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY;
- if( last_smple_idx >= DECISION_DELAY ) last_smple_idx -= DECISION_DELAY;
-
- /* Find winner */
- RDmin_Q10 = psSampleState[ 0 ].RD_Q10[ 0 ];
- Winner_ind = 0;
- for( k = 1; k < nStatesDelayedDecision; k++ ) {
- if( psSampleState[ 0 ].RD_Q10[ k ] < RDmin_Q10 ) {
- RDmin_Q10 = psSampleState[ 0 ].RD_Q10[ k ];
- Winner_ind = k;
- }
- }
-
- /* Increase RD values of expired states */
- {
- uint32x4_t t_u32x4;
- Winner_rand_state = psDelDec->RandState[ last_smple_idx ][ Winner_ind ];
- t_u32x4 = vceqq_s32( vld1q_s32( psDelDec->RandState[ last_smple_idx ] ), vdupq_n_s32( Winner_rand_state ) );
- t_u32x4 = vmvnq_u32( t_u32x4 );
- t_u32x4 = vshrq_n_u32( t_u32x4, 5 );
- tmp1_s32x4 = vld1q_s32( psSampleState[ 0 ].RD_Q10 );
- tmp2_s32x4 = vld1q_s32( psSampleState[ 1 ].RD_Q10 );
- tmp1_s32x4 = vaddq_s32( tmp1_s32x4, vreinterpretq_s32_u32( t_u32x4 ) );
- tmp2_s32x4 = vaddq_s32( tmp2_s32x4, vreinterpretq_s32_u32( t_u32x4 ) );
- vst1q_s32( psSampleState[ 0 ].RD_Q10, tmp1_s32x4 );
- vst1q_s32( psSampleState[ 1 ].RD_Q10, tmp2_s32x4 );
-
- /* Find worst in first set and best in second set */
- RDmax_Q10 = psSampleState[ 0 ].RD_Q10[ 0 ];
- RDmin_Q10 = psSampleState[ 1 ].RD_Q10[ 0 ];
- RDmax_ind = 0;
- RDmin_ind = 0;
- for( k = 1; k < nStatesDelayedDecision; k++ ) {
- /* find worst in first set */
- if( psSampleState[ 0 ].RD_Q10[ k ] > RDmax_Q10 ) {
- RDmax_Q10 = psSampleState[ 0 ].RD_Q10[ k ];
- RDmax_ind = k;
- }
- /* find best in second set */
- if( psSampleState[ 1 ].RD_Q10[ k ] < RDmin_Q10 ) {
- RDmin_Q10 = psSampleState[ 1 ].RD_Q10[ k ];
- RDmin_ind = k;
- }
- }
- }
-
- /* Replace a state if best from second set outperforms worst in first set */
- if( RDmin_Q10 < RDmax_Q10 ) {
- opus_int32 (*ptr)[NEON_MAX_DEL_DEC_STATES] = psDelDec->RandState;
- const int numOthers = (int)( ( sizeof( NSQ_del_decs_struct ) - sizeof( ( (NSQ_del_decs_struct *)0 )->sLPC_Q14 ) )
- / ( NEON_MAX_DEL_DEC_STATES * sizeof( opus_int32 ) ) );
- /* Only ( predictLPCOrder - 1 ) of sLPC_Q14 buffer need to be updated, though the first several */
- /* useless sLPC_Q14[] will be different comparing with C when predictLPCOrder < NSQ_LPC_BUF_LENGTH. */
- /* Here just update constant ( NSQ_LPC_BUF_LENGTH - 1 ) for simplicity. */
- for( j = i + 1; j < i + NSQ_LPC_BUF_LENGTH; j++ ) {
- psDelDec->sLPC_Q14[ j ][ RDmax_ind ] = psDelDec->sLPC_Q14[ j ][ RDmin_ind ];
- }
- for( j = 0; j < numOthers; j++ ) {
- ptr[ j ][ RDmax_ind ] = ptr[ j ][ RDmin_ind ];
- }
-
- psSampleState[ 0 ].Q_Q10[ RDmax_ind ] = psSampleState[ 1 ].Q_Q10[ RDmin_ind ];
- psSampleState[ 0 ].RD_Q10[ RDmax_ind ] = psSampleState[ 1 ].RD_Q10[ RDmin_ind ];
- psSampleState[ 0 ].xq_Q14[ RDmax_ind ] = psSampleState[ 1 ].xq_Q14[ RDmin_ind ];
- psSampleState[ 0 ].LF_AR_Q14[ RDmax_ind ] = psSampleState[ 1 ].LF_AR_Q14[ RDmin_ind ];
- psSampleState[ 0 ].Diff_Q14[ RDmax_ind ] = psSampleState[ 1 ].Diff_Q14[ RDmin_ind ];
- psSampleState[ 0 ].sLTP_shp_Q14[ RDmax_ind ] = psSampleState[ 1 ].sLTP_shp_Q14[ RDmin_ind ];
- psSampleState[ 0 ].LPC_exc_Q14[ RDmax_ind ] = psSampleState[ 1 ].LPC_exc_Q14[ RDmin_ind ];
- }
-
- /* Write samples from winner to output and long-term filter states */
- if( subfr > 0 || i >= decisionDelay ) {
- pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDelDec->Q_Q10[ last_smple_idx ][ Winner_ind ], 10 );
- xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
- silk_SMULWW( psDelDec->Xq_Q14[ last_smple_idx ][ Winner_ind ], delayedGain_Q10[ last_smple_idx ] ), 8 ) );
- NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDelDec->Shape_Q14[ last_smple_idx ][ Winner_ind ];
- sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDelDec->Pred_Q15[ last_smple_idx ][ Winner_ind ];
- }
- NSQ->sLTP_shp_buf_idx++;
- NSQ->sLTP_buf_idx++;
-
- /* Update states */
- vst1q_s32( psDelDec->LF_AR_Q14, vld1q_s32( psSampleState[ 0 ].LF_AR_Q14 ) );
- vst1q_s32( psDelDec->Diff_Q14, vld1q_s32( psSampleState[ 0 ].Diff_Q14 ) );
- vst1q_s32( psDelDec->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ], vld1q_s32( psSampleState[ 0 ].xq_Q14 ) );
- vst1q_s32( psDelDec->Xq_Q14[ *smpl_buf_idx ], vld1q_s32( psSampleState[ 0 ].xq_Q14 ) );
- tmp1_s32x4 = vld1q_s32( psSampleState[ 0 ].Q_Q10 );
- vst1q_s32( psDelDec->Q_Q10[ *smpl_buf_idx ], tmp1_s32x4 );
- vst1q_s32( psDelDec->Pred_Q15[ *smpl_buf_idx ], vshlq_n_s32( vld1q_s32( psSampleState[ 0 ].LPC_exc_Q14 ), 1 ) );
- vst1q_s32( psDelDec->Shape_Q14[ *smpl_buf_idx ], vld1q_s32( psSampleState[ 0 ].sLTP_shp_Q14 ) );
- tmp1_s32x4 = vrshrq_n_s32( tmp1_s32x4, 10 );
- tmp1_s32x4 = vaddq_s32( vld1q_s32( psDelDec->Seed ), tmp1_s32x4 );
- vst1q_s32( psDelDec->Seed, tmp1_s32x4 );
- vst1q_s32( psDelDec->RandState[ *smpl_buf_idx ], tmp1_s32x4 );
- vst1q_s32( psDelDec->RD_Q10, vld1q_s32( psSampleState[ 0 ].RD_Q10 ) );
- delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10;
- }
- /* Update LPC states */
- silk_memcpy( psDelDec->sLPC_Q14[ 0 ], psDelDec->sLPC_Q14[ length ], NEON_MAX_DEL_DEC_STATES * NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) );
-
- RESTORE_STACK;
-}
-
-static OPUS_INLINE void silk_SMULWB_8_neon(
- const opus_int16 *a,
- const int32x2_t b,
- opus_int32 *o
-)
-{
- const int16x8_t a_s16x8 = vld1q_s16( a );
- int32x4_t o0_s32x4, o1_s32x4;
-
- o0_s32x4 = vshll_n_s16( vget_low_s16( a_s16x8 ), 15 );
- o1_s32x4 = vshll_n_s16( vget_high_s16( a_s16x8 ), 15 );
- o0_s32x4 = vqdmulhq_lane_s32( o0_s32x4, b, 0 );
- o1_s32x4 = vqdmulhq_lane_s32( o1_s32x4, b, 0 );
- vst1q_s32( o, o0_s32x4 );
- vst1q_s32( o + 4, o1_s32x4 );
-}
-
-/* Only works when ( b >= -65536 ) && ( b < 65536 ). */
-static OPUS_INLINE void silk_SMULWW_small_b_4_neon(
- opus_int32 *a,
- const int32x2_t b_s32x2)
-{
- int32x4_t o_s32x4;
-
- o_s32x4 = vld1q_s32( a );
- o_s32x4 = vqdmulhq_lane_s32( o_s32x4, b_s32x2, 0 );
- vst1q_s32( a, o_s32x4 );
-}
-
-/* Only works when ( b >= -65536 ) && ( b < 65536 ). */
-static OPUS_INLINE void silk_SMULWW_small_b_8_neon(
- opus_int32 *a,
- const int32x2_t b_s32x2
-)
-{
- int32x4_t o0_s32x4, o1_s32x4;
-
- o0_s32x4 = vld1q_s32( a );
- o1_s32x4 = vld1q_s32( a + 4 );
- o0_s32x4 = vqdmulhq_lane_s32( o0_s32x4, b_s32x2, 0 );
- o1_s32x4 = vqdmulhq_lane_s32( o1_s32x4, b_s32x2, 0 );
- vst1q_s32( a, o0_s32x4 );
- vst1q_s32( a + 4, o1_s32x4 );
-}
-
-static OPUS_INLINE void silk_SMULWW_4_neon(
- opus_int32 *a,
- const int32x2_t b_s32x2)
-{
- int32x4_t a_s32x4, o_s32x4;
-
- a_s32x4 = vld1q_s32( a );
- o_s32x4 = vqdmulhq_lane_s32( a_s32x4, b_s32x2, 0 );
- o_s32x4 = vmlaq_lane_s32( o_s32x4, a_s32x4, b_s32x2, 1 );
- vst1q_s32( a, o_s32x4 );
-}
-
-static OPUS_INLINE void silk_SMULWW_8_neon(
- opus_int32 *a,
- const int32x2_t b_s32x2
-)
-{
- int32x4_t a0_s32x4, a1_s32x4, o0_s32x4, o1_s32x4;
-
- a0_s32x4 = vld1q_s32( a );
- a1_s32x4 = vld1q_s32( a + 4 );
- o0_s32x4 = vqdmulhq_lane_s32( a0_s32x4, b_s32x2, 0 );
- o1_s32x4 = vqdmulhq_lane_s32( a1_s32x4, b_s32x2, 0 );
- o0_s32x4 = vmlaq_lane_s32( o0_s32x4, a0_s32x4, b_s32x2, 1 );
- o1_s32x4 = vmlaq_lane_s32( o1_s32x4, a1_s32x4, b_s32x2, 1 );
- vst1q_s32( a, o0_s32x4 );
- vst1q_s32( a + 4, o1_s32x4 );
-}
-
-static OPUS_INLINE void silk_SMULWW_loop_neon(
- const opus_int16 *a,
- const opus_int32 b,
- opus_int32 *o,
- const opus_int loop_num
-)
-{
- opus_int i;
- int32x2_t b_s32x2;
-
- b_s32x2 = vdup_n_s32( b );
- for( i = 0; i < loop_num - 7; i += 8 ) {
- silk_SMULWB_8_neon( a + i, b_s32x2, o + i );
- }
- for( ; i < loop_num; i++ ) {
- o[ i ] = silk_SMULWW( a[ i ], b );
- }
-}
-
-static OPUS_INLINE void silk_nsq_del_dec_scale_states_neon(
- const silk_encoder_state *psEncC, /* I Encoder State */
- silk_nsq_state *NSQ, /* I/O NSQ state */
- NSQ_del_decs_struct psDelDec[], /* I/O Delayed decision states */
- const opus_int16 x16[], /* I Input */
- opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */
- const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */
- opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */
- opus_int subfr, /* I Subframe number */
- const opus_int LTP_scale_Q14, /* I LTP state scaling */
- const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */
- const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */
- const opus_int signal_type, /* I Signal type */
- const opus_int decisionDelay /* I Decision delay */
-)
-{
- opus_int i, lag;
- opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q26;
-
- lag = pitchL[ subfr ];
- inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 );
- silk_assert( inv_gain_Q31 != 0 );
-
- /* Scale input */
- inv_gain_Q26 = silk_RSHIFT_ROUND( inv_gain_Q31, 5 );
- silk_SMULWW_loop_neon( x16, inv_gain_Q26, x_sc_Q10, psEncC->subfr_length );
-
- /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */
- if( NSQ->rewhite_flag ) {
- if( subfr == 0 ) {
- /* Do LTP downscaling */
- inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 );
- }
- 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 );
- }
-
- /* Adjust for changing gain */
- if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) {
- int32x2_t gain_adj_Q16_s32x2;
- gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 );
-
- /* Scale long-term shaping state */
- if( ( gain_adj_Q16 >= -65536 ) && ( gain_adj_Q16 < 65536 ) ) {
- gain_adj_Q16_s32x2 = vdup_n_s32( silk_LSHIFT32( gain_adj_Q16, 15 ) );
- for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 7; i += 8 ) {
- silk_SMULWW_small_b_8_neon( NSQ->sLTP_shp_Q14 + i, gain_adj_Q16_s32x2 );
- }
- for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) {
- NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
- }
-
- /* Scale long-term prediction state */
- if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
- for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay - 7; i += 8 ) {
- silk_SMULWW_small_b_8_neon( sLTP_Q15 + i, gain_adj_Q16_s32x2 );
- }
- for( ; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
- sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
- }
- }
-
- /* Scale scalar states */
- silk_SMULWW_small_b_4_neon( psDelDec->LF_AR_Q14, gain_adj_Q16_s32x2 );
- silk_SMULWW_small_b_4_neon( psDelDec->Diff_Q14, gain_adj_Q16_s32x2 );
-
- /* Scale short-term prediction and shaping states */
- for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
- silk_SMULWW_small_b_4_neon( psDelDec->sLPC_Q14[ i ], gain_adj_Q16_s32x2 );
- }
-
- for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
- silk_SMULWW_small_b_4_neon( psDelDec->sAR2_Q14[ i ], gain_adj_Q16_s32x2 );
- }
-
- for( i = 0; i < DECISION_DELAY; i++ ) {
- silk_SMULWW_small_b_4_neon( psDelDec->Pred_Q15[ i ], gain_adj_Q16_s32x2 );
- silk_SMULWW_small_b_4_neon( psDelDec->Shape_Q14[ i ], gain_adj_Q16_s32x2 );
- }
- } else {
- gain_adj_Q16_s32x2 = vdup_n_s32( silk_LSHIFT32( gain_adj_Q16 & 0x0000FFFF, 15 ) );
- gain_adj_Q16_s32x2 = vset_lane_s32( gain_adj_Q16 >> 16, gain_adj_Q16_s32x2, 1 );
- for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx - 7; i += 8 ) {
- silk_SMULWW_8_neon( NSQ->sLTP_shp_Q14 + i, gain_adj_Q16_s32x2 );
- }
- for( ; i < NSQ->sLTP_shp_buf_idx; i++ ) {
- NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] );
- }
-
- /* Scale long-term prediction state */
- if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) {
- for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay - 7; i += 8 ) {
- silk_SMULWW_8_neon( sLTP_Q15 + i, gain_adj_Q16_s32x2 );
- }
- for( ; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) {
- sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] );
- }
- }
-
- /* Scale scalar states */
- silk_SMULWW_4_neon( psDelDec->LF_AR_Q14, gain_adj_Q16_s32x2 );
- silk_SMULWW_4_neon( psDelDec->Diff_Q14, gain_adj_Q16_s32x2 );
-
- /* Scale short-term prediction and shaping states */
- for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) {
- silk_SMULWW_4_neon( psDelDec->sLPC_Q14[ i ], gain_adj_Q16_s32x2 );
- }
-
- for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) {
- silk_SMULWW_4_neon( psDelDec->sAR2_Q14[ i ], gain_adj_Q16_s32x2 );
- }
-
- for( i = 0; i < DECISION_DELAY; i++ ) {
- silk_SMULWW_4_neon( psDelDec->Pred_Q15[ i ], gain_adj_Q16_s32x2 );
- silk_SMULWW_4_neon( psDelDec->Shape_Q14[ i ], gain_adj_Q16_s32x2 );
- }
- }
-
- /* Save inverse gain */
- NSQ->prev_gain_Q16 = Gains_Q16[ subfr ];
- }
-}
diff --git a/thirdparty/opus/silk/arm/NSQ_neon.h b/thirdparty/opus/silk/arm/NSQ_neon.h
index b31d9442d6..77c946af85 100644
--- a/thirdparty/opus/silk/arm/NSQ_neon.h
+++ b/thirdparty/opus/silk/arm/NSQ_neon.h
@@ -28,31 +28,30 @@ POSSIBILITY OF SUCH DAMAGE.
#define SILK_NSQ_NEON_H
#include "cpu_support.h"
-#include "SigProc_FIX.h"
#undef silk_short_prediction_create_arch_coef
/* For vectorized calc, reverse a_Q12 coefs, convert to 32-bit, and shift for vqdmulhq_s32. */
static OPUS_INLINE void silk_short_prediction_create_arch_coef_neon(opus_int32 *out, const opus_int16 *in, opus_int order)
{
- out[15] = silk_LSHIFT32(in[0], 15);
- out[14] = silk_LSHIFT32(in[1], 15);
- out[13] = silk_LSHIFT32(in[2], 15);
- out[12] = silk_LSHIFT32(in[3], 15);
- out[11] = silk_LSHIFT32(in[4], 15);
- out[10] = silk_LSHIFT32(in[5], 15);
- out[9] = silk_LSHIFT32(in[6], 15);
- out[8] = silk_LSHIFT32(in[7], 15);
- out[7] = silk_LSHIFT32(in[8], 15);
- out[6] = silk_LSHIFT32(in[9], 15);
+ out[15] = in[0] << 15;
+ out[14] = in[1] << 15;
+ out[13] = in[2] << 15;
+ out[12] = in[3] << 15;
+ out[11] = in[4] << 15;
+ out[10] = in[5] << 15;
+ out[9] = in[6] << 15;
+ out[8] = in[7] << 15;
+ out[7] = in[8] << 15;
+ out[6] = in[9] << 15;
if (order == 16)
{
- out[5] = silk_LSHIFT32(in[10], 15);
- out[4] = silk_LSHIFT32(in[11], 15);
- out[3] = silk_LSHIFT32(in[12], 15);
- out[2] = silk_LSHIFT32(in[13], 15);
- out[1] = silk_LSHIFT32(in[14], 15);
- out[0] = silk_LSHIFT32(in[15], 15);
+ out[5] = in[10] << 15;
+ out[4] = in[11] << 15;
+ out[3] = in[12] << 15;
+ out[2] = in[13] << 15;
+ out[1] = in[14] << 15;
+ out[0] = in[15] << 15;
}
else
{
diff --git a/thirdparty/opus/silk/arm/arm_silk_map.c b/thirdparty/opus/silk/arm/arm_silk_map.c
index 0b9bfec2ca..9bd86a7b21 100644
--- a/thirdparty/opus/silk/arm/arm_silk_map.c
+++ b/thirdparty/opus/silk/arm/arm_silk_map.c
@@ -28,62 +28,13 @@ POSSIBILITY OF SUCH DAMAGE.
# include "config.h"
#endif
-#include "main_FIX.h"
#include "NSQ.h"
-#include "SigProc_FIX.h"
#if defined(OPUS_HAVE_RTCD)
# if (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && \
!defined(OPUS_ARM_PRESUME_NEON_INTR))
-void (*const SILK_BIQUAD_ALT_STRIDE2_IMPL[OPUS_ARCHMASK + 1])(
- const opus_int16 *in, /* I input signal */
- const opus_int32 *B_Q28, /* I MA coefficients [3] */
- const opus_int32 *A_Q28, /* I AR coefficients [2] */
- opus_int32 *S, /* I/O State vector [4] */
- opus_int16 *out, /* O output signal */
- const opus_int32 len /* I signal length (must be even) */
-) = {
- silk_biquad_alt_stride2_c, /* ARMv4 */
- silk_biquad_alt_stride2_c, /* EDSP */
- silk_biquad_alt_stride2_c, /* Media */
- silk_biquad_alt_stride2_neon, /* Neon */
-};
-
-opus_int32 (*const SILK_LPC_INVERSE_PRED_GAIN_IMPL[OPUS_ARCHMASK + 1])( /* O Returns inverse prediction gain in energy domain, Q30 */
- const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */
- const opus_int order /* I Prediction order */
-) = {
- silk_LPC_inverse_pred_gain_c, /* ARMv4 */
- silk_LPC_inverse_pred_gain_c, /* EDSP */
- silk_LPC_inverse_pred_gain_c, /* Media */
- silk_LPC_inverse_pred_gain_neon, /* Neon */
-};
-
-void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])(
- const silk_encoder_state *psEncC, /* I Encoder State */
- silk_nsq_state *NSQ, /* I/O NSQ state */
- SideInfoIndices *psIndices, /* I/O Quantization Indices */
- const opus_int16 x16[], /* I Input */
- opus_int8 pulses[], /* O Quantized pulse signal */
- const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
- const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
- const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
- const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
- const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
- const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
- const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */
- const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */
- const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */
- const opus_int LTP_scale_Q14 /* I LTP state scaling */
-) = {
- silk_NSQ_del_dec_c, /* ARMv4 */
- silk_NSQ_del_dec_c, /* EDSP */
- silk_NSQ_del_dec_c, /* Media */
- silk_NSQ_del_dec_neon, /* Neon */
-};
-
/*There is no table for silk_noise_shape_quantizer_short_prediction because the
NEON version takes different parameters than the C version.
Instead RTCD is done via if statements at the call sites.
@@ -101,23 +52,4 @@ opus_int32
# endif
-# if defined(FIXED_POINT) && \
- defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)
-
-void (*const SILK_WARPED_AUTOCORRELATION_FIX_IMPL[OPUS_ARCHMASK + 1])(
- opus_int32 *corr, /* O Result [order + 1] */
- opus_int *scale, /* O Scaling of the correlation vector */
- const opus_int16 *input, /* I Input data to correlate */
- const opus_int warping_Q16, /* I Warping coefficient */
- const opus_int length, /* I Length of input */
- const opus_int order /* I Correlation order (even) */
-) = {
- silk_warped_autocorrelation_FIX_c, /* ARMv4 */
- silk_warped_autocorrelation_FIX_c, /* EDSP */
- silk_warped_autocorrelation_FIX_c, /* Media */
- silk_warped_autocorrelation_FIX_neon, /* Neon */
-};
-
-# endif
-
#endif /* OPUS_HAVE_RTCD */
diff --git a/thirdparty/opus/silk/arm/biquad_alt_arm.h b/thirdparty/opus/silk/arm/biquad_alt_arm.h
deleted file mode 100644
index 66ea9f43dd..0000000000
--- a/thirdparty/opus/silk/arm/biquad_alt_arm.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/***********************************************************************
-Copyright (c) 2017 Google Inc.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-- Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-- Neither the name of Internet Society, IETF or IETF Trust, nor the
-names of specific contributors, may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-***********************************************************************/
-
-#ifndef SILK_BIQUAD_ALT_ARM_H
-# define SILK_BIQUAD_ALT_ARM_H
-
-# include "celt/arm/armcpu.h"
-
-# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
-void silk_biquad_alt_stride2_neon(
- const opus_int16 *in, /* I input signal */
- const opus_int32 *B_Q28, /* I MA coefficients [3] */
- const opus_int32 *A_Q28, /* I AR coefficients [2] */
- opus_int32 *S, /* I/O State vector [4] */
- opus_int16 *out, /* O output signal */
- const opus_int32 len /* I signal length (must be even) */
-);
-
-# if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON)
-# define OVERRIDE_silk_biquad_alt_stride2 (1)
-# 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))
-# endif
-# endif
-
-# if !defined(OVERRIDE_silk_biquad_alt_stride2)
-/*Is run-time CPU detection enabled on this platform?*/
-# if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
-extern void (*const SILK_BIQUAD_ALT_STRIDE2_IMPL[OPUS_ARCHMASK+1])(
- const opus_int16 *in, /* I input signal */
- const opus_int32 *B_Q28, /* I MA coefficients [3] */
- const opus_int32 *A_Q28, /* I AR coefficients [2] */
- opus_int32 *S, /* I/O State vector [4] */
- opus_int16 *out, /* O output signal */
- const opus_int32 len /* I signal length (must be even) */
- );
-# define OVERRIDE_silk_biquad_alt_stride2 (1)
-# 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))
-# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
-# define OVERRIDE_silk_biquad_alt_stride2 (1)
-# 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))
-# endif
-# endif
-
-#endif /* end SILK_BIQUAD_ALT_ARM_H */
diff --git a/thirdparty/opus/silk/arm/biquad_alt_neon_intr.c b/thirdparty/opus/silk/arm/biquad_alt_neon_intr.c
deleted file mode 100644
index 9715733185..0000000000
--- a/thirdparty/opus/silk/arm/biquad_alt_neon_intr.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/***********************************************************************
-Copyright (c) 2017 Google Inc.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-- Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-- Neither the name of Internet Society, IETF or IETF Trust, nor the
-names of specific contributors, may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <arm_neon.h>
-#ifdef OPUS_CHECK_ASM
-# include <string.h>
-# include "stack_alloc.h"
-#endif
-#include "SigProc_FIX.h"
-
-static 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 )
-{
- int32x4_t t_s32x4, out32_Q14_s32x4;
-
- *out32_Q14_s32x2 = vadd_s32( vget_low_s32( *S_s32x4 ), t_s32x2 ); /* silk_SMLAWB( S{0,1}, B_Q28[ 0 ], in{0,1} ) */
- *S_s32x4 = vcombine_s32( vget_high_s32( *S_s32x4 ), vdup_n_s32( 0 ) ); /* S{0,1} = S{2,3}; S{2,3} = 0; */
- *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 ); */
- out32_Q14_s32x4 = vcombine_s32( *out32_Q14_s32x2, *out32_Q14_s32x2 ); /* out32_Q14_{0,1,0,1} */
- 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 ) */
- *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(); */
- 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 ) */
- *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 ); */
- t_s32x4 = vqdmulhq_s32( in_s32x4, B_Q28_s32x4 ); /* silk_SMULWB( B_Q28[ {1,1,2,2} ], in{0,1,0,1} ) */
- *S_s32x4 = vaddq_s32( *S_s32x4, t_s32x4 ); /* S0 = silk_SMLAWB( S0, B_Q28[ {1,1,2,2} ], in{0,1,0,1} ); */
-}
-
-void silk_biquad_alt_stride2_neon(
- const opus_int16 *in, /* I input signal */
- const opus_int32 *B_Q28, /* I MA coefficients [3] */
- const opus_int32 *A_Q28, /* I AR coefficients [2] */
- opus_int32 *S, /* I/O State vector [4] */
- opus_int16 *out, /* O output signal */
- const opus_int32 len /* I signal length (must be even) */
-)
-{
- /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
- opus_int k = 0;
- const int32x2_t offset_s32x2 = vdup_n_s32( (1<<14) - 1 );
- const int32x4_t offset_s32x4 = vcombine_s32( offset_s32x2, offset_s32x2 );
- int16x4_t in_s16x4 = vdup_n_s16( 0 );
- int16x4_t out_s16x4;
- int32x2_t A_Q28_s32x2, A_L_s32x2, A_U_s32x2, B_Q28_s32x2, t_s32x2;
- int32x4_t A_L_s32x4, A_U_s32x4, B_Q28_s32x4, S_s32x4, out32_Q14_s32x4;
- int32x2x2_t t0_s32x2x2, t1_s32x2x2, t2_s32x2x2, S_s32x2x2;
-
-#ifdef OPUS_CHECK_ASM
- opus_int32 S_c[ 4 ];
- VARDECL( opus_int16, out_c );
- SAVE_STACK;
- ALLOC( out_c, 2 * len, opus_int16 );
-
- silk_memcpy( &S_c, S, sizeof( S_c ) );
- silk_biquad_alt_stride2_c( in, B_Q28, A_Q28, S_c, out_c, len );
-#endif
-
- /* Negate A_Q28 values and split in two parts */
- A_Q28_s32x2 = vld1_s32( A_Q28 );
- A_Q28_s32x2 = vneg_s32( A_Q28_s32x2 );
- A_L_s32x2 = vshl_n_s32( A_Q28_s32x2, 18 ); /* ( -A_Q28[] & 0x00003FFF ) << 18 */
- A_L_s32x2 = vreinterpret_s32_u32( vshr_n_u32( vreinterpret_u32_s32( A_L_s32x2 ), 3 ) ); /* ( -A_Q28[] & 0x00003FFF ) << 15 */
- A_U_s32x2 = vshr_n_s32( A_Q28_s32x2, 14 ); /* silk_RSHIFT( -A_Q28[], 14 ) */
- 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.) */
- A_U_s32x2 = vshr_n_s32( A_U_s32x2, 1 ); /* silk_RSHIFT( -A_Q28[], 14 ) << 15 */
-
- B_Q28_s32x2 = vld1_s32( B_Q28 );
- t_s32x2 = vld1_s32( B_Q28 + 1 );
- t0_s32x2x2 = vzip_s32( A_L_s32x2, A_L_s32x2 );
- t1_s32x2x2 = vzip_s32( A_U_s32x2, A_U_s32x2 );
- t2_s32x2x2 = vzip_s32( t_s32x2, t_s32x2 );
- A_L_s32x4 = vcombine_s32( t0_s32x2x2.val[ 0 ], t0_s32x2x2.val[ 1 ] ); /* A{0,0,1,1}_L_Q28 */
- A_U_s32x4 = vcombine_s32( t1_s32x2x2.val[ 0 ], t1_s32x2x2.val[ 1 ] ); /* A{0,0,1,1}_U_Q28 */
- B_Q28_s32x4 = vcombine_s32( t2_s32x2x2.val[ 0 ], t2_s32x2x2.val[ 1 ] ); /* B_Q28[ {1,1,2,2} ] */
- S_s32x4 = vld1q_s32( S ); /* S0 = S[ 0 ]; S3 = S[ 3 ]; */
- S_s32x2x2 = vtrn_s32( vget_low_s32( S_s32x4 ), vget_high_s32( S_s32x4 ) ); /* S2 = S[ 1 ]; S1 = S[ 2 ]; */
- S_s32x4 = vcombine_s32( S_s32x2x2.val[ 0 ], S_s32x2x2.val[ 1 ] );
-
- for( ; k < len - 1; k += 2 ) {
- int32x4_t in_s32x4[ 2 ], t_s32x4;
- int32x2_t out32_Q14_s32x2[ 2 ];
-
- /* S[ 2 * i + 0 ], S[ 2 * i + 1 ], S[ 2 * i + 2 ], S[ 2 * i + 3 ]: Q12 */
- in_s16x4 = vld1_s16( &in[ 2 * k ] ); /* in{0,1,2,3} = in[ 2 * k + {0,1,2,3} ]; */
- in_s32x4[ 0 ] = vshll_n_s16( in_s16x4, 15 ); /* in{0,1,2,3} << 15 */
- t_s32x4 = vqdmulhq_lane_s32( in_s32x4[ 0 ], B_Q28_s32x2, 0 ); /* silk_SMULWB( B_Q28[ 0 ], in{0,1,2,3} ) */
- in_s32x4[ 1 ] = vcombine_s32( vget_high_s32( in_s32x4[ 0 ] ), vget_high_s32( in_s32x4[ 0 ] ) ); /* in{2,3,2,3} << 15 */
- in_s32x4[ 0 ] = vcombine_s32( vget_low_s32 ( in_s32x4[ 0 ] ), vget_low_s32 ( in_s32x4[ 0 ] ) ); /* in{0,1,0,1} << 15 */
- 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 ] );
- 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 ] );
-
- /* Scale back to Q0 and saturate */
- out32_Q14_s32x4 = vcombine_s32( out32_Q14_s32x2[ 0 ], out32_Q14_s32x2[ 1 ] ); /* out32_Q14_{0,1,2,3} */
- out32_Q14_s32x4 = vaddq_s32( out32_Q14_s32x4, offset_s32x4 ); /* out32_Q14_{0,1,2,3} + (1<<14) - 1 */
- 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 ) ) */
- 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 ) ); */
- }
-
- /* Process leftover. */
- if( k < len ) {
- int32x4_t in_s32x4;
- int32x2_t out32_Q14_s32x2;
-
- /* S[ 2 * i + 0 ], S[ 2 * i + 1 ]: Q12 */
- in_s16x4 = vld1_lane_s16( &in[ 2 * k + 0 ], in_s16x4, 0 ); /* in{0,1} = in[ 2 * k + {0,1} ]; */
- in_s16x4 = vld1_lane_s16( &in[ 2 * k + 1 ], in_s16x4, 1 ); /* in{0,1} = in[ 2 * k + {0,1} ]; */
- in_s32x4 = vshll_n_s16( in_s16x4, 15 ); /* in{0,1} << 15 */
- t_s32x2 = vqdmulh_lane_s32( vget_low_s32( in_s32x4 ), B_Q28_s32x2, 0 ); /* silk_SMULWB( B_Q28[ 0 ], in{0,1} ) */
- in_s32x4 = vcombine_s32( vget_low_s32( in_s32x4 ), vget_low_s32( in_s32x4 ) ); /* in{0,1,0,1} << 15 */
- silk_biquad_alt_stride2_kernel( A_L_s32x4, A_U_s32x4, B_Q28_s32x4, t_s32x2, in_s32x4, &S_s32x4, &out32_Q14_s32x2 );
-
- /* Scale back to Q0 and saturate */
- out32_Q14_s32x2 = vadd_s32( out32_Q14_s32x2, offset_s32x2 ); /* out32_Q14_{0,1} + (1<<14) - 1 */
- out32_Q14_s32x4 = vcombine_s32( out32_Q14_s32x2, out32_Q14_s32x2 ); /* out32_Q14_{0,1,0,1} + (1<<14) - 1 */
- 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 ) ) */
- 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 ) ); */
- 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 ) ); */
- }
-
- vst1q_lane_s32( &S[ 0 ], S_s32x4, 0 ); /* S[ 0 ] = S0; */
- vst1q_lane_s32( &S[ 1 ], S_s32x4, 2 ); /* S[ 1 ] = S2; */
- vst1q_lane_s32( &S[ 2 ], S_s32x4, 1 ); /* S[ 2 ] = S1; */
- vst1q_lane_s32( &S[ 3 ], S_s32x4, 3 ); /* S[ 3 ] = S3; */
-
-#ifdef OPUS_CHECK_ASM
- silk_assert( !memcmp( S_c, S, sizeof( S_c ) ) );
- silk_assert( !memcmp( out_c, out, 2 * len * sizeof( opus_int16 ) ) );
- RESTORE_STACK;
-#endif
-}
diff --git a/thirdparty/opus/silk/arm/macros_armv4.h b/thirdparty/opus/silk/arm/macros_armv4.h
index 877eb18dd5..3f30e97288 100644
--- a/thirdparty/opus/silk/arm/macros_armv4.h
+++ b/thirdparty/opus/silk/arm/macros_armv4.h
@@ -28,11 +28,6 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef SILK_MACROS_ARMv4_H
#define SILK_MACROS_ARMv4_H
-/* This macro only avoids the undefined behaviour from a left shift of
- a negative value. It should only be used in macros that can't include
- SigProc_FIX.h. In other cases, use silk_LSHIFT32(). */
-#define SAFE_SHL(a,b) ((opus_int32)((opus_uint32)(a) << (b)))
-
/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
#undef silk_SMULWB
static OPUS_INLINE opus_int32 silk_SMULWB_armv4(opus_int32 a, opus_int16 b)
@@ -43,7 +38,7 @@ static OPUS_INLINE opus_int32 silk_SMULWB_armv4(opus_int32 a, opus_int16 b)
"#silk_SMULWB\n\t"
"smull %0, %1, %2, %3\n\t"
: "=&r"(rd_lo), "=&r"(rd_hi)
- : "%r"(a), "r"(SAFE_SHL(b,16))
+ : "%r"(a), "r"(b<<16)
);
return rd_hi;
}
@@ -85,7 +80,7 @@ static OPUS_INLINE opus_int32 silk_SMULWW_armv4(opus_int32 a, opus_int32 b)
: "=&r"(rd_lo), "=&r"(rd_hi)
: "%r"(a), "r"(b)
);
- return SAFE_SHL(rd_hi,16)+(rd_lo>>16);
+ return (rd_hi<<16)+(rd_lo>>16);
}
#define silk_SMULWW(a, b) (silk_SMULWW_armv4(a, b))
@@ -101,10 +96,8 @@ static OPUS_INLINE opus_int32 silk_SMLAWW_armv4(opus_int32 a, opus_int32 b,
: "=&r"(rd_lo), "=&r"(rd_hi)
: "%r"(b), "r"(c)
);
- return a+SAFE_SHL(rd_hi,16)+(rd_lo>>16);
+ return a+(rd_hi<<16)+(rd_lo>>16);
}
#define silk_SMLAWW(a, b, c) (silk_SMLAWW_armv4(a, b, c))
-#undef SAFE_SHL
-
#endif /* SILK_MACROS_ARMv4_H */
diff --git a/thirdparty/opus/silk/arm/macros_armv5e.h b/thirdparty/opus/silk/arm/macros_armv5e.h
index b14ec65ddb..aad4117e46 100644
--- a/thirdparty/opus/silk/arm/macros_armv5e.h
+++ b/thirdparty/opus/silk/arm/macros_armv5e.h
@@ -29,11 +29,6 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef SILK_MACROS_ARMv5E_H
#define SILK_MACROS_ARMv5E_H
-/* This macro only avoids the undefined behaviour from a left shift of
- a negative value. It should only be used in macros that can't include
- SigProc_FIX.h. In other cases, use silk_LSHIFT32(). */
-#define SAFE_SHL(a,b) ((opus_int32)((opus_uint32)(a) << (b)))
-
/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
#undef silk_SMULWB
static OPUS_INLINE opus_int32 silk_SMULWB_armv5e(opus_int32 a, opus_int16 b)
@@ -195,7 +190,7 @@ static OPUS_INLINE opus_int32 silk_CLZ16_armv5(opus_int16 in16)
"#silk_CLZ16\n\t"
"clz %0, %1;\n"
: "=r"(res)
- : "r"(SAFE_SHL(in16,16)|0x8000)
+ : "r"(in16<<16|0x8000)
);
return res;
}
@@ -215,6 +210,4 @@ static OPUS_INLINE opus_int32 silk_CLZ32_armv5(opus_int32 in32)
}
#define silk_CLZ32(in32) (silk_CLZ32_armv5(in32))
-#undef SAFE_SHL
-
#endif /* SILK_MACROS_ARMv5E_H */
diff --git a/thirdparty/opus/silk/biquad_alt.c b/thirdparty/opus/silk/biquad_alt.c
index 54566a43c0..d55f5ee92e 100644
--- a/thirdparty/opus/silk/biquad_alt.c
+++ b/thirdparty/opus/silk/biquad_alt.c
@@ -39,13 +39,14 @@ POSSIBILITY OF SUCH DAMAGE.
#include "SigProc_FIX.h"
/* Second order ARMA filter, alternative implementation */
-void silk_biquad_alt_stride1(
+void silk_biquad_alt(
const opus_int16 *in, /* I input signal */
const opus_int32 *B_Q28, /* I MA coefficients [3] */
const opus_int32 *A_Q28, /* I AR coefficients [2] */
opus_int32 *S, /* I/O State vector [2] */
opus_int16 *out, /* O output signal */
- const opus_int32 len /* I signal length (must be even) */
+ const opus_int32 len, /* I signal length (must be even) */
+ opus_int stride /* I Operate on interleaved signal if > 1 */
)
{
/* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
@@ -60,7 +61,7 @@ void silk_biquad_alt_stride1(
for( k = 0; k < len; k++ ) {
/* S[ 0 ], S[ 1 ]: Q12 */
- inval = in[ k ];
+ inval = in[ k * stride ];
out32_Q14 = silk_LSHIFT( silk_SMLAWB( S[ 0 ], B_Q28[ 0 ], inval ), 2 );
S[ 0 ] = S[1] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A0_L_Q28 ), 14 );
@@ -72,50 +73,6 @@ void silk_biquad_alt_stride1(
S[ 1 ] = silk_SMLAWB( S[ 1 ], B_Q28[ 2 ], inval );
/* Scale back to Q0 and saturate */
- out[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14 + (1<<14) - 1, 14 ) );
- }
-}
-
-void silk_biquad_alt_stride2_c(
- const opus_int16 *in, /* I input signal */
- const opus_int32 *B_Q28, /* I MA coefficients [3] */
- const opus_int32 *A_Q28, /* I AR coefficients [2] */
- opus_int32 *S, /* I/O State vector [4] */
- opus_int16 *out, /* O output signal */
- const opus_int32 len /* I signal length (must be even) */
-)
-{
- /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
- opus_int k;
- opus_int32 A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14[ 2 ];
-
- /* Negate A_Q28 values and split in two parts */
- A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF; /* lower part */
- A0_U_Q28 = silk_RSHIFT( -A_Q28[ 0 ], 14 ); /* upper part */
- A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF; /* lower part */
- A1_U_Q28 = silk_RSHIFT( -A_Q28[ 1 ], 14 ); /* upper part */
-
- for( k = 0; k < len; k++ ) {
- /* S[ 0 ], S[ 1 ], S[ 2 ], S[ 3 ]: Q12 */
- out32_Q14[ 0 ] = silk_LSHIFT( silk_SMLAWB( S[ 0 ], B_Q28[ 0 ], in[ 2 * k + 0 ] ), 2 );
- out32_Q14[ 1 ] = silk_LSHIFT( silk_SMLAWB( S[ 2 ], B_Q28[ 0 ], in[ 2 * k + 1 ] ), 2 );
-
- S[ 0 ] = S[ 1 ] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 0 ], A0_L_Q28 ), 14 );
- S[ 2 ] = S[ 3 ] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 1 ], A0_L_Q28 ), 14 );
- S[ 0 ] = silk_SMLAWB( S[ 0 ], out32_Q14[ 0 ], A0_U_Q28 );
- S[ 2 ] = silk_SMLAWB( S[ 2 ], out32_Q14[ 1 ], A0_U_Q28 );
- S[ 0 ] = silk_SMLAWB( S[ 0 ], B_Q28[ 1 ], in[ 2 * k + 0 ] );
- S[ 2 ] = silk_SMLAWB( S[ 2 ], B_Q28[ 1 ], in[ 2 * k + 1 ] );
-
- S[ 1 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 0 ], A1_L_Q28 ), 14 );
- S[ 3 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14[ 1 ], A1_L_Q28 ), 14 );
- S[ 1 ] = silk_SMLAWB( S[ 1 ], out32_Q14[ 0 ], A1_U_Q28 );
- S[ 3 ] = silk_SMLAWB( S[ 3 ], out32_Q14[ 1 ], A1_U_Q28 );
- S[ 1 ] = silk_SMLAWB( S[ 1 ], B_Q28[ 2 ], in[ 2 * k + 0 ] );
- S[ 3 ] = silk_SMLAWB( S[ 3 ], B_Q28[ 2 ], in[ 2 * k + 1 ] );
-
- /* Scale back to Q0 and saturate */
- out[ 2 * k + 0 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14[ 0 ] + (1<<14) - 1, 14 ) );
- out[ 2 * k + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14[ 1 ] + (1<<14) - 1, 14 ) );
+ out[ k * stride ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14 + (1<<14) - 1, 14 ) );
}
}
diff --git a/thirdparty/opus/silk/bwexpander.c b/thirdparty/opus/silk/bwexpander.c
index afa97907ec..2eb4456695 100644
--- a/thirdparty/opus/silk/bwexpander.c
+++ b/thirdparty/opus/silk/bwexpander.c
@@ -45,7 +45,7 @@ void silk_bwexpander(
/* Bias in silk_SMULWB can lead to unstable filters */
for( i = 0; i < d - 1; i++ ) {
ar[ i ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ i ] ), 16 );
- chirp_Q16 += silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 );
+ chirp_Q16 += silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 );
}
ar[ d - 1 ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ d - 1 ] ), 16 );
}
diff --git a/thirdparty/opus/silk/check_control_input.c b/thirdparty/opus/silk/check_control_input.c
index 739fb01f1e..b5de9ce48d 100644
--- a/thirdparty/opus/silk/check_control_input.c
+++ b/thirdparty/opus/silk/check_control_input.c
@@ -38,7 +38,7 @@ opus_int check_control_input(
silk_EncControlStruct *encControl /* I Control structure */
)
{
- celt_assert( encControl != NULL );
+ silk_assert( encControl != NULL );
if( ( ( encControl->API_sampleRate != 8000 ) &&
( encControl->API_sampleRate != 12000 ) &&
@@ -59,46 +59,46 @@ opus_int check_control_input(
( encControl->minInternalSampleRate > encControl->desiredInternalSampleRate ) ||
( encControl->maxInternalSampleRate < encControl->desiredInternalSampleRate ) ||
( encControl->minInternalSampleRate > encControl->maxInternalSampleRate ) ) {
- celt_assert( 0 );
+ silk_assert( 0 );
return SILK_ENC_FS_NOT_SUPPORTED;
}
if( encControl->payloadSize_ms != 10 &&
encControl->payloadSize_ms != 20 &&
encControl->payloadSize_ms != 40 &&
encControl->payloadSize_ms != 60 ) {
- celt_assert( 0 );
+ silk_assert( 0 );
return SILK_ENC_PACKET_SIZE_NOT_SUPPORTED;
}
if( encControl->packetLossPercentage < 0 || encControl->packetLossPercentage > 100 ) {
- celt_assert( 0 );
+ silk_assert( 0 );
return SILK_ENC_INVALID_LOSS_RATE;
}
if( encControl->useDTX < 0 || encControl->useDTX > 1 ) {
- celt_assert( 0 );
+ silk_assert( 0 );
return SILK_ENC_INVALID_DTX_SETTING;
}
if( encControl->useCBR < 0 || encControl->useCBR > 1 ) {
- celt_assert( 0 );
+ silk_assert( 0 );
return SILK_ENC_INVALID_CBR_SETTING;
}
if( encControl->useInBandFEC < 0 || encControl->useInBandFEC > 1 ) {
- celt_assert( 0 );
+ silk_assert( 0 );
return SILK_ENC_INVALID_INBAND_FEC_SETTING;
}
if( encControl->nChannelsAPI < 1 || encControl->nChannelsAPI > ENCODER_NUM_CHANNELS ) {
- celt_assert( 0 );
+ silk_assert( 0 );
return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR;
}
if( encControl->nChannelsInternal < 1 || encControl->nChannelsInternal > ENCODER_NUM_CHANNELS ) {
- celt_assert( 0 );
+ silk_assert( 0 );
return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR;
}
if( encControl->nChannelsInternal > encControl->nChannelsAPI ) {
- celt_assert( 0 );
+ silk_assert( 0 );
return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR;
}
if( encControl->complexity < 0 || encControl->complexity > 10 ) {
- celt_assert( 0 );
+ silk_assert( 0 );
return SILK_ENC_INVALID_COMPLEXITY_SETTING;
}
diff --git a/thirdparty/opus/silk/control.h b/thirdparty/opus/silk/control.h
index b76ec33cd6..747e5426a0 100644
--- a/thirdparty/opus/silk/control.h
+++ b/thirdparty/opus/silk/control.h
@@ -77,9 +77,6 @@ typedef struct {
/* I: Flag to enable in-band Forward Error Correction (FEC); 0/1 */
opus_int useInBandFEC;
- /* I: Flag to actually code in-band Forward Error Correction (FEC) in the current packet; 0/1 */
- opus_int LBRR_coded;
-
/* I: Flag to enable discontinuous transmission (DTX); 0/1 */
opus_int useDTX;
@@ -113,11 +110,6 @@ typedef struct {
/* O: Tells the Opus encoder we're ready to switch */
opus_int switchReady;
- /* O: SILK Signal type */
- opus_int signalType;
-
- /* O: SILK offset (dithering) */
- opus_int offset;
} silk_EncControlStruct;
/**************************************************************************/
diff --git a/thirdparty/opus/silk/control_SNR.c b/thirdparty/opus/silk/control_SNR.c
index 9a6db27543..cee87eb0d8 100644
--- a/thirdparty/opus/silk/control_SNR.c
+++ b/thirdparty/opus/silk/control_SNR.c
@@ -32,82 +32,45 @@ POSSIBILITY OF SUCH DAMAGE.
#include "main.h"
#include "tuning_parameters.h"
-/* These tables hold SNR values divided by 21 (so they fit in 8 bits)
- for different target bitrates spaced at 400 bps interval. The first
- 10 values are omitted (0-4 kb/s) because they're all zeros.
- These tables were obtained by running different SNRs through the
- encoder and measuring the active bitrate. */
-static const unsigned char silk_TargetRate_NB_21[117 - 10] = {
- 0, 15, 39, 52, 61, 68,
- 74, 79, 84, 88, 92, 95, 99,102,105,108,111,114,117,119,122,124,
- 126,129,131,133,135,137,139,142,143,145,147,149,151,153,155,157,
- 158,160,162,163,165,167,168,170,171,173,174,176,177,179,180,182,
- 183,185,186,187,189,190,192,193,194,196,197,199,200,201,203,204,
- 205,207,208,209,211,212,213,215,216,217,219,220,221,223,224,225,
- 227,228,230,231,232,234,235,236,238,239,241,242,243,245,246,248,
- 249,250,252,253,255
-};
-
-static const unsigned char silk_TargetRate_MB_21[165 - 10] = {
- 0, 0, 28, 43, 52, 59,
- 65, 70, 74, 78, 81, 85, 87, 90, 93, 95, 98,100,102,105,107,109,
- 111,113,115,116,118,120,122,123,125,127,128,130,131,133,134,136,
- 137,138,140,141,143,144,145,147,148,149,151,152,153,154,156,157,
- 158,159,160,162,163,164,165,166,167,168,169,171,172,173,174,175,
- 176,177,178,179,180,181,182,183,184,185,186,187,188,188,189,190,
- 191,192,193,194,195,196,197,198,199,200,201,202,203,203,204,205,
- 206,207,208,209,210,211,212,213,214,214,215,216,217,218,219,220,
- 221,222,223,224,224,225,226,227,228,229,230,231,232,233,234,235,
- 236,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,
- 251,252,253,254,255
-};
-
-static const unsigned char silk_TargetRate_WB_21[201 - 10] = {
- 0, 0, 0, 8, 29, 41,
- 49, 56, 62, 66, 70, 74, 77, 80, 83, 86, 88, 91, 93, 95, 97, 99,
- 101,103,105,107,108,110,112,113,115,116,118,119,121,122,123,125,
- 126,127,129,130,131,132,134,135,136,137,138,140,141,142,143,144,
- 145,146,147,148,149,150,151,152,153,154,156,157,158,159,159,160,
- 161,162,163,164,165,166,167,168,169,170,171,171,172,173,174,175,
- 176,177,177,178,179,180,181,181,182,183,184,185,185,186,187,188,
- 189,189,190,191,192,192,193,194,195,195,196,197,198,198,199,200,
- 200,201,202,203,203,204,205,206,206,207,208,209,209,210,211,211,
- 212,213,214,214,215,216,216,217,218,219,219,220,221,221,222,223,
- 224,224,225,226,226,227,228,229,229,230,231,232,232,233,234,234,
- 235,236,237,237,238,239,240,240,241,242,243,243,244,245,246,246,
- 247,248,249,249,250,251,252,253,255
-};
-
/* Control SNR of redidual quantizer */
opus_int silk_control_SNR(
silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */
opus_int32 TargetRate_bps /* I Target max bitrate (bps) */
)
{
- int id;
- int bound;
- const unsigned char *snr_table;
+ opus_int k, ret = SILK_NO_ERROR;
+ opus_int32 frac_Q6;
+ const opus_int32 *rateTable;
- psEncC->TargetRate_bps = TargetRate_bps;
- if( psEncC->nb_subfr == 2 ) {
- TargetRate_bps -= 2000 + psEncC->fs_kHz/16;
- }
- if( psEncC->fs_kHz == 8 ) {
- bound = sizeof(silk_TargetRate_NB_21);
- snr_table = silk_TargetRate_NB_21;
- } else if( psEncC->fs_kHz == 12 ) {
- bound = sizeof(silk_TargetRate_MB_21);
- snr_table = silk_TargetRate_MB_21;
- } else {
- bound = sizeof(silk_TargetRate_WB_21);
- snr_table = silk_TargetRate_WB_21;
- }
- id = (TargetRate_bps+200)/400;
- id = silk_min(id - 10, bound-1);
- if( id <= 0 ) {
- psEncC->SNR_dB_Q7 = 0;
- } else {
- psEncC->SNR_dB_Q7 = snr_table[id]*21;
+ /* Set bitrate/coding quality */
+ TargetRate_bps = silk_LIMIT( TargetRate_bps, MIN_TARGET_RATE_BPS, MAX_TARGET_RATE_BPS );
+ if( TargetRate_bps != psEncC->TargetRate_bps ) {
+ psEncC->TargetRate_bps = TargetRate_bps;
+
+ /* If new TargetRate_bps, translate to SNR_dB value */
+ if( psEncC->fs_kHz == 8 ) {
+ rateTable = silk_TargetRate_table_NB;
+ } else if( psEncC->fs_kHz == 12 ) {
+ rateTable = silk_TargetRate_table_MB;
+ } else {
+ rateTable = silk_TargetRate_table_WB;
+ }
+
+ /* Reduce bitrate for 10 ms modes in these calculations */
+ if( psEncC->nb_subfr == 2 ) {
+ TargetRate_bps -= REDUCE_BITRATE_10_MS_BPS;
+ }
+
+ /* Find bitrate interval in table and interpolate */
+ for( k = 1; k < TARGET_RATE_TAB_SZ; k++ ) {
+ if( TargetRate_bps <= rateTable[ k ] ) {
+ frac_Q6 = silk_DIV32( silk_LSHIFT( TargetRate_bps - rateTable[ k - 1 ], 6 ),
+ rateTable[ k ] - rateTable[ k - 1 ] );
+ psEncC->SNR_dB_Q7 = silk_LSHIFT( silk_SNR_table_Q1[ k - 1 ], 6 ) + silk_MUL( frac_Q6, silk_SNR_table_Q1[ k ] - silk_SNR_table_Q1[ k - 1 ] );
+ break;
+ }
+ }
}
- return SILK_NO_ERROR;
+
+ return ret;
}
diff --git a/thirdparty/opus/silk/control_audio_bandwidth.c b/thirdparty/opus/silk/control_audio_bandwidth.c
index f6d22d8395..4f9bc5cbda 100644
--- a/thirdparty/opus/silk/control_audio_bandwidth.c
+++ b/thirdparty/opus/silk/control_audio_bandwidth.c
@@ -39,15 +39,9 @@ opus_int silk_control_audio_bandwidth(
)
{
opus_int fs_kHz;
- opus_int orig_kHz;
opus_int32 fs_Hz;
- orig_kHz = psEncC->fs_kHz;
- /* Handle a bandwidth-switching reset where we need to be aware what the last sampling rate was. */
- if( orig_kHz == 0 ) {
- orig_kHz = psEncC->sLP.saved_fs_kHz;
- }
- fs_kHz = orig_kHz;
+ fs_kHz = psEncC->fs_kHz;
fs_Hz = silk_SMULBB( fs_kHz, 1000 );
if( fs_Hz == 0 ) {
/* Encoder has just been initialized */
@@ -67,7 +61,7 @@ opus_int silk_control_audio_bandwidth(
}
if( psEncC->allow_bandwidth_switch || encControl->opusCanSwitch ) {
/* Check if we should switch down */
- if( silk_SMULBB( orig_kHz, 1000 ) > psEncC->desiredInternal_fs_Hz )
+ if( silk_SMULBB( psEncC->fs_kHz, 1000 ) > psEncC->desiredInternal_fs_Hz )
{
/* Switch down */
if( psEncC->sLP.mode == 0 ) {
@@ -82,7 +76,7 @@ opus_int silk_control_audio_bandwidth(
psEncC->sLP.mode = 0;
/* Switch to a lower sample frequency */
- fs_kHz = orig_kHz == 16 ? 12 : 8;
+ fs_kHz = psEncC->fs_kHz == 16 ? 12 : 8;
} else {
if( psEncC->sLP.transition_frame_no <= 0 ) {
encControl->switchReady = 1;
@@ -96,12 +90,12 @@ opus_int silk_control_audio_bandwidth(
}
else
/* Check if we should switch up */
- if( silk_SMULBB( orig_kHz, 1000 ) < psEncC->desiredInternal_fs_Hz )
+ if( silk_SMULBB( psEncC->fs_kHz, 1000 ) < psEncC->desiredInternal_fs_Hz )
{
/* Switch up */
if( encControl->opusCanSwitch ) {
/* Switch to a higher sample frequency */
- fs_kHz = orig_kHz == 8 ? 12 : 16;
+ fs_kHz = psEncC->fs_kHz == 8 ? 12 : 16;
/* New transition */
psEncC->sLP.transition_frame_no = 0;
diff --git a/thirdparty/opus/silk/control_codec.c b/thirdparty/opus/silk/control_codec.c
index 52aa8fded3..044eea3f2a 100644
--- a/thirdparty/opus/silk/control_codec.c
+++ b/thirdparty/opus/silk/control_codec.c
@@ -57,7 +57,7 @@ static opus_int silk_setup_complexity(
static OPUS_INLINE opus_int silk_setup_LBRR(
silk_encoder_state *psEncC, /* I/O */
- const silk_EncControlStruct *encControl /* I */
+ const opus_int32 TargetRate_bps /* I */
);
@@ -65,6 +65,7 @@ static OPUS_INLINE opus_int silk_setup_LBRR(
opus_int silk_control_encoder(
silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */
silk_EncControlStruct *encControl, /* I Control structure */
+ const opus_int32 TargetRate_bps, /* I Target max bitrate (bps) */
const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */
const opus_int channelNb, /* I Channel number */
const opus_int force_fs_kHz
@@ -124,7 +125,7 @@ opus_int silk_control_encoder(
/********************************************/
/* Set LBRR usage */
/********************************************/
- ret += silk_setup_LBRR( &psEnc->sCmn, encControl );
+ ret += silk_setup_LBRR( &psEnc->sCmn, TargetRate_bps );
psEnc->sCmn.controlled_since_last_payload = 1;
@@ -238,11 +239,12 @@ static opus_int silk_setup_fs(
}
/* Set internal sampling frequency */
- celt_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );
- celt_assert( psEnc->sCmn.nb_subfr == 2 || psEnc->sCmn.nb_subfr == 4 );
+ silk_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );
+ silk_assert( psEnc->sCmn.nb_subfr == 2 || psEnc->sCmn.nb_subfr == 4 );
if( psEnc->sCmn.fs_kHz != fs_kHz ) {
/* reset part of the state */
silk_memset( &psEnc->sShape, 0, sizeof( psEnc->sShape ) );
+ silk_memset( &psEnc->sPrefilt, 0, sizeof( psEnc->sPrefilt ) );
silk_memset( &psEnc->sCmn.sNSQ, 0, sizeof( psEnc->sCmn.sNSQ ) );
silk_memset( psEnc->sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) );
silk_memset( &psEnc->sCmn.sLP.In_LP_State, 0, sizeof( psEnc->sCmn.sLP.In_LP_State ) );
@@ -253,6 +255,7 @@ static opus_int silk_setup_fs(
/* Initialize non-zero parameters */
psEnc->sCmn.prevLag = 100;
psEnc->sCmn.first_frame_after_reset = 1;
+ psEnc->sPrefilt.lagPrev = 100;
psEnc->sShape.LastGainIndex = 10;
psEnc->sCmn.sNSQ.lagPrev = 100;
psEnc->sCmn.sNSQ.prev_gain_Q16 = 65536;
@@ -290,16 +293,19 @@ static opus_int silk_setup_fs(
psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz );
}
if( psEnc->sCmn.fs_kHz == 16 ) {
+ psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_WB, 9 );
psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform8_iCDF;
} else if( psEnc->sCmn.fs_kHz == 12 ) {
+ psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_MB, 9 );
psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform6_iCDF;
} else {
+ psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_NB, 9 );
psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform4_iCDF;
}
}
/* Check that settings are valid */
- celt_assert( ( psEnc->sCmn.subfr_length * psEnc->sCmn.nb_subfr ) == psEnc->sCmn.frame_length );
+ silk_assert( ( psEnc->sCmn.subfr_length * psEnc->sCmn.nb_subfr ) == psEnc->sCmn.frame_length );
return ret;
}
@@ -312,76 +318,61 @@ static opus_int silk_setup_complexity(
opus_int ret = 0;
/* Set encoding complexity */
- celt_assert( Complexity >= 0 && Complexity <= 10 );
- if( Complexity < 1 ) {
+ silk_assert( Complexity >= 0 && Complexity <= 10 );
+ if( Complexity < 2 ) {
psEncC->pitchEstimationComplexity = SILK_PE_MIN_COMPLEX;
psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.8, 16 );
psEncC->pitchEstimationLPCOrder = 6;
- psEncC->shapingLPCOrder = 12;
+ psEncC->shapingLPCOrder = 8;
psEncC->la_shape = 3 * psEncC->fs_kHz;
psEncC->nStatesDelayedDecision = 1;
psEncC->useInterpolatedNLSFs = 0;
- psEncC->NLSF_MSVQ_Survivors = 2;
- psEncC->warping_Q16 = 0;
- } else if( Complexity < 2 ) {
- psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
- psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.76, 16 );
- psEncC->pitchEstimationLPCOrder = 8;
- psEncC->shapingLPCOrder = 14;
- psEncC->la_shape = 5 * psEncC->fs_kHz;
- psEncC->nStatesDelayedDecision = 1;
- psEncC->useInterpolatedNLSFs = 0;
- psEncC->NLSF_MSVQ_Survivors = 3;
- psEncC->warping_Q16 = 0;
- } else if( Complexity < 3 ) {
- psEncC->pitchEstimationComplexity = SILK_PE_MIN_COMPLEX;
- psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.8, 16 );
- psEncC->pitchEstimationLPCOrder = 6;
- psEncC->shapingLPCOrder = 12;
- psEncC->la_shape = 3 * psEncC->fs_kHz;
- psEncC->nStatesDelayedDecision = 2;
- psEncC->useInterpolatedNLSFs = 0;
+ psEncC->LTPQuantLowComplexity = 1;
psEncC->NLSF_MSVQ_Survivors = 2;
psEncC->warping_Q16 = 0;
} else if( Complexity < 4 ) {
psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.76, 16 );
psEncC->pitchEstimationLPCOrder = 8;
- psEncC->shapingLPCOrder = 14;
+ psEncC->shapingLPCOrder = 10;
psEncC->la_shape = 5 * psEncC->fs_kHz;
- psEncC->nStatesDelayedDecision = 2;
+ psEncC->nStatesDelayedDecision = 1;
psEncC->useInterpolatedNLSFs = 0;
+ psEncC->LTPQuantLowComplexity = 0;
psEncC->NLSF_MSVQ_Survivors = 4;
psEncC->warping_Q16 = 0;
} else if( Complexity < 6 ) {
psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.74, 16 );
psEncC->pitchEstimationLPCOrder = 10;
- psEncC->shapingLPCOrder = 16;
+ psEncC->shapingLPCOrder = 12;
psEncC->la_shape = 5 * psEncC->fs_kHz;
psEncC->nStatesDelayedDecision = 2;
psEncC->useInterpolatedNLSFs = 1;
- psEncC->NLSF_MSVQ_Survivors = 6;
+ psEncC->LTPQuantLowComplexity = 0;
+ psEncC->NLSF_MSVQ_Survivors = 8;
psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
} else if( Complexity < 8 ) {
psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX;
psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.72, 16 );
psEncC->pitchEstimationLPCOrder = 12;
- psEncC->shapingLPCOrder = 20;
+ psEncC->shapingLPCOrder = 14;
psEncC->la_shape = 5 * psEncC->fs_kHz;
psEncC->nStatesDelayedDecision = 3;
psEncC->useInterpolatedNLSFs = 1;
- psEncC->NLSF_MSVQ_Survivors = 8;
+ psEncC->LTPQuantLowComplexity = 0;
+ psEncC->NLSF_MSVQ_Survivors = 16;
psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
} else {
psEncC->pitchEstimationComplexity = SILK_PE_MAX_COMPLEX;
psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.7, 16 );
psEncC->pitchEstimationLPCOrder = 16;
- psEncC->shapingLPCOrder = 24;
+ psEncC->shapingLPCOrder = 16;
psEncC->la_shape = 5 * psEncC->fs_kHz;
psEncC->nStatesDelayedDecision = MAX_DEL_DEC_STATES;
psEncC->useInterpolatedNLSFs = 1;
- psEncC->NLSF_MSVQ_Survivors = 16;
+ psEncC->LTPQuantLowComplexity = 0;
+ psEncC->NLSF_MSVQ_Survivors = 32;
psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
}
@@ -390,32 +381,46 @@ static opus_int silk_setup_complexity(
psEncC->shapeWinLength = SUB_FRAME_LENGTH_MS * psEncC->fs_kHz + 2 * psEncC->la_shape;
psEncC->Complexity = Complexity;
- celt_assert( psEncC->pitchEstimationLPCOrder <= MAX_FIND_PITCH_LPC_ORDER );
- celt_assert( psEncC->shapingLPCOrder <= MAX_SHAPE_LPC_ORDER );
- celt_assert( psEncC->nStatesDelayedDecision <= MAX_DEL_DEC_STATES );
- celt_assert( psEncC->warping_Q16 <= 32767 );
- celt_assert( psEncC->la_shape <= LA_SHAPE_MAX );
- celt_assert( psEncC->shapeWinLength <= SHAPE_LPC_WIN_MAX );
+ silk_assert( psEncC->pitchEstimationLPCOrder <= MAX_FIND_PITCH_LPC_ORDER );
+ silk_assert( psEncC->shapingLPCOrder <= MAX_SHAPE_LPC_ORDER );
+ silk_assert( psEncC->nStatesDelayedDecision <= MAX_DEL_DEC_STATES );
+ silk_assert( psEncC->warping_Q16 <= 32767 );
+ silk_assert( psEncC->la_shape <= LA_SHAPE_MAX );
+ silk_assert( psEncC->shapeWinLength <= SHAPE_LPC_WIN_MAX );
+ silk_assert( psEncC->NLSF_MSVQ_Survivors <= NLSF_VQ_MAX_SURVIVORS );
return ret;
}
static OPUS_INLINE opus_int silk_setup_LBRR(
silk_encoder_state *psEncC, /* I/O */
- const silk_EncControlStruct *encControl /* I */
+ const opus_int32 TargetRate_bps /* I */
)
{
opus_int LBRR_in_previous_packet, ret = SILK_NO_ERROR;
+ opus_int32 LBRR_rate_thres_bps;
LBRR_in_previous_packet = psEncC->LBRR_enabled;
- psEncC->LBRR_enabled = encControl->LBRR_coded;
- if( psEncC->LBRR_enabled ) {
- /* Set gain increase for coding LBRR excitation */
- if( LBRR_in_previous_packet == 0 ) {
- /* Previous packet did not have LBRR, and was therefore coded at a higher bitrate */
- psEncC->LBRR_GainIncreases = 7;
+ psEncC->LBRR_enabled = 0;
+ if( psEncC->useInBandFEC && psEncC->PacketLoss_perc > 0 ) {
+ if( psEncC->fs_kHz == 8 ) {
+ LBRR_rate_thres_bps = LBRR_NB_MIN_RATE_BPS;
+ } else if( psEncC->fs_kHz == 12 ) {
+ LBRR_rate_thres_bps = LBRR_MB_MIN_RATE_BPS;
} else {
- psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( (opus_int32)psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.4, 16 ) ), 2 );
+ LBRR_rate_thres_bps = LBRR_WB_MIN_RATE_BPS;
+ }
+ LBRR_rate_thres_bps = silk_SMULWB( silk_MUL( LBRR_rate_thres_bps, 125 - silk_min( psEncC->PacketLoss_perc, 25 ) ), SILK_FIX_CONST( 0.01, 16 ) );
+
+ if( TargetRate_bps > LBRR_rate_thres_bps ) {
+ /* Set gain increase for coding LBRR excitation */
+ if( LBRR_in_previous_packet == 0 ) {
+ /* Previous packet did not have LBRR, and was therefore coded at a higher bitrate */
+ psEncC->LBRR_GainIncreases = 7;
+ } else {
+ psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( (opus_int32)psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.4, 16 ) ), 2 );
+ }
+ psEncC->LBRR_enabled = 1;
}
}
diff --git a/thirdparty/opus/silk/debug.h b/thirdparty/opus/silk/debug.h
index 6f68c1ca0f..efb6d3e99e 100644
--- a/thirdparty/opus/silk/debug.h
+++ b/thirdparty/opus/silk/debug.h
@@ -39,10 +39,23 @@ extern "C"
unsigned long GetHighResolutionTime(void); /* O time in usec*/
-/* Set to 1 to enable DEBUG_STORE_DATA() macros for dumping
- * intermediate signals from the codec.
- */
-#define SILK_DEBUG 0
+/* make SILK_DEBUG dependent on compiler's _DEBUG */
+#if defined _WIN32
+ #ifdef _DEBUG
+ #define SILK_DEBUG 1
+ #else
+ #define SILK_DEBUG 0
+ #endif
+
+ /* overrule the above */
+ #if 0
+ /* #define NO_ASSERTS*/
+ #undef SILK_DEBUG
+ #define SILK_DEBUG 1
+ #endif
+#else
+ #define SILK_DEBUG 0
+#endif
/* Flag for using timers */
#define SILK_TIC_TOC 0
diff --git a/thirdparty/opus/silk/dec_API.c b/thirdparty/opus/silk/dec_API.c
index 7d5ca7fb9f..b7d8ed48d8 100644
--- a/thirdparty/opus/silk/dec_API.c
+++ b/thirdparty/opus/silk/dec_API.c
@@ -104,7 +104,7 @@ opus_int silk_Decode( /* O Returns error co
int delay_stack_alloc;
SAVE_STACK;
- celt_assert( decControl->nChannelsInternal == 1 || decControl->nChannelsInternal == 2 );
+ silk_assert( decControl->nChannelsInternal == 1 || decControl->nChannelsInternal == 2 );
/**********************************/
/* Test if first frame in payload */
@@ -143,13 +143,13 @@ opus_int silk_Decode( /* O Returns error co
channel_state[ n ].nFramesPerPacket = 3;
channel_state[ n ].nb_subfr = 4;
} else {
- celt_assert( 0 );
+ silk_assert( 0 );
RESTORE_STACK;
return SILK_DEC_INVALID_FRAME_SIZE;
}
fs_kHz_dec = ( decControl->internalSampleRate >> 10 ) + 1;
if( fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16 ) {
- celt_assert( 0 );
+ silk_assert( 0 );
RESTORE_STACK;
return SILK_DEC_INVALID_SAMPLING_FREQUENCY;
}
diff --git a/thirdparty/opus/silk/decode_core.c b/thirdparty/opus/silk/decode_core.c
index 1c352a6522..e569c0e72b 100644
--- a/thirdparty/opus/silk/decode_core.c
+++ b/thirdparty/opus/silk/decode_core.c
@@ -141,7 +141,7 @@ void silk_decode_core(
if( k == 0 || ( k == 2 && NLSF_interpolation_flag ) ) {
/* Rewhiten with new A coefs */
start_idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2;
- celt_assert( start_idx > 0 );
+ silk_assert( start_idx > 0 );
if( k == 2 ) {
silk_memcpy( &psDec->outBuf[ psDec->ltp_mem_length ], xq, 2 * psDec->subfr_length * sizeof( opus_int16 ) );
@@ -196,7 +196,7 @@ void silk_decode_core(
for( i = 0; i < psDec->subfr_length; i++ ) {
/* Short-term prediction */
- celt_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
+ silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
/* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 );
LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] );
@@ -225,6 +225,8 @@ void silk_decode_core(
pxq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14[ MAX_LPC_ORDER + i ], Gain_Q10 ), 8 ) );
}
+ /* DEBUG_STORE_DATA( dec.pcm, pxq, psDec->subfr_length * sizeof( opus_int16 ) ) */
+
/* Update LPC filter state */
silk_memcpy( sLPC_Q14, &sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );
pexc_Q14 += psDec->subfr_length;
diff --git a/thirdparty/opus/silk/decode_frame.c b/thirdparty/opus/silk/decode_frame.c
index e73825b267..a605d95ac6 100644
--- a/thirdparty/opus/silk/decode_frame.c
+++ b/thirdparty/opus/silk/decode_frame.c
@@ -55,7 +55,7 @@ opus_int silk_decode_frame(
psDecCtrl->LTP_scale_Q14 = 0;
/* Safety checks */
- celt_assert( L > 0 && L <= MAX_FRAME_LENGTH );
+ silk_assert( L > 0 && L <= MAX_FRAME_LENGTH );
if( lostFlag == FLAG_DECODE_NORMAL ||
( lostFlag == FLAG_DECODE_LBRR && psDec->LBRR_flags[ psDec->nFramesDecoded ] == 1 ) )
@@ -91,20 +91,19 @@ opus_int silk_decode_frame(
psDec->lossCnt = 0;
psDec->prevSignalType = psDec->indices.signalType;
- celt_assert( psDec->prevSignalType >= 0 && psDec->prevSignalType <= 2 );
+ silk_assert( psDec->prevSignalType >= 0 && psDec->prevSignalType <= 2 );
/* A frame has been decoded without errors */
psDec->first_frame_after_reset = 0;
} else {
/* Handle packet loss by extrapolation */
- psDec->indices.signalType = psDec->prevSignalType;
silk_PLC( psDec, psDecCtrl, pOut, 1, arch );
}
/*************************/
/* Update output buffer. */
/*************************/
- celt_assert( psDec->ltp_mem_length >= psDec->frame_length );
+ silk_assert( psDec->ltp_mem_length >= psDec->frame_length );
mv_len = psDec->ltp_mem_length - psDec->frame_length;
silk_memmove( psDec->outBuf, &psDec->outBuf[ psDec->frame_length ], mv_len * sizeof(opus_int16) );
silk_memcpy( &psDec->outBuf[ mv_len ], pOut, psDec->frame_length * sizeof( opus_int16 ) );
diff --git a/thirdparty/opus/silk/decode_indices.c b/thirdparty/opus/silk/decode_indices.c
index 0bb4a997a5..7afe5c26c1 100644
--- a/thirdparty/opus/silk/decode_indices.c
+++ b/thirdparty/opus/silk/decode_indices.c
@@ -79,7 +79,7 @@ void silk_decode_indices(
/**********************/
psDec->indices.NLSFIndices[ 0 ] = (opus_int8)ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->CB1_iCDF[ ( psDec->indices.signalType >> 1 ) * psDec->psNLSF_CB->nVectors ], 8 );
silk_NLSF_unpack( ec_ix, pred_Q8, psDec->psNLSF_CB, psDec->indices.NLSFIndices[ 0 ] );
- celt_assert( psDec->psNLSF_CB->order == psDec->LPC_order );
+ silk_assert( psDec->psNLSF_CB->order == psDec->LPC_order );
for( i = 0; i < psDec->psNLSF_CB->order; i++ ) {
Ix = ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );
if( Ix == 0 ) {
diff --git a/thirdparty/opus/silk/decode_parameters.c b/thirdparty/opus/silk/decode_parameters.c
index a56a409858..e345b1dcef 100644
--- a/thirdparty/opus/silk/decode_parameters.c
+++ b/thirdparty/opus/silk/decode_parameters.c
@@ -52,7 +52,7 @@ void silk_decode_parameters(
silk_NLSF_decode( pNLSF_Q15, psDec->indices.NLSFIndices, psDec->psNLSF_CB );
/* Convert NLSF parameters to AR prediction filter coefficients */
- silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order, psDec->arch );
+ silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order );
/* If just reset, e.g., because internal Fs changed, do not allow interpolation */
/* improves the case of packet loss in the first frame after a switch */
@@ -69,7 +69,7 @@ void silk_decode_parameters(
}
/* Convert NLSF parameters to AR prediction filter coefficients */
- silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order, psDec->arch );
+ silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order );
} else {
/* Copy LPC coefficients for first half from second half */
silk_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) );
diff --git a/thirdparty/opus/silk/decode_pitch.c b/thirdparty/opus/silk/decode_pitch.c
index fd1b6bf551..fedbc6a525 100644
--- a/thirdparty/opus/silk/decode_pitch.c
+++ b/thirdparty/opus/silk/decode_pitch.c
@@ -51,7 +51,7 @@ void silk_decode_pitch(
Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ];
cbk_size = PE_NB_CBKS_STAGE2_EXT;
} else {
- celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 );
+ silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 );
Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ];
cbk_size = PE_NB_CBKS_STAGE2_10MS;
}
@@ -60,7 +60,7 @@ void silk_decode_pitch(
Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ];
cbk_size = PE_NB_CBKS_STAGE3_MAX;
} else {
- celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 );
+ silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 );
Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
cbk_size = PE_NB_CBKS_STAGE3_10MS;
}
diff --git a/thirdparty/opus/silk/decode_pulses.c b/thirdparty/opus/silk/decode_pulses.c
index a56d2d3074..d6bbec9225 100644
--- a/thirdparty/opus/silk/decode_pulses.c
+++ b/thirdparty/opus/silk/decode_pulses.c
@@ -56,7 +56,7 @@ void silk_decode_pulses(
silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH );
iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH );
if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) {
- celt_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */
+ silk_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */
iter++;
}
diff --git a/thirdparty/opus/silk/decoder_set_fs.c b/thirdparty/opus/silk/decoder_set_fs.c
index d9a13d0f0c..eef0fd25e1 100644
--- a/thirdparty/opus/silk/decoder_set_fs.c
+++ b/thirdparty/opus/silk/decoder_set_fs.c
@@ -40,8 +40,8 @@ opus_int silk_decoder_set_fs(
{
opus_int frame_length, ret = 0;
- celt_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );
- celt_assert( psDec->nb_subfr == MAX_NB_SUBFR || psDec->nb_subfr == MAX_NB_SUBFR/2 );
+ silk_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 );
+ silk_assert( psDec->nb_subfr == MAX_NB_SUBFR || psDec->nb_subfr == MAX_NB_SUBFR/2 );
/* New (sub)frame length */
psDec->subfr_length = silk_SMULBB( SUB_FRAME_LENGTH_MS, fs_kHz );
@@ -86,7 +86,7 @@ opus_int silk_decoder_set_fs(
psDec->pitch_lag_low_bits_iCDF = silk_uniform4_iCDF;
} else {
/* unsupported sampling rate */
- celt_assert( 0 );
+ silk_assert( 0 );
}
psDec->first_frame_after_reset = 1;
psDec->lagPrev = 100;
@@ -101,7 +101,7 @@ opus_int silk_decoder_set_fs(
}
/* Check that settings are valid */
- celt_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH );
+ silk_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH );
return ret;
}
diff --git a/thirdparty/opus/silk/define.h b/thirdparty/opus/silk/define.h
index 247cb0bf71..19c9b00e25 100644
--- a/thirdparty/opus/silk/define.h
+++ b/thirdparty/opus/silk/define.h
@@ -46,6 +46,7 @@ extern "C"
/* Limits on bitrate */
#define MIN_TARGET_RATE_BPS 5000
#define MAX_TARGET_RATE_BPS 80000
+#define TARGET_RATE_TAB_SZ 8
/* LBRR thresholds */
#define LBRR_NB_MIN_RATE_BPS 12000
@@ -55,12 +56,6 @@ extern "C"
/* DTX settings */
#define NB_SPEECH_FRAMES_BEFORE_DTX 10 /* eq 200 ms */
#define MAX_CONSECUTIVE_DTX 20 /* eq 400 ms */
-#define DTX_ACTIVITY_THRESHOLD 0.1f
-
-/* VAD decision */
-#define VAD_NO_DECISION -1
-#define VAD_NO_ACTIVITY 0
-#define VAD_ACTIVITY 1
/* Maximum sampling frequency */
#define MAX_FS_KHZ 16
@@ -152,7 +147,7 @@ extern "C"
#define USE_HARM_SHAPING 1
/* Max LPC order of noise shaping filters */
-#define MAX_SHAPE_LPC_ORDER 24
+#define MAX_SHAPE_LPC_ORDER 16
#define HARM_SHAPE_FIR_TAPS 3
@@ -162,7 +157,8 @@ extern "C"
#define LTP_BUF_LENGTH 512
#define LTP_MASK ( LTP_BUF_LENGTH - 1 )
-#define DECISION_DELAY 40
+#define DECISION_DELAY 32
+#define DECISION_DELAY_MASK ( DECISION_DELAY - 1 )
/* Number of subframes for excitation entropy coding */
#define SHELL_CODEC_FRAME_LENGTH 16
@@ -177,7 +173,11 @@ extern "C"
#define MAX_MATRIX_SIZE MAX_LPC_ORDER /* Max of LPC Order and LTP order */
+#if( MAX_LPC_ORDER > DECISION_DELAY )
# define NSQ_LPC_BUF_LENGTH MAX_LPC_ORDER
+#else
+# define NSQ_LPC_BUF_LENGTH DECISION_DELAY
+#endif
/***************************/
/* Voice activity detector */
@@ -205,6 +205,7 @@ extern "C"
/******************/
#define NLSF_W_Q 2
#define NLSF_VQ_MAX_VECTORS 32
+#define NLSF_VQ_MAX_SURVIVORS 32
#define NLSF_QUANT_MAX_AMPLITUDE 4
#define NLSF_QUANT_MAX_AMPLITUDE_EXT 10
#define NLSF_QUANT_LEVEL_ADJ 0.1
diff --git a/thirdparty/opus/silk/enc_API.c b/thirdparty/opus/silk/enc_API.c
index 55a33f37e9..f8060286db 100644
--- a/thirdparty/opus/silk/enc_API.c
+++ b/thirdparty/opus/silk/enc_API.c
@@ -82,7 +82,7 @@ opus_int silk_InitEncoder( /* O Returns error co
silk_memset( psEnc, 0, sizeof( silk_encoder ) );
for( n = 0; n < ENCODER_NUM_CHANNELS; n++ ) {
if( ret += silk_init_encoder( &psEnc->state_Fxx[ n ], arch ) ) {
- celt_assert( 0 );
+ silk_assert( 0 );
}
}
@@ -91,7 +91,7 @@ opus_int silk_InitEncoder( /* O Returns error co
/* Read control structure */
if( ret += silk_QueryEncoder( encState, encStatus ) ) {
- celt_assert( 0 );
+ silk_assert( 0 );
}
return ret;
@@ -144,8 +144,7 @@ opus_int silk_Encode( /* O Returns error co
opus_int nSamplesIn, /* I Number of samples in input vector */
ec_enc *psRangeEnc, /* I/O Compressor data structure */
opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */
- const opus_int prefillFlag, /* I Flag to indicate prefilling buffers no coding */
- opus_int activity /* I Decision of Opus voice activity detector */
+ const opus_int prefillFlag /* I Flag to indicate prefilling buffers no coding */
)
{
opus_int n, i, nBits, flags, tmp_payloadSize_ms = 0, tmp_complexity = 0, ret = 0;
@@ -167,7 +166,7 @@ opus_int silk_Encode( /* O Returns error co
/* Check values in encoder control structure */
if( ( ret = check_control_input( encControl ) ) != 0 ) {
- celt_assert( 0 );
+ silk_assert( 0 );
RESTORE_STACK;
return ret;
}
@@ -200,26 +199,16 @@ opus_int silk_Encode( /* O Returns error co
tot_blocks = ( nBlocksOf10ms > 1 ) ? nBlocksOf10ms >> 1 : 1;
curr_block = 0;
if( prefillFlag ) {
- silk_LP_state save_LP;
/* Only accept input length of 10 ms */
if( nBlocksOf10ms != 1 ) {
- celt_assert( 0 );
+ silk_assert( 0 );
RESTORE_STACK;
return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
}
- if ( prefillFlag == 2 ) {
- save_LP = psEnc->state_Fxx[ 0 ].sCmn.sLP;
- /* Save the sampling rate so the bandwidth switching code can keep handling transitions. */
- save_LP.saved_fs_kHz = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz;
- }
/* Reset Encoder */
for( n = 0; n < encControl->nChannelsInternal; n++ ) {
ret = silk_init_encoder( &psEnc->state_Fxx[ n ], psEnc->state_Fxx[ n ].sCmn.arch );
- /* Restore the variable LP state. */
- if ( prefillFlag == 2 ) {
- psEnc->state_Fxx[ n ].sCmn.sLP = save_LP;
- }
- celt_assert( !ret );
+ silk_assert( !ret );
}
tmp_payloadSize_ms = encControl->payloadSize_ms;
encControl->payloadSize_ms = 10;
@@ -232,22 +221,23 @@ opus_int silk_Encode( /* O Returns error co
} else {
/* Only accept input lengths that are a multiple of 10 ms */
if( nBlocksOf10ms * encControl->API_sampleRate != 100 * nSamplesIn || nSamplesIn < 0 ) {
- celt_assert( 0 );
+ silk_assert( 0 );
RESTORE_STACK;
return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
}
/* Make sure no more than one packet can be produced */
if( 1000 * (opus_int32)nSamplesIn > encControl->payloadSize_ms * encControl->API_sampleRate ) {
- celt_assert( 0 );
+ silk_assert( 0 );
RESTORE_STACK;
return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
}
}
+ TargetRate_bps = silk_RSHIFT32( encControl->bitRate, encControl->nChannelsInternal - 1 );
for( n = 0; n < encControl->nChannelsInternal; n++ ) {
/* Force the side channel to the same rate as the mid */
opus_int force_fs_kHz = (n==1) ? psEnc->state_Fxx[0].sCmn.fs_kHz : 0;
- if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) {
+ if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, TargetRate_bps, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) {
silk_assert( 0 );
RESTORE_STACK;
return ret;
@@ -259,7 +249,7 @@ opus_int silk_Encode( /* O Returns error co
}
psEnc->state_Fxx[ n ].sCmn.inDTX = psEnc->state_Fxx[ n ].sCmn.useDTX;
}
- celt_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
+ silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz );
/* Input buffering/resampling and encoding */
nSamplesToBufferMax =
@@ -317,7 +307,7 @@ opus_int silk_Encode( /* O Returns error co
}
psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer;
} else {
- celt_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 );
+ silk_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 );
silk_memcpy(buf, samplesIn, nSamplesFromInput*sizeof(opus_int16));
ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state,
&psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput );
@@ -333,8 +323,8 @@ opus_int silk_Encode( /* O Returns error co
/* Silk encoder */
if( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx >= psEnc->state_Fxx[ 0 ].sCmn.frame_length ) {
/* Enough data in input buffer, so encode */
- celt_assert( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx == psEnc->state_Fxx[ 0 ].sCmn.frame_length );
- celt_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inputBufIx == psEnc->state_Fxx[ 1 ].sCmn.frame_length );
+ silk_assert( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx == psEnc->state_Fxx[ 0 ].sCmn.frame_length );
+ silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inputBufIx == psEnc->state_Fxx[ 1 ].sCmn.frame_length );
/* Deal with LBRR data */
if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 && !prefillFlag ) {
@@ -426,6 +416,7 @@ opus_int silk_Encode( /* O Returns error co
/* Reset side channel encoder memory for first frame with side coding */
if( psEnc->prev_decode_only_middle == 1 ) {
silk_memset( &psEnc->state_Fxx[ 1 ].sShape, 0, sizeof( psEnc->state_Fxx[ 1 ].sShape ) );
+ silk_memset( &psEnc->state_Fxx[ 1 ].sPrefilt, 0, sizeof( psEnc->state_Fxx[ 1 ].sPrefilt ) );
silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sNSQ, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sNSQ ) );
silk_memset( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15 ) );
silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State ) );
@@ -436,7 +427,7 @@ opus_int silk_Encode( /* O Returns error co
psEnc->state_Fxx[ 1 ].sCmn.sNSQ.prev_gain_Q16 = 65536;
psEnc->state_Fxx[ 1 ].sCmn.first_frame_after_reset = 1;
}
- silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 1 ], activity );
+ silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 1 ] );
} else {
psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] = 0;
}
@@ -451,7 +442,7 @@ opus_int silk_Encode( /* O Returns error co
silk_memcpy( psEnc->state_Fxx[ 0 ].sCmn.inputBuf, psEnc->sStereo.sMid, 2 * sizeof( opus_int16 ) );
silk_memcpy( psEnc->sStereo.sMid, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.frame_length ], 2 * sizeof( opus_int16 ) );
}
- silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 0 ], activity );
+ silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 0 ] );
/* Encode */
for( n = 0; n < encControl->nChannelsInternal; n++ ) {
@@ -566,10 +557,6 @@ opus_int silk_Encode( /* O Returns error co
}
}
- encControl->signalType = psEnc->state_Fxx[0].sCmn.indices.signalType;
- encControl->offset = silk_Quantization_Offsets_Q10
- [ psEnc->state_Fxx[0].sCmn.indices.signalType >> 1 ]
- [ psEnc->state_Fxx[0].sCmn.indices.quantOffsetType ];
RESTORE_STACK;
return ret;
}
diff --git a/thirdparty/opus/silk/encode_indices.c b/thirdparty/opus/silk/encode_indices.c
index 4bcbc3347b..666c8c0b13 100644
--- a/thirdparty/opus/silk/encode_indices.c
+++ b/thirdparty/opus/silk/encode_indices.c
@@ -56,8 +56,8 @@ void silk_encode_indices(
/* Encode signal type and quantizer offset */
/*******************************************/
typeOffset = 2 * psIndices->signalType + psIndices->quantOffsetType;
- celt_assert( typeOffset >= 0 && typeOffset < 6 );
- celt_assert( encode_LBRR == 0 || typeOffset >= 2 );
+ silk_assert( typeOffset >= 0 && typeOffset < 6 );
+ silk_assert( encode_LBRR == 0 || typeOffset >= 2 );
if( encode_LBRR || typeOffset >= 2 ) {
ec_enc_icdf( psRangeEnc, typeOffset - 2, silk_type_offset_VAD_iCDF, 8 );
} else {
@@ -90,7 +90,7 @@ void silk_encode_indices(
/****************/
ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ 0 ], &psEncC->psNLSF_CB->CB1_iCDF[ ( psIndices->signalType >> 1 ) * psEncC->psNLSF_CB->nVectors ], 8 );
silk_NLSF_unpack( ec_ix, pred_Q8, psEncC->psNLSF_CB, psIndices->NLSFIndices[ 0 ] );
- celt_assert( psEncC->psNLSF_CB->order == psEncC->predictLPCOrder );
+ silk_assert( psEncC->psNLSF_CB->order == psEncC->predictLPCOrder );
for( i = 0; i < psEncC->psNLSF_CB->order; i++ ) {
if( psIndices->NLSFIndices[ i+1 ] >= NLSF_QUANT_MAX_AMPLITUDE ) {
ec_enc_icdf( psRangeEnc, 2 * NLSF_QUANT_MAX_AMPLITUDE, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 );
diff --git a/thirdparty/opus/silk/encode_pulses.c b/thirdparty/opus/silk/encode_pulses.c
index 8a1999138b..ab00264f99 100644
--- a/thirdparty/opus/silk/encode_pulses.c
+++ b/thirdparty/opus/silk/encode_pulses.c
@@ -86,7 +86,7 @@ void silk_encode_pulses(
silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH );
iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH );
if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) {
- celt_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */
+ silk_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */
iter++;
silk_memset( &pulses[ frame_length ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof(opus_int8));
}
diff --git a/thirdparty/opus/silk/fixed/apply_sine_window_FIX.c b/thirdparty/opus/silk/fixed/apply_sine_window_FIX.c
index 03e088a6de..4502b7130e 100644
--- a/thirdparty/opus/silk/fixed/apply_sine_window_FIX.c
+++ b/thirdparty/opus/silk/fixed/apply_sine_window_FIX.c
@@ -57,15 +57,15 @@ void silk_apply_sine_window(
opus_int k, f_Q16, c_Q16;
opus_int32 S0_Q16, S1_Q16;
- celt_assert( win_type == 1 || win_type == 2 );
+ silk_assert( win_type == 1 || win_type == 2 );
/* Length must be in a range from 16 to 120 and a multiple of 4 */
- celt_assert( length >= 16 && length <= 120 );
- celt_assert( ( length & 3 ) == 0 );
+ silk_assert( length >= 16 && length <= 120 );
+ silk_assert( ( length & 3 ) == 0 );
/* Frequency */
k = ( length >> 2 ) - 4;
- celt_assert( k >= 0 && k <= 26 );
+ silk_assert( k >= 0 && k <= 26 );
f_Q16 = (opus_int)freq_table_Q16[ k ];
/* Factor used for cosine approximation */
diff --git a/thirdparty/opus/silk/fixed/arm/warped_autocorrelation_FIX_arm.h b/thirdparty/opus/silk/fixed/arm/warped_autocorrelation_FIX_arm.h
deleted file mode 100644
index 1992e43288..0000000000
--- a/thirdparty/opus/silk/fixed/arm/warped_autocorrelation_FIX_arm.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/***********************************************************************
-Copyright (c) 2017 Google Inc.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-- Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-- Neither the name of Internet Society, IETF or IETF Trust, nor the
-names of specific contributors, may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-***********************************************************************/
-
-#ifndef SILK_WARPED_AUTOCORRELATION_FIX_ARM_H
-# define SILK_WARPED_AUTOCORRELATION_FIX_ARM_H
-
-# include "celt/arm/armcpu.h"
-
-# if defined(FIXED_POINT)
-
-# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
-void silk_warped_autocorrelation_FIX_neon(
- opus_int32 *corr, /* O Result [order + 1] */
- opus_int *scale, /* O Scaling of the correlation vector */
- const opus_int16 *input, /* I Input data to correlate */
- const opus_int warping_Q16, /* I Warping coefficient */
- const opus_int length, /* I Length of input */
- const opus_int order /* I Correlation order (even) */
-);
-
-# if !defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_PRESUME_NEON)
-# define OVERRIDE_silk_warped_autocorrelation_FIX (1)
-# define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
- ((void)(arch), PRESUME_NEON(silk_warped_autocorrelation_FIX)(corr, scale, input, warping_Q16, length, order))
-# endif
-# endif
-
-# if !defined(OVERRIDE_silk_warped_autocorrelation_FIX)
-/*Is run-time CPU detection enabled on this platform?*/
-# if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
-extern 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);
-# define OVERRIDE_silk_warped_autocorrelation_FIX (1)
-# define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
- ((*SILK_WARPED_AUTOCORRELATION_FIX_IMPL[(arch)&OPUS_ARCHMASK])(corr, scale, input, warping_Q16, length, order))
-# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
-# define OVERRIDE_silk_warped_autocorrelation_FIX (1)
-# define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
- ((void)(arch), silk_warped_autocorrelation_FIX_neon(corr, scale, input, warping_Q16, length, order))
-# endif
-# endif
-
-# endif /* end FIXED_POINT */
-
-#endif /* end SILK_WARPED_AUTOCORRELATION_FIX_ARM_H */
diff --git a/thirdparty/opus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c b/thirdparty/opus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c
deleted file mode 100644
index 00a70cb51f..0000000000
--- a/thirdparty/opus/silk/fixed/arm/warped_autocorrelation_FIX_neon_intr.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/***********************************************************************
-Copyright (c) 2017 Google Inc., Jean-Marc Valin
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-- Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-- Neither the name of Internet Society, IETF or IETF Trust, nor the
-names of specific contributors, may be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-***********************************************************************/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <arm_neon.h>
-#ifdef OPUS_CHECK_ASM
-# include <string.h>
-#endif
-#include "stack_alloc.h"
-#include "main_FIX.h"
-
-static 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 )
-{
- int64x2_t corr_QC_s64x2[ 2 ], t_s64x2[ 2 ];
- const int32x4_t input_QS_s32x4 = vld1q_s32( input_QS + offset );
- corr_QC_s64x2[ 0 ] = vld1q_s64( corr_QC + offset + 0 );
- corr_QC_s64x2[ 1 ] = vld1q_s64( corr_QC + offset + 2 );
- t_s64x2[ 0 ] = vmull_s32( vget_low_s32( state_QS_s32x4 ), vget_low_s32( input_QS_s32x4 ) );
- t_s64x2[ 1 ] = vmull_s32( vget_high_s32( state_QS_s32x4 ), vget_high_s32( input_QS_s32x4 ) );
- corr_QC_s64x2[ 0 ] = vsraq_n_s64( corr_QC_s64x2[ 0 ], t_s64x2[ 0 ], 2 * QS - QC );
- corr_QC_s64x2[ 1 ] = vsraq_n_s64( corr_QC_s64x2[ 1 ], t_s64x2[ 1 ], 2 * QS - QC );
- vst1q_s64( corr_QC + offset + 0, corr_QC_s64x2[ 0 ] );
- vst1q_s64( corr_QC + offset + 2, corr_QC_s64x2[ 1 ] );
-}
-
-static 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 )
-{
- int32x4_t t_s32x4 = vsubq_s32( state_QS0_s32x4, state_QS0_1_s32x4 );
- t_s32x4 = vqdmulhq_s32( t_s32x4, warping_Q16_s32x4 );
- return vaddq_s32( state_QS1_1_s32x4, t_s32x4 );
-}
-
-void silk_warped_autocorrelation_FIX_neon(
- opus_int32 *corr, /* O Result [order + 1] */
- opus_int *scale, /* O Scaling of the correlation vector */
- const opus_int16 *input, /* I Input data to correlate */
- const opus_int warping_Q16, /* I Warping coefficient */
- const opus_int length, /* I Length of input */
- const opus_int order /* I Correlation order (even) */
-)
-{
- if( ( MAX_SHAPE_LPC_ORDER > 24 ) || ( order < 6 ) ) {
- silk_warped_autocorrelation_FIX_c( corr, scale, input, warping_Q16, length, order );
- } else {
- opus_int n, i, lsh;
- opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; /* In reverse order */
- opus_int64 corr_QC_orderT;
- int64x2_t lsh_s64x2;
- const opus_int orderT = ( order + 3 ) & ~3;
- opus_int64 *corr_QCT;
- opus_int32 *input_QS;
- VARDECL( opus_int32, input_QST );
- VARDECL( opus_int32, state );
- SAVE_STACK;
-
- /* Order must be even */
- silk_assert( ( order & 1 ) == 0 );
- silk_assert( 2 * QS - QC >= 0 );
-
- ALLOC( input_QST, length + 2 * MAX_SHAPE_LPC_ORDER, opus_int32 );
-
- input_QS = input_QST;
- /* input_QS has zero paddings in the beginning and end. */
- vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
- input_QS += 4;
- vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
- input_QS += 4;
- vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
- input_QS += 4;
- vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
- input_QS += 4;
- vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
- input_QS += 4;
- vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
- input_QS += 4;
-
- /* Loop over samples */
- for( n = 0; n < length - 7; n += 8, input_QS += 8 ) {
- const int16x8_t t0_s16x4 = vld1q_s16( input + n );
- vst1q_s32( input_QS + 0, vshll_n_s16( vget_low_s16( t0_s16x4 ), QS ) );
- vst1q_s32( input_QS + 4, vshll_n_s16( vget_high_s16( t0_s16x4 ), QS ) );
- }
- for( ; n < length; n++, input_QS++ ) {
- input_QS[ 0 ] = silk_LSHIFT32( (opus_int32)input[ n ], QS );
- }
- vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
- input_QS += 4;
- vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
- input_QS += 4;
- vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
- input_QS += 4;
- vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
- input_QS += 4;
- vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
- input_QS += 4;
- vst1q_s32( input_QS, vdupq_n_s32( 0 ) );
- input_QS = input_QST + MAX_SHAPE_LPC_ORDER - orderT;
-
- /* The following loop runs ( length + order ) times, with ( order ) extra epilogues. */
- /* The zero paddings in input_QS guarantee corr_QC's correctness even with the extra epilogues. */
- /* The values of state_QS will be polluted by the extra epilogues, however they are temporary values. */
-
- /* Keep the C code here to help understand the intrinsics optimization. */
- /*
- {
- opus_int32 state_QS[ 2 ][ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
- opus_int32 *state_QST[ 3 ];
- state_QST[ 0 ] = state_QS[ 0 ];
- state_QST[ 1 ] = state_QS[ 1 ];
- for( n = 0; n < length + order; n++, input_QS++ ) {
- state_QST[ 0 ][ orderT ] = input_QS[ orderT ];
- for( i = 0; i < orderT; i++ ) {
- corr_QC[ i ] += silk_RSHIFT64( silk_SMULL( state_QST[ 0 ][ i ], input_QS[ i ] ), 2 * QS - QC );
- state_QST[ 1 ][ i ] = silk_SMLAWB( state_QST[ 1 ][ i + 1 ], state_QST[ 0 ][ i ] - state_QST[ 0 ][ i + 1 ], warping_Q16 );
- }
- state_QST[ 2 ] = state_QST[ 0 ];
- state_QST[ 0 ] = state_QST[ 1 ];
- state_QST[ 1 ] = state_QST[ 2 ];
- }
- }
- */
-
- {
- const int32x4_t warping_Q16_s32x4 = vdupq_n_s32( warping_Q16 << 15 );
- const opus_int32 *in = input_QS + orderT;
- opus_int o = orderT;
- int32x4_t state_QS_s32x4[ 3 ][ 2 ];
-
- ALLOC( state, length + orderT, opus_int32 );
- state_QS_s32x4[ 2 ][ 1 ] = vdupq_n_s32( 0 );
-
- /* Calculate 8 taps of all inputs in each loop. */
- do {
- state_QS_s32x4[ 0 ][ 0 ] = state_QS_s32x4[ 0 ][ 1 ] =
- state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 1 ][ 1 ] = vdupq_n_s32( 0 );
- n = 0;
- do {
- calc_corr( input_QS + n, corr_QC, o - 8, state_QS_s32x4[ 0 ][ 0 ] );
- calc_corr( input_QS + n, corr_QC, o - 4, state_QS_s32x4[ 0 ][ 1 ] );
- state_QS_s32x4[ 2 ][ 1 ] = vld1q_s32( in + n );
- vst1q_lane_s32( state + n, state_QS_s32x4[ 0 ][ 0 ], 0 );
- state_QS_s32x4[ 2 ][ 0 ] = vextq_s32( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 0 ][ 1 ], 1 );
- state_QS_s32x4[ 2 ][ 1 ] = vextq_s32( state_QS_s32x4[ 0 ][ 1 ], state_QS_s32x4[ 2 ][ 1 ], 1 );
- 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 );
- 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 );
- state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 2 ][ 0 ];
- state_QS_s32x4[ 1 ][ 1 ] = state_QS_s32x4[ 2 ][ 1 ];
- } while( ++n < ( length + order ) );
- in = state;
- o -= 8;
- } while( o > 4 );
-
- if( o ) {
- /* Calculate the last 4 taps of all inputs. */
- opus_int32 *stateT = state;
- silk_assert( o == 4 );
- state_QS_s32x4[ 0 ][ 0 ] = state_QS_s32x4[ 1 ][ 0 ] = vdupq_n_s32( 0 );
- n = length + order;
- do {
- calc_corr( input_QS, corr_QC, 0, state_QS_s32x4[ 0 ][ 0 ] );
- state_QS_s32x4[ 2 ][ 0 ] = vld1q_s32( stateT );
- vst1q_lane_s32( stateT, state_QS_s32x4[ 0 ][ 0 ], 0 );
- state_QS_s32x4[ 2 ][ 0 ] = vextq_s32( state_QS_s32x4[ 0 ][ 0 ], state_QS_s32x4[ 2 ][ 0 ], 1 );
- 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 );
- state_QS_s32x4[ 1 ][ 0 ] = state_QS_s32x4[ 2 ][ 0 ];
- input_QS++;
- stateT++;
- } while( --n );
- }
- }
-
- {
- const opus_int16 *inputT = input;
- int32x4_t t_s32x4;
- int64x1_t t_s64x1;
- int64x2_t t_s64x2 = vdupq_n_s64( 0 );
- for( n = 0; n <= length - 8; n += 8 ) {
- int16x8_t input_s16x8 = vld1q_s16( inputT );
- t_s32x4 = vmull_s16( vget_low_s16( input_s16x8 ), vget_low_s16( input_s16x8 ) );
- t_s32x4 = vmlal_s16( t_s32x4, vget_high_s16( input_s16x8 ), vget_high_s16( input_s16x8 ) );
- t_s64x2 = vaddw_s32( t_s64x2, vget_low_s32( t_s32x4 ) );
- t_s64x2 = vaddw_s32( t_s64x2, vget_high_s32( t_s32x4 ) );
- inputT += 8;
- }
- t_s64x1 = vadd_s64( vget_low_s64( t_s64x2 ), vget_high_s64( t_s64x2 ) );
- corr_QC_orderT = vget_lane_s64( t_s64x1, 0 );
- for( ; n < length; n++ ) {
- corr_QC_orderT += silk_SMULL( input[ n ], input[ n ] );
- }
- corr_QC_orderT = silk_LSHIFT64( corr_QC_orderT, QC );
- corr_QC[ orderT ] = corr_QC_orderT;
- }
-
- corr_QCT = corr_QC + orderT - order;
- lsh = silk_CLZ64( corr_QC_orderT ) - 35;
- lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC );
- *scale = -( QC + lsh );
- silk_assert( *scale >= -30 && *scale <= 12 );
- lsh_s64x2 = vdupq_n_s64( lsh );
- for( i = 0; i <= order - 3; i += 4 ) {
- int32x4_t corr_s32x4;
- int64x2_t corr_QC0_s64x2, corr_QC1_s64x2;
- corr_QC0_s64x2 = vld1q_s64( corr_QCT + i );
- corr_QC1_s64x2 = vld1q_s64( corr_QCT + i + 2 );
- corr_QC0_s64x2 = vshlq_s64( corr_QC0_s64x2, lsh_s64x2 );
- corr_QC1_s64x2 = vshlq_s64( corr_QC1_s64x2, lsh_s64x2 );
- corr_s32x4 = vcombine_s32( vmovn_s64( corr_QC1_s64x2 ), vmovn_s64( corr_QC0_s64x2 ) );
- corr_s32x4 = vrev64q_s32( corr_s32x4 );
- vst1q_s32( corr + order - i - 3, corr_s32x4 );
- }
- if( lsh >= 0 ) {
- for( ; i < order + 1; i++ ) {
- corr[ order - i ] = (opus_int32)silk_CHECK_FIT32( silk_LSHIFT64( corr_QCT[ i ], lsh ) );
- }
- } else {
- for( ; i < order + 1; i++ ) {
- corr[ order - i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr_QCT[ i ], -lsh ) );
- }
- }
- silk_assert( corr_QCT[ order ] >= 0 ); /* If breaking, decrease QC*/
- RESTORE_STACK;
- }
-
-#ifdef OPUS_CHECK_ASM
- {
- opus_int32 corr_c[ MAX_SHAPE_LPC_ORDER + 1 ];
- opus_int scale_c;
- silk_warped_autocorrelation_FIX_c( corr_c, &scale_c, input, warping_Q16, length, order );
- silk_assert( !memcmp( corr_c, corr, sizeof( corr_c[ 0 ] ) * ( order + 1 ) ) );
- silk_assert( scale_c == *scale );
- }
-#endif
-}
diff --git a/thirdparty/opus/silk/fixed/burg_modified_FIX.c b/thirdparty/opus/silk/fixed/burg_modified_FIX.c
index 274d4b28e1..17d0e0993c 100644
--- a/thirdparty/opus/silk/fixed/burg_modified_FIX.c
+++ b/thirdparty/opus/silk/fixed/burg_modified_FIX.c
@@ -37,7 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */
#define QA 25
-#define N_BITS_HEAD_ROOM 3
+#define N_BITS_HEAD_ROOM 2
#define MIN_RSHIFTS -16
#define MAX_RSHIFTS (32 - QA)
@@ -65,7 +65,7 @@ void silk_burg_modified_c(
opus_int32 xcorr[ SILK_MAX_ORDER_LPC ];
opus_int64 C0_64;
- celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
+ silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
/* Compute autocorrelations, added over subframes */
C0_64 = silk_inner_prod16_aligned_64( x, x, subfr_length*nb_subfr, arch );
diff --git a/thirdparty/opus/silk/fixed/corrMatrix_FIX.c b/thirdparty/opus/silk/fixed/corrMatrix_FIX.c
index 1b4a29c232..c1d437c785 100644
--- a/thirdparty/opus/silk/fixed/corrMatrix_FIX.c
+++ b/thirdparty/opus/silk/fixed/corrMatrix_FIX.c
@@ -58,7 +58,7 @@ void silk_corrVector_FIX(
for( lag = 0; lag < order; lag++ ) {
inner_prod = 0;
for( i = 0; i < L; i++ ) {
- inner_prod = silk_ADD_RSHIFT32( inner_prod, silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts );
+ inner_prod += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts );
}
Xt[ lag ] = inner_prod; /* X[:,lag]'*t */
ptr1--; /* Go to next column of X */
@@ -77,54 +77,61 @@ void silk_corrMatrix_FIX(
const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
const opus_int L, /* I Length of vectors */
const opus_int order, /* I Max lag for correlation */
+ const opus_int head_room, /* I Desired headroom */
opus_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ] */
- opus_int32 *nrg, /* O Energy of x vector */
- opus_int *rshifts, /* O Right shifts of correlations and energy */
+ opus_int *rshifts, /* I/O Right shifts of correlations */
int arch /* I Run-time architecture */
)
{
- opus_int i, j, lag;
+ opus_int i, j, lag, rshifts_local, head_room_rshifts;
opus_int32 energy;
const opus_int16 *ptr1, *ptr2;
/* Calculate energy to find shift used to fit in 32 bits */
- silk_sum_sqr_shift( nrg, rshifts, x, L + order - 1 );
- energy = *nrg;
+ silk_sum_sqr_shift( &energy, &rshifts_local, x, L + order - 1 );
+ /* Add shifts to get the desired head room */
+ head_room_rshifts = silk_max( head_room - silk_CLZ32( energy ), 0 );
+
+ energy = silk_RSHIFT32( energy, head_room_rshifts );
+ rshifts_local += head_room_rshifts;
/* Calculate energy of first column (0) of X: X[:,0]'*X[:,0] */
/* Remove contribution of first order - 1 samples */
for( i = 0; i < order - 1; i++ ) {
- energy -= silk_RSHIFT32( silk_SMULBB( x[ i ], x[ i ] ), *rshifts );
+ energy -= silk_RSHIFT32( silk_SMULBB( x[ i ], x[ i ] ), rshifts_local );
+ }
+ if( rshifts_local < *rshifts ) {
+ /* Adjust energy */
+ energy = silk_RSHIFT32( energy, *rshifts - rshifts_local );
+ rshifts_local = *rshifts;
}
/* Calculate energy of remaining columns of X: X[:,j]'*X[:,j] */
/* Fill out the diagonal of the correlation matrix */
matrix_ptr( XX, 0, 0, order ) = energy;
- silk_assert( energy >= 0 );
ptr1 = &x[ order - 1 ]; /* First sample of column 0 of X */
for( j = 1; j < order; j++ ) {
- energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), *rshifts ) );
- energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr1[ -j ] ), *rshifts ) );
+ energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), rshifts_local ) );
+ energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr1[ -j ] ), rshifts_local ) );
matrix_ptr( XX, j, j, order ) = energy;
- silk_assert( energy >= 0 );
}
ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */
/* Calculate the remaining elements of the correlation matrix */
- if( *rshifts > 0 ) {
+ if( rshifts_local > 0 ) {
/* Right shifting used */
for( lag = 1; lag < order; lag++ ) {
/* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */
energy = 0;
for( i = 0; i < L; i++ ) {
- energy += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), *rshifts );
+ energy += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts_local );
}
/* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */
matrix_ptr( XX, lag, 0, order ) = energy;
matrix_ptr( XX, 0, lag, order ) = energy;
for( j = 1; j < ( order - lag ); j++ ) {
- energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), *rshifts ) );
- energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr2[ -j ] ), *rshifts ) );
+ energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), rshifts_local ) );
+ energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr2[ -j ] ), rshifts_local ) );
matrix_ptr( XX, lag + j, j, order ) = energy;
matrix_ptr( XX, j, lag + j, order ) = energy;
}
@@ -146,5 +153,6 @@ void silk_corrMatrix_FIX(
ptr2--;/* Update pointer to first sample of next column (lag) in X */
}
}
+ *rshifts = rshifts_local;
}
diff --git a/thirdparty/opus/silk/fixed/encode_frame_FIX.c b/thirdparty/opus/silk/fixed/encode_frame_FIX.c
index a02bf87dbb..5ef44b03fc 100644
--- a/thirdparty/opus/silk/fixed/encode_frame_FIX.c
+++ b/thirdparty/opus/silk/fixed/encode_frame_FIX.c
@@ -29,7 +29,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "config.h"
#endif
-#include <stdlib.h>
#include "main_FIX.h"
#include "stack_alloc.h"
#include "tuning_parameters.h"
@@ -38,33 +37,26 @@ POSSIBILITY OF SUCH DAMAGE.
static OPUS_INLINE void silk_LBRR_encode_FIX(
silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */
- const opus_int16 x16[], /* I Input signal */
+ const opus_int32 xfw_Q3[], /* I Input signal */
opus_int condCoding /* I The type of conditional coding used so far for this frame */
);
void silk_encode_do_VAD_FIX(
- silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
- opus_int activity /* I Decision of Opus voice activity detector */
+ silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk FIX encoder state */
)
{
- const opus_int activity_threshold = SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 );
-
/****************************/
/* Voice Activity Detection */
/****************************/
silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch );
- /* If Opus VAD is inactive and Silk VAD is active: lower Silk VAD to just under the threshold */
- if( activity == VAD_NO_ACTIVITY && psEnc->sCmn.speech_activity_Q8 >= activity_threshold ) {
- psEnc->sCmn.speech_activity_Q8 = activity_threshold - 1;
- }
/**************************************************/
/* Convert speech activity into VAD and DTX flags */
/**************************************************/
- if( psEnc->sCmn.speech_activity_Q8 < activity_threshold ) {
+ if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {
psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
psEnc->sCmn.noSpeechCounter++;
- if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) {
+ if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) {
psEnc->sCmn.inDTX = 0;
} else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {
psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;
@@ -102,9 +94,6 @@ opus_int silk_encode_frame_FIX(
opus_int16 ec_prevLagIndex_copy;
opus_int ec_prevSignalType_copy;
opus_int8 LastGainIndex_copy2;
- opus_int gain_lock[ MAX_NB_SUBFR ] = {0};
- opus_int16 best_gain_mult[ MAX_NB_SUBFR ];
- opus_int best_sum[ MAX_NB_SUBFR ];
SAVE_STACK;
/* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
@@ -129,6 +118,7 @@ opus_int silk_encode_frame_FIX(
silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
if( !psEnc->sCmn.prefillFlag ) {
+ VARDECL( opus_int32, xfw_Q3 );
VARDECL( opus_int16, res_pitch );
VARDECL( opus_uint8, ec_buf_copy );
opus_int16 *res_pitch_frame;
@@ -142,7 +132,7 @@ opus_int silk_encode_frame_FIX(
/*****************************************/
/* Find pitch lags, initial LPC analysis */
/*****************************************/
- silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame - psEnc->sCmn.ltp_mem_length, psEnc->sCmn.arch );
+ silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, psEnc->sCmn.arch );
/************************/
/* Noise shape analysis */
@@ -152,17 +142,23 @@ opus_int silk_encode_frame_FIX(
/***************************************************/
/* Find linear prediction coefficients (LPC + LTP) */
/***************************************************/
- silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding );
+ silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding );
/****************************************/
/* Process gains */
/****************************************/
silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding );
+ /*****************************************/
+ /* Prefiltering for noise shaper */
+ /*****************************************/
+ ALLOC( xfw_Q3, psEnc->sCmn.frame_length, opus_int32 );
+ silk_prefilter_FIX( psEnc, &sEncCtrl, xfw_Q3, x_frame );
+
/****************************************/
/* Low Bitrate Redundant Encoding */
/****************************************/
- silk_LBRR_encode_FIX( psEnc, &sEncCtrl, x_frame, condCoding );
+ silk_LBRR_encode_FIX( psEnc, &sEncCtrl, xfw_Q3, condCoding );
/* Loop over quantizer and entropy coding to control bitrate */
maxIter = 6;
@@ -198,21 +194,17 @@ opus_int silk_encode_frame_FIX(
/* Noise shaping quantization */
/*****************************************/
if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
- silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
- sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14,
+ silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses,
+ sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
psEnc->sCmn.arch );
} else {
- silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
- sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14,
+ silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses,
+ sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
psEnc->sCmn.arch);
}
- if ( iter == maxIter && !found_lower ) {
- silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
- }
-
/****************************************/
/* Encode Parameters */
/****************************************/
@@ -226,33 +218,6 @@ opus_int silk_encode_frame_FIX(
nBits = ec_tell( psRangeEnc );
- /* If we still bust after the last iteration, do some damage control. */
- if ( iter == maxIter && !found_lower && nBits > maxBits ) {
- silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
-
- /* Keep gains the same as the last frame. */
- psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
- for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
- psEnc->sCmn.indices.GainsIndices[ i ] = 4;
- }
- if (condCoding != CODE_CONDITIONALLY) {
- psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev;
- }
- psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
- psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
- /* Clear all pulses. */
- for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
- psEnc->sCmn.pulses[ i ] = 0;
- }
-
- silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
-
- silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
- psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
-
- nBits = ec_tell( psRangeEnc );
- }
-
if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
break;
}
@@ -262,7 +227,7 @@ opus_int silk_encode_frame_FIX(
if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {
/* Restore output state from earlier iteration that did meet the bitrate budget */
silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
- celt_assert( sRangeEnc_copy2.offs <= 1275 );
+ silk_assert( sRangeEnc_copy2.offs <= 1275 );
silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );
silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );
psEnc->sShape.LastGainIndex = LastGainIndex_copy2;
@@ -290,7 +255,7 @@ opus_int silk_encode_frame_FIX(
gainsID_lower = gainsID;
/* Copy part of the output state */
silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
- celt_assert( psRangeEnc->offs <= 1275 );
+ silk_assert( psRangeEnc->offs <= 1275 );
silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;
@@ -300,35 +265,15 @@ opus_int silk_encode_frame_FIX(
break;
}
- if ( !found_lower && nBits > maxBits ) {
- int j;
- for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
- int sum=0;
- for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) {
- sum += abs( psEnc->sCmn.pulses[j] );
- }
- if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) {
- best_sum[i] = sum;
- best_gain_mult[i] = gainMult_Q8;
- } else {
- gain_lock[i] = 1;
- }
- }
- }
if( ( found_lower & found_upper ) == 0 ) {
/* Adjust gain according to high-rate rate/distortion curve */
+ opus_int32 gain_factor_Q16;
+ gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
+ gain_factor_Q16 = silk_min_32( gain_factor_Q16, SILK_FIX_CONST( 2, 16 ) );
if( nBits > maxBits ) {
- if (gainMult_Q8 < 16384) {
- gainMult_Q8 *= 2;
- } else {
- gainMult_Q8 = 32767;
- }
- } else {
- opus_int32 gain_factor_Q16;
- gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
- gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
+ gain_factor_Q16 = silk_max_32( gain_factor_Q16, SILK_FIX_CONST( 1.3, 16 ) );
}
-
+ gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
} else {
/* Adjust gain by interpolating */
gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower );
@@ -342,13 +287,7 @@ opus_int silk_encode_frame_FIX(
}
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
- opus_int16 tmp;
- if ( gain_lock[i] ) {
- tmp = best_gain_mult[i];
- } else {
- tmp = gainMult_Q8;
- }
- sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 );
+ sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 );
}
/* Quantize gains */
@@ -392,7 +331,7 @@ opus_int silk_encode_frame_FIX(
static OPUS_INLINE void silk_LBRR_encode_FIX(
silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */
- const opus_int16 x16[], /* I Input signal */
+ const opus_int32 xfw_Q3[], /* I Input signal */
opus_int condCoding /* I The type of conditional coding used so far for this frame */
)
{
@@ -431,14 +370,14 @@ static OPUS_INLINE void silk_LBRR_encode_FIX(
/* Noise shaping quantization */
/*****************************************/
if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
- silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16,
+ silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q3,
psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
- psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
+ psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
} else {
- silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16,
+ silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q3,
psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
- psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
+ psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
}
diff --git a/thirdparty/opus/silk/fixed/find_LPC_FIX.c b/thirdparty/opus/silk/fixed/find_LPC_FIX.c
index c762a0f2a2..e11cdc86e6 100644
--- a/thirdparty/opus/silk/fixed/find_LPC_FIX.c
+++ b/thirdparty/opus/silk/fixed/find_LPC_FIX.c
@@ -92,7 +92,7 @@ void silk_find_LPC_FIX(
silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder );
/* Convert to LPC for residual energy evaluation */
- silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, psEncC->predictLPCOrder, psEncC->arch );
+ silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, psEncC->predictLPCOrder );
/* Calculate residual energy with NLSF interpolation */
silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, psEncC->predictLPCOrder, psEncC->arch );
@@ -146,6 +146,6 @@ void silk_find_LPC_FIX(
silk_A2NLSF( NLSF_Q15, a_Q16, psEncC->predictLPCOrder );
}
- celt_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );
+ silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );
RESTORE_STACK;
}
diff --git a/thirdparty/opus/silk/fixed/find_LTP_FIX.c b/thirdparty/opus/silk/fixed/find_LTP_FIX.c
index 62d4afb250..1314a28137 100644
--- a/thirdparty/opus/silk/fixed/find_LTP_FIX.c
+++ b/thirdparty/opus/silk/fixed/find_LTP_FIX.c
@@ -32,68 +32,214 @@ POSSIBILITY OF SUCH DAMAGE.
#include "main_FIX.h"
#include "tuning_parameters.h"
+/* Head room for correlations */
+#define LTP_CORRS_HEAD_ROOM 2
+
+void silk_fit_LTP(
+ opus_int32 LTP_coefs_Q16[ LTP_ORDER ],
+ opus_int16 LTP_coefs_Q14[ LTP_ORDER ]
+);
+
void silk_find_LTP_FIX(
- opus_int32 XXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Correlation matrix */
- opus_int32 xXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER ], /* O Correlation vector */
- const opus_int16 r_ptr[], /* I Residual signal after LPC */
+ opus_int16 b_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */
+ opus_int32 WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
+ opus_int *LTPredCodGain_Q7, /* O LTP coding gain */
+ const opus_int16 r_lpc[], /* I residual signal after LPC signal + state for first 10 ms */
const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
- const opus_int subfr_length, /* I Subframe length */
- const opus_int nb_subfr, /* I Number of subframes */
+ const opus_int32 Wght_Q15[ MAX_NB_SUBFR ], /* I weights */
+ const opus_int subfr_length, /* I subframe length */
+ const opus_int nb_subfr, /* I number of subframes */
+ const opus_int mem_offset, /* I number of samples in LTP memory */
+ opus_int corr_rshifts[ MAX_NB_SUBFR ], /* O right shifts applied to correlations */
int arch /* I Run-time architecture */
)
{
- opus_int i, k, extra_shifts;
- opus_int xx_shifts, xX_shifts, XX_shifts;
- const opus_int16 *lag_ptr;
- opus_int32 *XXLTP_Q17_ptr, *xXLTP_Q17_ptr;
- opus_int32 xx, nrg, temp;
-
- xXLTP_Q17_ptr = xXLTP_Q17;
- XXLTP_Q17_ptr = XXLTP_Q17;
+ opus_int i, k, lshift;
+ const opus_int16 *r_ptr, *lag_ptr;
+ opus_int16 *b_Q14_ptr;
+
+ opus_int32 regu;
+ opus_int32 *WLTP_ptr;
+ opus_int32 b_Q16[ LTP_ORDER ], delta_b_Q14[ LTP_ORDER ], d_Q14[ MAX_NB_SUBFR ], nrg[ MAX_NB_SUBFR ], g_Q26;
+ opus_int32 w[ MAX_NB_SUBFR ], WLTP_max, max_abs_d_Q14, max_w_bits;
+
+ opus_int32 temp32, denom32;
+ opus_int extra_shifts;
+ opus_int rr_shifts, maxRshifts, maxRshifts_wxtra, LZs;
+ opus_int32 LPC_res_nrg, LPC_LTP_res_nrg, div_Q16;
+ opus_int32 Rr[ LTP_ORDER ], rr[ MAX_NB_SUBFR ];
+ opus_int32 wd, m_Q12;
+
+ b_Q14_ptr = b_Q14;
+ WLTP_ptr = WLTP;
+ r_ptr = &r_lpc[ mem_offset ];
for( k = 0; k < nb_subfr; k++ ) {
lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 );
- silk_sum_sqr_shift( &xx, &xx_shifts, r_ptr, subfr_length + LTP_ORDER ); /* xx in Q( -xx_shifts ) */
- 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 ) */
- extra_shifts = xx_shifts - XX_shifts;
- if( extra_shifts > 0 ) {
- /* Shift XX */
- xX_shifts = xx_shifts;
- for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
- XXLTP_Q17_ptr[ i ] = silk_RSHIFT32( XXLTP_Q17_ptr[ i ], extra_shifts ); /* Q( -xX_shifts ) */
- }
- nrg = silk_RSHIFT32( nrg, extra_shifts ); /* Q( -xX_shifts ) */
- } else if( extra_shifts < 0 ) {
- /* Shift xx */
- xX_shifts = XX_shifts;
- xx = silk_RSHIFT32( xx, -extra_shifts ); /* Q( -xX_shifts ) */
- } else {
- xX_shifts = xx_shifts;
+ silk_sum_sqr_shift( &rr[ k ], &rr_shifts, r_ptr, subfr_length ); /* rr[ k ] in Q( -rr_shifts ) */
+
+ /* Assure headroom */
+ LZs = silk_CLZ32( rr[k] );
+ if( LZs < LTP_CORRS_HEAD_ROOM ) {
+ rr[ k ] = silk_RSHIFT_ROUND( rr[ k ], LTP_CORRS_HEAD_ROOM - LZs );
+ rr_shifts += ( LTP_CORRS_HEAD_ROOM - LZs );
}
- silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, xXLTP_Q17_ptr, xX_shifts, arch ); /* xXLTP_Q17_ptr in Q( -xX_shifts ) */
+ corr_rshifts[ k ] = rr_shifts;
+ silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, LTP_CORRS_HEAD_ROOM, WLTP_ptr, &corr_rshifts[ k ], arch ); /* WLTP_fix_ptr in Q( -corr_rshifts[ k ] ) */
+
+ /* The correlation vector always has lower max abs value than rr and/or RR so head room is assured */
+ silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr, corr_rshifts[ k ], arch ); /* Rr_fix_ptr in Q( -corr_rshifts[ k ] ) */
+ if( corr_rshifts[ k ] > rr_shifts ) {
+ rr[ k ] = silk_RSHIFT( rr[ k ], corr_rshifts[ k ] - rr_shifts ); /* rr[ k ] in Q( -corr_rshifts[ k ] ) */
+ }
+ silk_assert( rr[ k ] >= 0 );
+
+ regu = 1;
+ regu = silk_SMLAWB( regu, rr[ k ], SILK_FIX_CONST( LTP_DAMPING/3, 16 ) );
+ regu = silk_SMLAWB( regu, matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ), SILK_FIX_CONST( LTP_DAMPING/3, 16 ) );
+ regu = silk_SMLAWB( regu, matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER ), SILK_FIX_CONST( LTP_DAMPING/3, 16 ) );
+ silk_regularize_correlations_FIX( WLTP_ptr, &rr[k], regu, LTP_ORDER );
+
+ silk_solve_LDL_FIX( WLTP_ptr, LTP_ORDER, Rr, b_Q16 ); /* WLTP_fix_ptr and Rr_fix_ptr both in Q(-corr_rshifts[k]) */
+
+ /* Limit and store in Q14 */
+ silk_fit_LTP( b_Q16, b_Q14_ptr );
+
+ /* Calculate residual energy */
+ nrg[ k ] = silk_residual_energy16_covar_FIX( b_Q14_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER, 14 ); /* nrg_fix in Q( -corr_rshifts[ k ] ) */
+
+ /* temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); */
+ extra_shifts = silk_min_int( corr_rshifts[ k ], LTP_CORRS_HEAD_ROOM );
+ denom32 = silk_LSHIFT_SAT32( silk_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 + extra_shifts ) + /* Q( -corr_rshifts[ k ] + extra_shifts ) */
+ silk_RSHIFT( silk_SMULWB( (opus_int32)subfr_length, 655 ), corr_rshifts[ k ] - extra_shifts ); /* Q( -corr_rshifts[ k ] + extra_shifts ) */
+ denom32 = silk_max( denom32, 1 );
+ silk_assert( ((opus_int64)Wght_Q15[ k ] << 16 ) < silk_int32_MAX ); /* Wght always < 0.5 in Q0 */
+ temp32 = silk_DIV32( silk_LSHIFT( (opus_int32)Wght_Q15[ k ], 16 ), denom32 ); /* Q( 15 + 16 + corr_rshifts[k] - extra_shifts ) */
+ temp32 = silk_RSHIFT( temp32, 31 + corr_rshifts[ k ] - extra_shifts - 26 ); /* Q26 */
- /* At this point all correlations are in Q(-xX_shifts) */
- temp = silk_SMLAWB( 1, nrg, SILK_FIX_CONST( LTP_CORR_INV_MAX, 16 ) );
- temp = silk_max( temp, xx );
-TIC(div)
-#if 0
+ /* Limit temp such that the below scaling never wraps around */
+ WLTP_max = 0;
for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
- XXLTP_Q17_ptr[ i ] = silk_DIV32_varQ( XXLTP_Q17_ptr[ i ], temp, 17 );
+ WLTP_max = silk_max( WLTP_ptr[ i ], WLTP_max );
}
+ lshift = silk_CLZ32( WLTP_max ) - 1 - 3; /* keep 3 bits free for vq_nearest_neighbor_fix */
+ silk_assert( 26 - 18 + lshift >= 0 );
+ if( 26 - 18 + lshift < 31 ) {
+ temp32 = silk_min_32( temp32, silk_LSHIFT( (opus_int32)1, 26 - 18 + lshift ) );
+ }
+
+ silk_scale_vector32_Q26_lshift_18( WLTP_ptr, temp32, LTP_ORDER * LTP_ORDER ); /* WLTP_ptr in Q( 18 - corr_rshifts[ k ] ) */
+
+ w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER/2, LTP_ORDER/2, LTP_ORDER ); /* w in Q( 18 - corr_rshifts[ k ] ) */
+ silk_assert( w[k] >= 0 );
+
+ r_ptr += subfr_length;
+ b_Q14_ptr += LTP_ORDER;
+ WLTP_ptr += LTP_ORDER * LTP_ORDER;
+ }
+
+ maxRshifts = 0;
+ for( k = 0; k < nb_subfr; k++ ) {
+ maxRshifts = silk_max_int( corr_rshifts[ k ], maxRshifts );
+ }
+
+ /* Compute LTP coding gain */
+ if( LTPredCodGain_Q7 != NULL ) {
+ LPC_LTP_res_nrg = 0;
+ LPC_res_nrg = 0;
+ silk_assert( LTP_CORRS_HEAD_ROOM >= 2 ); /* Check that no overflow will happen when adding */
+ for( k = 0; k < nb_subfr; k++ ) {
+ LPC_res_nrg = silk_ADD32( LPC_res_nrg, silk_RSHIFT( silk_ADD32( silk_SMULWB( rr[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */
+ LPC_LTP_res_nrg = silk_ADD32( LPC_LTP_res_nrg, silk_RSHIFT( silk_ADD32( silk_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */
+ }
+ LPC_LTP_res_nrg = silk_max( LPC_LTP_res_nrg, 1 ); /* avoid division by zero */
+
+ div_Q16 = silk_DIV32_varQ( LPC_res_nrg, LPC_LTP_res_nrg, 16 );
+ *LTPredCodGain_Q7 = ( opus_int )silk_SMULBB( 3, silk_lin2log( div_Q16 ) - ( 16 << 7 ) );
+
+ silk_assert( *LTPredCodGain_Q7 == ( opus_int )silk_SAT16( silk_MUL( 3, silk_lin2log( div_Q16 ) - ( 16 << 7 ) ) ) );
+ }
+
+ /* smoothing */
+ /* d = sum( B, 1 ); */
+ b_Q14_ptr = b_Q14;
+ for( k = 0; k < nb_subfr; k++ ) {
+ d_Q14[ k ] = 0;
for( i = 0; i < LTP_ORDER; i++ ) {
- xXLTP_Q17_ptr[ i ] = silk_DIV32_varQ( xXLTP_Q17_ptr[ i ], temp, 17 );
+ d_Q14[ k ] += b_Q14_ptr[ i ];
}
-#else
- for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) {
- XXLTP_Q17_ptr[ i ] = (opus_int32)( silk_LSHIFT64( (opus_int64)XXLTP_Q17_ptr[ i ], 17 ) / temp );
+ b_Q14_ptr += LTP_ORDER;
+ }
+
+ /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */
+
+ /* Find maximum absolute value of d_Q14 and the bits used by w in Q0 */
+ max_abs_d_Q14 = 0;
+ max_w_bits = 0;
+ for( k = 0; k < nb_subfr; k++ ) {
+ max_abs_d_Q14 = silk_max_32( max_abs_d_Q14, silk_abs( d_Q14[ k ] ) );
+ /* w[ k ] is in Q( 18 - corr_rshifts[ k ] ) */
+ /* Find bits needed in Q( 18 - maxRshifts ) */
+ max_w_bits = silk_max_32( max_w_bits, 32 - silk_CLZ32( w[ k ] ) + corr_rshifts[ k ] - maxRshifts );
+ }
+
+ /* max_abs_d_Q14 = (5 << 15); worst case, i.e. LTP_ORDER * -silk_int16_MIN */
+ silk_assert( max_abs_d_Q14 <= ( 5 << 15 ) );
+
+ /* How many bits is needed for w*d' in Q( 18 - maxRshifts ) in the worst case, of all d_Q14's being equal to max_abs_d_Q14 */
+ extra_shifts = max_w_bits + 32 - silk_CLZ32( max_abs_d_Q14 ) - 14;
+
+ /* Subtract what we got available; bits in output var plus maxRshifts */
+ extra_shifts -= ( 32 - 1 - 2 + maxRshifts ); /* Keep sign bit free as well as 2 bits for accumulation */
+ extra_shifts = silk_max_int( extra_shifts, 0 );
+
+ maxRshifts_wxtra = maxRshifts + extra_shifts;
+
+ temp32 = silk_RSHIFT( 262, maxRshifts + extra_shifts ) + 1; /* 1e-3f in Q( 18 - (maxRshifts + extra_shifts) ) */
+ wd = 0;
+ for( k = 0; k < nb_subfr; k++ ) {
+ /* w has at least 2 bits of headroom so no overflow should happen */
+ temp32 = silk_ADD32( temp32, silk_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ) ); /* Q( 18 - maxRshifts_wxtra ) */
+ wd = silk_ADD32( wd, silk_LSHIFT( silk_SMULWW( silk_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ), d_Q14[ k ] ), 2 ) ); /* Q( 18 - maxRshifts_wxtra ) */
+ }
+ m_Q12 = silk_DIV32_varQ( wd, temp32, 12 );
+
+ b_Q14_ptr = b_Q14;
+ for( k = 0; k < nb_subfr; k++ ) {
+ /* w_fix[ k ] from Q( 18 - corr_rshifts[ k ] ) to Q( 16 ) */
+ if( 2 - corr_rshifts[k] > 0 ) {
+ temp32 = silk_RSHIFT( w[ k ], 2 - corr_rshifts[ k ] );
+ } else {
+ temp32 = silk_LSHIFT_SAT32( w[ k ], corr_rshifts[ k ] - 2 );
}
+
+ g_Q26 = silk_MUL(
+ silk_DIV32(
+ SILK_FIX_CONST( LTP_SMOOTHING, 26 ),
+ silk_RSHIFT( SILK_FIX_CONST( LTP_SMOOTHING, 26 ), 10 ) + temp32 ), /* Q10 */
+ silk_LSHIFT_SAT32( silk_SUB_SAT32( (opus_int32)m_Q12, silk_RSHIFT( d_Q14[ k ], 2 ) ), 4 ) ); /* Q16 */
+
+ temp32 = 0;
for( i = 0; i < LTP_ORDER; i++ ) {
- xXLTP_Q17_ptr[ i ] = (opus_int32)( silk_LSHIFT64( (opus_int64)xXLTP_Q17_ptr[ i ], 17 ) / temp );
+ delta_b_Q14[ i ] = silk_max_16( b_Q14_ptr[ i ], 1638 ); /* 1638_Q14 = 0.1_Q0 */
+ temp32 += delta_b_Q14[ i ]; /* Q14 */
}
-#endif
-TOC(div)
- r_ptr += subfr_length;
- XXLTP_Q17_ptr += LTP_ORDER * LTP_ORDER;
- xXLTP_Q17_ptr += LTP_ORDER;
+ temp32 = silk_DIV32( g_Q26, temp32 ); /* Q14 -> Q12 */
+ for( i = 0; i < LTP_ORDER; i++ ) {
+ b_Q14_ptr[ i ] = silk_LIMIT_32( (opus_int32)b_Q14_ptr[ i ] + silk_SMULWB( silk_LSHIFT_SAT32( temp32, 4 ), delta_b_Q14[ i ] ), -16000, 28000 );
+ }
+ b_Q14_ptr += LTP_ORDER;
+ }
+}
+
+void silk_fit_LTP(
+ opus_int32 LTP_coefs_Q16[ LTP_ORDER ],
+ opus_int16 LTP_coefs_Q14[ LTP_ORDER ]
+)
+{
+ opus_int i;
+
+ for( i = 0; i < LTP_ORDER; i++ ) {
+ LTP_coefs_Q14[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( LTP_coefs_Q16[ i ], 2 ) );
}
}
diff --git a/thirdparty/opus/silk/fixed/find_pitch_lags_FIX.c b/thirdparty/opus/silk/fixed/find_pitch_lags_FIX.c
index 6c3379f2bb..b8440a8247 100644
--- a/thirdparty/opus/silk/fixed/find_pitch_lags_FIX.c
+++ b/thirdparty/opus/silk/fixed/find_pitch_lags_FIX.c
@@ -44,7 +44,7 @@ void silk_find_pitch_lags_FIX(
{
opus_int buf_len, i, scale;
opus_int32 thrhld_Q13, res_nrg;
- const opus_int16 *x_ptr;
+ const opus_int16 *x_buf, *x_buf_ptr;
VARDECL( opus_int16, Wsig );
opus_int16 *Wsig_ptr;
opus_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ];
@@ -59,7 +59,9 @@ void silk_find_pitch_lags_FIX(
buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
/* Safety check */
- celt_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
+ silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
+
+ x_buf = x - psEnc->sCmn.ltp_mem_length;
/*************************************/
/* Estimate LPC AR coefficients */
@@ -70,19 +72,19 @@ void silk_find_pitch_lags_FIX(
ALLOC( Wsig, psEnc->sCmn.pitch_LPC_win_length, opus_int16 );
/* First LA_LTP samples */
- x_ptr = x + buf_len - psEnc->sCmn.pitch_LPC_win_length;
+ x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length;
Wsig_ptr = Wsig;
- silk_apply_sine_window( Wsig_ptr, x_ptr, 1, psEnc->sCmn.la_pitch );
+ silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch );
/* Middle un - windowed samples */
Wsig_ptr += psEnc->sCmn.la_pitch;
- x_ptr += psEnc->sCmn.la_pitch;
- silk_memcpy( Wsig_ptr, x_ptr, ( psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( opus_int16 ) );
+ x_buf_ptr += psEnc->sCmn.la_pitch;
+ silk_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( opus_int16 ) );
/* Last LA_LTP samples */
Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 );
- x_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 );
- silk_apply_sine_window( Wsig_ptr, x_ptr, 2, psEnc->sCmn.la_pitch );
+ x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 );
+ silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch );
/* Calculate autocorrelation sequence */
silk_autocorr( auto_corr, &scale, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1, arch );
@@ -110,7 +112,7 @@ void silk_find_pitch_lags_FIX(
/*****************************************/
/* LPC analysis filtering */
/*****************************************/
- silk_LPC_analysis_filter( res, x, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder, psEnc->sCmn.arch );
+ silk_LPC_analysis_filter( res, x_buf, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder, psEnc->sCmn.arch );
if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) {
/* Threshold for pitch estimator */
diff --git a/thirdparty/opus/silk/fixed/find_pred_coefs_FIX.c b/thirdparty/opus/silk/fixed/find_pred_coefs_FIX.c
index 606d863347..d308e9cf5f 100644
--- a/thirdparty/opus/silk/fixed/find_pred_coefs_FIX.c
+++ b/thirdparty/opus/silk/fixed/find_pred_coefs_FIX.c
@@ -41,12 +41,13 @@ void silk_find_pred_coefs_FIX(
)
{
opus_int i;
- opus_int32 invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ];
+ opus_int32 invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ], Wght_Q15[ MAX_NB_SUBFR ];
opus_int16 NLSF_Q15[ MAX_LPC_ORDER ];
const opus_int16 *x_ptr;
opus_int16 *x_pre_ptr;
VARDECL( opus_int16, LPC_in_pre );
- opus_int32 min_gain_Q16, minInvGain_Q30;
+ opus_int32 tmp, min_gain_Q16, minInvGain_Q30;
+ opus_int LTP_corrs_rshift[ MAX_NB_SUBFR ];
SAVE_STACK;
/* weighting for weighted least squares */
@@ -60,11 +61,13 @@ void silk_find_pred_coefs_FIX(
/* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */
invGains_Q16[ i ] = silk_DIV32_varQ( min_gain_Q16, psEncCtrl->Gains_Q16[ i ], 16 - 2 );
- /* Limit inverse */
- invGains_Q16[ i ] = silk_max( invGains_Q16[ i ], 100 );
+ /* Ensure Wght_Q15 a minimum value 1 */
+ invGains_Q16[ i ] = silk_max( invGains_Q16[ i ], 363 );
/* Square the inverted gains */
silk_assert( invGains_Q16[ i ] == silk_SAT16( invGains_Q16[ i ] ) );
+ tmp = silk_SMULWB( invGains_Q16[ i ], invGains_Q16[ i ] );
+ Wght_Q15[ i ] = silk_RSHIFT( tmp, 1 );
/* Invert the inverted and normalized gains */
local_gains[ i ] = silk_DIV32( ( (opus_int32)1 << 16 ), invGains_Q16[ i ] );
@@ -74,24 +77,24 @@ void silk_find_pred_coefs_FIX(
psEnc->sCmn.nb_subfr * psEnc->sCmn.predictLPCOrder
+ psEnc->sCmn.frame_length, opus_int16 );
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
- VARDECL( opus_int32, xXLTP_Q17 );
- VARDECL( opus_int32, XXLTP_Q17 );
+ VARDECL( opus_int32, WLTP );
/**********/
/* VOICED */
/**********/
- celt_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
+ silk_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
- ALLOC( xXLTP_Q17, psEnc->sCmn.nb_subfr * LTP_ORDER, opus_int32 );
- ALLOC( XXLTP_Q17, psEnc->sCmn.nb_subfr * LTP_ORDER * LTP_ORDER, opus_int32 );
+ ALLOC( WLTP, psEnc->sCmn.nb_subfr * LTP_ORDER * LTP_ORDER, opus_int32 );
/* LTP analysis */
- silk_find_LTP_FIX( XXLTP_Q17, xXLTP_Q17, res_pitch,
- psEncCtrl->pitchL, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch );
+ silk_find_LTP_FIX( psEncCtrl->LTPCoef_Q14, WLTP, &psEncCtrl->LTPredCodGain_Q7,
+ res_pitch, psEncCtrl->pitchL, Wght_Q15, psEnc->sCmn.subfr_length,
+ psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length, LTP_corrs_rshift, psEnc->sCmn.arch );
/* Quantize LTP gain parameters */
silk_quant_LTP_gains( psEncCtrl->LTPCoef_Q14, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex,
- &psEnc->sCmn.sum_log_gain_Q7, &psEncCtrl->LTPredCodGain_Q7, XXLTP_Q17, xXLTP_Q17, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch );
+ &psEnc->sCmn.sum_log_gain_Q7, WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr,
+ psEnc->sCmn.arch);
/* Control LTP scaling */
silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl, condCoding );
diff --git a/thirdparty/opus/silk/fixed/k2a_FIX.c b/thirdparty/opus/silk/fixed/k2a_FIX.c
index 549f6eadaa..5fee599bcb 100644
--- a/thirdparty/opus/silk/fixed/k2a_FIX.c
+++ b/thirdparty/opus/silk/fixed/k2a_FIX.c
@@ -39,15 +39,14 @@ void silk_k2a(
)
{
opus_int k, n;
- opus_int32 rc, tmp1, tmp2;
+ opus_int32 Atmp[ SILK_MAX_ORDER_LPC ];
for( k = 0; k < order; k++ ) {
- rc = rc_Q15[ k ];
- for( n = 0; n < (k + 1) >> 1; n++ ) {
- tmp1 = A_Q24[ n ];
- tmp2 = A_Q24[ k - n - 1 ];
- A_Q24[ n ] = silk_SMLAWB( tmp1, silk_LSHIFT( tmp2, 1 ), rc );
- A_Q24[ k - n - 1 ] = silk_SMLAWB( tmp2, silk_LSHIFT( tmp1, 1 ), rc );
+ for( n = 0; n < k; n++ ) {
+ Atmp[ n ] = A_Q24[ n ];
+ }
+ for( n = 0; n < k; n++ ) {
+ A_Q24[ n ] = silk_SMLAWB( A_Q24[ n ], silk_LSHIFT( Atmp[ k - n - 1 ], 1 ), rc_Q15[ k ] );
}
A_Q24[ k ] = -silk_LSHIFT( (opus_int32)rc_Q15[ k ], 9 );
}
diff --git a/thirdparty/opus/silk/fixed/k2a_Q16_FIX.c b/thirdparty/opus/silk/fixed/k2a_Q16_FIX.c
index 1595aa6212..3b03987544 100644
--- a/thirdparty/opus/silk/fixed/k2a_Q16_FIX.c
+++ b/thirdparty/opus/silk/fixed/k2a_Q16_FIX.c
@@ -39,16 +39,15 @@ void silk_k2a_Q16(
)
{
opus_int k, n;
- opus_int32 rc, tmp1, tmp2;
+ opus_int32 Atmp[ SILK_MAX_ORDER_LPC ];
for( k = 0; k < order; k++ ) {
- rc = rc_Q16[ k ];
- for( n = 0; n < (k + 1) >> 1; n++ ) {
- tmp1 = A_Q24[ n ];
- tmp2 = A_Q24[ k - n - 1 ];
- A_Q24[ n ] = silk_SMLAWW( tmp1, tmp2, rc );
- A_Q24[ k - n - 1 ] = silk_SMLAWW( tmp2, tmp1, rc );
+ for( n = 0; n < k; n++ ) {
+ Atmp[ n ] = A_Q24[ n ];
}
- A_Q24[ k ] = -silk_LSHIFT( rc, 8 );
+ for( n = 0; n < k; n++ ) {
+ A_Q24[ n ] = silk_SMLAWW( A_Q24[ n ], Atmp[ k - n - 1 ], rc_Q16[ k ] );
+ }
+ A_Q24[ k ] = -silk_LSHIFT( rc_Q16[ k ], 8 );
}
}
diff --git a/thirdparty/opus/silk/fixed/main_FIX.h b/thirdparty/opus/silk/fixed/main_FIX.h
index 6d2112e511..375b5eb32e 100644
--- a/thirdparty/opus/silk/fixed/main_FIX.h
+++ b/thirdparty/opus/silk/fixed/main_FIX.h
@@ -36,11 +36,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "debug.h"
#include "entenc.h"
-#if ((defined(OPUS_ARM_ASM) && defined(FIXED_POINT)) \
- || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
-#include "fixed/arm/warped_autocorrelation_FIX_arm.h"
-#endif
-
#ifndef FORCE_CPP_BUILD
#ifdef __cplusplus
extern "C"
@@ -52,9 +47,6 @@ extern "C"
#define silk_encode_do_VAD_Fxx silk_encode_do_VAD_FIX
#define silk_encode_frame_Fxx silk_encode_frame_FIX
-#define QC 10
-#define QS 13
-
/*********************/
/* Encoder Functions */
/*********************/
@@ -66,8 +58,7 @@ void silk_HP_variable_cutoff(
/* Encoder main function */
void silk_encode_do_VAD_FIX(
- silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */
- opus_int activity /* I Decision of Opus voice activity detector */
+ silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk FIX encoder state */
);
/* Encoder main function */
@@ -90,11 +81,33 @@ opus_int silk_init_encoder(
opus_int silk_control_encoder(
silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */
silk_EncControlStruct *encControl, /* I Control structure */
+ const opus_int32 TargetRate_bps, /* I Target max bitrate (bps) */
const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */
const opus_int channelNb, /* I Channel number */
const opus_int force_fs_kHz
);
+/****************/
+/* Prefiltering */
+/****************/
+void silk_prefilter_FIX(
+ silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
+ const silk_encoder_control_FIX *psEncCtrl, /* I Encoder control */
+ opus_int32 xw_Q10[], /* O Weighted signal */
+ const opus_int16 x[] /* I Speech signal */
+);
+
+void silk_warped_LPC_analysis_filter_FIX_c(
+ opus_int32 state[], /* I/O State [order + 1] */
+ opus_int32 res_Q2[], /* O Residual signal [length] */
+ const opus_int16 coef_Q13[], /* I Coefficients [order] */
+ const opus_int16 input[], /* I Input signal [length] */
+ const opus_int16 lambda_Q16, /* I Warping factor */
+ const opus_int length, /* I Length of input signal */
+ const opus_int order /* I Filter order (even) */
+);
+
+
/**************************/
/* Noise shaping analysis */
/**************************/
@@ -108,7 +121,7 @@ void silk_noise_shape_analysis_FIX(
);
/* Autocorrelations for a warped frequency axis */
-void silk_warped_autocorrelation_FIX_c(
+void silk_warped_autocorrelation_FIX(
opus_int32 *corr, /* O Result [order + 1] */
opus_int *scale, /* O Scaling of the correlation vector */
const opus_int16 *input, /* I Input data to correlate */
@@ -117,11 +130,6 @@ void silk_warped_autocorrelation_FIX_c(
const opus_int order /* I Correlation order (even) */
);
-#if !defined(OVERRIDE_silk_warped_autocorrelation_FIX)
-#define silk_warped_autocorrelation_FIX(corr, scale, input, warping_Q16, length, order, arch) \
- ((void)(arch), silk_warped_autocorrelation_FIX_c(corr, scale, input, warping_Q16, length, order))
-#endif
-
/* Calculation of LTP state scaling */
void silk_LTP_scale_ctrl_FIX(
silk_encoder_state_FIX *psEnc, /* I/O encoder state */
@@ -160,12 +168,16 @@ void silk_find_LPC_FIX(
/* LTP analysis */
void silk_find_LTP_FIX(
- opus_int32 XXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Correlation matrix */
- opus_int32 xXLTP_Q17[ MAX_NB_SUBFR * LTP_ORDER ], /* O Correlation vector */
- const opus_int16 r_lpc[], /* I Residual signal after LPC */
+ opus_int16 b_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */
+ opus_int32 WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
+ opus_int *LTPredCodGain_Q7, /* O LTP coding gain */
+ const opus_int16 r_lpc[], /* I residual signal after LPC signal + state for first 10 ms */
const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
- const opus_int subfr_length, /* I Subframe length */
- const opus_int nb_subfr, /* I Number of subframes */
+ const opus_int32 Wght_Q15[ MAX_NB_SUBFR ], /* I weights */
+ const opus_int subfr_length, /* I subframe length */
+ const opus_int nb_subfr, /* I number of subframes */
+ const opus_int mem_offset, /* I number of samples in LTP memory */
+ opus_int corr_rshifts[ MAX_NB_SUBFR ], /* O right shifts applied to correlations */
int arch /* I Run-time architecture */
);
@@ -219,9 +231,9 @@ void silk_corrMatrix_FIX(
const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */
const opus_int L, /* I Length of vectors */
const opus_int order, /* I Max lag for correlation */
+ const opus_int head_room, /* I Desired headroom */
opus_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ] */
- opus_int32 *nrg, /* O Energy of x vector */
- opus_int *rshifts, /* O Right shifts of correlations */
+ opus_int *rshifts, /* I/O Right shifts of correlations */
int arch /* I Run-time architecture */
);
@@ -236,6 +248,22 @@ void silk_corrVector_FIX(
int arch /* I Run-time architecture */
);
+/* Add noise to matrix diagonal */
+void silk_regularize_correlations_FIX(
+ opus_int32 *XX, /* I/O Correlation matrices */
+ opus_int32 *xx, /* I/O Correlation values */
+ opus_int32 noise, /* I Noise to add */
+ opus_int D /* I Dimension of XX */
+);
+
+/* Solves Ax = b, assuming A is symmetric */
+void silk_solve_LDL_FIX(
+ opus_int32 *A, /* I Pointer to symetric square matrix A */
+ opus_int M, /* I Size of matrix */
+ const opus_int32 *b, /* I Pointer to b vector */
+ opus_int32 *x_Q16 /* O Pointer to x solution vector */
+);
+
#ifndef FORCE_CPP_BUILD
#ifdef __cplusplus
}
diff --git a/thirdparty/opus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h b/thirdparty/opus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h
index 3999b5bd09..c30481e437 100644
--- a/thirdparty/opus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h
+++ b/thirdparty/opus/silk/fixed/mips/noise_shape_analysis_FIX_mipsr1.h
@@ -169,7 +169,7 @@ void silk_noise_shape_analysis_FIX(
if( psEnc->sCmn.warping_Q16 > 0 ) {
/* Calculate warped auto correlation */
- silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch );
+ silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder );
} else {
/* Calculate regular auto correlation */
silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch );
@@ -224,8 +224,8 @@ void silk_noise_shape_analysis_FIX(
silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 );
/* Ratio of prediction gains, in energy domain */
- pre_nrg_Q30 = silk_LPC_inverse_pred_gain_Q24( AR2_Q24, psEnc->sCmn.shapingLPCOrder, arch );
- nrg = silk_LPC_inverse_pred_gain_Q24( AR1_Q24, psEnc->sCmn.shapingLPCOrder, arch );
+ pre_nrg_Q30 = silk_LPC_inverse_pred_gain_Q24( AR2_Q24, psEnc->sCmn.shapingLPCOrder );
+ nrg = silk_LPC_inverse_pred_gain_Q24( AR1_Q24, psEnc->sCmn.shapingLPCOrder );
/*psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;*/
pre_nrg_Q30 = silk_LSHIFT32( silk_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 );
diff --git a/thirdparty/opus/silk/fixed/mips/prefilter_FIX_mipsr1.h b/thirdparty/opus/silk/fixed/mips/prefilter_FIX_mipsr1.h
new file mode 100644
index 0000000000..21b256885f
--- /dev/null
+++ b/thirdparty/opus/silk/fixed/mips/prefilter_FIX_mipsr1.h
@@ -0,0 +1,184 @@
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Internet Society, IETF or IETF Trust, nor the
+names of specific contributors, may be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+#ifndef __PREFILTER_FIX_MIPSR1_H__
+#define __PREFILTER_FIX_MIPSR1_H__
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "main_FIX.h"
+#include "stack_alloc.h"
+#include "tuning_parameters.h"
+
+#define OVERRIDE_silk_warped_LPC_analysis_filter_FIX
+void silk_warped_LPC_analysis_filter_FIX(
+ opus_int32 state[], /* I/O State [order + 1] */
+ opus_int32 res_Q2[], /* O Residual signal [length] */
+ const opus_int16 coef_Q13[], /* I Coefficients [order] */
+ const opus_int16 input[], /* I Input signal [length] */
+ const opus_int16 lambda_Q16, /* I Warping factor */
+ const opus_int length, /* I Length of input signal */
+ const opus_int order, /* I Filter order (even) */
+ int arch
+)
+{
+ opus_int n, i;
+ opus_int32 acc_Q11, acc_Q22, tmp1, tmp2, tmp3, tmp4;
+ opus_int32 state_cur, state_next;
+
+ (void)arch;
+
+ /* Order must be even */
+ /* Length must be even */
+
+ silk_assert( ( order & 1 ) == 0 );
+ silk_assert( ( length & 1 ) == 0 );
+
+ for( n = 0; n < length; n+=2 ) {
+ /* Output of lowpass section */
+ tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 );
+ state_cur = silk_LSHIFT( input[ n ], 14 );
+ /* Output of allpass section */
+ tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 );
+ state_next = tmp2;
+ acc_Q11 = silk_RSHIFT( order, 1 );
+ acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] );
+
+
+ /* Output of lowpass section */
+ tmp4 = silk_SMLAWB( state_cur, state_next, lambda_Q16 );
+ state[ 0 ] = silk_LSHIFT( input[ n+1 ], 14 );
+ /* Output of allpass section */
+ tmp3 = silk_SMLAWB( state_next, tmp1 - tmp4, lambda_Q16 );
+ state[ 1 ] = tmp4;
+ acc_Q22 = silk_RSHIFT( order, 1 );
+ acc_Q22 = silk_SMLAWB( acc_Q22, tmp4, coef_Q13[ 0 ] );
+
+ /* Loop over allpass sections */
+ for( i = 2; i < order; i += 2 ) {
+ /* Output of allpass section */
+ tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 );
+ state_cur = tmp1;
+ acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] );
+ /* Output of allpass section */
+ tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 );
+ state_next = tmp2;
+ acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] );
+
+
+ /* Output of allpass section */
+ tmp4 = silk_SMLAWB( state_cur, state_next - tmp3, lambda_Q16 );
+ state[ i ] = tmp3;
+ acc_Q22 = silk_SMLAWB( acc_Q22, tmp3, coef_Q13[ i - 1 ] );
+ /* Output of allpass section */
+ tmp3 = silk_SMLAWB( state_next, tmp1 - tmp4, lambda_Q16 );
+ state[ i + 1 ] = tmp4;
+ acc_Q22 = silk_SMLAWB( acc_Q22, tmp4, coef_Q13[ i ] );
+ }
+ acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );
+ res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 );
+
+ state[ order ] = tmp3;
+ acc_Q22 = silk_SMLAWB( acc_Q22, tmp3, coef_Q13[ order - 1 ] );
+ res_Q2[ n+1 ] = silk_LSHIFT( (opus_int32)input[ n+1 ], 2 ) - silk_RSHIFT_ROUND( acc_Q22, 9 );
+ }
+}
+
+
+
+/* Prefilter for finding Quantizer input signal */
+#define OVERRIDE_silk_prefilt_FIX
+static inline void silk_prefilt_FIX(
+ silk_prefilter_state_FIX *P, /* I/O state */
+ opus_int32 st_res_Q12[], /* I short term residual signal */
+ opus_int32 xw_Q3[], /* O prefiltered signal */
+ opus_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */
+ opus_int Tilt_Q14, /* I Tilt shaping coeficient */
+ opus_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients */
+ opus_int lag, /* I Lag for harmonic shaping */
+ opus_int length /* I Length of signals */
+)
+{
+ opus_int i, idx, LTP_shp_buf_idx;
+ opus_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10;
+ opus_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12;
+ opus_int16 *LTP_shp_buf;
+
+ /* To speed up use temp variables instead of using the struct */
+ LTP_shp_buf = P->sLTP_shp;
+ LTP_shp_buf_idx = P->sLTP_shp_buf_idx;
+ sLF_AR_shp_Q12 = P->sLF_AR_shp_Q12;
+ sLF_MA_shp_Q12 = P->sLF_MA_shp_Q12;
+
+ if( lag > 0 ) {
+ for( i = 0; i < length; i++ ) {
+ /* unrolled loop */
+ silk_assert( HARM_SHAPE_FIR_TAPS == 3 );
+ idx = lag + LTP_shp_buf_idx;
+ n_LTP_Q12 = silk_SMULBB( LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
+ n_LTP_Q12 = silk_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
+ n_LTP_Q12 = silk_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
+
+ n_Tilt_Q10 = silk_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );
+ n_LF_Q10 = silk_SMLAWB( silk_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );
+
+ sLF_AR_shp_Q12 = silk_SUB32( st_res_Q12[ i ], silk_LSHIFT( n_Tilt_Q10, 2 ) );
+ sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12, silk_LSHIFT( n_LF_Q10, 2 ) );
+
+ LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
+ LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );
+
+ xw_Q3[i] = silk_RSHIFT_ROUND( silk_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 9 );
+ }
+ }
+ else
+ {
+ for( i = 0; i < length; i++ ) {
+
+ n_LTP_Q12 = 0;
+
+ n_Tilt_Q10 = silk_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );
+ n_LF_Q10 = silk_SMLAWB( silk_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );
+
+ sLF_AR_shp_Q12 = silk_SUB32( st_res_Q12[ i ], silk_LSHIFT( n_Tilt_Q10, 2 ) );
+ sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12, silk_LSHIFT( n_LF_Q10, 2 ) );
+
+ LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
+ LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );
+
+ xw_Q3[i] = silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 9 );
+ }
+ }
+
+ /* Copy temp variable back to state */
+ P->sLF_AR_shp_Q12 = sLF_AR_shp_Q12;
+ P->sLF_MA_shp_Q12 = sLF_MA_shp_Q12;
+ P->sLTP_shp_buf_idx = LTP_shp_buf_idx;
+}
+
+#endif /* __PREFILTER_FIX_MIPSR1_H__ */
diff --git a/thirdparty/opus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h b/thirdparty/opus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h
index 66eb2ed26d..e803ef0fce 100644
--- a/thirdparty/opus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h
+++ b/thirdparty/opus/silk/fixed/mips/warped_autocorrelation_FIX_mipsr1.h
@@ -41,8 +41,8 @@ POSSIBILITY OF SUCH DAMAGE.
#define QS 14
/* Autocorrelations for a warped frequency axis */
-#define OVERRIDE_silk_warped_autocorrelation_FIX_c
-void silk_warped_autocorrelation_FIX_c(
+#define OVERRIDE_silk_warped_autocorrelation_FIX
+void silk_warped_autocorrelation_FIX(
opus_int32 *corr, /* O Result [order + 1] */
opus_int *scale, /* O Scaling of the correlation vector */
const opus_int16 *input, /* I Input data to correlate */
diff --git a/thirdparty/opus/silk/fixed/noise_shape_analysis_FIX.c b/thirdparty/opus/silk/fixed/noise_shape_analysis_FIX.c
index 85fea0bf09..22a89f75ae 100644
--- a/thirdparty/opus/silk/fixed/noise_shape_analysis_FIX.c
+++ b/thirdparty/opus/silk/fixed/noise_shape_analysis_FIX.c
@@ -57,79 +57,88 @@ static OPUS_INLINE opus_int32 warped_gain( /* gain in Q16*/
/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */
/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */
static OPUS_INLINE void limit_warped_coefs(
- opus_int32 *coefs_Q24,
+ opus_int32 *coefs_syn_Q24,
+ opus_int32 *coefs_ana_Q24,
opus_int lambda_Q16,
opus_int32 limit_Q24,
opus_int order
) {
opus_int i, iter, ind = 0;
- opus_int32 tmp, maxabs_Q24, chirp_Q16, gain_Q16;
+ opus_int32 tmp, maxabs_Q24, chirp_Q16, gain_syn_Q16, gain_ana_Q16;
opus_int32 nom_Q16, den_Q24;
- opus_int32 limit_Q20, maxabs_Q20;
/* Convert to monic coefficients */
lambda_Q16 = -lambda_Q16;
for( i = order - 1; i > 0; i-- ) {
- coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
+ coefs_syn_Q24[ i - 1 ] = silk_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );
+ coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );
}
lambda_Q16 = -lambda_Q16;
- nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 );
- den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 );
- gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
+ nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 );
+ den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 );
+ gain_syn_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
+ den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 );
+ gain_ana_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
for( i = 0; i < order; i++ ) {
- coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
+ coefs_syn_Q24[ i ] = silk_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );
+ coefs_ana_Q24[ i ] = silk_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );
}
- limit_Q20 = silk_RSHIFT(limit_Q24, 4);
+
for( iter = 0; iter < 10; iter++ ) {
/* Find maximum absolute value */
maxabs_Q24 = -1;
for( i = 0; i < order; i++ ) {
- tmp = silk_abs_int32( coefs_Q24[ i ] );
+ tmp = silk_max( silk_abs_int32( coefs_syn_Q24[ i ] ), silk_abs_int32( coefs_ana_Q24[ i ] ) );
if( tmp > maxabs_Q24 ) {
maxabs_Q24 = tmp;
ind = i;
}
}
- /* Use Q20 to avoid any overflow when multiplying by (ind + 1) later. */
- maxabs_Q20 = silk_RSHIFT(maxabs_Q24, 4);
- if( maxabs_Q20 <= limit_Q20 ) {
+ if( maxabs_Q24 <= limit_Q24 ) {
/* Coefficients are within range - done */
return;
}
/* Convert back to true warped coefficients */
for( i = 1; i < order; i++ ) {
- coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
+ coefs_syn_Q24[ i - 1 ] = silk_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );
+ coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );
}
- gain_Q16 = silk_INVERSE32_varQ( gain_Q16, 32 );
+ gain_syn_Q16 = silk_INVERSE32_varQ( gain_syn_Q16, 32 );
+ gain_ana_Q16 = silk_INVERSE32_varQ( gain_ana_Q16, 32 );
for( i = 0; i < order; i++ ) {
- coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
+ coefs_syn_Q24[ i ] = silk_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );
+ coefs_ana_Q24[ i ] = silk_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );
}
/* Apply bandwidth expansion */
chirp_Q16 = SILK_FIX_CONST( 0.99, 16 ) - silk_DIV32_varQ(
- silk_SMULWB( maxabs_Q20 - limit_Q20, silk_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ),
- silk_MUL( maxabs_Q20, ind + 1 ), 22 );
- silk_bwexpander_32( coefs_Q24, order, chirp_Q16 );
+ silk_SMULWB( maxabs_Q24 - limit_Q24, silk_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ),
+ silk_MUL( maxabs_Q24, ind + 1 ), 22 );
+ silk_bwexpander_32( coefs_syn_Q24, order, chirp_Q16 );
+ silk_bwexpander_32( coefs_ana_Q24, order, chirp_Q16 );
/* Convert to monic warped coefficients */
lambda_Q16 = -lambda_Q16;
for( i = order - 1; i > 0; i-- ) {
- coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
+ coefs_syn_Q24[ i - 1 ] = silk_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 );
+ coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 );
}
lambda_Q16 = -lambda_Q16;
nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 );
- den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 );
- gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
+ den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 );
+ gain_syn_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
+ den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 );
+ gain_ana_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
for( i = 0; i < order; i++ ) {
- coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
+ coefs_syn_Q24[ i ] = silk_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] );
+ coefs_ana_Q24[ i ] = silk_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] );
}
}
silk_assert( 0 );
}
-/* Disable MIPS version until it's updated. */
-#if 0 && defined(MIPSr1_ASM)
+#if defined(MIPSr1_ASM)
#include "mips/noise_shape_analysis_FIX_mipsr1.h"
#endif
@@ -146,13 +155,14 @@ void silk_noise_shape_analysis_FIX(
)
{
silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
- opus_int k, i, nSamples, nSegs, Qnrg, b_Q14, warping_Q16, scale = 0;
- opus_int32 SNR_adj_dB_Q7, HarmShapeGain_Q16, Tilt_Q16, tmp32;
- opus_int32 nrg, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
- opus_int32 BWExp_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;
+ opus_int k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0;
+ opus_int32 SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32;
+ opus_int32 nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
+ opus_int32 delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;
opus_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ];
opus_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];
- opus_int32 AR_Q24[ MAX_SHAPE_LPC_ORDER ];
+ opus_int32 AR1_Q24[ MAX_SHAPE_LPC_ORDER ];
+ opus_int32 AR2_Q24[ MAX_SHAPE_LPC_ORDER ];
VARDECL( opus_int16, x_windowed );
const opus_int16 *x_ptr, *pitch_res_ptr;
SAVE_STACK;
@@ -199,14 +209,14 @@ void silk_noise_shape_analysis_FIX(
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
/* Initially set to 0; may be overruled in process_gains(..) */
psEnc->sCmn.indices.quantOffsetType = 0;
+ psEncCtrl->sparseness_Q8 = 0;
} else {
/* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 );
energy_variation_Q7 = 0;
log_energy_prev_Q7 = 0;
pitch_res_ptr = pitch_res;
- nSegs = silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2;
- for( k = 0; k < nSegs; k++ ) {
+ for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) {
silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );
nrg += silk_RSHIFT( nSamples, scale ); /* Q(-scale)*/
@@ -218,12 +228,18 @@ void silk_noise_shape_analysis_FIX(
pitch_res_ptr += nSamples;
}
+ psEncCtrl->sparseness_Q8 = silk_RSHIFT( silk_sigm_Q15( silk_SMULWB( energy_variation_Q7 -
+ SILK_FIX_CONST( 5.0, 7 ), SILK_FIX_CONST( 0.1, 16 ) ) ), 7 );
+
/* Set quantization offset depending on sparseness measure */
- if( energy_variation_Q7 > SILK_FIX_CONST( ENERGY_VARIATION_THRESHOLD_QNT_OFFSET, 7 ) * (nSegs-1) ) {
+ if( psEncCtrl->sparseness_Q8 > SILK_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) {
psEnc->sCmn.indices.quantOffsetType = 0;
} else {
psEnc->sCmn.indices.quantOffsetType = 1;
}
+
+ /* Increase coding SNR for sparse signals */
+ SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( SPARSE_SNR_INCR_dB, 15 ), psEncCtrl->sparseness_Q8 - SILK_FIX_CONST( 0.5, 8 ) );
}
/*******************************/
@@ -231,8 +247,14 @@ void silk_noise_shape_analysis_FIX(
/*******************************/
/* More BWE for signals with high prediction gain */
strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );
- BWExp_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ),
+ BWExp1_Q16 = BWExp2_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ),
silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 );
+ delta_Q16 = silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - silk_SMULBB( 3, psEncCtrl->coding_quality_Q14 ),
+ SILK_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) );
+ BWExp1_Q16 = silk_SUB32( BWExp1_Q16, delta_Q16 );
+ BWExp2_Q16 = silk_ADD32( BWExp2_Q16, delta_Q16 );
+ /* BWExp1 will be applied after BWExp2, so make it relative */
+ BWExp1_Q16 = silk_DIV32_16( silk_LSHIFT( BWExp1_Q16, 14 ), silk_RSHIFT( BWExp2_Q16, 2 ) );
if( psEnc->sCmn.warping_Q16 > 0 ) {
/* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
@@ -262,7 +284,7 @@ void silk_noise_shape_analysis_FIX(
if( psEnc->sCmn.warping_Q16 > 0 ) {
/* Calculate warped auto correlation */
- silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch );
+ silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder );
} else {
/* Calculate regular auto correlation */
silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch );
@@ -277,7 +299,7 @@ void silk_noise_shape_analysis_FIX(
silk_assert( nrg >= 0 );
/* Convert reflection coefficients to prediction coefficients */
- silk_k2a_Q16( AR_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );
+ silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );
Qnrg = -scale; /* range: -12...30*/
silk_assert( Qnrg >= -12 );
@@ -296,34 +318,40 @@ void silk_noise_shape_analysis_FIX(
if( psEnc->sCmn.warping_Q16 > 0 ) {
/* Adjust gain for warping */
- gain_mult_Q16 = warped_gain( AR_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );
- silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 );
- if( psEncCtrl->Gains_Q16[ k ] < SILK_FIX_CONST( 0.25, 16 ) ) {
- psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
+ gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );
+ silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
+ if ( silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 ) >= ( silk_int32_MAX >> 1 ) ) {
+ psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX;
} else {
- psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 );
- if ( psEncCtrl->Gains_Q16[ k ] >= ( silk_int32_MAX >> 1 ) ) {
- psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX;
- } else {
- psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT32( psEncCtrl->Gains_Q16[ k ], 1 );
- }
+ psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
}
- silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 );
}
- /* Bandwidth expansion */
- silk_bwexpander_32( AR_Q24, psEnc->sCmn.shapingLPCOrder, BWExp_Q16 );
+ /* Bandwidth expansion for synthesis filter shaping */
+ silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 );
- if( psEnc->sCmn.warping_Q16 > 0 ) {
- /* Convert to monic warped prediction coefficients and limit absolute values */
- limit_warped_coefs( AR_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );
+ /* Compute noise shaping filter coefficients */
+ silk_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( opus_int32 ) );
- /* Convert from Q24 to Q13 and store in int16 */
- for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {
- psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR_Q24[ i ], 11 ) );
- }
- } else {
- silk_LPC_fit( &psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER ], AR_Q24, 13, 24, psEnc->sCmn.shapingLPCOrder );
+ /* Bandwidth expansion for analysis filter shaping */
+ silk_assert( BWExp1_Q16 <= SILK_FIX_CONST( 1.0, 16 ) );
+ silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 );
+
+ /* Ratio of prediction gains, in energy domain */
+ pre_nrg_Q30 = silk_LPC_inverse_pred_gain_Q24( AR2_Q24, psEnc->sCmn.shapingLPCOrder );
+ nrg = silk_LPC_inverse_pred_gain_Q24( AR1_Q24, psEnc->sCmn.shapingLPCOrder );
+
+ /*psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;*/
+ pre_nrg_Q30 = silk_LSHIFT32( silk_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 );
+ psEncCtrl->GainsPre_Q14[ k ] = ( opus_int ) SILK_FIX_CONST( 0.3, 14 ) + silk_DIV32_varQ( pre_nrg_Q30, nrg, 14 );
+
+ /* Convert to monic warped prediction coefficients and limit absolute values */
+ limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );
+
+ /* Convert from Q24 to Q13 and store in int16 */
+ for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {
+ psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) );
+ psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) );
}
}
@@ -340,6 +368,11 @@ void silk_noise_shape_analysis_FIX(
psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 );
}
+ gain_mult_Q16 = SILK_FIX_CONST( 1.0, 16 ) + silk_RSHIFT_ROUND( silk_MLA( SILK_FIX_CONST( INPUT_TILT, 26 ),
+ psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 );
+ for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
+ psEncCtrl->GainsPre_Q14[ k ] = silk_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] );
+ }
/************************************************/
/* Control low-frequency shaping and noise tilt */
@@ -377,6 +410,14 @@ void silk_noise_shape_analysis_FIX(
/****************************/
/* HARMONIC SHAPING CONTROL */
/****************************/
+ /* Control boosting of harmonic frequencies */
+ HarmBoost_Q16 = silk_SMULWB( silk_SMULWB( SILK_FIX_CONST( 1.0, 17 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ),
+ psEnc->LTPCorr_Q15 ), SILK_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) );
+
+ /* More harmonic boost for noisy input signals */
+ HarmBoost_Q16 = silk_SMLAWB( HarmBoost_Q16,
+ SILK_FIX_CONST( 1.0, 16 ) - silk_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SILK_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) );
+
if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
/* More harmonic noise shaping for high bitrates or noisy input */
HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ),
@@ -394,11 +435,14 @@ void silk_noise_shape_analysis_FIX(
/* Smooth over subframes */
/*************************/
for( k = 0; k < MAX_NB_SUBFR; k++ ) {
+ psShapeSt->HarmBoost_smth_Q16 =
+ silk_SMLAWB( psShapeSt->HarmBoost_smth_Q16, HarmBoost_Q16 - psShapeSt->HarmBoost_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
psShapeSt->HarmShapeGain_smth_Q16 =
silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
psShapeSt->Tilt_smth_Q16 =
silk_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
+ psEncCtrl->HarmBoost_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16, 2 );
psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );
psEncCtrl->Tilt_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 );
}
diff --git a/thirdparty/opus/silk/fixed/pitch_analysis_core_FIX.c b/thirdparty/opus/silk/fixed/pitch_analysis_core_FIX.c
index 14729046d2..01bb9fc0a8 100644
--- a/thirdparty/opus/silk/fixed/pitch_analysis_core_FIX.c
+++ b/thirdparty/opus/silk/fixed/pitch_analysis_core_FIX.c
@@ -80,7 +80,7 @@ static void silk_P_Ana_calc_energy_st3(
/* FIXED POINT CORE PITCH ANALYSIS FUNCTION */
/*************************************************************/
opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */
- const opus_int16 *frame_unscaled, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */
+ const opus_int16 *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */
opus_int *pitch_out, /* O 4 pitch lag values */
opus_int16 *lagIndex, /* O Lag Index */
opus_int8 *contourIndex, /* O Pitch contour Index */
@@ -94,17 +94,16 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
int arch /* I Run-time architecture */
)
{
- VARDECL( opus_int16, frame_8kHz_buf );
+ VARDECL( opus_int16, frame_8kHz );
VARDECL( opus_int16, frame_4kHz );
- VARDECL( opus_int16, frame_scaled );
opus_int32 filt_state[ 6 ];
- const opus_int16 *frame, *frame_8kHz;
+ const opus_int16 *input_frame_ptr;
opus_int i, k, d, j;
VARDECL( opus_int16, C );
VARDECL( opus_int32, xcorr32 );
const opus_int16 *target_ptr, *basis_ptr;
- opus_int32 cross_corr, normalizer, energy, energy_basis, energy_target;
- opus_int d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp, shift;
+ opus_int32 cross_corr, normalizer, energy, shift, energy_basis, energy_target;
+ opus_int d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp;
VARDECL( opus_int16, d_comp );
opus_int32 sum, threshold, lag_counter;
opus_int CBimax, CBimax_new, CBimax_old, lag, start_lag, end_lag, lag_new;
@@ -120,13 +119,12 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
opus_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q13;
const opus_int8 *Lag_CB_ptr;
SAVE_STACK;
-
/* Check for valid sampling frequency */
- celt_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
+ silk_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
/* Check for valid complexity setting */
- celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
- celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
+ silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
+ silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
silk_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) );
silk_assert( search_thres2_Q13 >= 0 && search_thres2_Q13 <= (1<<13) );
@@ -139,33 +137,17 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
min_lag = PE_MIN_LAG_MS * Fs_kHz;
max_lag = PE_MAX_LAG_MS * Fs_kHz - 1;
- /* Downscale input if necessary */
- silk_sum_sqr_shift( &energy, &shift, frame_unscaled, frame_length );
- shift += 3 - silk_CLZ32( energy ); /* at least two bits headroom */
- ALLOC( frame_scaled, frame_length, opus_int16 );
- if( shift > 0 ) {
- shift = silk_RSHIFT( shift + 1, 1 );
- for( i = 0; i < frame_length; i++ ) {
- frame_scaled[ i ] = silk_RSHIFT( frame_unscaled[ i ], shift );
- }
- frame = frame_scaled;
- } else {
- frame = frame_unscaled;
- }
-
- ALLOC( frame_8kHz_buf, ( Fs_kHz == 8 ) ? 1 : frame_length_8kHz, opus_int16 );
/* Resample from input sampled at Fs_kHz to 8 kHz */
+ ALLOC( frame_8kHz, frame_length_8kHz, opus_int16 );
if( Fs_kHz == 16 ) {
silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );
- silk_resampler_down2( filt_state, frame_8kHz_buf, frame, frame_length );
- frame_8kHz = frame_8kHz_buf;
+ silk_resampler_down2( filt_state, frame_8kHz, frame, frame_length );
} else if( Fs_kHz == 12 ) {
silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) );
- silk_resampler_down2_3( filt_state, frame_8kHz_buf, frame, frame_length );
- frame_8kHz = frame_8kHz_buf;
+ silk_resampler_down2_3( filt_state, frame_8kHz, frame, frame_length );
} else {
- celt_assert( Fs_kHz == 8 );
- frame_8kHz = frame;
+ silk_assert( Fs_kHz == 8 );
+ silk_memcpy( frame_8kHz, frame, frame_length_8kHz * sizeof(opus_int16) );
}
/* Decimate again to 4 kHz */
@@ -178,6 +160,19 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] );
}
+ /*******************************************************************************
+ ** Scale 4 kHz signal down to prevent correlations measures from overflowing
+ ** find scaling as max scaling for each 8kHz(?) subframe
+ *******************************************************************************/
+
+ /* Inner product is calculated with different lengths, so scale for the worst case */
+ silk_sum_sqr_shift( &energy, &shift, frame_4kHz, frame_length_4kHz );
+ if( shift > 0 ) {
+ shift = silk_RSHIFT( shift, 1 );
+ for( i = 0; i < frame_length_4kHz; i++ ) {
+ frame_4kHz[ i ] = silk_RSHIFT( frame_4kHz[ i ], shift );
+ }
+ }
/******************************************************************************
* FIRST STAGE, operating in 4 khz
@@ -188,14 +183,14 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
target_ptr = &frame_4kHz[ silk_LSHIFT( SF_LENGTH_4KHZ, 2 ) ];
for( k = 0; k < nb_subfr >> 1; k++ ) {
/* Check that we are within range of the array */
- celt_assert( target_ptr >= frame_4kHz );
- celt_assert( target_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
+ silk_assert( target_ptr >= frame_4kHz );
+ silk_assert( target_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
basis_ptr = target_ptr - MIN_LAG_4KHZ;
/* Check that we are within range of the array */
- celt_assert( basis_ptr >= frame_4kHz );
- celt_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
+ silk_assert( basis_ptr >= frame_4kHz );
+ silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz );
celt_pitch_xcorr( target_ptr, target_ptr - MAX_LAG_4KHZ, xcorr32, SF_LENGTH_8KHZ, MAX_LAG_4KHZ - MIN_LAG_4KHZ + 1, arch );
@@ -249,7 +244,7 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
/* Sort */
length_d_srch = silk_ADD_LSHIFT32( 4, complexity, 1 );
- celt_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
+ silk_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
silk_insertion_sort_decreasing_int16( C, d_srch, CSTRIDE_4KHZ,
length_d_srch );
@@ -274,7 +269,7 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
break;
}
}
- celt_assert( length_d_srch > 0 );
+ silk_assert( length_d_srch > 0 );
ALLOC( d_comp, D_COMP_STRIDE, opus_int16 );
for( i = D_COMP_MIN; i < D_COMP_MAX; i++ ) {
@@ -316,6 +311,18 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation
*************************************************************************************/
+ /******************************************************************************
+ ** Scale signal down to avoid correlations measures from overflowing
+ *******************************************************************************/
+ /* find scaling as max scaling for each subframe */
+ silk_sum_sqr_shift( &energy, &shift, frame_8kHz, frame_length_8kHz );
+ if( shift > 0 ) {
+ shift = silk_RSHIFT( shift, 1 );
+ for( i = 0; i < frame_length_8kHz; i++ ) {
+ frame_8kHz[ i ] = silk_RSHIFT( frame_8kHz[ i ], shift );
+ }
+ }
+
/*********************************************************************************
* Find energy of each subframe projected onto its history, for a range of delays
*********************************************************************************/
@@ -325,8 +332,8 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
for( k = 0; k < nb_subfr; k++ ) {
/* Check that we are within range of the array */
- celt_assert( target_ptr >= frame_8kHz );
- celt_assert( target_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz );
+ silk_assert( target_ptr >= frame_8kHz );
+ silk_assert( target_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz );
energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ, arch ), 1 );
for( j = 0; j < length_d_comp; j++ ) {
@@ -455,6 +462,24 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
silk_assert( *LTPCorr_Q15 >= 0 );
if( Fs_kHz > 8 ) {
+ VARDECL( opus_int16, scratch_mem );
+ /***************************************************************************/
+ /* Scale input signal down to avoid correlations measures from overflowing */
+ /***************************************************************************/
+ /* find scaling as max scaling for each subframe */
+ silk_sum_sqr_shift( &energy, &shift, frame, frame_length );
+ ALLOC( scratch_mem, shift > 0 ? frame_length : ALLOC_NONE, opus_int16 );
+ if( shift > 0 ) {
+ /* Move signal to scratch mem because the input signal should be unchanged */
+ shift = silk_RSHIFT( shift, 1 );
+ for( i = 0; i < frame_length; i++ ) {
+ scratch_mem[ i ] = silk_RSHIFT( frame[ i ], shift );
+ }
+ input_frame_ptr = scratch_mem;
+ } else {
+ input_frame_ptr = frame;
+ }
+
/* Search in original signal */
CBimax_old = CBimax;
@@ -494,14 +519,14 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
/* Calculate the correlations and energies needed in stage 3 */
ALLOC( energies_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals );
ALLOC( cross_corr_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals );
- silk_P_Ana_calc_corr_st3( cross_corr_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch );
- silk_P_Ana_calc_energy_st3( energies_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch );
+ silk_P_Ana_calc_corr_st3( cross_corr_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity, arch );
+ silk_P_Ana_calc_energy_st3( energies_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity, arch );
lag_counter = 0;
silk_assert( lag == silk_SAT16( lag ) );
contour_bias_Q15 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 15 ), lag );
- target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ];
+ target_ptr = &input_frame_ptr[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ];
energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, nb_subfr * sf_length, arch ), 1 );
for( d = start_lag; d <= end_lag; d++ ) {
for( j = 0; j < nb_cbk_search; j++ ) {
@@ -550,7 +575,7 @@ opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0
*lagIndex = (opus_int16)( lag - MIN_LAG_8KHZ );
*contourIndex = (opus_int8)CBimax;
}
- celt_assert( *lagIndex >= 0 );
+ silk_assert( *lagIndex >= 0 );
/* return as voiced */
RESTORE_STACK;
return 0;
@@ -587,8 +612,8 @@ static void silk_P_Ana_calc_corr_st3(
const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
SAVE_STACK;
- celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
- celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
+ silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
+ silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
if( nb_subfr == PE_MAX_NB_SUBFR ) {
Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
@@ -596,7 +621,7 @@ static void silk_P_Ana_calc_corr_st3(
nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
cbk_size = PE_NB_CBKS_STAGE3_MAX;
} else {
- celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
+ silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
@@ -612,7 +637,7 @@ static void silk_P_Ana_calc_corr_st3(
/* Calculate the correlations for each subframe */
lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 );
lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 );
- celt_assert(lag_high-lag_low+1 <= SCRATCH_SIZE);
+ silk_assert(lag_high-lag_low+1 <= SCRATCH_SIZE);
celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr32, sf_length, lag_high - lag_low + 1, arch );
for( j = lag_low; j <= lag_high; j++ ) {
silk_assert( lag_counter < SCRATCH_SIZE );
@@ -659,8 +684,8 @@ static void silk_P_Ana_calc_energy_st3(
const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
SAVE_STACK;
- celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
- celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
+ silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
+ silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
if( nb_subfr == PE_MAX_NB_SUBFR ) {
Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
@@ -668,7 +693,7 @@ static void silk_P_Ana_calc_energy_st3(
nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
cbk_size = PE_NB_CBKS_STAGE3_MAX;
} else {
- celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
+ silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
diff --git a/thirdparty/opus/silk/fixed/prefilter_FIX.c b/thirdparty/opus/silk/fixed/prefilter_FIX.c
new file mode 100644
index 0000000000..6a8e35152e
--- /dev/null
+++ b/thirdparty/opus/silk/fixed/prefilter_FIX.c
@@ -0,0 +1,221 @@
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Internet Society, IETF or IETF Trust, nor the
+names of specific contributors, may be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "main_FIX.h"
+#include "stack_alloc.h"
+#include "tuning_parameters.h"
+
+#if defined(MIPSr1_ASM)
+#include "mips/prefilter_FIX_mipsr1.h"
+#endif
+
+
+#if !defined(OVERRIDE_silk_warped_LPC_analysis_filter_FIX)
+#define silk_warped_LPC_analysis_filter_FIX(state, res_Q2, coef_Q13, input, lambda_Q16, length, order, arch) \
+ ((void)(arch),silk_warped_LPC_analysis_filter_FIX_c(state, res_Q2, coef_Q13, input, lambda_Q16, length, order))
+#endif
+
+/* Prefilter for finding Quantizer input signal */
+static OPUS_INLINE void silk_prefilt_FIX(
+ silk_prefilter_state_FIX *P, /* I/O state */
+ opus_int32 st_res_Q12[], /* I short term residual signal */
+ opus_int32 xw_Q3[], /* O prefiltered signal */
+ opus_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */
+ opus_int Tilt_Q14, /* I Tilt shaping coeficient */
+ opus_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients */
+ opus_int lag, /* I Lag for harmonic shaping */
+ opus_int length /* I Length of signals */
+);
+
+void silk_warped_LPC_analysis_filter_FIX_c(
+ opus_int32 state[], /* I/O State [order + 1] */
+ opus_int32 res_Q2[], /* O Residual signal [length] */
+ const opus_int16 coef_Q13[], /* I Coefficients [order] */
+ const opus_int16 input[], /* I Input signal [length] */
+ const opus_int16 lambda_Q16, /* I Warping factor */
+ const opus_int length, /* I Length of input signal */
+ const opus_int order /* I Filter order (even) */
+)
+{
+ opus_int n, i;
+ opus_int32 acc_Q11, tmp1, tmp2;
+
+ /* Order must be even */
+ silk_assert( ( order & 1 ) == 0 );
+
+ for( n = 0; n < length; n++ ) {
+ /* Output of lowpass section */
+ tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 );
+ state[ 0 ] = silk_LSHIFT( input[ n ], 14 );
+ /* Output of allpass section */
+ tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 );
+ state[ 1 ] = tmp2;
+ acc_Q11 = silk_RSHIFT( order, 1 );
+ acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] );
+ /* Loop over allpass sections */
+ for( i = 2; i < order; i += 2 ) {
+ /* Output of allpass section */
+ tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 );
+ state[ i ] = tmp1;
+ acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] );
+ /* Output of allpass section */
+ tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 );
+ state[ i + 1 ] = tmp2;
+ acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] );
+ }
+ state[ order ] = tmp1;
+ acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );
+ res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 );
+ }
+}
+
+void silk_prefilter_FIX(
+ silk_encoder_state_FIX *psEnc, /* I/O Encoder state */
+ const silk_encoder_control_FIX *psEncCtrl, /* I Encoder control */
+ opus_int32 xw_Q3[], /* O Weighted signal */
+ const opus_int16 x[] /* I Speech signal */
+)
+{
+ silk_prefilter_state_FIX *P = &psEnc->sPrefilt;
+ opus_int j, k, lag;
+ opus_int32 tmp_32;
+ const opus_int16 *AR1_shp_Q13;
+ const opus_int16 *px;
+ opus_int32 *pxw_Q3;
+ opus_int HarmShapeGain_Q12, Tilt_Q14;
+ opus_int32 HarmShapeFIRPacked_Q12, LF_shp_Q14;
+ VARDECL( opus_int32, x_filt_Q12 );
+ VARDECL( opus_int32, st_res_Q2 );
+ opus_int16 B_Q10[ 2 ];
+ SAVE_STACK;
+
+ /* Set up pointers */
+ px = x;
+ pxw_Q3 = xw_Q3;
+ lag = P->lagPrev;
+ ALLOC( x_filt_Q12, psEnc->sCmn.subfr_length, opus_int32 );
+ ALLOC( st_res_Q2, psEnc->sCmn.subfr_length, opus_int32 );
+ for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
+ /* Update Variables that change per sub frame */
+ if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
+ lag = psEncCtrl->pitchL[ k ];
+ }
+
+ /* Noise shape parameters */
+ HarmShapeGain_Q12 = silk_SMULWB( (opus_int32)psEncCtrl->HarmShapeGain_Q14[ k ], 16384 - psEncCtrl->HarmBoost_Q14[ k ] );
+ silk_assert( HarmShapeGain_Q12 >= 0 );
+ HarmShapeFIRPacked_Q12 = silk_RSHIFT( HarmShapeGain_Q12, 2 );
+ HarmShapeFIRPacked_Q12 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q12, 1 ), 16 );
+ Tilt_Q14 = psEncCtrl->Tilt_Q14[ k ];
+ LF_shp_Q14 = psEncCtrl->LF_shp_Q14[ k ];
+ AR1_shp_Q13 = &psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER ];
+
+ /* Short term FIR filtering*/
+ silk_warped_LPC_analysis_filter_FIX( P->sAR_shp, st_res_Q2, AR1_shp_Q13, px,
+ psEnc->sCmn.warping_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder, psEnc->sCmn.arch );
+
+ /* Reduce (mainly) low frequencies during harmonic emphasis */
+ B_Q10[ 0 ] = silk_RSHIFT_ROUND( psEncCtrl->GainsPre_Q14[ k ], 4 );
+ tmp_32 = silk_SMLABB( SILK_FIX_CONST( INPUT_TILT, 26 ), psEncCtrl->HarmBoost_Q14[ k ], HarmShapeGain_Q12 ); /* Q26 */
+ tmp_32 = silk_SMLABB( tmp_32, psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ); /* Q26 */
+ tmp_32 = silk_SMULWB( tmp_32, -psEncCtrl->GainsPre_Q14[ k ] ); /* Q24 */
+ tmp_32 = silk_RSHIFT_ROUND( tmp_32, 14 ); /* Q10 */
+ B_Q10[ 1 ]= silk_SAT16( tmp_32 );
+ x_filt_Q12[ 0 ] = silk_MLA( silk_MUL( st_res_Q2[ 0 ], B_Q10[ 0 ] ), P->sHarmHP_Q2, B_Q10[ 1 ] );
+ for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) {
+ x_filt_Q12[ j ] = silk_MLA( silk_MUL( st_res_Q2[ j ], B_Q10[ 0 ] ), st_res_Q2[ j - 1 ], B_Q10[ 1 ] );
+ }
+ P->sHarmHP_Q2 = st_res_Q2[ psEnc->sCmn.subfr_length - 1 ];
+
+ silk_prefilt_FIX( P, x_filt_Q12, pxw_Q3, HarmShapeFIRPacked_Q12, Tilt_Q14, LF_shp_Q14, lag, psEnc->sCmn.subfr_length );
+
+ px += psEnc->sCmn.subfr_length;
+ pxw_Q3 += psEnc->sCmn.subfr_length;
+ }
+
+ P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ];
+ RESTORE_STACK;
+}
+
+#ifndef OVERRIDE_silk_prefilt_FIX
+/* Prefilter for finding Quantizer input signal */
+static OPUS_INLINE void silk_prefilt_FIX(
+ silk_prefilter_state_FIX *P, /* I/O state */
+ opus_int32 st_res_Q12[], /* I short term residual signal */
+ opus_int32 xw_Q3[], /* O prefiltered signal */
+ opus_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */
+ opus_int Tilt_Q14, /* I Tilt shaping coeficient */
+ opus_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients */
+ opus_int lag, /* I Lag for harmonic shaping */
+ opus_int length /* I Length of signals */
+)
+{
+ opus_int i, idx, LTP_shp_buf_idx;
+ opus_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10;
+ opus_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12;
+ opus_int16 *LTP_shp_buf;
+
+ /* To speed up use temp variables instead of using the struct */
+ LTP_shp_buf = P->sLTP_shp;
+ LTP_shp_buf_idx = P->sLTP_shp_buf_idx;
+ sLF_AR_shp_Q12 = P->sLF_AR_shp_Q12;
+ sLF_MA_shp_Q12 = P->sLF_MA_shp_Q12;
+
+ for( i = 0; i < length; i++ ) {
+ if( lag > 0 ) {
+ /* unrolled loop */
+ silk_assert( HARM_SHAPE_FIR_TAPS == 3 );
+ idx = lag + LTP_shp_buf_idx;
+ n_LTP_Q12 = silk_SMULBB( LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
+ n_LTP_Q12 = silk_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
+ n_LTP_Q12 = silk_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
+ } else {
+ n_LTP_Q12 = 0;
+ }
+
+ n_Tilt_Q10 = silk_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );
+ n_LF_Q10 = silk_SMLAWB( silk_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );
+
+ sLF_AR_shp_Q12 = silk_SUB32( st_res_Q12[ i ], silk_LSHIFT( n_Tilt_Q10, 2 ) );
+ sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12, silk_LSHIFT( n_LF_Q10, 2 ) );
+
+ LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
+ LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );
+
+ xw_Q3[i] = silk_RSHIFT_ROUND( silk_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 9 );
+ }
+
+ /* Copy temp variable back to state */
+ P->sLF_AR_shp_Q12 = sLF_AR_shp_Q12;
+ P->sLF_MA_shp_Q12 = sLF_MA_shp_Q12;
+ P->sLTP_shp_buf_idx = LTP_shp_buf_idx;
+}
+#endif /* OVERRIDE_silk_prefilt_FIX */
diff --git a/thirdparty/opus/silk/fixed/residual_energy16_FIX.c b/thirdparty/opus/silk/fixed/residual_energy16_FIX.c
index 7f130f3d3d..ebffb2a66f 100644
--- a/thirdparty/opus/silk/fixed/residual_energy16_FIX.c
+++ b/thirdparty/opus/silk/fixed/residual_energy16_FIX.c
@@ -47,10 +47,10 @@ opus_int32 silk_residual_energy16_covar_FIX(
const opus_int32 *pRow;
/* Safety checks */
- celt_assert( D >= 0 );
- celt_assert( D <= 16 );
- celt_assert( cQ > 0 );
- celt_assert( cQ < 16 );
+ silk_assert( D >= 0 );
+ silk_assert( D <= 16 );
+ silk_assert( cQ > 0 );
+ silk_assert( cQ < 16 );
lshifts = 16 - cQ;
Qxtra = lshifts;
diff --git a/thirdparty/opus/silk/fixed/residual_energy_FIX.c b/thirdparty/opus/silk/fixed/residual_energy_FIX.c
index 6c7cade9a0..41f74778e8 100644
--- a/thirdparty/opus/silk/fixed/residual_energy_FIX.c
+++ b/thirdparty/opus/silk/fixed/residual_energy_FIX.c
@@ -58,7 +58,7 @@ void silk_residual_energy_FIX(
/* Filter input to create the LPC residual for each frame half, and measure subframe energies */
ALLOC( LPC_res, ( MAX_NB_SUBFR >> 1 ) * offset, opus_int16 );
- celt_assert( ( nb_subfr >> 1 ) * ( MAX_NB_SUBFR >> 1 ) == nb_subfr );
+ silk_assert( ( nb_subfr >> 1 ) * ( MAX_NB_SUBFR >> 1 ) == nb_subfr );
for( i = 0; i < nb_subfr >> 1; i++ ) {
/* Calculate half frame LPC residual signal including preceding samples */
silk_LPC_analysis_filter( LPC_res, x_ptr, a_Q12[ i ], ( MAX_NB_SUBFR >> 1 ) * offset, LPC_order, arch );
diff --git a/thirdparty/opus/silk/fixed/schur64_FIX.c b/thirdparty/opus/silk/fixed/schur64_FIX.c
index 4b7e19ea59..764a10ef3e 100644
--- a/thirdparty/opus/silk/fixed/schur64_FIX.c
+++ b/thirdparty/opus/silk/fixed/schur64_FIX.c
@@ -43,7 +43,7 @@ opus_int32 silk_schur64( /* O returns residual ene
opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
opus_int32 Ctmp1_Q30, Ctmp2_Q30, rc_tmp_Q31;
- celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
+ silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 );
/* Check for invalid input */
if( c[ 0 ] <= 0 ) {
@@ -51,10 +51,9 @@ opus_int32 silk_schur64( /* O returns residual ene
return 0;
}
- k = 0;
- do {
+ for( k = 0; k < order + 1; k++ ) {
C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
- } while( ++k <= order );
+ }
for( k = 0; k < order; k++ ) {
/* Check that we won't be getting an unstable rc, otherwise stop here. */
diff --git a/thirdparty/opus/silk/fixed/schur_FIX.c b/thirdparty/opus/silk/fixed/schur_FIX.c
index 2840f6b1aa..c4c0ef23b4 100644
--- a/thirdparty/opus/silk/fixed/schur_FIX.c
+++ b/thirdparty/opus/silk/fixed/schur_FIX.c
@@ -43,29 +43,28 @@ opus_int32 silk_schur( /* O Returns residual ene
opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
opus_int32 Ctmp1, Ctmp2, rc_tmp_Q15;
- celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
+ silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 );
/* Get number of leading zeros */
lz = silk_CLZ32( c[ 0 ] );
/* Copy correlations and adjust level to Q30 */
- k = 0;
if( lz < 2 ) {
/* lz must be 1, so shift one to the right */
- do {
+ for( k = 0; k < order + 1; k++ ) {
C[ k ][ 0 ] = C[ k ][ 1 ] = silk_RSHIFT( c[ k ], 1 );
- } while( ++k <= order );
+ }
} else if( lz > 2 ) {
/* Shift to the left */
lz -= 2;
- do {
+ for( k = 0; k < order + 1; k++ ) {
C[ k ][ 0 ] = C[ k ][ 1 ] = silk_LSHIFT( c[ k ], lz );
- } while( ++k <= order );
+ }
} else {
/* No need to shift */
- do {
+ for( k = 0; k < order + 1; k++ ) {
C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ];
- } while( ++k <= order );
+ }
}
for( k = 0; k < order; k++ ) {
diff --git a/thirdparty/opus/silk/fixed/solve_LS_FIX.c b/thirdparty/opus/silk/fixed/solve_LS_FIX.c
new file mode 100644
index 0000000000..51d7d49d02
--- /dev/null
+++ b/thirdparty/opus/silk/fixed/solve_LS_FIX.c
@@ -0,0 +1,249 @@
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Internet Society, IETF or IETF Trust, nor the
+names of specific contributors, may be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "main_FIX.h"
+#include "stack_alloc.h"
+#include "tuning_parameters.h"
+
+/*****************************/
+/* Internal function headers */
+/*****************************/
+
+typedef struct {
+ opus_int32 Q36_part;
+ opus_int32 Q48_part;
+} inv_D_t;
+
+/* Factorize square matrix A into LDL form */
+static OPUS_INLINE void silk_LDL_factorize_FIX(
+ opus_int32 *A, /* I/O Pointer to Symetric Square Matrix */
+ opus_int M, /* I Size of Matrix */
+ opus_int32 *L_Q16, /* I/O Pointer to Square Upper triangular Matrix */
+ inv_D_t *inv_D /* I/O Pointer to vector holding inverted diagonal elements of D */
+);
+
+/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */
+static OPUS_INLINE void silk_LS_SolveFirst_FIX(
+ const opus_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */
+ opus_int M, /* I Dim of Matrix equation */
+ const opus_int32 *b, /* I b Vector */
+ opus_int32 *x_Q16 /* O x Vector */
+);
+
+/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */
+static OPUS_INLINE void silk_LS_SolveLast_FIX(
+ const opus_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */
+ const opus_int M, /* I Dim of Matrix equation */
+ const opus_int32 *b, /* I b Vector */
+ opus_int32 *x_Q16 /* O x Vector */
+);
+
+static OPUS_INLINE void silk_LS_divide_Q16_FIX(
+ opus_int32 T[], /* I/O Numenator vector */
+ inv_D_t *inv_D, /* I 1 / D vector */
+ opus_int M /* I dimension */
+);
+
+/* Solves Ax = b, assuming A is symmetric */
+void silk_solve_LDL_FIX(
+ opus_int32 *A, /* I Pointer to symetric square matrix A */
+ opus_int M, /* I Size of matrix */
+ const opus_int32 *b, /* I Pointer to b vector */
+ opus_int32 *x_Q16 /* O Pointer to x solution vector */
+)
+{
+ VARDECL( opus_int32, L_Q16 );
+ opus_int32 Y[ MAX_MATRIX_SIZE ];
+ inv_D_t inv_D[ MAX_MATRIX_SIZE ];
+ SAVE_STACK;
+
+ silk_assert( M <= MAX_MATRIX_SIZE );
+ ALLOC( L_Q16, M * M, opus_int32 );
+
+ /***************************************************
+ Factorize A by LDL such that A = L*D*L',
+ where L is lower triangular with ones on diagonal
+ ****************************************************/
+ silk_LDL_factorize_FIX( A, M, L_Q16, inv_D );
+
+ /****************************************************
+ * substitute D*L'*x = Y. ie:
+ L*D*L'*x = b => L*Y = b <=> Y = inv(L)*b
+ ******************************************************/
+ silk_LS_SolveFirst_FIX( L_Q16, M, b, Y );
+
+ /****************************************************
+ D*L'*x = Y <=> L'*x = inv(D)*Y, because D is
+ diagonal just multiply with 1/d_i
+ ****************************************************/
+ silk_LS_divide_Q16_FIX( Y, inv_D, M );
+
+ /****************************************************
+ x = inv(L') * inv(D) * Y
+ *****************************************************/
+ silk_LS_SolveLast_FIX( L_Q16, M, Y, x_Q16 );
+ RESTORE_STACK;
+}
+
+static OPUS_INLINE void silk_LDL_factorize_FIX(
+ opus_int32 *A, /* I/O Pointer to Symetric Square Matrix */
+ opus_int M, /* I Size of Matrix */
+ opus_int32 *L_Q16, /* I/O Pointer to Square Upper triangular Matrix */
+ inv_D_t *inv_D /* I/O Pointer to vector holding inverted diagonal elements of D */
+)
+{
+ opus_int i, j, k, status, loop_count;
+ const opus_int32 *ptr1, *ptr2;
+ opus_int32 diag_min_value, tmp_32, err;
+ opus_int32 v_Q0[ MAX_MATRIX_SIZE ], D_Q0[ MAX_MATRIX_SIZE ];
+ opus_int32 one_div_diag_Q36, one_div_diag_Q40, one_div_diag_Q48;
+
+ silk_assert( M <= MAX_MATRIX_SIZE );
+
+ status = 1;
+ diag_min_value = silk_max_32( silk_SMMUL( silk_ADD_SAT32( A[ 0 ], A[ silk_SMULBB( M, M ) - 1 ] ), SILK_FIX_CONST( FIND_LTP_COND_FAC, 31 ) ), 1 << 9 );
+ for( loop_count = 0; loop_count < M && status == 1; loop_count++ ) {
+ status = 0;
+ for( j = 0; j < M; j++ ) {
+ ptr1 = matrix_adr( L_Q16, j, 0, M );
+ tmp_32 = 0;
+ for( i = 0; i < j; i++ ) {
+ v_Q0[ i ] = silk_SMULWW( D_Q0[ i ], ptr1[ i ] ); /* Q0 */
+ tmp_32 = silk_SMLAWW( tmp_32, v_Q0[ i ], ptr1[ i ] ); /* Q0 */
+ }
+ tmp_32 = silk_SUB32( matrix_ptr( A, j, j, M ), tmp_32 );
+
+ if( tmp_32 < diag_min_value ) {
+ tmp_32 = silk_SUB32( silk_SMULBB( loop_count + 1, diag_min_value ), tmp_32 );
+ /* Matrix not positive semi-definite, or ill conditioned */
+ for( i = 0; i < M; i++ ) {
+ matrix_ptr( A, i, i, M ) = silk_ADD32( matrix_ptr( A, i, i, M ), tmp_32 );
+ }
+ status = 1;
+ break;
+ }
+ D_Q0[ j ] = tmp_32; /* always < max(Correlation) */
+
+ /* two-step division */
+ one_div_diag_Q36 = silk_INVERSE32_varQ( tmp_32, 36 ); /* Q36 */
+ one_div_diag_Q40 = silk_LSHIFT( one_div_diag_Q36, 4 ); /* Q40 */
+ err = silk_SUB32( (opus_int32)1 << 24, silk_SMULWW( tmp_32, one_div_diag_Q40 ) ); /* Q24 */
+ one_div_diag_Q48 = silk_SMULWW( err, one_div_diag_Q40 ); /* Q48 */
+
+ /* Save 1/Ds */
+ inv_D[ j ].Q36_part = one_div_diag_Q36;
+ inv_D[ j ].Q48_part = one_div_diag_Q48;
+
+ matrix_ptr( L_Q16, j, j, M ) = 65536; /* 1.0 in Q16 */
+ ptr1 = matrix_adr( A, j, 0, M );
+ ptr2 = matrix_adr( L_Q16, j + 1, 0, M );
+ for( i = j + 1; i < M; i++ ) {
+ tmp_32 = 0;
+ for( k = 0; k < j; k++ ) {
+ tmp_32 = silk_SMLAWW( tmp_32, v_Q0[ k ], ptr2[ k ] ); /* Q0 */
+ }
+ tmp_32 = silk_SUB32( ptr1[ i ], tmp_32 ); /* always < max(Correlation) */
+
+ /* tmp_32 / D_Q0[j] : Divide to Q16 */
+ matrix_ptr( L_Q16, i, j, M ) = silk_ADD32( silk_SMMUL( tmp_32, one_div_diag_Q48 ),
+ silk_RSHIFT( silk_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) );
+
+ /* go to next column */
+ ptr2 += M;
+ }
+ }
+ }
+
+ silk_assert( status == 0 );
+}
+
+static OPUS_INLINE void silk_LS_divide_Q16_FIX(
+ opus_int32 T[], /* I/O Numenator vector */
+ inv_D_t *inv_D, /* I 1 / D vector */
+ opus_int M /* I dimension */
+)
+{
+ opus_int i;
+ opus_int32 tmp_32;
+ opus_int32 one_div_diag_Q36, one_div_diag_Q48;
+
+ for( i = 0; i < M; i++ ) {
+ one_div_diag_Q36 = inv_D[ i ].Q36_part;
+ one_div_diag_Q48 = inv_D[ i ].Q48_part;
+
+ tmp_32 = T[ i ];
+ T[ i ] = silk_ADD32( silk_SMMUL( tmp_32, one_div_diag_Q48 ), silk_RSHIFT( silk_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) );
+ }
+}
+
+/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */
+static OPUS_INLINE void silk_LS_SolveFirst_FIX(
+ const opus_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */
+ opus_int M, /* I Dim of Matrix equation */
+ const opus_int32 *b, /* I b Vector */
+ opus_int32 *x_Q16 /* O x Vector */
+)
+{
+ opus_int i, j;
+ const opus_int32 *ptr32;
+ opus_int32 tmp_32;
+
+ for( i = 0; i < M; i++ ) {
+ ptr32 = matrix_adr( L_Q16, i, 0, M );
+ tmp_32 = 0;
+ for( j = 0; j < i; j++ ) {
+ tmp_32 = silk_SMLAWW( tmp_32, ptr32[ j ], x_Q16[ j ] );
+ }
+ x_Q16[ i ] = silk_SUB32( b[ i ], tmp_32 );
+ }
+}
+
+/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */
+static OPUS_INLINE void silk_LS_SolveLast_FIX(
+ const opus_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */
+ const opus_int M, /* I Dim of Matrix equation */
+ const opus_int32 *b, /* I b Vector */
+ opus_int32 *x_Q16 /* O x Vector */
+)
+{
+ opus_int i, j;
+ const opus_int32 *ptr32;
+ opus_int32 tmp_32;
+
+ for( i = M - 1; i >= 0; i-- ) {
+ ptr32 = matrix_adr( L_Q16, 0, i, M );
+ tmp_32 = 0;
+ for( j = M - 1; j > i; j-- ) {
+ tmp_32 = silk_SMLAWW( tmp_32, ptr32[ silk_SMULBB( j, M ) ], x_Q16[ j ] );
+ }
+ x_Q16[ i ] = silk_SUB32( b[ i ], tmp_32 );
+ }
+}
diff --git a/thirdparty/opus/silk/fixed/structs_FIX.h b/thirdparty/opus/silk/fixed/structs_FIX.h
index 2774a97b24..3294b25128 100644
--- a/thirdparty/opus/silk/fixed/structs_FIX.h
+++ b/thirdparty/opus/silk/fixed/structs_FIX.h
@@ -48,16 +48,30 @@ typedef struct {
} silk_shape_state_FIX;
/********************************/
+/* Prefilter state */
+/********************************/
+typedef struct {
+ opus_int16 sLTP_shp[ LTP_BUF_LENGTH ];
+ opus_int32 sAR_shp[ MAX_SHAPE_LPC_ORDER + 1 ];
+ opus_int sLTP_shp_buf_idx;
+ opus_int32 sLF_AR_shp_Q12;
+ opus_int32 sLF_MA_shp_Q12;
+ opus_int32 sHarmHP_Q2;
+ opus_int32 rand_seed;
+ opus_int lagPrev;
+} silk_prefilter_state_FIX;
+
+/********************************/
/* Encoder state FIX */
/********************************/
typedef struct {
silk_encoder_state sCmn; /* Common struct, shared with floating-point code */
silk_shape_state_FIX sShape; /* Shape state */
+ silk_prefilter_state_FIX sPrefilt; /* Prefilter State */
/* Buffer for find pitch and noise shape analysis */
silk_DWORD_ALIGN opus_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */
opus_int LTPCorr_Q15; /* Normalized correlation from pitch lag estimator */
- opus_int32 resNrgSmth;
} silk_encoder_state_FIX;
/************************/
@@ -73,8 +87,11 @@ typedef struct {
/* Noise shaping parameters */
/* Testing */
- silk_DWORD_ALIGN opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
+ silk_DWORD_ALIGN opus_int16 AR1_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
+ silk_DWORD_ALIGN opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */
+ opus_int GainsPre_Q14[ MAX_NB_SUBFR ];
+ opus_int HarmBoost_Q14[ MAX_NB_SUBFR ];
opus_int Tilt_Q14[ MAX_NB_SUBFR ];
opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ];
opus_int Lambda_Q10;
@@ -82,6 +99,7 @@ typedef struct {
opus_int coding_quality_Q14;
/* measures */
+ opus_int sparseness_Q8;
opus_int32 predGain_Q16;
opus_int LTPredCodGain_Q7;
opus_int32 ResNrg[ MAX_NB_SUBFR ]; /* Residual energy per subframe */
diff --git a/thirdparty/opus/silk/fixed/warped_autocorrelation_FIX.c b/thirdparty/opus/silk/fixed/warped_autocorrelation_FIX.c
index 5c79553bc0..6ca6c1184d 100644
--- a/thirdparty/opus/silk/fixed/warped_autocorrelation_FIX.c
+++ b/thirdparty/opus/silk/fixed/warped_autocorrelation_FIX.c
@@ -31,14 +31,17 @@ POSSIBILITY OF SUCH DAMAGE.
#include "main_FIX.h"
+#define QC 10
+#define QS 14
+
#if defined(MIPSr1_ASM)
#include "mips/warped_autocorrelation_FIX_mipsr1.h"
#endif
+#ifndef OVERRIDE_silk_warped_autocorrelation_FIX
/* Autocorrelations for a warped frequency axis */
-#ifndef OVERRIDE_silk_warped_autocorrelation_FIX_c
-void silk_warped_autocorrelation_FIX_c(
+void silk_warped_autocorrelation_FIX(
opus_int32 *corr, /* O Result [order + 1] */
opus_int *scale, /* O Scaling of the correlation vector */
const opus_int16 *input, /* I Input data to correlate */
@@ -53,7 +56,7 @@ void silk_warped_autocorrelation_FIX_c(
opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
/* Order must be even */
- celt_assert( ( order & 1 ) == 0 );
+ silk_assert( ( order & 1 ) == 0 );
silk_assert( 2 * QS - QC >= 0 );
/* Loop over samples */
@@ -89,4 +92,4 @@ void silk_warped_autocorrelation_FIX_c(
}
silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/
}
-#endif /* OVERRIDE_silk_warped_autocorrelation_FIX_c */
+#endif /* OVERRIDE_silk_warped_autocorrelation_FIX */
diff --git a/thirdparty/opus/silk/fixed/x86/burg_modified_FIX_sse4_1.c b/thirdparty/opus/silk/fixed/x86/burg_modified_FIX_sse.c
index bbb1ce0fcc..3c3583c5fc 100644
--- a/thirdparty/opus/silk/fixed/x86/burg_modified_FIX_sse4_1.c
+++ b/thirdparty/opus/silk/fixed/x86/burg_modified_FIX_sse.c
@@ -72,7 +72,7 @@ void silk_burg_modified_sse4_1(
__m128i FIRST_3210, LAST_3210, ATMP_3210, TMP1_3210, TMP2_3210, T1_3210, T2_3210, PTR_3210, SUBFR_3210, X1_3210, X2_3210;
__m128i CONST1 = _mm_set1_epi32(1);
- celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
+ silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
/* Compute autocorrelations, added over subframes */
silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length );
diff --git a/thirdparty/opus/silk/fixed/x86/prefilter_FIX_sse.c b/thirdparty/opus/silk/fixed/x86/prefilter_FIX_sse.c
new file mode 100644
index 0000000000..488a603f5d
--- /dev/null
+++ b/thirdparty/opus/silk/fixed/x86/prefilter_FIX_sse.c
@@ -0,0 +1,160 @@
+/* Copyright (c) 2014, Cisco Systems, INC
+ Written by XiangMingZhu WeiZhou MinPeng YanWang
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <xmmintrin.h>
+#include <emmintrin.h>
+#include <smmintrin.h>
+#include "main.h"
+#include "celt/x86/x86cpu.h"
+
+void silk_warped_LPC_analysis_filter_FIX_sse4_1(
+ opus_int32 state[], /* I/O State [order + 1] */
+ opus_int32 res_Q2[], /* O Residual signal [length] */
+ const opus_int16 coef_Q13[], /* I Coefficients [order] */
+ const opus_int16 input[], /* I Input signal [length] */
+ const opus_int16 lambda_Q16, /* I Warping factor */
+ const opus_int length, /* I Length of input signal */
+ const opus_int order /* I Filter order (even) */
+)
+{
+ opus_int n, i;
+ opus_int32 acc_Q11, tmp1, tmp2;
+
+ /* Order must be even */
+ silk_assert( ( order & 1 ) == 0 );
+
+ if (order == 10)
+ {
+ if (0 == lambda_Q16)
+ {
+ __m128i coef_Q13_3210, coef_Q13_7654;
+ __m128i coef_Q13_0123, coef_Q13_4567;
+ __m128i state_0123, state_4567;
+ __m128i xmm_product1, xmm_product2;
+ __m128i xmm_tempa, xmm_tempb;
+
+ register opus_int32 sum;
+ register opus_int32 state_8, state_9, state_a;
+ register opus_int64 coef_Q13_8, coef_Q13_9;
+
+ silk_assert( length > 0 );
+
+ coef_Q13_3210 = OP_CVTEPI16_EPI32_M64( &coef_Q13[ 0 ] );
+ coef_Q13_7654 = OP_CVTEPI16_EPI32_M64( &coef_Q13[ 4 ] );
+
+ coef_Q13_0123 = _mm_shuffle_epi32( coef_Q13_3210, _MM_SHUFFLE( 0, 1, 2, 3 ) );
+ coef_Q13_4567 = _mm_shuffle_epi32( coef_Q13_7654, _MM_SHUFFLE( 0, 1, 2, 3 ) );
+
+ coef_Q13_8 = (opus_int64) coef_Q13[ 8 ];
+ coef_Q13_9 = (opus_int64) coef_Q13[ 9 ];
+
+ state_0123 = _mm_loadu_si128( (__m128i *)(&state[ 0 ] ) );
+ state_4567 = _mm_loadu_si128( (__m128i *)(&state[ 4 ] ) );
+
+ state_0123 = _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) );
+ state_4567 = _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) );
+
+ state_8 = state[ 8 ];
+ state_9 = state[ 9 ];
+ state_a = 0;
+
+ for( n = 0; n < length; n++ )
+ {
+ xmm_product1 = _mm_mul_epi32( coef_Q13_0123, state_0123 ); /* 64-bit multiply, only 2 pairs */
+ xmm_product2 = _mm_mul_epi32( coef_Q13_4567, state_4567 );
+
+ xmm_tempa = _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) );
+ xmm_tempb = _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) );
+
+ xmm_product1 = _mm_srli_epi64( xmm_product1, 16 ); /* >> 16, zero extending works */
+ xmm_product2 = _mm_srli_epi64( xmm_product2, 16 );
+
+ xmm_tempa = _mm_mul_epi32( coef_Q13_3210, xmm_tempa );
+ xmm_tempb = _mm_mul_epi32( coef_Q13_7654, xmm_tempb );
+
+ xmm_tempa = _mm_srli_epi64( xmm_tempa, 16 );
+ xmm_tempb = _mm_srli_epi64( xmm_tempb, 16 );
+
+ xmm_tempa = _mm_add_epi32( xmm_tempa, xmm_product1 );
+ xmm_tempb = _mm_add_epi32( xmm_tempb, xmm_product2 );
+ xmm_tempa = _mm_add_epi32( xmm_tempa, xmm_tempb );
+
+ sum = (coef_Q13_8 * state_8) >> 16;
+ sum += (coef_Q13_9 * state_9) >> 16;
+
+ xmm_tempa = _mm_add_epi32( xmm_tempa, _mm_shuffle_epi32( xmm_tempa, _MM_SHUFFLE( 0, 0, 0, 2 ) ) );
+ sum += _mm_cvtsi128_si32( xmm_tempa);
+ res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( ( 5 + sum ), 9);
+
+ /* move right */
+ state_a = state_9;
+ state_9 = state_8;
+ state_8 = _mm_cvtsi128_si32( state_4567 );
+ state_4567 = _mm_alignr_epi8( state_0123, state_4567, 4 );
+
+ state_0123 = _mm_alignr_epi8( _mm_cvtsi32_si128( silk_LSHIFT( input[ n ], 14 ) ), state_0123, 4 );
+ }
+
+ _mm_storeu_si128( (__m128i *)( &state[ 0 ] ), _mm_shuffle_epi32( state_0123, _MM_SHUFFLE( 0, 1, 2, 3 ) ) );
+ _mm_storeu_si128( (__m128i *)( &state[ 4 ] ), _mm_shuffle_epi32( state_4567, _MM_SHUFFLE( 0, 1, 2, 3 ) ) );
+ state[ 8 ] = state_8;
+ state[ 9 ] = state_9;
+ state[ 10 ] = state_a;
+
+ return;
+ }
+ }
+
+ for( n = 0; n < length; n++ ) {
+ /* Output of lowpass section */
+ tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 );
+ state[ 0 ] = silk_LSHIFT( input[ n ], 14 );
+ /* Output of allpass section */
+ tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 );
+ state[ 1 ] = tmp2;
+ acc_Q11 = silk_RSHIFT( order, 1 );
+ acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] );
+ /* Loop over allpass sections */
+ for( i = 2; i < order; i += 2 ) {
+ /* Output of allpass section */
+ tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 );
+ state[ i ] = tmp1;
+ acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] );
+ /* Output of allpass section */
+ tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 );
+ state[ i + 1 ] = tmp2;
+ acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] );
+ }
+ state[ order ] = tmp1;
+ acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] );
+ res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 );
+ }
+}
diff --git a/thirdparty/opus/silk/fixed/x86/vector_ops_FIX_sse4_1.c b/thirdparty/opus/silk/fixed/x86/vector_ops_FIX_sse.c
index c1e90564d0..c1e90564d0 100644
--- a/thirdparty/opus/silk/fixed/x86/vector_ops_FIX_sse4_1.c
+++ b/thirdparty/opus/silk/fixed/x86/vector_ops_FIX_sse.c
diff --git a/thirdparty/opus/silk/float/LPC_analysis_filter_FLP.c b/thirdparty/opus/silk/float/LPC_analysis_filter_FLP.c
index 0e1a1fed0f..cae89a0a18 100644
--- a/thirdparty/opus/silk/float/LPC_analysis_filter_FLP.c
+++ b/thirdparty/opus/silk/float/LPC_analysis_filter_FLP.c
@@ -215,7 +215,7 @@ void silk_LPC_analysis_filter_FLP(
const opus_int Order /* I LPC order */
)
{
- celt_assert( Order <= length );
+ silk_assert( Order <= length );
switch( Order ) {
case 6:
@@ -239,7 +239,7 @@ void silk_LPC_analysis_filter_FLP(
break;
default:
- celt_assert( 0 );
+ silk_assert( 0 );
break;
}
diff --git a/thirdparty/opus/silk/float/LPC_inv_pred_gain_FLP.c b/thirdparty/opus/silk/float/LPC_inv_pred_gain_FLP.c
index 2be2122d61..25178bacdd 100644
--- a/thirdparty/opus/silk/float/LPC_inv_pred_gain_FLP.c
+++ b/thirdparty/opus/silk/float/LPC_inv_pred_gain_FLP.c
@@ -31,7 +31,8 @@ POSSIBILITY OF SUCH DAMAGE.
#include "SigProc_FIX.h"
#include "SigProc_FLP.h"
-#include "define.h"
+
+#define RC_THRESHOLD 0.9999f
/* compute inverse of LPC prediction gain, and */
/* test if LPC coefficients are stable (all poles within unit circle) */
@@ -42,32 +43,34 @@ silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction ga
)
{
opus_int k, n;
- double invGain, rc, rc_mult1, rc_mult2, tmp1, tmp2;
- silk_float Atmp[ SILK_MAX_ORDER_LPC ];
+ double invGain, rc, rc_mult1, rc_mult2;
+ silk_float Atmp[ 2 ][ SILK_MAX_ORDER_LPC ];
+ silk_float *Aold, *Anew;
- silk_memcpy( Atmp, A, order * sizeof(silk_float) );
+ Anew = Atmp[ order & 1 ];
+ silk_memcpy( Anew, A, order * sizeof(silk_float) );
invGain = 1.0;
for( k = order - 1; k > 0; k-- ) {
- rc = -Atmp[ k ];
- rc_mult1 = 1.0f - rc * rc;
- invGain *= rc_mult1;
- if( invGain * MAX_PREDICTION_POWER_GAIN < 1.0f ) {
+ rc = -Anew[ k ];
+ if( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) {
return 0.0f;
}
+ rc_mult1 = 1.0f - rc * rc;
rc_mult2 = 1.0f / rc_mult1;
- for( n = 0; n < (k + 1) >> 1; n++ ) {
- tmp1 = Atmp[ n ];
- tmp2 = Atmp[ k - n - 1 ];
- Atmp[ n ] = (silk_float)( ( tmp1 - tmp2 * rc ) * rc_mult2 );
- Atmp[ k - n - 1 ] = (silk_float)( ( tmp2 - tmp1 * rc ) * rc_mult2 );
+ invGain *= rc_mult1;
+ /* swap pointers */
+ Aold = Anew;
+ Anew = Atmp[ k & 1 ];
+ for( n = 0; n < k; n++ ) {
+ Anew[ n ] = (silk_float)( ( Aold[ n ] - Aold[ k - n - 1 ] * rc ) * rc_mult2 );
}
}
- rc = -Atmp[ 0 ];
- rc_mult1 = 1.0f - rc * rc;
- invGain *= rc_mult1;
- if( invGain * MAX_PREDICTION_POWER_GAIN < 1.0f ) {
+ rc = -Anew[ 0 ];
+ if( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) {
return 0.0f;
}
+ rc_mult1 = 1.0f - rc * rc;
+ invGain *= rc_mult1;
return (silk_float)invGain;
}
diff --git a/thirdparty/opus/silk/float/SigProc_FLP.h b/thirdparty/opus/silk/float/SigProc_FLP.h
index 953de8b09e..f0cb3733be 100644
--- a/thirdparty/opus/silk/float/SigProc_FLP.h
+++ b/thirdparty/opus/silk/float/SigProc_FLP.h
@@ -68,6 +68,13 @@ void silk_k2a_FLP(
opus_int32 order /* I prediction order */
);
+/* Solve the normal equations using the Levinson-Durbin recursion */
+silk_float silk_levinsondurbin_FLP( /* O prediction error energy */
+ silk_float A[], /* O prediction coefficients [order] */
+ const silk_float corr[], /* I input auto-correlations [order + 1] */
+ const opus_int order /* I prediction order */
+);
+
/* compute autocorrelation */
void silk_autocorrelation_FLP(
silk_float *results, /* O result (length correlationCount) */
diff --git a/thirdparty/opus/silk/float/apply_sine_window_FLP.c b/thirdparty/opus/silk/float/apply_sine_window_FLP.c
index e49e717991..6aae57c0ab 100644
--- a/thirdparty/opus/silk/float/apply_sine_window_FLP.c
+++ b/thirdparty/opus/silk/float/apply_sine_window_FLP.c
@@ -45,10 +45,10 @@ void silk_apply_sine_window_FLP(
opus_int k;
silk_float freq, c, S0, S1;
- celt_assert( win_type == 1 || win_type == 2 );
+ silk_assert( win_type == 1 || win_type == 2 );
/* Length must be multiple of 4 */
- celt_assert( ( length & 3 ) == 0 );
+ silk_assert( ( length & 3 ) == 0 );
freq = PI / ( length + 1 );
diff --git a/thirdparty/opus/silk/float/burg_modified_FLP.c b/thirdparty/opus/silk/float/burg_modified_FLP.c
index 756b76a35b..ea5dc25a93 100644
--- a/thirdparty/opus/silk/float/burg_modified_FLP.c
+++ b/thirdparty/opus/silk/float/burg_modified_FLP.c
@@ -52,7 +52,7 @@ silk_float silk_burg_modified_FLP( /* O returns residual energy
double CAf[ SILK_MAX_ORDER_LPC + 1 ], CAb[ SILK_MAX_ORDER_LPC + 1 ];
double Af[ SILK_MAX_ORDER_LPC ];
- celt_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
+ silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE );
/* Compute autocorrelations, added over subframes */
C0 = silk_energy_FLP( x, nb_subfr * subfr_length );
diff --git a/thirdparty/opus/silk/float/encode_frame_FLP.c b/thirdparty/opus/silk/float/encode_frame_FLP.c
index b029c3f5ca..2092a4d9e2 100644
--- a/thirdparty/opus/silk/float/encode_frame_FLP.c
+++ b/thirdparty/opus/silk/float/encode_frame_FLP.c
@@ -29,7 +29,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "config.h"
#endif
-#include <stdlib.h>
#include "main_FLP.h"
#include "tuning_parameters.h"
@@ -42,28 +41,21 @@ static OPUS_INLINE void silk_LBRR_encode_FLP(
);
void silk_encode_do_VAD_FLP(
- silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
- opus_int activity /* I Decision of Opus voice activity detector */
+ silk_encoder_state_FLP *psEnc /* I/O Encoder state FLP */
)
{
- const opus_int activity_threshold = SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 );
-
/****************************/
/* Voice Activity Detection */
/****************************/
silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch );
- /* If Opus VAD is inactive and Silk VAD is active: lower Silk VAD to just under the threshold */
- if( activity == VAD_NO_ACTIVITY && psEnc->sCmn.speech_activity_Q8 >= activity_threshold ) {
- psEnc->sCmn.speech_activity_Q8 = activity_threshold - 1;
- }
/**************************************************/
/* Convert speech activity into VAD and DTX flags */
/**************************************************/
- if( psEnc->sCmn.speech_activity_Q8 < activity_threshold ) {
+ if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {
psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
psEnc->sCmn.noSpeechCounter++;
- if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) {
+ if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) {
psEnc->sCmn.inDTX = 0;
} else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {
psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;
@@ -93,6 +85,7 @@ opus_int silk_encode_frame_FLP(
silk_encoder_control_FLP sEncCtrl;
opus_int i, iter, maxIter, found_upper, found_lower, ret = 0;
silk_float *x_frame, *res_pitch_frame;
+ silk_float xfw[ MAX_FRAME_LENGTH ];
silk_float res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
ec_enc sRangeEnc_copy, sRangeEnc_copy2;
silk_nsq_state sNSQ_copy, sNSQ_copy2;
@@ -104,9 +97,6 @@ opus_int silk_encode_frame_FLP(
opus_int8 LastGainIndex_copy2;
opus_int32 pGains_Q16[ MAX_NB_SUBFR ];
opus_uint8 ec_buf_copy[ 1275 ];
- opus_int gain_lock[ MAX_NB_SUBFR ] = {0};
- opus_int16 best_gain_mult[ MAX_NB_SUBFR ];
- opus_int best_sum[ MAX_NB_SUBFR ];
/* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;
@@ -149,17 +139,22 @@ opus_int silk_encode_frame_FLP(
/***************************************************/
/* Find linear prediction coefficients (LPC + LTP) */
/***************************************************/
- silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding );
+ silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding );
/****************************************/
/* Process gains */
/****************************************/
silk_process_gains_FLP( psEnc, &sEncCtrl, condCoding );
+ /*****************************************/
+ /* Prefiltering for noise shaper */
+ /*****************************************/
+ silk_prefilter_FLP( psEnc, &sEncCtrl, xfw, x_frame );
+
/****************************************/
/* Low Bitrate Redundant Encoding */
/****************************************/
- silk_LBRR_encode_FLP( psEnc, &sEncCtrl, x_frame, condCoding );
+ silk_LBRR_encode_FLP( psEnc, &sEncCtrl, xfw, condCoding );
/* Loop over quantizer and entroy coding to control bitrate */
maxIter = 6;
@@ -193,11 +188,7 @@ opus_int silk_encode_frame_FLP(
/*****************************************/
/* Noise shaping quantization */
/*****************************************/
- silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, x_frame );
-
- if ( iter == maxIter && !found_lower ) {
- silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
- }
+ silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, xfw );
/****************************************/
/* Encode Parameters */
@@ -212,33 +203,6 @@ opus_int silk_encode_frame_FLP(
nBits = ec_tell( psRangeEnc );
- /* If we still bust after the last iteration, do some damage control. */
- if ( iter == maxIter && !found_lower && nBits > maxBits ) {
- silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
-
- /* Keep gains the same as the last frame. */
- psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
- for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
- psEnc->sCmn.indices.GainsIndices[ i ] = 4;
- }
- if (condCoding != CODE_CONDITIONALLY) {
- psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev;
- }
- psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
- psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
- /* Clear all pulses. */
- for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
- psEnc->sCmn.pulses[ i ] = 0;
- }
-
- silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
-
- silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
- psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
-
- nBits = ec_tell( psRangeEnc );
- }
-
if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
break;
}
@@ -248,7 +212,7 @@ opus_int silk_encode_frame_FLP(
if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {
/* Restore output state from earlier iteration that did meet the bitrate budget */
silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
- celt_assert( sRangeEnc_copy2.offs <= 1275 );
+ silk_assert( sRangeEnc_copy2.offs <= 1275 );
silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );
silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );
psEnc->sShape.LastGainIndex = LastGainIndex_copy2;
@@ -259,9 +223,7 @@ opus_int silk_encode_frame_FLP(
if( nBits > maxBits ) {
if( found_lower == 0 && iter >= 2 ) {
/* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
- sEncCtrl.Lambda = silk_max_float(sEncCtrl.Lambda*1.5f, 1.5f);
- /* Reducing dithering can help us hit the target. */
- psEnc->sCmn.indices.quantOffsetType = 0;
+ sEncCtrl.Lambda *= 1.5f;
found_upper = 0;
gainsID_upper = -1;
} else {
@@ -278,7 +240,7 @@ opus_int silk_encode_frame_FLP(
gainsID_lower = gainsID;
/* Copy part of the output state */
silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
- celt_assert( psRangeEnc->offs <= 1275 );
+ silk_assert( psRangeEnc->offs <= 1275 );
silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;
@@ -288,34 +250,15 @@ opus_int silk_encode_frame_FLP(
break;
}
- if ( !found_lower && nBits > maxBits ) {
- int j;
- for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
- int sum=0;
- for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) {
- sum += abs( psEnc->sCmn.pulses[j] );
- }
- if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) {
- best_sum[i] = sum;
- best_gain_mult[i] = gainMult_Q8;
- } else {
- gain_lock[i] = 1;
- }
- }
- }
if( ( found_lower & found_upper ) == 0 ) {
/* Adjust gain according to high-rate rate/distortion curve */
+ opus_int32 gain_factor_Q16;
+ gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
+ gain_factor_Q16 = silk_min_32( gain_factor_Q16, SILK_FIX_CONST( 2, 16 ) );
if( nBits > maxBits ) {
- if (gainMult_Q8 < 16384) {
- gainMult_Q8 *= 2;
- } else {
- gainMult_Q8 = 32767;
- }
- } else {
- opus_int32 gain_factor_Q16;
- gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
- gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
+ gain_factor_Q16 = silk_max_32( gain_factor_Q16, SILK_FIX_CONST( 1.3, 16 ) );
}
+ gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
} else {
/* Adjust gain by interpolating */
gainMult_Q8 = gainMult_lower + ( ( gainMult_upper - gainMult_lower ) * ( maxBits - nBits_lower ) ) / ( nBits_upper - nBits_lower );
@@ -329,13 +272,7 @@ opus_int silk_encode_frame_FLP(
}
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
- opus_int16 tmp;
- if ( gain_lock[i] ) {
- tmp = best_gain_mult[i];
- } else {
- tmp = gainMult_Q8;
- }
- pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 );
+ pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 );
}
/* Quantize gains */
diff --git a/thirdparty/opus/silk/float/energy_FLP.c b/thirdparty/opus/silk/float/energy_FLP.c
index 7bc7173c9c..24b8179f9e 100644
--- a/thirdparty/opus/silk/float/energy_FLP.c
+++ b/thirdparty/opus/silk/float/energy_FLP.c
@@ -37,12 +37,13 @@ double silk_energy_FLP(
opus_int dataSize
)
{
- opus_int i;
+ opus_int i, dataSize4;
double result;
/* 4x unrolled loop */
result = 0.0;
- for( i = 0; i < dataSize - 3; i += 4 ) {
+ dataSize4 = dataSize & 0xFFFC;
+ for( i = 0; i < dataSize4; i += 4 ) {
result += data[ i + 0 ] * (double)data[ i + 0 ] +
data[ i + 1 ] * (double)data[ i + 1 ] +
data[ i + 2 ] * (double)data[ i + 2 ] +
diff --git a/thirdparty/opus/silk/float/find_LPC_FLP.c b/thirdparty/opus/silk/float/find_LPC_FLP.c
index fa3ffe7f8b..fcfe1c3681 100644
--- a/thirdparty/opus/silk/float/find_LPC_FLP.c
+++ b/thirdparty/opus/silk/float/find_LPC_FLP.c
@@ -73,7 +73,7 @@ void silk_find_LPC_FLP(
silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder );
/* Convert to LPC for residual energy evaluation */
- silk_NLSF2A_FLP( a_tmp, NLSF0_Q15, psEncC->predictLPCOrder, psEncC->arch );
+ silk_NLSF2A_FLP( a_tmp, NLSF0_Q15, psEncC->predictLPCOrder );
/* Calculate residual energy with LSF interpolation */
silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, psEncC->predictLPCOrder );
@@ -99,6 +99,6 @@ void silk_find_LPC_FLP(
silk_A2NLSF_FLP( NLSF_Q15, a, psEncC->predictLPCOrder );
}
- celt_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 ||
+ silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 ||
( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );
}
diff --git a/thirdparty/opus/silk/float/find_LTP_FLP.c b/thirdparty/opus/silk/float/find_LTP_FLP.c
index f97064930e..7229996014 100644
--- a/thirdparty/opus/silk/float/find_LTP_FLP.c
+++ b/thirdparty/opus/silk/float/find_LTP_FLP.c
@@ -33,32 +33,100 @@ POSSIBILITY OF SUCH DAMAGE.
#include "tuning_parameters.h"
void silk_find_LTP_FLP(
- silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
- silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* O Weight for LTP quantization */
- const silk_float r_ptr[], /* I LPC residual */
- const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
+ silk_float b[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */
+ silk_float WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
+ silk_float *LTPredCodGain, /* O LTP coding gain */
+ const silk_float r_lpc[], /* I LPC residual */
+ const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
+ const silk_float Wght[ MAX_NB_SUBFR ], /* I Weights */
const opus_int subfr_length, /* I Subframe length */
- const opus_int nb_subfr /* I number of subframes */
+ const opus_int nb_subfr, /* I number of subframes */
+ const opus_int mem_offset /* I Number of samples in LTP memory */
)
{
- opus_int k;
- silk_float *xX_ptr, *XX_ptr;
- const silk_float *lag_ptr;
- silk_float xx, temp;
+ opus_int i, k;
+ silk_float *b_ptr, temp, *WLTP_ptr;
+ silk_float LPC_res_nrg, LPC_LTP_res_nrg;
+ silk_float d[ MAX_NB_SUBFR ], m, g, delta_b[ LTP_ORDER ];
+ silk_float w[ MAX_NB_SUBFR ], nrg[ MAX_NB_SUBFR ], regu;
+ silk_float Rr[ LTP_ORDER ], rr[ MAX_NB_SUBFR ];
+ const silk_float *r_ptr, *lag_ptr;
- xX_ptr = xX;
- XX_ptr = XX;
+ b_ptr = b;
+ WLTP_ptr = WLTP;
+ r_ptr = &r_lpc[ mem_offset ];
for( k = 0; k < nb_subfr; k++ ) {
lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 );
- silk_corrMatrix_FLP( lag_ptr, subfr_length, LTP_ORDER, XX_ptr );
- silk_corrVector_FLP( lag_ptr, r_ptr, subfr_length, LTP_ORDER, xX_ptr );
- xx = ( silk_float )silk_energy_FLP( r_ptr, subfr_length + LTP_ORDER );
- temp = 1.0f / silk_max( xx, LTP_CORR_INV_MAX * 0.5f * ( XX_ptr[ 0 ] + XX_ptr[ 24 ] ) + 1.0f );
- silk_scale_vector_FLP( XX_ptr, temp, LTP_ORDER * LTP_ORDER );
- silk_scale_vector_FLP( xX_ptr, temp, LTP_ORDER );
- r_ptr += subfr_length;
- XX_ptr += LTP_ORDER * LTP_ORDER;
- xX_ptr += LTP_ORDER;
+ silk_corrMatrix_FLP( lag_ptr, subfr_length, LTP_ORDER, WLTP_ptr );
+ silk_corrVector_FLP( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr );
+
+ rr[ k ] = ( silk_float )silk_energy_FLP( r_ptr, subfr_length );
+ regu = 1.0f + rr[ k ] +
+ matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ) +
+ matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER );
+ regu *= LTP_DAMPING / 3;
+ silk_regularize_correlations_FLP( WLTP_ptr, &rr[ k ], regu, LTP_ORDER );
+ silk_solve_LDL_FLP( WLTP_ptr, LTP_ORDER, Rr, b_ptr );
+
+ /* Calculate residual energy */
+ nrg[ k ] = silk_residual_energy_covar_FLP( b_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER );
+
+ temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length );
+ silk_scale_vector_FLP( WLTP_ptr, temp, LTP_ORDER * LTP_ORDER );
+ w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER / 2, LTP_ORDER / 2, LTP_ORDER );
+
+ r_ptr += subfr_length;
+ b_ptr += LTP_ORDER;
+ WLTP_ptr += LTP_ORDER * LTP_ORDER;
+ }
+
+ /* Compute LTP coding gain */
+ if( LTPredCodGain != NULL ) {
+ LPC_LTP_res_nrg = 1e-6f;
+ LPC_res_nrg = 0.0f;
+ for( k = 0; k < nb_subfr; k++ ) {
+ LPC_res_nrg += rr[ k ] * Wght[ k ];
+ LPC_LTP_res_nrg += nrg[ k ] * Wght[ k ];
+ }
+
+ silk_assert( LPC_LTP_res_nrg > 0 );
+ *LTPredCodGain = 3.0f * silk_log2( LPC_res_nrg / LPC_LTP_res_nrg );
+ }
+
+ /* Smoothing */
+ /* d = sum( B, 1 ); */
+ b_ptr = b;
+ for( k = 0; k < nb_subfr; k++ ) {
+ d[ k ] = 0;
+ for( i = 0; i < LTP_ORDER; i++ ) {
+ d[ k ] += b_ptr[ i ];
+ }
+ b_ptr += LTP_ORDER;
+ }
+ /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */
+ temp = 1e-3f;
+ for( k = 0; k < nb_subfr; k++ ) {
+ temp += w[ k ];
+ }
+ m = 0;
+ for( k = 0; k < nb_subfr; k++ ) {
+ m += d[ k ] * w[ k ];
+ }
+ m = m / temp;
+
+ b_ptr = b;
+ for( k = 0; k < nb_subfr; k++ ) {
+ g = LTP_SMOOTHING / ( LTP_SMOOTHING + w[ k ] ) * ( m - d[ k ] );
+ temp = 0;
+ for( i = 0; i < LTP_ORDER; i++ ) {
+ delta_b[ i ] = silk_max_float( b_ptr[ i ], 0.1f );
+ temp += delta_b[ i ];
+ }
+ temp = g / temp;
+ for( i = 0; i < LTP_ORDER; i++ ) {
+ b_ptr[ i ] = b_ptr[ i ] + delta_b[ i ] * temp;
+ }
+ b_ptr += LTP_ORDER;
}
}
diff --git a/thirdparty/opus/silk/float/find_pitch_lags_FLP.c b/thirdparty/opus/silk/float/find_pitch_lags_FLP.c
index dedbcd2836..f3b22d25ce 100644
--- a/thirdparty/opus/silk/float/find_pitch_lags_FLP.c
+++ b/thirdparty/opus/silk/float/find_pitch_lags_FLP.c
@@ -56,7 +56,7 @@ void silk_find_pitch_lags_FLP(
buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;
/* Safety check */
- celt_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
+ silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );
x_buf = x - psEnc->sCmn.ltp_mem_length;
diff --git a/thirdparty/opus/silk/float/find_pred_coefs_FLP.c b/thirdparty/opus/silk/float/find_pred_coefs_FLP.c
index dcf7c5202d..1af4fe5f1b 100644
--- a/thirdparty/opus/silk/float/find_pred_coefs_FLP.c
+++ b/thirdparty/opus/silk/float/find_pred_coefs_FLP.c
@@ -41,9 +41,8 @@ void silk_find_pred_coefs_FLP(
)
{
opus_int i;
- silk_float XXLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ];
- silk_float xXLTP[ MAX_NB_SUBFR * LTP_ORDER ];
- silk_float invGains[ MAX_NB_SUBFR ];
+ silk_float WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ];
+ silk_float invGains[ MAX_NB_SUBFR ], Wght[ MAX_NB_SUBFR ];
opus_int16 NLSF_Q15[ MAX_LPC_ORDER ];
const silk_float *x_ptr;
silk_float *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ];
@@ -53,20 +52,23 @@ void silk_find_pred_coefs_FLP(
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
silk_assert( psEncCtrl->Gains[ i ] > 0.0f );
invGains[ i ] = 1.0f / psEncCtrl->Gains[ i ];
+ Wght[ i ] = invGains[ i ] * invGains[ i ];
}
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
/**********/
/* VOICED */
/**********/
- celt_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
+ silk_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 );
/* LTP analysis */
- silk_find_LTP_FLP( XXLTP, xXLTP, res_pitch, psEncCtrl->pitchL, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr );
+ silk_find_LTP_FLP( psEncCtrl->LTPCoef, WLTP, &psEncCtrl->LTPredCodGain, res_pitch,
+ psEncCtrl->pitchL, Wght, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length );
/* Quantize LTP gain parameters */
silk_quant_LTP_gains_FLP( psEncCtrl->LTPCoef, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex,
- &psEnc->sCmn.sum_log_gain_Q7, &psEncCtrl->LTPredCodGain, XXLTP, xXLTP, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.arch );
+ &psEnc->sCmn.sum_log_gain_Q7, WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr,
+ psEnc->sCmn.arch );
/* Control LTP scaling */
silk_LTP_scale_ctrl_FLP( psEnc, psEncCtrl, condCoding );
diff --git a/thirdparty/opus/silk/float/inner_product_FLP.c b/thirdparty/opus/silk/float/inner_product_FLP.c
index cdd39d24ce..029c012911 100644
--- a/thirdparty/opus/silk/float/inner_product_FLP.c
+++ b/thirdparty/opus/silk/float/inner_product_FLP.c
@@ -38,12 +38,13 @@ double silk_inner_product_FLP(
opus_int dataSize
)
{
- opus_int i;
+ opus_int i, dataSize4;
double result;
/* 4x unrolled loop */
result = 0.0;
- for( i = 0; i < dataSize - 3; i += 4 ) {
+ dataSize4 = dataSize & 0xFFFC;
+ for( i = 0; i < dataSize4; i += 4 ) {
result += data1[ i + 0 ] * (double)data2[ i + 0 ] +
data1[ i + 1 ] * (double)data2[ i + 1 ] +
data1[ i + 2 ] * (double)data2[ i + 2 ] +
diff --git a/thirdparty/opus/silk/float/k2a_FLP.c b/thirdparty/opus/silk/float/k2a_FLP.c
index 1448008dbb..12af4e7669 100644
--- a/thirdparty/opus/silk/float/k2a_FLP.c
+++ b/thirdparty/opus/silk/float/k2a_FLP.c
@@ -39,16 +39,15 @@ void silk_k2a_FLP(
)
{
opus_int k, n;
- silk_float rck, tmp1, tmp2;
+ silk_float Atmp[ SILK_MAX_ORDER_LPC ];
for( k = 0; k < order; k++ ) {
- rck = rc[ k ];
- for( n = 0; n < (k + 1) >> 1; n++ ) {
- tmp1 = A[ n ];
- tmp2 = A[ k - n - 1 ];
- A[ n ] = tmp1 + tmp2 * rck;
- A[ k - n - 1 ] = tmp2 + tmp1 * rck;
+ for( n = 0; n < k; n++ ) {
+ Atmp[ n ] = A[ n ];
}
- A[ k ] = -rck;
+ for( n = 0; n < k; n++ ) {
+ A[ n ] += Atmp[ k - n - 1 ] * rc[ k ];
+ }
+ A[ k ] = -rc[ k ];
}
}
diff --git a/thirdparty/opus/silk/float/levinsondurbin_FLP.c b/thirdparty/opus/silk/float/levinsondurbin_FLP.c
new file mode 100644
index 0000000000..f0ba606981
--- /dev/null
+++ b/thirdparty/opus/silk/float/levinsondurbin_FLP.c
@@ -0,0 +1,81 @@
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Internet Society, IETF or IETF Trust, nor the
+names of specific contributors, may be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "SigProc_FLP.h"
+
+/* Solve the normal equations using the Levinson-Durbin recursion */
+silk_float silk_levinsondurbin_FLP( /* O prediction error energy */
+ silk_float A[], /* O prediction coefficients [order] */
+ const silk_float corr[], /* I input auto-correlations [order + 1] */
+ const opus_int order /* I prediction order */
+)
+{
+ opus_int i, mHalf, m;
+ silk_float min_nrg, nrg, t, km, Atmp1, Atmp2;
+
+ min_nrg = 1e-12f * corr[ 0 ] + 1e-9f;
+ nrg = corr[ 0 ];
+ nrg = silk_max_float(min_nrg, nrg);
+ A[ 0 ] = corr[ 1 ] / nrg;
+ nrg -= A[ 0 ] * corr[ 1 ];
+ nrg = silk_max_float(min_nrg, nrg);
+
+ for( m = 1; m < order; m++ )
+ {
+ t = corr[ m + 1 ];
+ for( i = 0; i < m; i++ ) {
+ t -= A[ i ] * corr[ m - i ];
+ }
+
+ /* reflection coefficient */
+ km = t / nrg;
+
+ /* residual energy */
+ nrg -= km * t;
+ nrg = silk_max_float(min_nrg, nrg);
+
+ mHalf = m >> 1;
+ for( i = 0; i < mHalf; i++ ) {
+ Atmp1 = A[ i ];
+ Atmp2 = A[ m - i - 1 ];
+ A[ m - i - 1 ] -= km * Atmp1;
+ A[ i ] -= km * Atmp2;
+ }
+ if( m & 1 ) {
+ A[ mHalf ] -= km * A[ mHalf ];
+ }
+ A[ m ] = km;
+ }
+
+ /* return the residual energy */
+ return nrg;
+}
+
diff --git a/thirdparty/opus/silk/float/main_FLP.h b/thirdparty/opus/silk/float/main_FLP.h
index 5dc0ccf4a4..e5a75972e5 100644
--- a/thirdparty/opus/silk/float/main_FLP.h
+++ b/thirdparty/opus/silk/float/main_FLP.h
@@ -56,8 +56,7 @@ void silk_HP_variable_cutoff(
/* Encoder main function */
void silk_encode_do_VAD_FLP(
- silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
- opus_int activity /* I Decision of Opus voice activity detector */
+ silk_encoder_state_FLP *psEnc /* I/O Encoder state FLP */
);
/* Encoder main function */
@@ -80,11 +79,22 @@ opus_int silk_init_encoder(
opus_int silk_control_encoder(
silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */
silk_EncControlStruct *encControl, /* I Control structure */
+ const opus_int32 TargetRate_bps, /* I Target max bitrate (bps) */
const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */
const opus_int channelNb, /* I Channel number */
const opus_int force_fs_kHz
);
+/****************/
+/* Prefiltering */
+/****************/
+void silk_prefilter_FLP(
+ silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
+ const silk_encoder_control_FLP *psEncCtrl, /* I Encoder control FLP */
+ silk_float xw[], /* O Weighted signal */
+ const silk_float x[] /* I Speech signal */
+);
+
/**************************/
/* Noise shaping analysis */
/**************************/
@@ -143,12 +153,15 @@ void silk_find_LPC_FLP(
/* LTP analysis */
void silk_find_LTP_FLP(
- silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
- silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* O Weight for LTP quantization */
- const silk_float r_ptr[], /* I LPC residual */
+ silk_float b[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */
+ silk_float WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */
+ silk_float *LTPredCodGain, /* O LTP coding gain */
+ const silk_float r_lpc[], /* I LPC residual */
const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */
+ const silk_float Wght[ MAX_NB_SUBFR ], /* I Weights */
const opus_int subfr_length, /* I Subframe length */
- const opus_int nb_subfr /* I number of subframes */
+ const opus_int nb_subfr, /* I number of subframes */
+ const opus_int mem_offset /* I Number of samples in LTP memory */
);
void silk_LTP_analysis_filter_FLP(
@@ -185,15 +198,14 @@ void silk_LPC_analysis_filter_FLP(
/* LTP tap quantizer */
void silk_quant_LTP_gains_FLP(
- silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */
+ silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (Un-)quantized LTP gains */
opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */
opus_int8 *periodicity_index, /* O Periodicity index */
opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */
- silk_float *pred_gain_dB, /* O LTP prediction gain */
- const silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Correlation matrix */
- const silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* I Correlation vector */
- const opus_int subfr_len, /* I Number of samples per subframe */
- const opus_int nb_subfr, /* I Number of subframes */
+ const silk_float W[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Error weights */
+ const opus_int mu_Q10, /* I Mu value (R/D tradeoff) */
+ const opus_int lowComplexity, /* I Flag for low complexity */
+ const opus_int nb_subfr, /* I number of subframes */
int arch /* I Run-time architecture */
);
@@ -233,6 +245,22 @@ void silk_corrVector_FLP(
silk_float *Xt /* O X'*t correlation vector [order] */
);
+/* Add noise to matrix diagonal */
+void silk_regularize_correlations_FLP(
+ silk_float *XX, /* I/O Correlation matrices */
+ silk_float *xx, /* I/O Correlation values */
+ const silk_float noise, /* I Noise energy to add */
+ const opus_int D /* I Dimension of XX */
+);
+
+/* Function to solve linear equation Ax = b, where A is an MxM symmetric matrix */
+void silk_solve_LDL_FLP(
+ silk_float *A, /* I/O Symmetric square matrix, out: reg. */
+ const opus_int M, /* I Size of matrix */
+ const silk_float *b, /* I Pointer to b vector */
+ silk_float *x /* O Pointer to x solution vector */
+);
+
/* Apply sine window to signal vector. */
/* Window types: */
/* 1 -> sine window from 0 to pi/2 */
@@ -257,8 +285,7 @@ void silk_A2NLSF_FLP(
void silk_NLSF2A_FLP(
silk_float *pAR, /* O LPC coefficients [ LPC_order ] */
const opus_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */
- const opus_int LPC_order, /* I LPC order */
- int arch /* I Run-time architecture */
+ const opus_int LPC_order /* I LPC order */
);
/* Limit, stabilize, and quantize NLSFs */
diff --git a/thirdparty/opus/silk/float/noise_shape_analysis_FLP.c b/thirdparty/opus/silk/float/noise_shape_analysis_FLP.c
index cb3d8a50b7..65f6ea5870 100644
--- a/thirdparty/opus/silk/float/noise_shape_analysis_FLP.c
+++ b/thirdparty/opus/silk/float/noise_shape_analysis_FLP.c
@@ -55,21 +55,25 @@ static OPUS_INLINE silk_float warped_gain(
/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */
/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */
static OPUS_INLINE void warped_true2monic_coefs(
- silk_float *coefs,
+ silk_float *coefs_syn,
+ silk_float *coefs_ana,
silk_float lambda,
silk_float limit,
opus_int order
) {
opus_int i, iter, ind = 0;
- silk_float tmp, maxabs, chirp, gain;
+ silk_float tmp, maxabs, chirp, gain_syn, gain_ana;
/* Convert to monic coefficients */
for( i = order - 1; i > 0; i-- ) {
- coefs[ i - 1 ] -= lambda * coefs[ i ];
+ coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ];
+ coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ];
}
- gain = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs[ 0 ] );
+ gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] );
+ gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] );
for( i = 0; i < order; i++ ) {
- coefs[ i ] *= gain;
+ coefs_syn[ i ] *= gain_syn;
+ coefs_ana[ i ] *= gain_ana;
}
/* Limit */
@@ -77,7 +81,7 @@ static OPUS_INLINE void warped_true2monic_coefs(
/* Find maximum absolute value */
maxabs = -1.0f;
for( i = 0; i < order; i++ ) {
- tmp = silk_abs_float( coefs[ i ] );
+ tmp = silk_max( silk_abs_float( coefs_syn[ i ] ), silk_abs_float( coefs_ana[ i ] ) );
if( tmp > maxabs ) {
maxabs = tmp;
ind = i;
@@ -90,59 +94,36 @@ static OPUS_INLINE void warped_true2monic_coefs(
/* Convert back to true warped coefficients */
for( i = 1; i < order; i++ ) {
- coefs[ i - 1 ] += lambda * coefs[ i ];
+ coefs_syn[ i - 1 ] += lambda * coefs_syn[ i ];
+ coefs_ana[ i - 1 ] += lambda * coefs_ana[ i ];
}
- gain = 1.0f / gain;
+ gain_syn = 1.0f / gain_syn;
+ gain_ana = 1.0f / gain_ana;
for( i = 0; i < order; i++ ) {
- coefs[ i ] *= gain;
+ coefs_syn[ i ] *= gain_syn;
+ coefs_ana[ i ] *= gain_ana;
}
/* Apply bandwidth expansion */
chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) );
- silk_bwexpander_FLP( coefs, order, chirp );
+ silk_bwexpander_FLP( coefs_syn, order, chirp );
+ silk_bwexpander_FLP( coefs_ana, order, chirp );
/* Convert to monic warped coefficients */
for( i = order - 1; i > 0; i-- ) {
- coefs[ i - 1 ] -= lambda * coefs[ i ];
+ coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ];
+ coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ];
}
- gain = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs[ 0 ] );
+ gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] );
+ gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] );
for( i = 0; i < order; i++ ) {
- coefs[ i ] *= gain;
+ coefs_syn[ i ] *= gain_syn;
+ coefs_ana[ i ] *= gain_ana;
}
}
silk_assert( 0 );
}
-static OPUS_INLINE void limit_coefs(
- silk_float *coefs,
- silk_float limit,
- opus_int order
-) {
- opus_int i, iter, ind = 0;
- silk_float tmp, maxabs, chirp;
-
- for( iter = 0; iter < 10; iter++ ) {
- /* Find maximum absolute value */
- maxabs = -1.0f;
- for( i = 0; i < order; i++ ) {
- tmp = silk_abs_float( coefs[ i ] );
- if( tmp > maxabs ) {
- maxabs = tmp;
- ind = i;
- }
- }
- if( maxabs <= limit ) {
- /* Coefficients are within range - done */
- return;
- }
-
- /* Apply bandwidth expansion */
- chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) );
- silk_bwexpander_FLP( coefs, order, chirp );
- }
- silk_assert( 0 );
-}
-
/* Compute noise shaping coefficients and initial gain values */
void silk_noise_shape_analysis_FLP(
silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
@@ -152,13 +133,12 @@ void silk_noise_shape_analysis_FLP(
)
{
silk_shape_state_FLP *psShapeSt = &psEnc->sShape;
- opus_int k, nSamples, nSegs;
- silk_float SNR_adj_dB, HarmShapeGain, Tilt;
- silk_float nrg, log_energy, log_energy_prev, energy_variation;
- silk_float BWExp, gain_mult, gain_add, strength, b, warping;
+ opus_int k, nSamples;
+ silk_float SNR_adj_dB, HarmBoost, HarmShapeGain, Tilt;
+ silk_float nrg, pre_nrg, log_energy, log_energy_prev, energy_variation;
+ silk_float delta, BWExp1, BWExp2, gain_mult, gain_add, strength, b, warping;
silk_float x_windowed[ SHAPE_LPC_WIN_MAX ];
silk_float auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ];
- silk_float rc[ MAX_SHAPE_LPC_ORDER + 1 ];
const silk_float *x_ptr, *pitch_res_ptr;
/* Point to start of first LPC analysis block */
@@ -196,14 +176,14 @@ void silk_noise_shape_analysis_FLP(
if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
/* Initially set to 0; may be overruled in process_gains(..) */
psEnc->sCmn.indices.quantOffsetType = 0;
+ psEncCtrl->sparseness = 0.0f;
} else {
/* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
nSamples = 2 * psEnc->sCmn.fs_kHz;
energy_variation = 0.0f;
log_energy_prev = 0.0f;
pitch_res_ptr = pitch_res;
- nSegs = silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2;
- for( k = 0; k < nSegs; k++ ) {
+ for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) {
nrg = ( silk_float )nSamples + ( silk_float )silk_energy_FLP( pitch_res_ptr, nSamples );
log_energy = silk_log2( nrg );
if( k > 0 ) {
@@ -212,13 +192,17 @@ void silk_noise_shape_analysis_FLP(
log_energy_prev = log_energy;
pitch_res_ptr += nSamples;
}
+ psEncCtrl->sparseness = silk_sigmoid( 0.4f * ( energy_variation - 5.0f ) );
/* Set quantization offset depending on sparseness measure */
- if( energy_variation > ENERGY_VARIATION_THRESHOLD_QNT_OFFSET * (nSegs-1) ) {
+ if( psEncCtrl->sparseness > SPARSENESS_THRESHOLD_QNT_OFFSET ) {
psEnc->sCmn.indices.quantOffsetType = 0;
} else {
psEnc->sCmn.indices.quantOffsetType = 1;
}
+
+ /* Increase coding SNR for sparse signals */
+ SNR_adj_dB += SPARSE_SNR_INCR_dB * ( psEncCtrl->sparseness - 0.5f );
}
/*******************************/
@@ -226,10 +210,19 @@ void silk_noise_shape_analysis_FLP(
/*******************************/
/* More BWE for signals with high prediction gain */
strength = FIND_PITCH_WHITE_NOISE_FRACTION * psEncCtrl->predGain; /* between 0.0 and 1.0 */
- BWExp = BANDWIDTH_EXPANSION / ( 1.0f + strength * strength );
-
- /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
- warping = (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f + 0.01f * psEncCtrl->coding_quality;
+ BWExp1 = BWExp2 = BANDWIDTH_EXPANSION / ( 1.0f + strength * strength );
+ delta = LOW_RATE_BANDWIDTH_EXPANSION_DELTA * ( 1.0f - 0.75f * psEncCtrl->coding_quality );
+ BWExp1 -= delta;
+ BWExp2 += delta;
+ /* BWExp1 will be applied after BWExp2, so make it relative */
+ BWExp1 /= BWExp2;
+
+ if( psEnc->sCmn.warping_Q16 > 0 ) {
+ /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
+ warping = (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f + 0.01f * psEncCtrl->coding_quality;
+ } else {
+ warping = 0.0f;
+ }
/********************************************/
/* Compute noise shaping AR coefs and gains */
@@ -259,28 +252,37 @@ void silk_noise_shape_analysis_FLP(
}
/* Add white noise, as a fraction of energy */
- auto_corr[ 0 ] += auto_corr[ 0 ] * SHAPE_WHITE_NOISE_FRACTION + 1.0f;
+ auto_corr[ 0 ] += auto_corr[ 0 ] * SHAPE_WHITE_NOISE_FRACTION;
/* Convert correlations to prediction coefficients, and compute residual energy */
- nrg = silk_schur_FLP( rc, auto_corr, psEnc->sCmn.shapingLPCOrder );
- silk_k2a_FLP( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], rc, psEnc->sCmn.shapingLPCOrder );
+ nrg = silk_levinsondurbin_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], auto_corr, psEnc->sCmn.shapingLPCOrder );
psEncCtrl->Gains[ k ] = ( silk_float )sqrt( nrg );
if( psEnc->sCmn.warping_Q16 > 0 ) {
/* Adjust gain for warping */
- psEncCtrl->Gains[ k ] *= warped_gain( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], warping, psEnc->sCmn.shapingLPCOrder );
+ psEncCtrl->Gains[ k ] *= warped_gain( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], warping, psEnc->sCmn.shapingLPCOrder );
}
/* Bandwidth expansion for synthesis filter shaping */
- silk_bwexpander_FLP( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp );
+ silk_bwexpander_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp2 );
- if( psEnc->sCmn.warping_Q16 > 0 ) {
- /* Convert to monic warped prediction coefficients and limit absolute values */
- warped_true2monic_coefs( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], warping, 3.999f, psEnc->sCmn.shapingLPCOrder );
- } else {
- /* Limit absolute values */
- limit_coefs( &psEncCtrl->AR[ k * MAX_SHAPE_LPC_ORDER ], 3.999f, psEnc->sCmn.shapingLPCOrder );
- }
+ /* Compute noise shaping filter coefficients */
+ silk_memcpy(
+ &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ],
+ &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ],
+ psEnc->sCmn.shapingLPCOrder * sizeof( silk_float ) );
+
+ /* Bandwidth expansion for analysis filter shaping */
+ silk_bwexpander_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp1 );
+
+ /* Ratio of prediction gains, in energy domain */
+ pre_nrg = silk_LPC_inverse_pred_gain_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder );
+ nrg = silk_LPC_inverse_pred_gain_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder );
+ psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg );
+
+ /* Convert to monic warped prediction coefficients and limit absolute values */
+ warped_true2monic_coefs( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ],
+ warping, 3.999f, psEnc->sCmn.shapingLPCOrder );
}
/*****************/
@@ -294,6 +296,11 @@ void silk_noise_shape_analysis_FLP(
psEncCtrl->Gains[ k ] += gain_add;
}
+ gain_mult = 1.0f + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT;
+ for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
+ psEncCtrl->GainsPre[ k ] *= gain_mult;
+ }
+
/************************************************/
/* Control low-frequency shaping and noise tilt */
/************************************************/
@@ -324,6 +331,12 @@ void silk_noise_shape_analysis_FLP(
/****************************/
/* HARMONIC SHAPING CONTROL */
/****************************/
+ /* Control boosting of harmonic frequencies */
+ HarmBoost = LOW_RATE_HARMONIC_BOOST * ( 1.0f - psEncCtrl->coding_quality ) * psEnc->LTPCorr;
+
+ /* More harmonic boost for noisy input signals */
+ HarmBoost += LOW_INPUT_QUALITY_HARMONIC_BOOST * ( 1.0f - psEncCtrl->input_quality );
+
if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
/* Harmonic noise shaping */
HarmShapeGain = HARMONIC_SHAPING;
@@ -342,6 +355,8 @@ void silk_noise_shape_analysis_FLP(
/* Smooth over subframes */
/*************************/
for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
+ psShapeSt->HarmBoost_smth += SUBFR_SMTH_COEF * ( HarmBoost - psShapeSt->HarmBoost_smth );
+ psEncCtrl->HarmBoost[ k ] = psShapeSt->HarmBoost_smth;
psShapeSt->HarmShapeGain_smth += SUBFR_SMTH_COEF * ( HarmShapeGain - psShapeSt->HarmShapeGain_smth );
psEncCtrl->HarmShapeGain[ k ] = psShapeSt->HarmShapeGain_smth;
psShapeSt->Tilt_smth += SUBFR_SMTH_COEF * ( Tilt - psShapeSt->Tilt_smth );
diff --git a/thirdparty/opus/silk/float/pitch_analysis_core_FLP.c b/thirdparty/opus/silk/float/pitch_analysis_core_FLP.c
index f351bc3718..d0e637a29d 100644
--- a/thirdparty/opus/silk/float/pitch_analysis_core_FLP.c
+++ b/thirdparty/opus/silk/float/pitch_analysis_core_FLP.c
@@ -109,11 +109,11 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced,
const opus_int8 *Lag_CB_ptr;
/* Check for valid sampling frequency */
- celt_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
+ silk_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 );
/* Check for valid complexity setting */
- celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
- celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
+ silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
+ silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
silk_assert( search_thres1 >= 0.0f && search_thres1 <= 1.0f );
silk_assert( search_thres2 >= 0.0f && search_thres2 <= 1.0f );
@@ -148,7 +148,7 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced,
silk_resampler_down2_3( filt_state, frame_8_FIX, frame_12_FIX, frame_length );
silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz );
} else {
- celt_assert( Fs_kHz == 8 );
+ silk_assert( Fs_kHz == 8 );
silk_float2short_array( frame_8_FIX, frame, frame_length_8kHz );
}
@@ -159,7 +159,7 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced,
/* Low-pass filter */
for( i = frame_length_4kHz - 1; i > 0; i-- ) {
- frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] );
+ frame_4kHz[ i ] += frame_4kHz[ i - 1 ];
}
/******************************************************************************
@@ -169,14 +169,14 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced,
target_ptr = &frame_4kHz[ silk_LSHIFT( sf_length_4kHz, 2 ) ];
for( k = 0; k < nb_subfr >> 1; k++ ) {
/* Check that we are within range of the array */
- celt_assert( target_ptr >= frame_4kHz );
- celt_assert( target_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
+ silk_assert( target_ptr >= frame_4kHz );
+ silk_assert( target_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
basis_ptr = target_ptr - min_lag_4kHz;
/* Check that we are within range of the array */
- celt_assert( basis_ptr >= frame_4kHz );
- celt_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
+ silk_assert( basis_ptr >= frame_4kHz );
+ silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz );
celt_pitch_xcorr( target_ptr, target_ptr-max_lag_4kHz, xcorr, sf_length_8kHz, max_lag_4kHz - min_lag_4kHz + 1, arch );
@@ -215,7 +215,7 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced,
/* Sort */
length_d_srch = 4 + 2 * complexity;
- celt_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
+ silk_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH );
silk_insertion_sort_decreasing_FLP( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch );
/* Escape if correlation is very low already here */
@@ -238,7 +238,7 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced,
break;
}
}
- celt_assert( length_d_srch > 0 );
+ silk_assert( length_d_srch > 0 );
for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) {
d_comp[ i ] = 0;
@@ -471,7 +471,7 @@ opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced,
*lagIndex = (opus_int16)( lag - min_lag_8kHz );
*contourIndex = (opus_int8)CBimax;
}
- celt_assert( *lagIndex >= 0 );
+ silk_assert( *lagIndex >= 0 );
/* return as voiced */
return 0;
}
@@ -506,8 +506,8 @@ static void silk_P_Ana_calc_corr_st3(
opus_val32 xcorr[ SCRATCH_SIZE ];
const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
- celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
- celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
+ silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
+ silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
if( nb_subfr == PE_MAX_NB_SUBFR ) {
Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
@@ -515,7 +515,7 @@ static void silk_P_Ana_calc_corr_st3(
nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
cbk_size = PE_NB_CBKS_STAGE3_MAX;
} else {
- celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
+ silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
@@ -572,8 +572,8 @@ static void silk_P_Ana_calc_energy_st3(
silk_float scratch_mem[ SCRATCH_SIZE ];
const opus_int8 *Lag_range_ptr, *Lag_CB_ptr;
- celt_assert( complexity >= SILK_PE_MIN_COMPLEX );
- celt_assert( complexity <= SILK_PE_MAX_COMPLEX );
+ silk_assert( complexity >= SILK_PE_MIN_COMPLEX );
+ silk_assert( complexity <= SILK_PE_MAX_COMPLEX );
if( nb_subfr == PE_MAX_NB_SUBFR ) {
Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ];
@@ -581,7 +581,7 @@ static void silk_P_Ana_calc_energy_st3(
nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ];
cbk_size = PE_NB_CBKS_STAGE3_MAX;
} else {
- celt_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
+ silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1);
Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ];
Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ];
nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
diff --git a/thirdparty/opus/silk/float/prefilter_FLP.c b/thirdparty/opus/silk/float/prefilter_FLP.c
new file mode 100644
index 0000000000..8bc32fb410
--- /dev/null
+++ b/thirdparty/opus/silk/float/prefilter_FLP.c
@@ -0,0 +1,206 @@
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Internet Society, IETF or IETF Trust, nor the
+names of specific contributors, may be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "main_FLP.h"
+#include "tuning_parameters.h"
+
+/*
+* Prefilter for finding Quantizer input signal
+*/
+static OPUS_INLINE void silk_prefilt_FLP(
+ silk_prefilter_state_FLP *P, /* I/O state */
+ silk_float st_res[], /* I */
+ silk_float xw[], /* O */
+ silk_float *HarmShapeFIR, /* I */
+ silk_float Tilt, /* I */
+ silk_float LF_MA_shp, /* I */
+ silk_float LF_AR_shp, /* I */
+ opus_int lag, /* I */
+ opus_int length /* I */
+);
+
+static void silk_warped_LPC_analysis_filter_FLP(
+ silk_float state[], /* I/O State [order + 1] */
+ silk_float res[], /* O Residual signal [length] */
+ const silk_float coef[], /* I Coefficients [order] */
+ const silk_float input[], /* I Input signal [length] */
+ const silk_float lambda, /* I Warping factor */
+ const opus_int length, /* I Length of input signal */
+ const opus_int order /* I Filter order (even) */
+)
+{
+ opus_int n, i;
+ silk_float acc, tmp1, tmp2;
+
+ /* Order must be even */
+ silk_assert( ( order & 1 ) == 0 );
+
+ for( n = 0; n < length; n++ ) {
+ /* Output of lowpass section */
+ tmp2 = state[ 0 ] + lambda * state[ 1 ];
+ state[ 0 ] = input[ n ];
+ /* Output of allpass section */
+ tmp1 = state[ 1 ] + lambda * ( state[ 2 ] - tmp2 );
+ state[ 1 ] = tmp2;
+ acc = coef[ 0 ] * tmp2;
+ /* Loop over allpass sections */
+ for( i = 2; i < order; i += 2 ) {
+ /* Output of allpass section */
+ tmp2 = state[ i ] + lambda * ( state[ i + 1 ] - tmp1 );
+ state[ i ] = tmp1;
+ acc += coef[ i - 1 ] * tmp1;
+ /* Output of allpass section */
+ tmp1 = state[ i + 1 ] + lambda * ( state[ i + 2 ] - tmp2 );
+ state[ i + 1 ] = tmp2;
+ acc += coef[ i ] * tmp2;
+ }
+ state[ order ] = tmp1;
+ acc += coef[ order - 1 ] * tmp1;
+ res[ n ] = input[ n ] - acc;
+ }
+}
+
+/*
+* silk_prefilter. Main prefilter function
+*/
+void silk_prefilter_FLP(
+ silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
+ const silk_encoder_control_FLP *psEncCtrl, /* I Encoder control FLP */
+ silk_float xw[], /* O Weighted signal */
+ const silk_float x[] /* I Speech signal */
+)
+{
+ silk_prefilter_state_FLP *P = &psEnc->sPrefilt;
+ opus_int j, k, lag;
+ silk_float HarmShapeGain, Tilt, LF_MA_shp, LF_AR_shp;
+ silk_float B[ 2 ];
+ const silk_float *AR1_shp;
+ const silk_float *px;
+ silk_float *pxw;
+ silk_float HarmShapeFIR[ 3 ];
+ silk_float st_res[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ];
+
+ /* Set up pointers */
+ px = x;
+ pxw = xw;
+ lag = P->lagPrev;
+ for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
+ /* Update Variables that change per sub frame */
+ if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
+ lag = psEncCtrl->pitchL[ k ];
+ }
+
+ /* Noise shape parameters */
+ HarmShapeGain = psEncCtrl->HarmShapeGain[ k ] * ( 1.0f - psEncCtrl->HarmBoost[ k ] );
+ HarmShapeFIR[ 0 ] = 0.25f * HarmShapeGain;
+ HarmShapeFIR[ 1 ] = 32767.0f / 65536.0f * HarmShapeGain;
+ HarmShapeFIR[ 2 ] = 0.25f * HarmShapeGain;
+ Tilt = psEncCtrl->Tilt[ k ];
+ LF_MA_shp = psEncCtrl->LF_MA_shp[ k ];
+ LF_AR_shp = psEncCtrl->LF_AR_shp[ k ];
+ AR1_shp = &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ];
+
+ /* Short term FIR filtering */
+ silk_warped_LPC_analysis_filter_FLP( P->sAR_shp, st_res, AR1_shp, px,
+ (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder );
+
+ /* Reduce (mainly) low frequencies during harmonic emphasis */
+ B[ 0 ] = psEncCtrl->GainsPre[ k ];
+ B[ 1 ] = -psEncCtrl->GainsPre[ k ] *
+ ( psEncCtrl->HarmBoost[ k ] * HarmShapeGain + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT );
+ pxw[ 0 ] = B[ 0 ] * st_res[ 0 ] + B[ 1 ] * P->sHarmHP;
+ for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) {
+ pxw[ j ] = B[ 0 ] * st_res[ j ] + B[ 1 ] * st_res[ j - 1 ];
+ }
+ P->sHarmHP = st_res[ psEnc->sCmn.subfr_length - 1 ];
+
+ silk_prefilt_FLP( P, pxw, pxw, HarmShapeFIR, Tilt, LF_MA_shp, LF_AR_shp, lag, psEnc->sCmn.subfr_length );
+
+ px += psEnc->sCmn.subfr_length;
+ pxw += psEnc->sCmn.subfr_length;
+ }
+ P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ];
+}
+
+/*
+* Prefilter for finding Quantizer input signal
+*/
+static OPUS_INLINE void silk_prefilt_FLP(
+ silk_prefilter_state_FLP *P, /* I/O state */
+ silk_float st_res[], /* I */
+ silk_float xw[], /* O */
+ silk_float *HarmShapeFIR, /* I */
+ silk_float Tilt, /* I */
+ silk_float LF_MA_shp, /* I */
+ silk_float LF_AR_shp, /* I */
+ opus_int lag, /* I */
+ opus_int length /* I */
+)
+{
+ opus_int i;
+ opus_int idx, LTP_shp_buf_idx;
+ silk_float n_Tilt, n_LF, n_LTP;
+ silk_float sLF_AR_shp, sLF_MA_shp;
+ silk_float *LTP_shp_buf;
+
+ /* To speed up use temp variables instead of using the struct */
+ LTP_shp_buf = P->sLTP_shp;
+ LTP_shp_buf_idx = P->sLTP_shp_buf_idx;
+ sLF_AR_shp = P->sLF_AR_shp;
+ sLF_MA_shp = P->sLF_MA_shp;
+
+ for( i = 0; i < length; i++ ) {
+ if( lag > 0 ) {
+ silk_assert( HARM_SHAPE_FIR_TAPS == 3 );
+ idx = lag + LTP_shp_buf_idx;
+ n_LTP = LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ] * HarmShapeFIR[ 0 ];
+ n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ] * HarmShapeFIR[ 1 ];
+ n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ] * HarmShapeFIR[ 2 ];
+ } else {
+ n_LTP = 0;
+ }
+
+ n_Tilt = sLF_AR_shp * Tilt;
+ n_LF = sLF_AR_shp * LF_AR_shp + sLF_MA_shp * LF_MA_shp;
+
+ sLF_AR_shp = st_res[ i ] - n_Tilt;
+ sLF_MA_shp = sLF_AR_shp - n_LF;
+
+ LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
+ LTP_shp_buf[ LTP_shp_buf_idx ] = sLF_MA_shp;
+
+ xw[ i ] = sLF_MA_shp - n_LTP;
+ }
+ /* Copy temp variable back to state */
+ P->sLF_AR_shp = sLF_AR_shp;
+ P->sLF_MA_shp = sLF_MA_shp;
+ P->sLTP_shp_buf_idx = LTP_shp_buf_idx;
+}
diff --git a/thirdparty/opus/silk/float/residual_energy_FLP.c b/thirdparty/opus/silk/float/residual_energy_FLP.c
index 1bd07b33a4..b2e03a86a4 100644
--- a/thirdparty/opus/silk/float/residual_energy_FLP.c
+++ b/thirdparty/opus/silk/float/residual_energy_FLP.c
@@ -47,7 +47,7 @@ silk_float silk_residual_energy_covar_FLP( /* O
silk_float tmp, nrg = 0.0f, regularization;
/* Safety checks */
- celt_assert( D >= 0 );
+ silk_assert( D >= 0 );
regularization = REGULARIZATION_FACTOR * ( wXX[ 0 ] + wXX[ D * D - 1 ] );
for( k = 0; k < MAX_ITERATIONS_RESIDUAL_NRG; k++ ) {
diff --git a/thirdparty/opus/silk/float/schur_FLP.c b/thirdparty/opus/silk/float/schur_FLP.c
index 8526c748d3..ee436f8351 100644
--- a/thirdparty/opus/silk/float/schur_FLP.c
+++ b/thirdparty/opus/silk/float/schur_FLP.c
@@ -38,23 +38,22 @@ silk_float silk_schur_FLP( /* O returns residual energy
)
{
opus_int k, n;
- double C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
- double Ctmp1, Ctmp2, rc_tmp;
+ silk_float C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ];
+ silk_float Ctmp1, Ctmp2, rc_tmp;
- celt_assert( order >= 0 && order <= SILK_MAX_ORDER_LPC );
+ silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 );
/* Copy correlations */
- k = 0;
- do {
+ for( k = 0; k < order+1; k++ ) {
C[ k ][ 0 ] = C[ k ][ 1 ] = auto_corr[ k ];
- } while( ++k <= order );
+ }
for( k = 0; k < order; k++ ) {
/* Get reflection coefficient */
rc_tmp = -C[ k + 1 ][ 0 ] / silk_max_float( C[ 0 ][ 1 ], 1e-9f );
/* Save the output */
- refl_coef[ k ] = (silk_float)rc_tmp;
+ refl_coef[ k ] = rc_tmp;
/* Update correlations */
for( n = 0; n < order - k; n++ ) {
@@ -66,5 +65,6 @@ silk_float silk_schur_FLP( /* O returns residual energy
}
/* Return residual energy */
- return (silk_float)C[ 0 ][ 1 ];
+ return C[ 0 ][ 1 ];
}
+
diff --git a/thirdparty/opus/silk/float/solve_LS_FLP.c b/thirdparty/opus/silk/float/solve_LS_FLP.c
new file mode 100644
index 0000000000..7c90d665a0
--- /dev/null
+++ b/thirdparty/opus/silk/float/solve_LS_FLP.c
@@ -0,0 +1,207 @@
+/***********************************************************************
+Copyright (c) 2006-2011, Skype Limited. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+- Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+- Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+- Neither the name of Internet Society, IETF or IETF Trust, nor the
+names of specific contributors, may be used to endorse or promote
+products derived from this software without specific prior written
+permission.
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "main_FLP.h"
+#include "tuning_parameters.h"
+
+/**********************************************************************
+ * LDL Factorisation. Finds the upper triangular matrix L and the diagonal
+ * Matrix D (only the diagonal elements returned in a vector)such that
+ * the symmetric matric A is given by A = L*D*L'.
+ **********************************************************************/
+static OPUS_INLINE void silk_LDL_FLP(
+ silk_float *A, /* I/O Pointer to Symetric Square Matrix */
+ opus_int M, /* I Size of Matrix */
+ silk_float *L, /* I/O Pointer to Square Upper triangular Matrix */
+ silk_float *Dinv /* I/O Pointer to vector holding the inverse diagonal elements of D */
+);
+
+/**********************************************************************
+ * Function to solve linear equation Ax = b, when A is a MxM lower
+ * triangular matrix, with ones on the diagonal.
+ **********************************************************************/
+static OPUS_INLINE void silk_SolveWithLowerTriangularWdiagOnes_FLP(
+ const silk_float *L, /* I Pointer to Lower Triangular Matrix */
+ opus_int M, /* I Dim of Matrix equation */
+ const silk_float *b, /* I b Vector */
+ silk_float *x /* O x Vector */
+);
+
+/**********************************************************************
+ * Function to solve linear equation (A^T)x = b, when A is a MxM lower
+ * triangular, with ones on the diagonal. (ie then A^T is upper triangular)
+ **********************************************************************/
+static OPUS_INLINE void silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP(
+ const silk_float *L, /* I Pointer to Lower Triangular Matrix */
+ opus_int M, /* I Dim of Matrix equation */
+ const silk_float *b, /* I b Vector */
+ silk_float *x /* O x Vector */
+);
+
+/**********************************************************************
+ * Function to solve linear equation Ax = b, when A is a MxM
+ * symmetric square matrix - using LDL factorisation
+ **********************************************************************/
+void silk_solve_LDL_FLP(
+ silk_float *A, /* I/O Symmetric square matrix, out: reg. */
+ const opus_int M, /* I Size of matrix */
+ const silk_float *b, /* I Pointer to b vector */
+ silk_float *x /* O Pointer to x solution vector */
+)
+{
+ opus_int i;
+ silk_float L[ MAX_MATRIX_SIZE ][ MAX_MATRIX_SIZE ];
+ silk_float T[ MAX_MATRIX_SIZE ];
+ silk_float Dinv[ MAX_MATRIX_SIZE ]; /* inverse diagonal elements of D*/
+
+ silk_assert( M <= MAX_MATRIX_SIZE );
+
+ /***************************************************
+ Factorize A by LDL such that A = L*D*(L^T),
+ where L is lower triangular with ones on diagonal
+ ****************************************************/
+ silk_LDL_FLP( A, M, &L[ 0 ][ 0 ], Dinv );
+
+ /****************************************************
+ * substitute D*(L^T) = T. ie:
+ L*D*(L^T)*x = b => L*T = b <=> T = inv(L)*b
+ ******************************************************/
+ silk_SolveWithLowerTriangularWdiagOnes_FLP( &L[ 0 ][ 0 ], M, b, T );
+
+ /****************************************************
+ D*(L^T)*x = T <=> (L^T)*x = inv(D)*T, because D is
+ diagonal just multiply with 1/d_i
+ ****************************************************/
+ for( i = 0; i < M; i++ ) {
+ T[ i ] = T[ i ] * Dinv[ i ];
+ }
+ /****************************************************
+ x = inv(L') * inv(D) * T
+ *****************************************************/
+ silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( &L[ 0 ][ 0 ], M, T, x );
+}
+
+static OPUS_INLINE void silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP(
+ const silk_float *L, /* I Pointer to Lower Triangular Matrix */
+ opus_int M, /* I Dim of Matrix equation */
+ const silk_float *b, /* I b Vector */
+ silk_float *x /* O x Vector */
+)
+{
+ opus_int i, j;
+ silk_float temp;
+ const silk_float *ptr1;
+
+ for( i = M - 1; i >= 0; i-- ) {
+ ptr1 = matrix_adr( L, 0, i, M );
+ temp = 0;
+ for( j = M - 1; j > i ; j-- ) {
+ temp += ptr1[ j * M ] * x[ j ];
+ }
+ temp = b[ i ] - temp;
+ x[ i ] = temp;
+ }
+}
+
+static OPUS_INLINE void silk_SolveWithLowerTriangularWdiagOnes_FLP(
+ const silk_float *L, /* I Pointer to Lower Triangular Matrix */
+ opus_int M, /* I Dim of Matrix equation */
+ const silk_float *b, /* I b Vector */
+ silk_float *x /* O x Vector */
+)
+{
+ opus_int i, j;
+ silk_float temp;
+ const silk_float *ptr1;
+
+ for( i = 0; i < M; i++ ) {
+ ptr1 = matrix_adr( L, i, 0, M );
+ temp = 0;
+ for( j = 0; j < i; j++ ) {
+ temp += ptr1[ j ] * x[ j ];
+ }
+ temp = b[ i ] - temp;
+ x[ i ] = temp;
+ }
+}
+
+static OPUS_INLINE void silk_LDL_FLP(
+ silk_float *A, /* I/O Pointer to Symetric Square Matrix */
+ opus_int M, /* I Size of Matrix */
+ silk_float *L, /* I/O Pointer to Square Upper triangular Matrix */
+ silk_float *Dinv /* I/O Pointer to vector holding the inverse diagonal elements of D */
+)
+{
+ opus_int i, j, k, loop_count, err = 1;
+ silk_float *ptr1, *ptr2;
+ double temp, diag_min_value;
+ silk_float v[ MAX_MATRIX_SIZE ], D[ MAX_MATRIX_SIZE ]; /* temp arrays*/
+
+ silk_assert( M <= MAX_MATRIX_SIZE );
+
+ diag_min_value = FIND_LTP_COND_FAC * 0.5f * ( A[ 0 ] + A[ M * M - 1 ] );
+ for( loop_count = 0; loop_count < M && err == 1; loop_count++ ) {
+ err = 0;
+ for( j = 0; j < M; j++ ) {
+ ptr1 = matrix_adr( L, j, 0, M );
+ temp = matrix_ptr( A, j, j, M ); /* element in row j column j*/
+ for( i = 0; i < j; i++ ) {
+ v[ i ] = ptr1[ i ] * D[ i ];
+ temp -= ptr1[ i ] * v[ i ];
+ }
+ if( temp < diag_min_value ) {
+ /* Badly conditioned matrix: add white noise and run again */
+ temp = ( loop_count + 1 ) * diag_min_value - temp;
+ for( i = 0; i < M; i++ ) {
+ matrix_ptr( A, i, i, M ) += ( silk_float )temp;
+ }
+ err = 1;
+ break;
+ }
+ D[ j ] = ( silk_float )temp;
+ Dinv[ j ] = ( silk_float )( 1.0f / temp );
+ matrix_ptr( L, j, j, M ) = 1.0f;
+
+ ptr1 = matrix_adr( A, j, 0, M );
+ ptr2 = matrix_adr( L, j + 1, 0, M);
+ for( i = j + 1; i < M; i++ ) {
+ temp = 0.0;
+ for( k = 0; k < j; k++ ) {
+ temp += ptr2[ k ] * v[ k ];
+ }
+ matrix_ptr( L, i, j, M ) = ( silk_float )( ( ptr1[ i ] - temp ) * Dinv[ j ] );
+ ptr2 += M; /* go to next column*/
+ }
+ }
+ }
+ silk_assert( err == 0 );
+}
+
diff --git a/thirdparty/opus/silk/float/sort_FLP.c b/thirdparty/opus/silk/float/sort_FLP.c
index 0e18f31950..f08d7592c5 100644
--- a/thirdparty/opus/silk/float/sort_FLP.c
+++ b/thirdparty/opus/silk/float/sort_FLP.c
@@ -47,9 +47,9 @@ void silk_insertion_sort_decreasing_FLP(
opus_int i, j;
/* Safety checks */
- celt_assert( K > 0 );
- celt_assert( L > 0 );
- celt_assert( L >= K );
+ silk_assert( K > 0 );
+ silk_assert( L > 0 );
+ silk_assert( L >= K );
/* Write start indices in index vector */
for( i = 0; i < K; i++ ) {
diff --git a/thirdparty/opus/silk/float/structs_FLP.h b/thirdparty/opus/silk/float/structs_FLP.h
index 3150b386e4..14d647ced2 100644
--- a/thirdparty/opus/silk/float/structs_FLP.h
+++ b/thirdparty/opus/silk/float/structs_FLP.h
@@ -42,16 +42,32 @@ extern "C"
/********************************/
typedef struct {
opus_int8 LastGainIndex;
+ silk_float HarmBoost_smth;
silk_float HarmShapeGain_smth;
silk_float Tilt_smth;
} silk_shape_state_FLP;
/********************************/
+/* Prefilter state */
+/********************************/
+typedef struct {
+ silk_float sLTP_shp[ LTP_BUF_LENGTH ];
+ silk_float sAR_shp[ MAX_SHAPE_LPC_ORDER + 1 ];
+ opus_int sLTP_shp_buf_idx;
+ silk_float sLF_AR_shp;
+ silk_float sLF_MA_shp;
+ silk_float sHarmHP;
+ opus_int32 rand_seed;
+ opus_int lagPrev;
+} silk_prefilter_state_FLP;
+
+/********************************/
/* Encoder state FLP */
/********************************/
typedef struct {
silk_encoder_state sCmn; /* Common struct, shared with fixed-point code */
silk_shape_state_FLP sShape; /* Noise shaping state */
+ silk_prefilter_state_FLP sPrefilt; /* Prefilter State */
/* Buffer for find pitch and noise shape analysis */
silk_float x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */
@@ -70,9 +86,12 @@ typedef struct {
opus_int pitchL[ MAX_NB_SUBFR ];
/* Noise shaping parameters */
- silk_float AR[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
+ silk_float AR1[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
+ silk_float AR2[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
silk_float LF_MA_shp[ MAX_NB_SUBFR ];
silk_float LF_AR_shp[ MAX_NB_SUBFR ];
+ silk_float GainsPre[ MAX_NB_SUBFR ];
+ silk_float HarmBoost[ MAX_NB_SUBFR ];
silk_float Tilt[ MAX_NB_SUBFR ];
silk_float HarmShapeGain[ MAX_NB_SUBFR ];
silk_float Lambda;
@@ -80,6 +99,7 @@ typedef struct {
silk_float coding_quality;
/* Measures */
+ silk_float sparseness;
silk_float predGain;
silk_float LTPredCodGain;
silk_float ResNrg[ MAX_NB_SUBFR ]; /* Residual energy per subframe */
diff --git a/thirdparty/opus/silk/float/warped_autocorrelation_FLP.c b/thirdparty/opus/silk/float/warped_autocorrelation_FLP.c
index 09186e73d4..542414f48e 100644
--- a/thirdparty/opus/silk/float/warped_autocorrelation_FLP.c
+++ b/thirdparty/opus/silk/float/warped_autocorrelation_FLP.c
@@ -42,11 +42,11 @@ void silk_warped_autocorrelation_FLP(
{
opus_int n, i;
double tmp1, tmp2;
- double state[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
- double C[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 };
+ double state[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
+ double C[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
/* Order must be even */
- celt_assert( ( order & 1 ) == 0 );
+ silk_assert( ( order & 1 ) == 0 );
/* Loop over samples */
for( n = 0; n < length; n++ ) {
diff --git a/thirdparty/opus/silk/float/wrappers_FLP.c b/thirdparty/opus/silk/float/wrappers_FLP.c
index ad90b874a4..6666b8efaa 100644
--- a/thirdparty/opus/silk/float/wrappers_FLP.c
+++ b/thirdparty/opus/silk/float/wrappers_FLP.c
@@ -54,14 +54,13 @@ void silk_A2NLSF_FLP(
void silk_NLSF2A_FLP(
silk_float *pAR, /* O LPC coefficients [ LPC_order ] */
const opus_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */
- const opus_int LPC_order, /* I LPC order */
- int arch /* I Run-time architecture */
+ const opus_int LPC_order /* I LPC order */
)
{
opus_int i;
opus_int16 a_fix_Q12[ MAX_LPC_ORDER ];
- silk_NLSF2A( a_fix_Q12, NLSF_Q15, LPC_order, arch );
+ silk_NLSF2A( a_fix_Q12, NLSF_Q15, LPC_order );
for( i = 0; i < LPC_order; i++ ) {
pAR[ i ] = ( silk_float )a_fix_Q12[ i ] * ( 1.0f / 4096.0f );
@@ -103,14 +102,14 @@ void silk_NSQ_wrapper_FLP(
)
{
opus_int i, j;
- opus_int16 x16[ MAX_FRAME_LENGTH ];
+ opus_int32 x_Q3[ MAX_FRAME_LENGTH ];
opus_int32 Gains_Q16[ MAX_NB_SUBFR ];
silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ];
opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ];
opus_int LTP_scale_Q14;
/* Noise shaping parameters */
- opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
+ opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ];
opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */
opus_int Lambda_Q10;
opus_int Tilt_Q14[ MAX_NB_SUBFR ];
@@ -120,7 +119,7 @@ void silk_NSQ_wrapper_FLP(
/* Noise shape parameters */
for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
for( j = 0; j < psEnc->sCmn.shapingLPCOrder; j++ ) {
- AR_Q13[ i * MAX_SHAPE_LPC_ORDER + j ] = silk_float2int( psEncCtrl->AR[ i * MAX_SHAPE_LPC_ORDER + j ] * 8192.0f );
+ AR2_Q13[ i * MAX_SHAPE_LPC_ORDER + j ] = silk_float2int( psEncCtrl->AR2[ i * MAX_SHAPE_LPC_ORDER + j ] * 8192.0f );
}
}
@@ -156,16 +155,16 @@ void silk_NSQ_wrapper_FLP(
/* Convert input to fix */
for( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
- x16[ i ] = silk_float2int( x[ i ] );
+ x_Q3[ i ] = silk_float2int( 8.0f * x[ i ] );
}
/* Call NSQ */
if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
- silk_NSQ_del_dec( &psEnc->sCmn, psNSQ, psIndices, x16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
- AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch );
+ silk_NSQ_del_dec( &psEnc->sCmn, psNSQ, psIndices, x_Q3, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
+ AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch );
} else {
- silk_NSQ( &psEnc->sCmn, psNSQ, psIndices, x16, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
- AR_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch );
+ silk_NSQ( &psEnc->sCmn, psNSQ, psIndices, x_Q3, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14,
+ AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14, psEnc->sCmn.arch );
}
}
@@ -173,35 +172,31 @@ void silk_NSQ_wrapper_FLP(
/* Floating-point Silk LTP quantiation wrapper */
/***********************************************/
void silk_quant_LTP_gains_FLP(
- silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */
+ silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (Un-)quantized LTP gains */
opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */
opus_int8 *periodicity_index, /* O Periodicity index */
opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */
- silk_float *pred_gain_dB, /* O LTP prediction gain */
- const silk_float XX[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Correlation matrix */
- const silk_float xX[ MAX_NB_SUBFR * LTP_ORDER ], /* I Correlation vector */
- const opus_int subfr_len, /* I Number of samples per subframe */
- const opus_int nb_subfr, /* I Number of subframes */
+ const silk_float W[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Error weights */
+ const opus_int mu_Q10, /* I Mu value (R/D tradeoff) */
+ const opus_int lowComplexity, /* I Flag for low complexity */
+ const opus_int nb_subfr, /* I number of subframes */
int arch /* I Run-time architecture */
)
{
- opus_int i, pred_gain_dB_Q7;
+ opus_int i;
opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ];
- opus_int32 XX_Q17[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ];
- opus_int32 xX_Q17[ MAX_NB_SUBFR * LTP_ORDER ];
+ opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ];
- for( i = 0; i < nb_subfr * LTP_ORDER * LTP_ORDER; i++ ) {
- XX_Q17[ i ] = (opus_int32)silk_float2int( XX[ i ] * 131072.0f );
- }
for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) {
- xX_Q17[ i ] = (opus_int32)silk_float2int( xX[ i ] * 131072.0f );
+ B_Q14[ i ] = (opus_int16)silk_float2int( B[ i ] * 16384.0f );
+ }
+ for( i = 0; i < nb_subfr * LTP_ORDER * LTP_ORDER; i++ ) {
+ W_Q18[ i ] = (opus_int32)silk_float2int( W[ i ] * 262144.0f );
}
- silk_quant_LTP_gains( B_Q14, cbk_index, periodicity_index, sum_log_gain_Q7, &pred_gain_dB_Q7, XX_Q17, xX_Q17, subfr_len, nb_subfr, arch );
+ silk_quant_LTP_gains( B_Q14, cbk_index, periodicity_index, sum_log_gain_Q7, W_Q18, mu_Q10, lowComplexity, nb_subfr, arch );
for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) {
B[ i ] = (silk_float)B_Q14[ i ] * ( 1.0f / 16384.0f );
}
-
- *pred_gain_dB = (silk_float)pred_gain_dB_Q7 * ( 1.0f / 128.0f );
}
diff --git a/thirdparty/opus/silk/gain_quant.c b/thirdparty/opus/silk/gain_quant.c
index ee65245aa3..64ccd0611b 100644
--- a/thirdparty/opus/silk/gain_quant.c
+++ b/thirdparty/opus/silk/gain_quant.c
@@ -76,7 +76,6 @@ void silk_gains_quant(
/* Accumulate deltas */
if( ind[ k ] > double_step_size_threshold ) {
*prev_ind += silk_LSHIFT( ind[ k ], 1 ) - double_step_size_threshold;
- *prev_ind = silk_min_int( *prev_ind, N_LEVELS_QGAIN - 1 );
} else {
*prev_ind += ind[ k ];
}
diff --git a/thirdparty/opus/silk/init_decoder.c b/thirdparty/opus/silk/init_decoder.c
index 16c03dcd1c..f887c67886 100644
--- a/thirdparty/opus/silk/init_decoder.c
+++ b/thirdparty/opus/silk/init_decoder.c
@@ -44,7 +44,6 @@ opus_int silk_init_decoder(
/* Used to deactivate LSF interpolation */
psDec->first_frame_after_reset = 1;
psDec->prev_gain_Q16 = 65536;
- psDec->arch = opus_select_arch();
/* Reset CNG state */
silk_CNG_Reset( psDec );
diff --git a/thirdparty/opus/silk/interpolate.c b/thirdparty/opus/silk/interpolate.c
index 833c28ef8e..1bd8ca4d53 100644
--- a/thirdparty/opus/silk/interpolate.c
+++ b/thirdparty/opus/silk/interpolate.c
@@ -42,8 +42,8 @@ void silk_interpolate(
{
opus_int i;
- celt_assert( ifact_Q2 >= 0 );
- celt_assert( ifact_Q2 <= 4 );
+ silk_assert( ifact_Q2 >= 0 );
+ silk_assert( ifact_Q2 <= 4 );
for( i = 0; i < d; i++ ) {
xi[ i ] = (opus_int16)silk_ADD_RSHIFT( x0[ i ], silk_SMULBB( x1[ i ] - x0[ i ], ifact_Q2 ), 2 );
diff --git a/thirdparty/opus/silk/lin2log.c b/thirdparty/opus/silk/lin2log.c
index 0d5155aa86..d4fe515321 100644
--- a/thirdparty/opus/silk/lin2log.c
+++ b/thirdparty/opus/silk/lin2log.c
@@ -41,6 +41,6 @@ opus_int32 silk_lin2log(
silk_CLZ_FRAC( inLin, &lz, &frac_Q7 );
/* Piece-wise parabolic approximation */
- return silk_ADD_LSHIFT32( silk_SMLAWB( frac_Q7, silk_MUL( frac_Q7, 128 - frac_Q7 ), 179 ), 31 - lz, 7 );
+ return silk_LSHIFT( 31 - lz, 7 ) + silk_SMLAWB( frac_Q7, silk_MUL( frac_Q7, 128 - frac_Q7 ), 179 );
}
diff --git a/thirdparty/opus/silk/macros.h b/thirdparty/opus/silk/macros.h
index 3c67b6e5d9..d3ca347520 100644
--- a/thirdparty/opus/silk/macros.h
+++ b/thirdparty/opus/silk/macros.h
@@ -36,6 +36,14 @@ POSSIBILITY OF SUCH DAMAGE.
#include "opus_defines.h"
#include "arch.h"
+#if OPUS_GNUC_PREREQ(3, 0)
+#define opus_likely(x) (__builtin_expect(!!(x), 1))
+#define opus_unlikely(x) (__builtin_expect(!!(x), 0))
+#else
+#define opus_likely(x) (!!(x))
+#define opus_unlikely(x) (!!(x))
+#endif
+
/* This is an OPUS_INLINE header file for general platform. */
/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
diff --git a/thirdparty/opus/silk/main.h b/thirdparty/opus/silk/main.h
index 1a33eed549..2f90d68f7d 100644
--- a/thirdparty/opus/silk/main.h
+++ b/thirdparty/opus/silk/main.h
@@ -42,10 +42,6 @@ POSSIBILITY OF SUCH DAMAGE.
#include "x86/main_sse.h"
#endif
-#if (defined(OPUS_ARM_ASM) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR))
-#include "arm/NSQ_del_dec_arm.h"
-#endif
-
/* Convert Left/Right stereo signal to adaptive Mid/Side representation */
void silk_stereo_LR_to_MS(
stereo_enc_state *state, /* I/O State */
@@ -113,22 +109,22 @@ void silk_stereo_decode_mid_only(
/* Encodes signs of excitation */
void silk_encode_signs(
- ec_enc *psRangeEnc, /* I/O Compressor data structure */
- const opus_int8 pulses[], /* I pulse signal */
- opus_int length, /* I length of input */
- const opus_int signalType, /* I Signal type */
- const opus_int quantOffsetType, /* I Quantization offset type */
- const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */
+ ec_enc *psRangeEnc, /* I/O Compressor data structure */
+ const opus_int8 pulses[], /* I pulse signal */
+ opus_int length, /* I length of input */
+ const opus_int signalType, /* I Signal type */
+ const opus_int quantOffsetType, /* I Quantization offset type */
+ const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */
);
/* Decodes signs of excitation */
void silk_decode_signs(
- ec_dec *psRangeDec, /* I/O Compressor data structure */
- opus_int16 pulses[], /* I/O pulse signal */
- opus_int length, /* I length of input */
- const opus_int signalType, /* I Signal type */
- const opus_int quantOffsetType, /* I Quantization offset type */
- const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */
+ ec_dec *psRangeDec, /* I/O Compressor data structure */
+ opus_int16 pulses[], /* I/O pulse signal */
+ opus_int length, /* I length of input */
+ const opus_int signalType, /* I Signal type */
+ const opus_int quantOffsetType, /* I Quantization offset type */
+ const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */
);
/* Check encoder control struct */
@@ -209,37 +205,37 @@ void silk_interpolate(
/* LTP tap quantizer */
void silk_quant_LTP_gains(
- opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */
+ opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (un)quantized LTP gains */
opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */
opus_int8 *periodicity_index, /* O Periodicity Index */
opus_int32 *sum_gain_dB_Q7, /* I/O Cumulative max prediction gain */
- opus_int *pred_gain_dB_Q7, /* O LTP prediction gain */
- const opus_int32 XX_Q17[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Correlation matrix in Q18 */
- const opus_int32 xX_Q17[ MAX_NB_SUBFR*LTP_ORDER ], /* I Correlation vector in Q18 */
- const opus_int subfr_len, /* I Number of samples per subframe */
- const opus_int nb_subfr, /* I Number of subframes */
+ const opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Error Weights in Q18 */
+ opus_int mu_Q9, /* I Mu value (R/D tradeoff) */
+ opus_int lowComplexity, /* I Flag for low complexity */
+ const opus_int nb_subfr, /* I number of subframes */
int arch /* I Run-time architecture */
);
/* Entropy constrained matrix-weighted VQ, for a single input data vector */
void silk_VQ_WMat_EC_c(
opus_int8 *ind, /* O index of best codebook vector */
- opus_int32 *res_nrg_Q15, /* O best residual energy */
- opus_int32 *rate_dist_Q8, /* O best total bitrate */
+ opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */
opus_int *gain_Q7, /* O sum of absolute LTP coefficients */
- const opus_int32 *XX_Q17, /* I correlation matrix */
- const opus_int32 *xX_Q17, /* I correlation vector */
+ const opus_int16 *in_Q14, /* I input vector to be quantized */
+ const opus_int32 *W_Q18, /* I weighting matrix */
const opus_int8 *cb_Q7, /* I codebook */
const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */
const opus_uint8 *cl_Q5, /* I code length for each codebook vector */
- const opus_int subfr_len, /* I number of samples per subframe */
+ const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */
const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
- const opus_int L /* I number of vectors in codebook */
+ opus_int L /* I number of vectors in codebook */
);
#if !defined(OVERRIDE_silk_VQ_WMat_EC)
-#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) \
- ((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))
+#define silk_VQ_WMat_EC(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \
+ mu_Q9, max_gain_Q7, L, arch) \
+ ((void)(arch),silk_VQ_WMat_EC_c(ind, rate_dist_Q14, gain_Q7, in_Q14, W_Q18, cb_Q7, cb_gain_Q7, cl_Q5, \
+ mu_Q9, max_gain_Q7, L))
#endif
/************************************/
@@ -247,14 +243,14 @@ void silk_VQ_WMat_EC_c(
/************************************/
void silk_NSQ_c(
- const silk_encoder_state *psEncC, /* I Encoder State */
+ const silk_encoder_state *psEncC, /* I/O Encoder State */
silk_nsq_state *NSQ, /* I/O NSQ state */
SideInfoIndices *psIndices, /* I/O Quantization Indices */
- const opus_int16 x16[], /* I Input */
+ const opus_int32 x_Q3[], /* I Prefiltered input signal */
opus_int8 pulses[], /* O Quantized pulse signal */
const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
- const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
+ const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
@@ -265,22 +261,22 @@ void silk_NSQ_c(
);
#if !defined(OVERRIDE_silk_NSQ)
-#define silk_NSQ(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \
+#define silk_NSQ(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \
- ((void)(arch),silk_NSQ_c(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \
+ ((void)(arch),silk_NSQ_c(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))
#endif
/* Noise shaping using delayed decision */
void silk_NSQ_del_dec_c(
- const silk_encoder_state *psEncC, /* I Encoder State */
+ const silk_encoder_state *psEncC, /* I/O Encoder State */
silk_nsq_state *NSQ, /* I/O NSQ state */
SideInfoIndices *psIndices, /* I/O Quantization Indices */
- const opus_int16 x16[], /* I Input */
+ const opus_int32 x_Q3[], /* I Prefiltered input signal */
opus_int8 pulses[], /* O Quantized pulse signal */
const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */
const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */
- const opus_int16 AR_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
+ const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */
const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */
const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */
const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */
@@ -291,9 +287,9 @@ void silk_NSQ_del_dec_c(
);
#if !defined(OVERRIDE_silk_NSQ_del_dec)
-#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \
+#define silk_NSQ_del_dec(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14, arch) \
- ((void)(arch),silk_NSQ_del_dec_c(psEncC, NSQ, psIndices, x16, pulses, PredCoef_Q12, LTPCoef_Q14, AR_Q13, \
+ ((void)(arch),silk_NSQ_del_dec_c(psEncC, NSQ, psIndices, x_Q3, pulses, PredCoef_Q12, LTPCoef_Q14, AR2_Q13, \
HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))
#endif
@@ -350,7 +346,6 @@ void silk_NLSF_VQ(
opus_int32 err_Q26[], /* O Quantization errors [K] */
const opus_int16 in_Q15[], /* I Input vectors to be quantized [LPC_order] */
const opus_uint8 pCB_Q8[], /* I Codebook vectors [K*LPC_order] */
- const opus_int16 pWght_Q9[], /* I Codebook weights [K*LPC_order] */
const opus_int K, /* I Number of codebook vectors */
const opus_int LPC_order /* I Number of LPCs */
);
diff --git a/thirdparty/opus/silk/mips/NSQ_del_dec_mipsr1.h b/thirdparty/opus/silk/mips/NSQ_del_dec_mipsr1.h
index cd70713a8f..ad1cfe2a9b 100644
--- a/thirdparty/opus/silk/mips/NSQ_del_dec_mipsr1.h
+++ b/thirdparty/opus/silk/mips/NSQ_del_dec_mipsr1.h
@@ -61,7 +61,7 @@ static inline void silk_noise_shape_quantizer_del_dec(
opus_int predictLPCOrder, /* I Prediction filter order */
opus_int warping_Q16, /* I */
opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
- opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
+ opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */
opus_int decisionDelay, /* I */
int arch /* I */
)
@@ -323,9 +323,8 @@ static inline void silk_noise_shape_quantizer_del_dec(
psSS[ 1 ].xq_Q14 = xq_Q14;
}
- *smpl_buf_idx = ( *smpl_buf_idx - 1 ) % DECISION_DELAY;
- if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY;
- last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY;
+ *smpl_buf_idx = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK; /* Index to newest samples */
+ last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK; /* Index to decisionDelay old samples */
/* Find winner */
RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
diff --git a/thirdparty/opus/silk/mips/sigproc_fix_mipsr1.h b/thirdparty/opus/silk/mips/sigproc_fix_mipsr1.h
index 51520c0a6f..3b0a695365 100644
--- a/thirdparty/opus/silk/mips/sigproc_fix_mipsr1.h
+++ b/thirdparty/opus/silk/mips/sigproc_fix_mipsr1.h
@@ -28,6 +28,11 @@ POSSIBILITY OF SUCH DAMAGE.
#ifndef SILK_SIGPROC_FIX_MIPSR1_H
#define SILK_SIGPROC_FIX_MIPSR1_H
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
#undef silk_SAT16
static inline short int silk_SAT16(int a)
{
diff --git a/thirdparty/opus/silk/process_NLSFs.c b/thirdparty/opus/silk/process_NLSFs.c
index d130809541..0ab71f0163 100644
--- a/thirdparty/opus/silk/process_NLSFs.c
+++ b/thirdparty/opus/silk/process_NLSFs.c
@@ -48,7 +48,7 @@ void silk_process_NLSFs(
silk_assert( psEncC->speech_activity_Q8 >= 0 );
silk_assert( psEncC->speech_activity_Q8 <= SILK_FIX_CONST( 1.0, 8 ) );
- celt_assert( psEncC->useInterpolatedNLSFs == 1 || psEncC->indices.NLSFInterpCoef_Q2 == ( 1 << 2 ) );
+ silk_assert( psEncC->useInterpolatedNLSFs == 1 || psEncC->indices.NLSFInterpCoef_Q2 == ( 1 << 2 ) );
/***********************/
/* Calculate mu values */
@@ -60,7 +60,7 @@ void silk_process_NLSFs(
NLSF_mu_Q20 = silk_ADD_RSHIFT( NLSF_mu_Q20, NLSF_mu_Q20, 1 );
}
- celt_assert( NLSF_mu_Q20 > 0 );
+ silk_assert( NLSF_mu_Q20 > 0 );
silk_assert( NLSF_mu_Q20 <= SILK_FIX_CONST( 0.005, 20 ) );
/* Calculate NLSF weights */
@@ -89,7 +89,7 @@ void silk_process_NLSFs(
NLSF_mu_Q20, psEncC->NLSF_MSVQ_Survivors, psEncC->indices.signalType );
/* Convert quantized NLSFs back to LPC coefficients */
- silk_NLSF2A( PredCoef_Q12[ 1 ], pNLSF_Q15, psEncC->predictLPCOrder, psEncC->arch );
+ silk_NLSF2A( PredCoef_Q12[ 1 ], pNLSF_Q15, psEncC->predictLPCOrder );
if( doInterpolate ) {
/* Calculate the interpolated, quantized LSF vector for the first half */
@@ -97,11 +97,11 @@ void silk_process_NLSFs(
psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder );
/* Convert back to LPC coefficients */
- silk_NLSF2A( PredCoef_Q12[ 0 ], pNLSF0_temp_Q15, psEncC->predictLPCOrder, psEncC->arch );
+ silk_NLSF2A( PredCoef_Q12[ 0 ], pNLSF0_temp_Q15, psEncC->predictLPCOrder );
} else {
/* Copy LPC coefficients for first half from second half */
- celt_assert( psEncC->predictLPCOrder <= MAX_LPC_ORDER );
+ silk_assert( psEncC->predictLPCOrder <= MAX_LPC_ORDER );
silk_memcpy( PredCoef_Q12[ 0 ], PredCoef_Q12[ 1 ], psEncC->predictLPCOrder * sizeof( opus_int16 ) );
}
}
diff --git a/thirdparty/opus/silk/quant_LTP_gains.c b/thirdparty/opus/silk/quant_LTP_gains.c
index d6b8eff8d1..513a8c4468 100644
--- a/thirdparty/opus/silk/quant_LTP_gains.c
+++ b/thirdparty/opus/silk/quant_LTP_gains.c
@@ -33,15 +33,14 @@ POSSIBILITY OF SUCH DAMAGE.
#include "tuning_parameters.h"
void silk_quant_LTP_gains(
- opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O Quantized LTP gains */
+ opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (un)quantized LTP gains */
opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */
opus_int8 *periodicity_index, /* O Periodicity Index */
opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */
- opus_int *pred_gain_dB_Q7, /* O LTP prediction gain */
- const opus_int32 XX_Q17[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Correlation matrix in Q18 */
- const opus_int32 xX_Q17[ MAX_NB_SUBFR*LTP_ORDER ], /* I Correlation vector in Q18 */
- const opus_int subfr_len, /* I Number of samples per subframe */
- const opus_int nb_subfr, /* I Number of subframes */
+ const opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Error Weights in Q18 */
+ opus_int mu_Q9, /* I Mu value (R/D tradeoff) */
+ opus_int lowComplexity, /* I Flag for low complexity */
+ const opus_int nb_subfr, /* I number of subframes */
int arch /* I Run-time architecture */
)
{
@@ -50,16 +49,16 @@ void silk_quant_LTP_gains(
const opus_uint8 *cl_ptr_Q5;
const opus_int8 *cbk_ptr_Q7;
const opus_uint8 *cbk_gain_ptr_Q7;
- const opus_int32 *XX_Q17_ptr, *xX_Q17_ptr;
- opus_int32 res_nrg_Q15_subfr, res_nrg_Q15, rate_dist_Q7_subfr, rate_dist_Q7, min_rate_dist_Q7;
- opus_int32 sum_log_gain_tmp_Q7, best_sum_log_gain_Q7, max_gain_Q7;
- opus_int gain_Q7;
+ const opus_int16 *b_Q14_ptr;
+ const opus_int32 *W_Q18_ptr;
+ opus_int32 rate_dist_Q14_subfr, rate_dist_Q14, min_rate_dist_Q14;
+ opus_int32 sum_log_gain_tmp_Q7, best_sum_log_gain_Q7, max_gain_Q7, gain_Q7;
/***************************************************/
/* iterate over different codebooks with different */
/* rates/distortions, and choose best */
/***************************************************/
- min_rate_dist_Q7 = silk_int32_MAX;
+ min_rate_dist_Q14 = silk_int32_MAX;
best_sum_log_gain_Q7 = 0;
for( k = 0; k < 3; k++ ) {
/* Safety margin for pitch gain control, to take into account factors
@@ -71,47 +70,53 @@ void silk_quant_LTP_gains(
cbk_gain_ptr_Q7 = silk_LTP_vq_gain_ptrs_Q7[ k ];
cbk_size = silk_LTP_vq_sizes[ k ];
- /* Set up pointers to first subframe */
- XX_Q17_ptr = XX_Q17;
- xX_Q17_ptr = xX_Q17;
+ /* Set up pointer to first subframe */
+ W_Q18_ptr = W_Q18;
+ b_Q14_ptr = B_Q14;
- res_nrg_Q15 = 0;
- rate_dist_Q7 = 0;
+ rate_dist_Q14 = 0;
sum_log_gain_tmp_Q7 = *sum_log_gain_Q7;
for( j = 0; j < nb_subfr; j++ ) {
max_gain_Q7 = silk_log2lin( ( SILK_FIX_CONST( MAX_SUM_LOG_GAIN_DB / 6.0, 7 ) - sum_log_gain_tmp_Q7 )
+ SILK_FIX_CONST( 7, 7 ) ) - gain_safety;
+
silk_VQ_WMat_EC(
&temp_idx[ j ], /* O index of best codebook vector */
- &res_nrg_Q15_subfr, /* O residual energy */
- &rate_dist_Q7_subfr, /* O best weighted quantization error + mu * rate */
+ &rate_dist_Q14_subfr, /* O best weighted quantization error + mu * rate */
&gain_Q7, /* O sum of absolute LTP coefficients */
- XX_Q17_ptr, /* I correlation matrix */
- xX_Q17_ptr, /* I correlation vector */
+ b_Q14_ptr, /* I input vector to be quantized */
+ W_Q18_ptr, /* I weighting matrix */
cbk_ptr_Q7, /* I codebook */
cbk_gain_ptr_Q7, /* I codebook effective gains */
cl_ptr_Q5, /* I code length for each codebook vector */
- subfr_len, /* I number of samples per subframe */
+ mu_Q9, /* I tradeoff between weighted error and rate */
max_gain_Q7, /* I maximum sum of absolute LTP coefficients */
cbk_size, /* I number of vectors in codebook */
arch /* I Run-time architecture */
);
- res_nrg_Q15 = silk_ADD_POS_SAT32( res_nrg_Q15, res_nrg_Q15_subfr );
- rate_dist_Q7 = silk_ADD_POS_SAT32( rate_dist_Q7, rate_dist_Q7_subfr );
+ rate_dist_Q14 = silk_ADD_POS_SAT32( rate_dist_Q14, rate_dist_Q14_subfr );
sum_log_gain_tmp_Q7 = silk_max(0, sum_log_gain_tmp_Q7
+ silk_lin2log( gain_safety + gain_Q7 ) - SILK_FIX_CONST( 7, 7 ));
- XX_Q17_ptr += LTP_ORDER * LTP_ORDER;
- xX_Q17_ptr += LTP_ORDER;
+ b_Q14_ptr += LTP_ORDER;
+ W_Q18_ptr += LTP_ORDER * LTP_ORDER;
}
- if( rate_dist_Q7 <= min_rate_dist_Q7 ) {
- min_rate_dist_Q7 = rate_dist_Q7;
+ /* Avoid never finding a codebook */
+ rate_dist_Q14 = silk_min( silk_int32_MAX - 1, rate_dist_Q14 );
+
+ if( rate_dist_Q14 < min_rate_dist_Q14 ) {
+ min_rate_dist_Q14 = rate_dist_Q14;
*periodicity_index = (opus_int8)k;
silk_memcpy( cbk_index, temp_idx, nb_subfr * sizeof( opus_int8 ) );
best_sum_log_gain_Q7 = sum_log_gain_tmp_Q7;
}
+
+ /* Break early in low-complexity mode if rate distortion is below threshold */
+ if( lowComplexity && ( rate_dist_Q14 < silk_LTP_gain_middle_avg_RD_Q14 ) ) {
+ break;
+ }
}
cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ *periodicity_index ];
@@ -120,13 +125,5 @@ void silk_quant_LTP_gains(
B_Q14[ j * LTP_ORDER + k ] = silk_LSHIFT( cbk_ptr_Q7[ cbk_index[ j ] * LTP_ORDER + k ], 7 );
}
}
-
- if( nb_subfr == 2 ) {
- res_nrg_Q15 = silk_RSHIFT32( res_nrg_Q15, 1 );
- } else {
- res_nrg_Q15 = silk_RSHIFT32( res_nrg_Q15, 2 );
- }
-
*sum_log_gain_Q7 = best_sum_log_gain_Q7;
- *pred_gain_dB_Q7 = (opus_int)silk_SMULBB( -3, silk_lin2log( res_nrg_Q15 ) - ( 15 << 7 ) );
}
diff --git a/thirdparty/opus/silk/resampler.c b/thirdparty/opus/silk/resampler.c
index 1f11e50891..374fbb3722 100644
--- a/thirdparty/opus/silk/resampler.c
+++ b/thirdparty/opus/silk/resampler.c
@@ -91,14 +91,14 @@ opus_int silk_resampler_init(
if( forEnc ) {
if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 && Fs_Hz_in != 24000 && Fs_Hz_in != 48000 ) ||
( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 ) ) {
- celt_assert( 0 );
+ silk_assert( 0 );
return -1;
}
S->inputDelay = delay_matrix_enc[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ];
} else {
if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 ) ||
( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 && Fs_Hz_out != 24000 && Fs_Hz_out != 48000 ) ) {
- celt_assert( 0 );
+ silk_assert( 0 );
return -1;
}
S->inputDelay = delay_matrix_dec[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ];
@@ -151,7 +151,7 @@ opus_int silk_resampler_init(
S->Coefs = silk_Resampler_1_6_COEFS;
} else {
/* None available */
- celt_assert( 0 );
+ silk_assert( 0 );
return -1;
}
} else {
@@ -181,9 +181,9 @@ opus_int silk_resampler(
opus_int nSamples;
/* Need at least 1 ms of input data */
- celt_assert( inLen >= S->Fs_in_kHz );
+ silk_assert( inLen >= S->Fs_in_kHz );
/* Delay can't exceed the 1 ms of buffering */
- celt_assert( S->inputDelay <= S->Fs_in_kHz );
+ silk_assert( S->inputDelay <= S->Fs_in_kHz );
nSamples = S->Fs_in_kHz - S->inputDelay;
diff --git a/thirdparty/opus/silk/resampler_down2.c b/thirdparty/opus/silk/resampler_down2.c
index 971d7bfd4a..cec3634640 100644
--- a/thirdparty/opus/silk/resampler_down2.c
+++ b/thirdparty/opus/silk/resampler_down2.c
@@ -43,8 +43,8 @@ void silk_resampler_down2(
opus_int32 k, len2 = silk_RSHIFT32( inLen, 1 );
opus_int32 in32, out32, Y, X;
- celt_assert( silk_resampler_down2_0 > 0 );
- celt_assert( silk_resampler_down2_1 < 0 );
+ silk_assert( silk_resampler_down2_0 > 0 );
+ silk_assert( silk_resampler_down2_1 < 0 );
/* Internal variables and state are in Q10 format */
for( k = 0; k < len2; k++ ) {
diff --git a/thirdparty/opus/silk/resampler_private_down_FIR.c b/thirdparty/opus/silk/resampler_private_down_FIR.c
index 3e8735a35a..783e42b356 100644
--- a/thirdparty/opus/silk/resampler_private_down_FIR.c
+++ b/thirdparty/opus/silk/resampler_private_down_FIR.c
@@ -136,7 +136,7 @@ static OPUS_INLINE opus_int16 *silk_resampler_private_down_FIR_INTERPOL(
}
break;
default:
- celt_assert( 0 );
+ silk_assert( 0 );
}
return out;
}
diff --git a/thirdparty/opus/silk/sort.c b/thirdparty/opus/silk/sort.c
index 4fba16f831..7187c9efb1 100644
--- a/thirdparty/opus/silk/sort.c
+++ b/thirdparty/opus/silk/sort.c
@@ -48,9 +48,9 @@ void silk_insertion_sort_increasing(
opus_int i, j;
/* Safety checks */
- celt_assert( K > 0 );
- celt_assert( L > 0 );
- celt_assert( L >= K );
+ silk_assert( K > 0 );
+ silk_assert( L > 0 );
+ silk_assert( L >= K );
/* Write start indices in index vector */
for( i = 0; i < K; i++ ) {
@@ -96,9 +96,9 @@ void silk_insertion_sort_decreasing_int16(
opus_int value;
/* Safety checks */
- celt_assert( K > 0 );
- celt_assert( L > 0 );
- celt_assert( L >= K );
+ silk_assert( K > 0 );
+ silk_assert( L > 0 );
+ silk_assert( L >= K );
/* Write start indices in index vector */
for( i = 0; i < K; i++ ) {
@@ -141,7 +141,7 @@ void silk_insertion_sort_increasing_all_values_int16(
opus_int i, j;
/* Safety checks */
- celt_assert( L > 0 );
+ silk_assert( L > 0 );
/* Sort vector elements by value, increasing order */
for( i = 1; i < L; i++ ) {
diff --git a/thirdparty/opus/silk/stereo_LR_to_MS.c b/thirdparty/opus/silk/stereo_LR_to_MS.c
index c8226663c8..dda0298de2 100644
--- a/thirdparty/opus/silk/stereo_LR_to_MS.c
+++ b/thirdparty/opus/silk/stereo_LR_to_MS.c
@@ -109,7 +109,7 @@ void silk_stereo_LR_to_MS(
if( total_rate_bps < 1 ) {
total_rate_bps = 1;
}
- min_mid_rate_bps = silk_SMLABB( 2000, fs_kHz, 600 );
+ min_mid_rate_bps = silk_SMLABB( 2000, fs_kHz, 900 );
silk_assert( min_mid_rate_bps < 32767 );
/* Default bitrate distribution: 8 parts for Mid and (5+3*frac) parts for Side. so: mid_rate = ( 8 / ( 13 + 3 * frac ) ) * total_ rate */
frac_3_Q16 = silk_MUL( 3, frac_Q16 );
diff --git a/thirdparty/opus/silk/stereo_encode_pred.c b/thirdparty/opus/silk/stereo_encode_pred.c
index 03becb6736..e6dd195066 100644
--- a/thirdparty/opus/silk/stereo_encode_pred.c
+++ b/thirdparty/opus/silk/stereo_encode_pred.c
@@ -41,11 +41,11 @@ void silk_stereo_encode_pred(
/* Entropy coding */
n = 5 * ix[ 0 ][ 2 ] + ix[ 1 ][ 2 ];
- celt_assert( n < 25 );
+ silk_assert( n < 25 );
ec_enc_icdf( psRangeEnc, n, silk_stereo_pred_joint_iCDF, 8 );
for( n = 0; n < 2; n++ ) {
- celt_assert( ix[ n ][ 0 ] < 3 );
- celt_assert( ix[ n ][ 1 ] < STEREO_QUANT_SUB_STEPS );
+ silk_assert( ix[ n ][ 0 ] < 3 );
+ silk_assert( ix[ n ][ 1 ] < STEREO_QUANT_SUB_STEPS );
ec_enc_icdf( psRangeEnc, ix[ n ][ 0 ], silk_uniform3_iCDF, 8 );
ec_enc_icdf( psRangeEnc, ix[ n ][ 1 ], silk_uniform5_iCDF, 8 );
}
diff --git a/thirdparty/opus/silk/structs.h b/thirdparty/opus/silk/structs.h
index 3380c757b2..827829dc6f 100644
--- a/thirdparty/opus/silk/structs.h
+++ b/thirdparty/opus/silk/structs.h
@@ -48,7 +48,6 @@ typedef struct {
opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ];
opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ];
opus_int32 sLF_AR_shp_Q14;
- opus_int32 sDiff_shp_Q14;
opus_int lagPrev;
opus_int sLTP_buf_idx;
opus_int sLTP_shp_buf_idx;
@@ -78,7 +77,6 @@ typedef struct {
opus_int32 In_LP_State[ 2 ]; /* Low pass filter state */
opus_int32 transition_frame_no; /* Counter which is mapped to a cut-off frequency */
opus_int mode; /* Operating mode, <0: switch down, >0: switch up; 0: do nothing */
- opus_int32 saved_fs_kHz; /* If non-zero, holds the last sampling rate before a bandwidth switching reset. */
} silk_LP_state;
/* Structure containing NLSF codebook */
@@ -88,7 +86,6 @@ typedef struct {
const opus_int16 quantStepSize_Q16;
const opus_int16 invQuantStepSize_Q6;
const opus_uint8 *CB1_NLSF_Q8;
- const opus_int16 *CB1_Wght_Q9;
const opus_uint8 *CB1_iCDF;
const opus_uint8 *pred_Q8;
const opus_uint8 *ec_sel;
@@ -172,6 +169,8 @@ typedef struct {
opus_int pitchEstimationComplexity; /* Complexity level for pitch estimator */
opus_int pitchEstimationLPCOrder; /* Whitening filter order for pitch estimator */
opus_int32 pitchEstimationThreshold_Q16; /* Threshold for pitch estimator */
+ opus_int LTPQuantLowComplexity; /* Flag for low complexity LTP quantization */
+ opus_int mu_LTP_Q9; /* Rate-distortion tradeoff in LTP quantization */
opus_int32 sum_log_gain_Q7; /* Cumulative max prediction gain */
opus_int NLSF_MSVQ_Survivors; /* Number of survivors in NLSF MSVQ */
opus_int first_frame_after_reset; /* Flag for deactivating NLSF interpolation, pitch prediction */
@@ -302,7 +301,6 @@ typedef struct {
/* Stuff used for PLC */
opus_int lossCnt;
opus_int prevSignalType;
- int arch;
silk_PLC_struct sPLC;
diff --git a/thirdparty/opus/silk/sum_sqr_shift.c b/thirdparty/opus/silk/sum_sqr_shift.c
index 4fd0c3d7d5..129df191d8 100644
--- a/thirdparty/opus/silk/sum_sqr_shift.c
+++ b/thirdparty/opus/silk/sum_sqr_shift.c
@@ -41,40 +41,43 @@ void silk_sum_sqr_shift(
)
{
opus_int i, shft;
- opus_uint32 nrg_tmp;
- opus_int32 nrg;
+ opus_int32 nrg_tmp, nrg;
- /* Do a first run with the maximum shift we could have. */
- shft = 31-silk_CLZ32(len);
- /* Let's be conservative with rounding and start with nrg=len. */
- nrg = len;
- for( i = 0; i < len - 1; i += 2 ) {
- nrg_tmp = silk_SMULBB( x[ i ], x[ i ] );
- nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] );
- nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft );
+ nrg = 0;
+ shft = 0;
+ len--;
+ for( i = 0; i < len; i += 2 ) {
+ nrg = silk_SMLABB_ovflw( nrg, x[ i ], x[ i ] );
+ nrg = silk_SMLABB_ovflw( nrg, x[ i + 1 ], x[ i + 1 ] );
+ if( nrg < 0 ) {
+ /* Scale down */
+ nrg = (opus_int32)silk_RSHIFT_uint( (opus_uint32)nrg, 2 );
+ shft = 2;
+ i+=2;
+ break;
+ }
}
- if( i < len ) {
- /* One sample left to process */
- nrg_tmp = silk_SMULBB( x[ i ], x[ i ] );
- nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft );
- }
- silk_assert( nrg >= 0 );
- /* Make sure the result will fit in a 32-bit signed integer with two bits
- of headroom. */
- shft = silk_max_32(0, shft+3 - silk_CLZ32(nrg));
- nrg = 0;
- for( i = 0 ; i < len - 1; i += 2 ) {
+ for( ; i < len; i += 2 ) {
nrg_tmp = silk_SMULBB( x[ i ], x[ i ] );
nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] );
- nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft );
+ nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, (opus_uint32)nrg_tmp, shft );
+ if( nrg < 0 ) {
+ /* Scale down */
+ nrg = (opus_int32)silk_RSHIFT_uint( (opus_uint32)nrg, 2 );
+ shft += 2;
+ }
}
- if( i < len ) {
+ if( i == len ) {
/* One sample left to process */
nrg_tmp = silk_SMULBB( x[ i ], x[ i ] );
nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft );
}
- silk_assert( nrg >= 0 );
+ /* Make sure to have at least one extra leading zero (two leading zeros in total) */
+ if( nrg & 0xC0000000 ) {
+ nrg = silk_RSHIFT_uint( (opus_uint32)nrg, 2 );
+ shft += 2;
+ }
/* Output arguments */
*shift = shft;
diff --git a/thirdparty/opus/silk/tables.h b/thirdparty/opus/silk/tables.h
index 95230c451a..7fea6fda39 100644
--- a/thirdparty/opus/silk/tables.h
+++ b/thirdparty/opus/silk/tables.h
@@ -76,8 +76,10 @@ extern const opus_uint8 silk_NLSF_EXT_iCDF[ 7 ];
extern const opus_uint8 silk_LTP_per_index_iCDF[ 3 ]; /* 3 */
extern const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[ NB_LTP_CBKS ]; /* 3 */
extern const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[ NB_LTP_CBKS ]; /* 3 */
+extern const opus_int16 silk_LTP_gain_middle_avg_RD_Q14;
extern const opus_int8 * const silk_LTP_vq_ptrs_Q7[ NB_LTP_CBKS ]; /* 168 */
extern const opus_uint8 * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS];
+
extern const opus_int8 silk_LTP_vq_sizes[ NB_LTP_CBKS ]; /* 3 */
extern const opus_uint8 silk_LTPscale_iCDF[ 3 ]; /* 4 */
@@ -97,6 +99,12 @@ extern const opus_uint8 silk_NLSF_interpolation_factor_iCDF[ 5 ];
extern const silk_NLSF_CB_struct silk_NLSF_CB_WB; /* 1040 */
extern const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB; /* 728 */
+/* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */
+extern const opus_int32 silk_TargetRate_table_NB[ TARGET_RATE_TAB_SZ ]; /* 32 */
+extern const opus_int32 silk_TargetRate_table_MB[ TARGET_RATE_TAB_SZ ]; /* 32 */
+extern const opus_int32 silk_TargetRate_table_WB[ TARGET_RATE_TAB_SZ ]; /* 32 */
+extern const opus_int16 silk_SNR_table_Q1[ TARGET_RATE_TAB_SZ ]; /* 32 */
+
/* Quantization offsets */
extern const opus_int16 silk_Quantization_Offsets_Q10[ 2 ][ 2 ]; /* 8 */
diff --git a/thirdparty/opus/silk/tables_LTP.c b/thirdparty/opus/silk/tables_LTP.c
index 5e12c8643e..0e6a0254d5 100644
--- a/thirdparty/opus/silk/tables_LTP.c
+++ b/thirdparty/opus/silk/tables_LTP.c
@@ -51,6 +51,8 @@ static const opus_uint8 silk_LTP_gain_iCDF_2[32] = {
24, 20, 16, 12, 9, 5, 2, 0
};
+const opus_int16 silk_LTP_gain_middle_avg_RD_Q14 = 12304;
+
static const opus_uint8 silk_LTP_gain_BITS_Q5_0[8] = {
15, 131, 138, 138, 155, 155, 173, 173
};
diff --git a/thirdparty/opus/silk/tables_NLSF_CB_NB_MB.c b/thirdparty/opus/silk/tables_NLSF_CB_NB_MB.c
index 195d5b95bd..8c59d207aa 100644
--- a/thirdparty/opus/silk/tables_NLSF_CB_NB_MB.c
+++ b/thirdparty/opus/silk/tables_NLSF_CB_NB_MB.c
@@ -74,41 +74,6 @@ static const opus_uint8 silk_NLSF_CB1_NB_MB_Q8[ 320 ] = {
64, 84, 104, 118, 156, 177, 201, 230
};
-static const opus_int16 silk_NLSF_CB1_Wght_Q9[ 320 ] = {
- 2897, 2314, 2314, 2314, 2287, 2287, 2314, 2300, 2327, 2287,
- 2888, 2580, 2394, 2367, 2314, 2274, 2274, 2274, 2274, 2194,
- 2487, 2340, 2340, 2314, 2314, 2314, 2340, 2340, 2367, 2354,
- 3216, 2766, 2340, 2340, 2314, 2274, 2221, 2207, 2261, 2194,
- 2460, 2474, 2367, 2394, 2394, 2394, 2394, 2367, 2407, 2314,
- 3479, 3056, 2127, 2207, 2274, 2274, 2274, 2287, 2314, 2261,
- 3282, 3141, 2580, 2394, 2247, 2221, 2207, 2194, 2194, 2114,
- 4096, 3845, 2221, 2620, 2620, 2407, 2314, 2394, 2367, 2074,
- 3178, 3244, 2367, 2221, 2553, 2434, 2340, 2314, 2167, 2221,
- 3338, 3488, 2726, 2194, 2261, 2460, 2354, 2367, 2207, 2101,
- 2354, 2420, 2327, 2367, 2394, 2420, 2420, 2420, 2460, 2367,
- 3779, 3629, 2434, 2527, 2367, 2274, 2274, 2300, 2207, 2048,
- 3254, 3225, 2713, 2846, 2447, 2327, 2300, 2300, 2274, 2127,
- 3263, 3300, 2753, 2806, 2447, 2261, 2261, 2247, 2127, 2101,
- 2873, 2981, 2633, 2367, 2407, 2354, 2194, 2247, 2247, 2114,
- 3225, 3197, 2633, 2580, 2274, 2181, 2247, 2221, 2221, 2141,
- 3178, 3310, 2740, 2407, 2274, 2274, 2274, 2287, 2194, 2114,
- 3141, 3272, 2460, 2061, 2287, 2500, 2367, 2487, 2434, 2181,
- 3507, 3282, 2314, 2700, 2647, 2474, 2367, 2394, 2340, 2127,
- 3423, 3535, 3038, 3056, 2300, 1950, 2221, 2274, 2274, 2274,
- 3404, 3366, 2087, 2687, 2873, 2354, 2420, 2274, 2474, 2540,
- 3760, 3488, 1950, 2660, 2897, 2527, 2394, 2367, 2460, 2261,
- 3028, 3272, 2740, 2888, 2740, 2154, 2127, 2287, 2234, 2247,
- 3695, 3657, 2025, 1969, 2660, 2700, 2580, 2500, 2327, 2367,
- 3207, 3413, 2354, 2074, 2888, 2888, 2340, 2487, 2247, 2167,
- 3338, 3366, 2846, 2780, 2327, 2154, 2274, 2287, 2114, 2061,
- 2327, 2300, 2181, 2167, 2181, 2367, 2633, 2700, 2700, 2553,
- 2407, 2434, 2221, 2261, 2221, 2221, 2340, 2420, 2607, 2700,
- 3038, 3244, 2806, 2888, 2474, 2074, 2300, 2314, 2354, 2380,
- 2221, 2154, 2127, 2287, 2500, 2793, 2793, 2620, 2580, 2367,
- 3676, 3713, 2234, 1838, 2181, 2753, 2726, 2673, 2513, 2207,
- 2793, 3160, 2726, 2553, 2846, 2513, 2181, 2394, 2221, 2181
-};
-
static const opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = {
212, 178, 148, 129, 108, 96, 85, 82,
79, 77, 61, 59, 57, 56, 51, 49,
@@ -185,7 +150,6 @@ const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB =
SILK_FIX_CONST( 0.18, 16 ),
SILK_FIX_CONST( 1.0 / 0.18, 6 ),
silk_NLSF_CB1_NB_MB_Q8,
- silk_NLSF_CB1_Wght_Q9,
silk_NLSF_CB1_iCDF_NB_MB,
silk_NLSF_PRED_NB_MB_Q8,
silk_NLSF_CB2_SELECT_NB_MB,
diff --git a/thirdparty/opus/silk/tables_NLSF_CB_WB.c b/thirdparty/opus/silk/tables_NLSF_CB_WB.c
index 5cc9f57bff..50af87eb2e 100644
--- a/thirdparty/opus/silk/tables_NLSF_CB_WB.c
+++ b/thirdparty/opus/silk/tables_NLSF_CB_WB.c
@@ -98,41 +98,6 @@ static const opus_uint8 silk_NLSF_CB1_WB_Q8[ 512 ] = {
110, 119, 129, 141, 175, 198, 218, 237
};
-static const opus_int16 silk_NLSF_CB1_WB_Wght_Q9[ 512 ] = {
- 3657, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2925, 2963, 2963, 2925, 2846,
- 3216, 3085, 2972, 3056, 3056, 3010, 3010, 3010, 2963, 2963, 3010, 2972, 2888, 2846, 2846, 2726,
- 3920, 4014, 2981, 3207, 3207, 2934, 3056, 2846, 3122, 3244, 2925, 2846, 2620, 2553, 2780, 2925,
- 3516, 3197, 3010, 3103, 3019, 2888, 2925, 2925, 2925, 2925, 2888, 2888, 2888, 2888, 2888, 2753,
- 5054, 5054, 2934, 3573, 3385, 3056, 3085, 2793, 3160, 3160, 2972, 2846, 2513, 2540, 2753, 2888,
- 4428, 4149, 2700, 2753, 2972, 3010, 2925, 2846, 2981, 3019, 2925, 2925, 2925, 2925, 2888, 2726,
- 3620, 3019, 2972, 3056, 3056, 2873, 2806, 3056, 3216, 3047, 2981, 3291, 3291, 2981, 3310, 2991,
- 5227, 5014, 2540, 3338, 3526, 3385, 3197, 3094, 3376, 2981, 2700, 2647, 2687, 2793, 2846, 2673,
- 5081, 5174, 4615, 4428, 2460, 2897, 3047, 3207, 3169, 2687, 2740, 2888, 2846, 2793, 2846, 2700,
- 3122, 2888, 2963, 2925, 2925, 2925, 2925, 2963, 2963, 2963, 2963, 2925, 2925, 2963, 2963, 2963,
- 4202, 3207, 2981, 3103, 3010, 2888, 2888, 2925, 2972, 2873, 2916, 3019, 2972, 3010, 3197, 2873,
- 3760, 3760, 3244, 3103, 2981, 2888, 2925, 2888, 2972, 2934, 2793, 2793, 2846, 2888, 2888, 2660,
- 3854, 4014, 3207, 3122, 3244, 2934, 3047, 2963, 2963, 3085, 2846, 2793, 2793, 2793, 2793, 2580,
- 3845, 4080, 3357, 3516, 3094, 2740, 3010, 2934, 3122, 3085, 2846, 2846, 2647, 2647, 2846, 2806,
- 5147, 4894, 3225, 3845, 3441, 3169, 2897, 3413, 3451, 2700, 2580, 2673, 2740, 2846, 2806, 2753,
- 4109, 3789, 3291, 3160, 2925, 2888, 2888, 2925, 2793, 2740, 2793, 2740, 2793, 2846, 2888, 2806,
- 5081, 5054, 3047, 3545, 3244, 3056, 3085, 2944, 3103, 2897, 2740, 2740, 2740, 2846, 2793, 2620,
- 4309, 4309, 2860, 2527, 3207, 3376, 3376, 3075, 3075, 3376, 3056, 2846, 2647, 2580, 2726, 2753,
- 3056, 2916, 2806, 2888, 2740, 2687, 2897, 3103, 3150, 3150, 3216, 3169, 3056, 3010, 2963, 2846,
- 4375, 3882, 2925, 2888, 2846, 2888, 2846, 2846, 2888, 2888, 2888, 2846, 2888, 2925, 2888, 2846,
- 2981, 2916, 2916, 2981, 2981, 3056, 3122, 3216, 3150, 3056, 3010, 2972, 2972, 2972, 2925, 2740,
- 4229, 4149, 3310, 3347, 2925, 2963, 2888, 2981, 2981, 2846, 2793, 2740, 2846, 2846, 2846, 2793,
- 4080, 4014, 3103, 3010, 2925, 2925, 2925, 2888, 2925, 2925, 2846, 2846, 2846, 2793, 2888, 2780,
- 4615, 4575, 3169, 3441, 3207, 2981, 2897, 3038, 3122, 2740, 2687, 2687, 2687, 2740, 2793, 2700,
- 4149, 4269, 3789, 3657, 2726, 2780, 2888, 2888, 3010, 2972, 2925, 2846, 2687, 2687, 2793, 2888,
- 4215, 3554, 2753, 2846, 2846, 2888, 2888, 2888, 2925, 2925, 2888, 2925, 2925, 2925, 2963, 2888,
- 5174, 4921, 2261, 3432, 3789, 3479, 3347, 2846, 3310, 3479, 3150, 2897, 2460, 2487, 2753, 2925,
- 3451, 3685, 3122, 3197, 3357, 3047, 3207, 3207, 2981, 3216, 3085, 2925, 2925, 2687, 2540, 2434,
- 2981, 3010, 2793, 2793, 2740, 2793, 2846, 2972, 3056, 3103, 3150, 3150, 3150, 3103, 3010, 3010,
- 2944, 2873, 2687, 2726, 2780, 3010, 3432, 3545, 3357, 3244, 3056, 3010, 2963, 2925, 2888, 2846,
- 3019, 2944, 2897, 3010, 3010, 2972, 3019, 3103, 3056, 3056, 3010, 2888, 2846, 2925, 2925, 2888,
- 3920, 3967, 3010, 3197, 3357, 3216, 3291, 3291, 3479, 3704, 3441, 2726, 2181, 2460, 2580, 2607
-};
-
static const opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = {
225, 204, 201, 184, 183, 175, 158, 154,
153, 135, 119, 115, 113, 110, 109, 99,
@@ -223,7 +188,6 @@ const silk_NLSF_CB_struct silk_NLSF_CB_WB =
SILK_FIX_CONST( 0.15, 16 ),
SILK_FIX_CONST( 1.0 / 0.15, 6 ),
silk_NLSF_CB1_WB_Q8,
- silk_NLSF_CB1_WB_Wght_Q9,
silk_NLSF_CB1_iCDF_WB,
silk_NLSF_PRED_WB_Q8,
silk_NLSF_CB2_SELECT_WB,
diff --git a/thirdparty/opus/silk/tables_other.c b/thirdparty/opus/silk/tables_other.c
index e34d90777b..398686bf26 100644
--- a/thirdparty/opus/silk/tables_other.c
+++ b/thirdparty/opus/silk/tables_other.c
@@ -38,6 +38,20 @@ extern "C"
{
#endif
+/* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */
+const opus_int32 silk_TargetRate_table_NB[ TARGET_RATE_TAB_SZ ] = {
+ 0, 8000, 9400, 11500, 13500, 17500, 25000, MAX_TARGET_RATE_BPS
+};
+const opus_int32 silk_TargetRate_table_MB[ TARGET_RATE_TAB_SZ ] = {
+ 0, 9000, 12000, 14500, 18500, 24500, 35500, MAX_TARGET_RATE_BPS
+};
+const opus_int32 silk_TargetRate_table_WB[ TARGET_RATE_TAB_SZ ] = {
+ 0, 10500, 14000, 17000, 21500, 28500, 42000, MAX_TARGET_RATE_BPS
+};
+const opus_int16 silk_SNR_table_Q1[ TARGET_RATE_TAB_SZ ] = {
+ 18, 29, 38, 40, 46, 52, 62, 84
+};
+
/* Tables for stereo predictor coding */
const opus_int16 silk_stereo_pred_quant_Q13[ STEREO_QUANT_TAB_SIZE ] = {
-13732, -10050, -8266, -7526, -6500, -5000, -2950, -820,
diff --git a/thirdparty/opus/silk/tuning_parameters.h b/thirdparty/opus/silk/tuning_parameters.h
index d70275fd8f..5b8f404235 100644
--- a/thirdparty/opus/silk/tuning_parameters.h
+++ b/thirdparty/opus/silk/tuning_parameters.h
@@ -53,12 +53,19 @@ extern "C"
/* LPC analysis regularization */
#define FIND_LPC_COND_FAC 1e-5f
+/* LTP analysis defines */
+#define FIND_LTP_COND_FAC 1e-5f
+#define LTP_DAMPING 0.05f
+#define LTP_SMOOTHING 0.1f
+
+/* LTP quantization settings */
+#define MU_LTP_QUANT_NB 0.03f
+#define MU_LTP_QUANT_MB 0.025f
+#define MU_LTP_QUANT_WB 0.02f
+
/* Max cumulative LTP gain */
#define MAX_SUM_LOG_GAIN_DB 250.0f
-/* LTP analysis defines */
-#define LTP_CORR_INV_MAX 0.03f
-
/***********************/
/* High pass filtering */
/***********************/
@@ -96,16 +103,25 @@ extern "C"
#define SPARSE_SNR_INCR_dB 2.0f
/* threshold for sparseness measure above which to use lower quantization offset during unvoiced */
-#define ENERGY_VARIATION_THRESHOLD_QNT_OFFSET 0.6f
+#define SPARSENESS_THRESHOLD_QNT_OFFSET 0.75f
/* warping control */
#define WARPING_MULTIPLIER 0.015f
/* fraction added to first autocorrelation value */
-#define SHAPE_WHITE_NOISE_FRACTION 3e-5f
+#define SHAPE_WHITE_NOISE_FRACTION 5e-5f
/* noise shaping filter chirp factor */
-#define BANDWIDTH_EXPANSION 0.94f
+#define BANDWIDTH_EXPANSION 0.95f
+
+/* difference between chirp factors for analysis and synthesis noise shaping filters at low bitrates */
+#define LOW_RATE_BANDWIDTH_EXPANSION_DELTA 0.01f
+
+/* extra harmonic boosting (signal shaping) at low bitrates */
+#define LOW_RATE_HARMONIC_BOOST 0.1f
+
+/* extra harmonic boosting (signal shaping) for noisy input signals */
+#define LOW_INPUT_QUALITY_HARMONIC_BOOST 0.1f
/* harmonic noise shaping */
#define HARMONIC_SHAPING 0.3f
diff --git a/thirdparty/opus/silk/x86/NSQ_del_dec_sse4_1.c b/thirdparty/opus/silk/x86/NSQ_del_dec_sse.c
index 2c75ede2dd..21d4a8bc1e 100644
--- a/thirdparty/opus/silk/x86/NSQ_del_dec_sse4_1.c
+++ b/thirdparty/opus/silk/x86/NSQ_del_dec_sse.c
@@ -107,12 +107,12 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1(
opus_int predictLPCOrder, /* I Prediction filter order */
opus_int warping_Q16, /* I */
opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
- opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
+ opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */
opus_int decisionDelay /* I */
);
void silk_NSQ_del_dec_sse4_1(
- const silk_encoder_state *psEncC, /* I Encoder State */
+ const silk_encoder_state *psEncC, /* I/O Encoder State */
silk_nsq_state *NSQ, /* I/O NSQ state */
SideInfoIndices *psIndices, /* I/O Quantization Indices */
const opus_int32 x_Q3[], /* I Prefiltered input signal */
@@ -234,8 +234,7 @@ void silk_NSQ_del_dec_sse4_1(
psDD = &psDelDec[ Winner_ind ];
last_smple_idx = smpl_buf_idx + decisionDelay;
for( i = 0; i < decisionDelay; i++ ) {
- last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY;
- if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY;
+ last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) );
@@ -247,7 +246,7 @@ void silk_NSQ_del_dec_sse4_1(
/* Rewhiten with new A coefs */
start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
- celt_assert( start_idx > 0 );
+ silk_assert( start_idx > 0 );
silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
@@ -286,8 +285,7 @@ void silk_NSQ_del_dec_sse4_1(
last_smple_idx = smpl_buf_idx + decisionDelay;
Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 );
for( i = 0; i < decisionDelay; i++ ) {
- last_smple_idx = ( last_smple_idx - 1 ) % DECISION_DELAY;
- if( last_smple_idx < 0 ) last_smple_idx += DECISION_DELAY;
+ last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK;
pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 );
pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND(
silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) );
@@ -301,6 +299,7 @@ void silk_NSQ_del_dec_sse4_1(
NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
/* Save quantized speech signal */
+ /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[psEncC->ltp_mem_length], psEncC->frame_length * sizeof( opus_int16 ) ) */
silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
RESTORE_STACK;
@@ -334,7 +333,7 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1(
opus_int predictLPCOrder, /* I Prediction filter order */
opus_int warping_Q16, /* I */
opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
- opus_int *smpl_buf_idx, /* I/O Index to newest samples in buffers */
+ opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */
opus_int decisionDelay /* I */
)
{
@@ -353,7 +352,7 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1(
__m128i b_Q12_0123, b_sr_Q12_0123;
SAVE_STACK;
- celt_assert( nStatesDelayedDecision > 0 );
+ silk_assert( nStatesDelayedDecision > 0 );
ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair );
shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
@@ -639,9 +638,8 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec_sse4_1(
psSS[ 1 ].xq_Q14 = xq_Q14;
}
}
- *smpl_buf_idx = ( *smpl_buf_idx - 1 ) % DECISION_DELAY;
- if( *smpl_buf_idx < 0 ) *smpl_buf_idx += DECISION_DELAY;
- last_smple_idx = ( *smpl_buf_idx + decisionDelay ) % DECISION_DELAY;
+ *smpl_buf_idx = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK; /* Index to newest samples */
+ last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK; /* Index to decisionDelay old samples */
/* Find winner */
RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10;
diff --git a/thirdparty/opus/silk/x86/NSQ_sse4_1.c b/thirdparty/opus/silk/x86/NSQ_sse.c
index b0315e35fc..bb3c5f1955 100644
--- a/thirdparty/opus/silk/x86/NSQ_sse4_1.c
+++ b/thirdparty/opus/silk/x86/NSQ_sse.c
@@ -71,7 +71,7 @@ static OPUS_INLINE void silk_noise_shape_quantizer_10_16_sse4_1(
);
void silk_NSQ_sse4_1(
- const silk_encoder_state *psEncC, /* I Encoder State */
+ const silk_encoder_state *psEncC, /* I/O Encoder State */
silk_nsq_state *NSQ, /* I/O NSQ state */
SideInfoIndices *psIndices, /* I/O Quantization Indices */
const opus_int32 x_Q3[], /* I Prefiltered input signal */
@@ -199,7 +199,7 @@ void silk_NSQ_sse4_1(
if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) {
/* Rewhiten with new A coefs */
start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2;
- celt_assert( start_idx > 0 );
+ silk_assert( start_idx > 0 );
silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ],
A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder, psEncC->arch );
@@ -233,6 +233,7 @@ void silk_NSQ_sse4_1(
NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ];
/* Save quantized speech and noise shaping signals */
+ /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[ psEncC->ltp_mem_length ], psEncC->frame_length * sizeof( opus_int16 ) ) */
silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) );
silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) );
RESTORE_STACK;
diff --git a/thirdparty/opus/silk/x86/VAD_sse4_1.c b/thirdparty/opus/silk/x86/VAD_sse.c
index d02ddf4ad0..4e90f4410d 100644
--- a/thirdparty/opus/silk/x86/VAD_sse4_1.c
+++ b/thirdparty/opus/silk/x86/VAD_sse.c
@@ -65,9 +65,9 @@ opus_int silk_VAD_GetSA_Q8_sse4_1( /* O Return value, 0 if s
/* Safety checks */
silk_assert( VAD_N_BANDS == 4 );
- celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
- celt_assert( psEncC->frame_length <= 512 );
- celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
+ silk_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
+ silk_assert( psEncC->frame_length <= 512 );
+ silk_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
/***********************/
/* Filter and Decimate */
diff --git a/thirdparty/opus/silk/x86/VQ_WMat_EC_sse4_1.c b/thirdparty/opus/silk/x86/VQ_WMat_EC_sse.c
index 74d6c6d0ec..74d6c6d0ec 100644
--- a/thirdparty/opus/silk/x86/VQ_WMat_EC_sse4_1.c
+++ b/thirdparty/opus/silk/x86/VQ_WMat_EC_sse.c
diff --git a/thirdparty/opus/silk/x86/main_sse.h b/thirdparty/opus/silk/x86/main_sse.h
index 2f15d44869..d8d61310ed 100644
--- a/thirdparty/opus/silk/x86/main_sse.h
+++ b/thirdparty/opus/silk/x86/main_sse.h
@@ -34,7 +34,6 @@
# if defined(OPUS_X86_MAY_HAVE_SSE4_1)
-#if 0 /* FIXME: SSE disabled until silk_VQ_WMat_EC_sse4_1() gets updated. */
# define OVERRIDE_silk_VQ_WMat_EC
void silk_VQ_WMat_EC_sse4_1(
@@ -80,13 +79,11 @@ extern void (*const SILK_VQ_WMAT_EC_IMPL[OPUS_ARCHMASK + 1])(
mu_Q9, max_gain_Q7, L))
#endif
-#endif
-#if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */
# define OVERRIDE_silk_NSQ
void silk_NSQ_sse4_1(
- const silk_encoder_state *psEncC, /* I Encoder State */
+ const silk_encoder_state *psEncC, /* I/O Encoder State */
silk_nsq_state *NSQ, /* I/O NSQ state */
SideInfoIndices *psIndices, /* I/O Quantization Indices */
const opus_int32 x_Q3[], /* I Prefiltered input signal */
@@ -113,7 +110,7 @@ void silk_NSQ_sse4_1(
#else
extern void (*const SILK_NSQ_IMPL[OPUS_ARCHMASK + 1])(
- const silk_encoder_state *psEncC, /* I Encoder State */
+ const silk_encoder_state *psEncC, /* I/O Encoder State */
silk_nsq_state *NSQ, /* I/O NSQ state */
SideInfoIndices *psIndices, /* I/O Quantization Indices */
const opus_int32 x_Q3[], /* I Prefiltered input signal */
@@ -140,7 +137,7 @@ extern void (*const SILK_NSQ_IMPL[OPUS_ARCHMASK + 1])(
# define OVERRIDE_silk_NSQ_del_dec
void silk_NSQ_del_dec_sse4_1(
- const silk_encoder_state *psEncC, /* I Encoder State */
+ const silk_encoder_state *psEncC, /* I/O Encoder State */
silk_nsq_state *NSQ, /* I/O NSQ state */
SideInfoIndices *psIndices, /* I/O Quantization Indices */
const opus_int32 x_Q3[], /* I Prefiltered input signal */
@@ -167,7 +164,7 @@ void silk_NSQ_del_dec_sse4_1(
#else
extern void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])(
- const silk_encoder_state *psEncC, /* I Encoder State */
+ const silk_encoder_state *psEncC, /* I/O Encoder State */
silk_nsq_state *NSQ, /* I/O NSQ state */
SideInfoIndices *psIndices, /* I/O Quantization Indices */
const opus_int32 x_Q3[], /* I Prefiltered input signal */
@@ -190,7 +187,6 @@ extern void (*const SILK_NSQ_DEL_DEC_IMPL[OPUS_ARCHMASK + 1])(
HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, pitchL, Lambda_Q10, LTP_scale_Q14))
#endif
-#endif
void silk_noise_shape_quantizer(
silk_nsq_state *NSQ, /* I/O NSQ state */
@@ -242,6 +238,39 @@ extern opus_int (*const SILK_VAD_GETSA_Q8_IMPL[OPUS_ARCHMASK + 1])(
silk_encoder_state *psEnC,
const opus_int16 pIn[]);
+# define OVERRIDE_silk_warped_LPC_analysis_filter_FIX
+
+#endif
+
+void silk_warped_LPC_analysis_filter_FIX_sse4_1(
+ opus_int32 state[], /* I/O State [order + 1] */
+ opus_int32 res_Q2[], /* O Residual signal [length] */
+ const opus_int16 coef_Q13[], /* I Coefficients [order] */
+ const opus_int16 input[], /* I Input signal [length] */
+ const opus_int16 lambda_Q16, /* I Warping factor */
+ const opus_int length, /* I Length of input signal */
+ const opus_int order /* I Filter order (even) */
+);
+
+#if defined(OPUS_X86_PRESUME_SSE4_1)
+#define silk_warped_LPC_analysis_filter_FIX(state, res_Q2, coef_Q13, input, lambda_Q16, length, order, arch) \
+ ((void)(arch),silk_warped_LPC_analysis_filter_FIX_c(state, res_Q2, coef_Q13, input, lambda_Q16, length, order))
+
+#else
+
+extern void (*const SILK_WARPED_LPC_ANALYSIS_FILTER_FIX_IMPL[OPUS_ARCHMASK + 1])(
+ opus_int32 state[], /* I/O State [order + 1] */
+ opus_int32 res_Q2[], /* O Residual signal [length] */
+ const opus_int16 coef_Q13[], /* I Coefficients [order] */
+ const opus_int16 input[], /* I Input signal [length] */
+ const opus_int16 lambda_Q16, /* I Warping factor */
+ const opus_int length, /* I Length of input signal */
+ const opus_int order /* I Filter order (even) */
+);
+
+# define silk_warped_LPC_analysis_filter_FIX(state, res_Q2, coef_Q13, input, lambda_Q16, length, order, arch) \
+ ((*SILK_WARPED_LPC_ANALYSIS_FILTER_FIX_IMPL[(arch) & OPUS_ARCHMASK])(state, res_Q2, coef_Q13, input, lambda_Q16, length, order))
+
#endif
# endif
diff --git a/thirdparty/opus/silk/x86/x86_silk_map.c b/thirdparty/opus/silk/x86/x86_silk_map.c
index 32dcc3cab7..818841f2c1 100644
--- a/thirdparty/opus/silk/x86/x86_silk_map.c
+++ b/thirdparty/opus/silk/x86/x86_silk_map.c
@@ -66,9 +66,8 @@ opus_int (*const SILK_VAD_GETSA_Q8_IMPL[ OPUS_ARCHMASK + 1 ] )(
MAY_HAVE_SSE4_1( silk_VAD_GetSA_Q8 ) /* avx */
};
-#if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */
void (*const SILK_NSQ_IMPL[ OPUS_ARCHMASK + 1 ] )(
- const silk_encoder_state *psEncC, /* I Encoder State */
+ const silk_encoder_state *psEncC, /* I/O Encoder State */
silk_nsq_state *NSQ, /* I/O NSQ state */
SideInfoIndices *psIndices, /* I/O Quantization Indices */
const opus_int32 x_Q3[], /* I Prefiltered input signal */
@@ -90,9 +89,7 @@ void (*const SILK_NSQ_IMPL[ OPUS_ARCHMASK + 1 ] )(
MAY_HAVE_SSE4_1( silk_NSQ ), /* sse4.1 */
MAY_HAVE_SSE4_1( silk_NSQ ) /* avx */
};
-#endif
-#if 0 /* FIXME: SSE disabled until silk_VQ_WMat_EC_sse4_1() gets updated. */
void (*const SILK_VQ_WMAT_EC_IMPL[ OPUS_ARCHMASK + 1 ] )(
opus_int8 *ind, /* O index of best codebook vector */
opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */
@@ -112,11 +109,9 @@ void (*const SILK_VQ_WMAT_EC_IMPL[ OPUS_ARCHMASK + 1 ] )(
MAY_HAVE_SSE4_1( silk_VQ_WMat_EC ), /* sse4.1 */
MAY_HAVE_SSE4_1( silk_VQ_WMat_EC ) /* avx */
};
-#endif
-#if 0 /* FIXME: SSE disabled until the NSQ code gets updated. */
void (*const SILK_NSQ_DEL_DEC_IMPL[ OPUS_ARCHMASK + 1 ] )(
- const silk_encoder_state *psEncC, /* I Encoder State */
+ const silk_encoder_state *psEncC, /* I/O Encoder State */
silk_nsq_state *NSQ, /* I/O NSQ state */
SideInfoIndices *psIndices, /* I/O Quantization Indices */
const opus_int32 x_Q3[], /* I Prefiltered input signal */
@@ -138,10 +133,25 @@ void (*const SILK_NSQ_DEL_DEC_IMPL[ OPUS_ARCHMASK + 1 ] )(
MAY_HAVE_SSE4_1( silk_NSQ_del_dec ), /* sse4.1 */
MAY_HAVE_SSE4_1( silk_NSQ_del_dec ) /* avx */
};
-#endif
#if defined(FIXED_POINT)
+void (*const SILK_WARPED_LPC_ANALYSIS_FILTER_FIX_IMPL[ OPUS_ARCHMASK + 1 ] )(
+ opus_int32 state[], /* I/O State [order + 1] */
+ opus_int32 res_Q2[], /* O Residual signal [length] */
+ const opus_int16 coef_Q13[], /* I Coefficients [order] */
+ const opus_int16 input[], /* I Input signal [length] */
+ const opus_int16 lambda_Q16, /* I Warping factor */
+ const opus_int length, /* I Length of input signal */
+ const opus_int order /* I Filter order (even) */
+) = {
+ silk_warped_LPC_analysis_filter_FIX_c, /* non-sse */
+ silk_warped_LPC_analysis_filter_FIX_c,
+ silk_warped_LPC_analysis_filter_FIX_c,
+ MAY_HAVE_SSE4_1( silk_warped_LPC_analysis_filter_FIX ), /* sse4.1 */
+ MAY_HAVE_SSE4_1( silk_warped_LPC_analysis_filter_FIX ) /* avx */
+};
+
void (*const SILK_BURG_MODIFIED_IMPL[ OPUS_ARCHMASK + 1 ] )(
opus_int32 *res_nrg, /* O Residual energy */
opus_int *res_nrg_Q, /* O Residual energy Q value */
diff --git a/thirdparty/opus/stream.c b/thirdparty/opus/stream.c
index 6a85197a66..0238a6b31b 100644
--- a/thirdparty/opus/stream.c
+++ b/thirdparty/opus/stream.c
@@ -235,7 +235,8 @@ void *op_fopen(OpusFileCallbacks *_cb,const char *_path,const char *_mode){
fp=fopen(_path,_mode);
#else
fp=NULL;
- {
+ if(_path==NULL||_mode==NULL)errno=EINVAL;
+ else{
wchar_t *wpath;
wchar_t *wmode;
wpath=op_utf8_to_utf16(_path);
@@ -265,7 +266,8 @@ void *op_freopen(OpusFileCallbacks *_cb,const char *_path,const char *_mode,
fp=freopen(_path,_mode,(FILE *)_stream);
#else
fp=NULL;
- {
+ if(_path==NULL||_mode==NULL)errno=EINVAL;
+ else{
wchar_t *wpath;
wchar_t *wmode;
wpath=op_utf8_to_utf16(_path);