From 069a176d27fc5deca75d1bf951f5849ec8870c2b Mon Sep 17 00:00:00 2001 From: "Tom M." Date: Sun, 17 Nov 2024 18:07:57 +0100 Subject: [PATCH] Add regression test cases for IIR filter (#1429) --- test/CMakeLists.txt | 61 +++++++++++++ .../1415_the-nervous-filter/.gitattributes | 4 + .../The Nervous Filter trimmed.mid | Bin 0 -> 3018 bytes .../The Nervous Filter trimmed.ogg | 3 + .../The Nervous Filter.mid | Bin 0 -> 24450 bytes .../1417_filter-envelope-noise/.gitattributes | 5 + .../filter envelope-noise-Roland SC8820.flac | 3 + .../filter-envelope-noise-1345 reverted.flac | 3 + .../filter-envelope-noise-FluidSynth 2.4.flac | 3 + .../filter-envelope-noise.mid | 3 + .../.gitattributes | 1 + .../1424.mid | Bin 0 -> 69 bytes .../echo_drops.sf2 | 3 + .../1427_high-Q-note-cutoff/.gitattributes | 3 + .../fluidsynth_iir-tests.flac | 3 + .../high_Q_note_cutoff_test.mid | 3 + .../high_Q_note_cutoff_test.sf2 | 3 + .../iir_filter/interactive_biquad_lowpass.m | 86 ++++++++++++++++++ 18 files changed, 187 insertions(+) create mode 100644 test/manual/iir_filter/1415_the-nervous-filter/.gitattributes create mode 100644 test/manual/iir_filter/1415_the-nervous-filter/The Nervous Filter trimmed.mid create mode 100644 test/manual/iir_filter/1415_the-nervous-filter/The Nervous Filter trimmed.ogg create mode 100644 test/manual/iir_filter/1415_the-nervous-filter/The Nervous Filter.mid create mode 100644 test/manual/iir_filter/1417_filter-envelope-noise/.gitattributes create mode 100755 test/manual/iir_filter/1417_filter-envelope-noise/filter envelope-noise-Roland SC8820.flac create mode 100755 test/manual/iir_filter/1417_filter-envelope-noise/filter-envelope-noise-1345 reverted.flac create mode 100755 test/manual/iir_filter/1417_filter-envelope-noise/filter-envelope-noise-FluidSynth 2.4.flac create mode 100755 test/manual/iir_filter/1417_filter-envelope-noise/filter-envelope-noise.mid create mode 100644 test/manual/iir_filter/1424_clicks-on-ModEnv-FilterFc-change/.gitattributes create mode 100644 test/manual/iir_filter/1424_clicks-on-ModEnv-FilterFc-change/1424.mid create mode 100644 test/manual/iir_filter/1424_clicks-on-ModEnv-FilterFc-change/echo_drops.sf2 create mode 100644 test/manual/iir_filter/1427_high-Q-note-cutoff/.gitattributes create mode 100755 test/manual/iir_filter/1427_high-Q-note-cutoff/fluidsynth_iir-tests.flac create mode 100755 test/manual/iir_filter/1427_high-Q-note-cutoff/high_Q_note_cutoff_test.mid create mode 100755 test/manual/iir_filter/1427_high-Q-note-cutoff/high_Q_note_cutoff_test.sf2 create mode 100644 test/manual/iir_filter/interactive_biquad_lowpass.m diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a1b1b80e2..3ce90a3b2 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -43,3 +43,64 @@ if ( LIBSNDFILE_HASVORBIS ) ADD_FLUID_TEST(test_sf3_sfont_loading) ADD_FLUID_SF_DUMP_TEST(VintageDreamsWaves-v2.sf3) endif ( LIBSNDFILE_HASVORBIS ) + + +# Prepare the manual test suite down here +if(NOT DEFINED GENERAL_USER_GS2) + add_custom_target(check_manual + COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --red "In order to run the manual test suite, you need to set variable GENERAL_USER_GS2 to the path of the soundfont.") +else() + + set(IIR_FILTER_RENDER_DIR "${CMAKE_CURRENT_BINARY_DIR}/manual/iir_filter") + + if(LIBSNDFILE_SUPPORT) + set(FEXT "wav") + else() + set(FEXT "raw") + endif() + + # Add an empty pseudo target + add_custom_target(check_manual) + + add_custom_target(create_iir_dir + COMMAND ${CMAKE_COMMAND} -E make_directory ${IIR_FILTER_RENDER_DIR}) + + add_custom_target(render1415 + COMMAND fluidsynth -R 0 -C 0 -g 1 -F ${IIR_FILTER_RENDER_DIR}/1415_the-nervous-filter.${FEXT} "The Nervous Filter trimmed.mid" ${GENERAL_USER_GS2} + COMMENT "Rendering testfile of issue 1415" + DEPENDS fluidsynth create_iir_dir + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/manual/iir_filter/1415_the-nervous-filter/ + VERBATIM + ) + + add_custom_target(render1417 + COMMAND fluidsynth -R 0 -C 0 -g 1 -F ${IIR_FILTER_RENDER_DIR}/1417_filter-envelope-noise.${FEXT} filter-envelope-noise.mid ${GENERAL_USER_GS2} + COMMENT "Rendering testfile of issue 1417" + DEPENDS fluidsynth create_iir_dir + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/manual/iir_filter/1417_filter-envelope-noise/ + VERBATIM + ) + + add_custom_target(render1424 + COMMAND fluidsynth -R 0 -C 0 -g 1 -F ${IIR_FILTER_RENDER_DIR}/1424_clicks-on-ModEnv-FilterFc-change.${FEXT} 1424.mid echo_drops.sf2 + COMMENT "Rendering testfile of issue 1424" + DEPENDS fluidsynth create_iir_dir + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/manual/iir_filter/1424_clicks-on-ModEnv-FilterFc-change/ + VERBATIM + ) + + add_custom_target(render1427 + COMMAND fluidsynth -R 0 -C 0 -g 5 -F ${IIR_FILTER_RENDER_DIR}/1427_high-Q-note-cutoff.${FEXT} high_Q_note_cutoff_test.mid high_Q_note_cutoff_test.sf2 + COMMENT "Rendering testfile of issue 1427" + DEPENDS fluidsynth create_iir_dir + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/manual/iir_filter/1427_high-Q-note-cutoff/ + VERBATIM + ) + + # Add a dependency so that rendering targets depends on check_manual + add_dependencies(check_manual render1415) + add_dependencies(check_manual render1417) + add_dependencies(check_manual render1424) + add_dependencies(check_manual render1427) + +endif() diff --git a/test/manual/iir_filter/1415_the-nervous-filter/.gitattributes b/test/manual/iir_filter/1415_the-nervous-filter/.gitattributes new file mode 100644 index 000000000..6f4a0fef5 --- /dev/null +++ b/test/manual/iir_filter/1415_the-nervous-filter/.gitattributes @@ -0,0 +1,4 @@ +*.ogg filter=lfs diff=lfs merge=lfs -text +*.flac filter=lfs diff=lfs merge=lfs -text +*.wav filter=lfs diff=lfs merge=lfs -text +*.sf2 filter=lfs diff=lfs merge=lfs -text diff --git a/test/manual/iir_filter/1415_the-nervous-filter/The Nervous Filter trimmed.mid b/test/manual/iir_filter/1415_the-nervous-filter/The Nervous Filter trimmed.mid new file mode 100644 index 0000000000000000000000000000000000000000..a853ab088f1db261a242be84f2424fc38c7b6a6e GIT binary patch literal 3018 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 Z+*GeBEH6DJG!Y0CkozxDLGfWk{0}uV+J*oC literal 0 HcmV?d00001 diff --git a/test/manual/iir_filter/1417_filter-envelope-noise/.gitattributes b/test/manual/iir_filter/1417_filter-envelope-noise/.gitattributes new file mode 100644 index 000000000..6a0d372f1 --- /dev/null +++ b/test/manual/iir_filter/1417_filter-envelope-noise/.gitattributes @@ -0,0 +1,5 @@ +filter-envelope-noise-1345[[:space:]]reverted.flac filter=lfs diff=lfs merge=lfs -text +filter-envelope-noise-FluidSynth[[:space:]]2.4.flac filter=lfs diff=lfs merge=lfs -text +filter-envelope-noise.mid filter=lfs diff=lfs merge=lfs -text +*.flac filter=lfs diff=lfs merge=lfs -text +*.sf2 filter=lfs diff=lfs merge=lfs -text diff --git a/test/manual/iir_filter/1417_filter-envelope-noise/filter envelope-noise-Roland SC8820.flac b/test/manual/iir_filter/1417_filter-envelope-noise/filter envelope-noise-Roland SC8820.flac new file mode 100755 index 000000000..08322a487 --- /dev/null +++ b/test/manual/iir_filter/1417_filter-envelope-noise/filter envelope-noise-Roland SC8820.flac @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bea148b158f8932b8ca74d4e1246492115d01361c2192156c41820388cee6b9e +size 406106 diff --git a/test/manual/iir_filter/1417_filter-envelope-noise/filter-envelope-noise-1345 reverted.flac b/test/manual/iir_filter/1417_filter-envelope-noise/filter-envelope-noise-1345 reverted.flac new file mode 100755 index 000000000..3abd442cf --- /dev/null +++ b/test/manual/iir_filter/1417_filter-envelope-noise/filter-envelope-noise-1345 reverted.flac @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:62579bbbaab0ae97b873e666102741a72e05bd6322c4c8fb64dbc8062def73f1 +size 415449 diff --git a/test/manual/iir_filter/1417_filter-envelope-noise/filter-envelope-noise-FluidSynth 2.4.flac b/test/manual/iir_filter/1417_filter-envelope-noise/filter-envelope-noise-FluidSynth 2.4.flac new file mode 100755 index 000000000..79dd125fb --- /dev/null +++ b/test/manual/iir_filter/1417_filter-envelope-noise/filter-envelope-noise-FluidSynth 2.4.flac @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:415e71eff4668d1d6261a652cacee2ead5202637b40bd87f2a2cd3cf488c8a11 +size 472080 diff --git a/test/manual/iir_filter/1417_filter-envelope-noise/filter-envelope-noise.mid b/test/manual/iir_filter/1417_filter-envelope-noise/filter-envelope-noise.mid new file mode 100755 index 000000000..d0cae2d09 --- /dev/null +++ b/test/manual/iir_filter/1417_filter-envelope-noise/filter-envelope-noise.mid @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7423868b1028c96e2068176a9122a37f31113bed86002ff35091e9e80a2f497b +size 662 diff --git a/test/manual/iir_filter/1424_clicks-on-ModEnv-FilterFc-change/.gitattributes b/test/manual/iir_filter/1424_clicks-on-ModEnv-FilterFc-change/.gitattributes new file mode 100644 index 000000000..4be35afce --- /dev/null +++ b/test/manual/iir_filter/1424_clicks-on-ModEnv-FilterFc-change/.gitattributes @@ -0,0 +1 @@ +echo_drops.sf2 filter=lfs diff=lfs merge=lfs -text diff --git a/test/manual/iir_filter/1424_clicks-on-ModEnv-FilterFc-change/1424.mid b/test/manual/iir_filter/1424_clicks-on-ModEnv-FilterFc-change/1424.mid new file mode 100644 index 0000000000000000000000000000000000000000..a65a2ef36a70249b1190d193fefeb3aea094ef9e GIT binary patch literal 69 zcmeYb$w*;fU|<7cM#cu;kfLlLOP}FCGkZu;Vsf^EA;W<*hW~-g>z literal 0 HcmV?d00001 diff --git a/test/manual/iir_filter/1424_clicks-on-ModEnv-FilterFc-change/echo_drops.sf2 b/test/manual/iir_filter/1424_clicks-on-ModEnv-FilterFc-change/echo_drops.sf2 new file mode 100644 index 000000000..d018fcf1d --- /dev/null +++ b/test/manual/iir_filter/1424_clicks-on-ModEnv-FilterFc-change/echo_drops.sf2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:832763abda84a34030f272a608918cfb1e51a5cf52eccc9c88691f938827f725 +size 16835580 diff --git a/test/manual/iir_filter/1427_high-Q-note-cutoff/.gitattributes b/test/manual/iir_filter/1427_high-Q-note-cutoff/.gitattributes new file mode 100644 index 000000000..26fae88dd --- /dev/null +++ b/test/manual/iir_filter/1427_high-Q-note-cutoff/.gitattributes @@ -0,0 +1,3 @@ +high_Q_note_cutoff_test.sf2 filter=lfs diff=lfs merge=lfs -text +fluidsynth_iir-tests.flac filter=lfs diff=lfs merge=lfs -text +high_Q_note_cutoff_test.mid filter=lfs diff=lfs merge=lfs -text diff --git a/test/manual/iir_filter/1427_high-Q-note-cutoff/fluidsynth_iir-tests.flac b/test/manual/iir_filter/1427_high-Q-note-cutoff/fluidsynth_iir-tests.flac new file mode 100755 index 000000000..c74958755 --- /dev/null +++ b/test/manual/iir_filter/1427_high-Q-note-cutoff/fluidsynth_iir-tests.flac @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c198b5b32c3a8516f049c4e7e6cfee764b0855595fdda46750f92c614808d940 +size 224675 diff --git a/test/manual/iir_filter/1427_high-Q-note-cutoff/high_Q_note_cutoff_test.mid b/test/manual/iir_filter/1427_high-Q-note-cutoff/high_Q_note_cutoff_test.mid new file mode 100755 index 000000000..a882f2b7e --- /dev/null +++ b/test/manual/iir_filter/1427_high-Q-note-cutoff/high_Q_note_cutoff_test.mid @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d17f36961affa6f913a40398800b58872bc4a4d57019a8467dce72715950d8c8 +size 100 diff --git a/test/manual/iir_filter/1427_high-Q-note-cutoff/high_Q_note_cutoff_test.sf2 b/test/manual/iir_filter/1427_high-Q-note-cutoff/high_Q_note_cutoff_test.sf2 new file mode 100755 index 000000000..669d6d257 --- /dev/null +++ b/test/manual/iir_filter/1427_high-Q-note-cutoff/high_Q_note_cutoff_test.sf2 @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6636a4c9344de49c7b040017f1e0381c95150a2cf5d0f6a3b1178a154bbc7064 +size 235772 diff --git a/test/manual/iir_filter/interactive_biquad_lowpass.m b/test/manual/iir_filter/interactive_biquad_lowpass.m new file mode 100644 index 000000000..0c53abec7 --- /dev/null +++ b/test/manual/iir_filter/interactive_biquad_lowpass.m @@ -0,0 +1,86 @@ +# +# This Matlab script implements an interactive Bode plot of fluidsynth's IIR filter. +# To run it, just call interactive_biquad_lowpass() and a window will open up, allowing +# you to adjust the cutoff frequency and Q. +# Note that Q is in linear range here! +# +function interactive_biquad_lowpass() + % Initial values + f_c = 1000; % Initial cutoff frequency in Hz + Q = 0.707; % Initial quality factor + f_s = 48000; % Sampling frequency in Hz + + % Create the figure + hFig = figure('Name', 'Interactive Biquad Lowpass Filter', 'NumberTitle', 'off'); + + % Create axes for the magnitude and phase plots + hAxesMag = subplot(2, 1, 1, 'Parent', hFig); + hAxesPhase = subplot(2, 1, 2, 'Parent', hFig); + + % Plot the initial response + plot_response(hAxesMag, hAxesPhase, f_c, Q, f_s); + + % Create slider for cutoff frequency + uicontrol('Style', 'text', 'Position', [20 20 150 20], 'String', 'Cutoff Frequency (Hz)'); + hSliderFc = uicontrol('Style', 'slider', 'Min', 100, 'Max', 20000, 'Value', f_c, ... + 'Position', [20 40 300 20]); + hTextFc = uicontrol('Style', 'text', 'Position', [330 40 50 20], 'String', num2str(f_c)); + + % Create slider for quality factor + uicontrol('Style', 'text', 'Position', [20 80 150 20], 'String', 'Quality Factor (Q)'); + hSliderQ = uicontrol('Style', 'slider', 'Min', 0.1, 'Max', 100, 'Value', Q, ... + 'Position', [20 100 300 20]); + hTextQ = uicontrol('Style', 'text', 'Position', [330 100 50 20], 'String', num2str(Q)); + + % Add listeners for both sliders + addlistener(hSliderFc, 'Value', 'PreSet', @(src, event) update_plot(hAxesMag, hAxesPhase, hSliderFc, hSliderQ, f_s, hTextFc, hTextQ)); + addlistener(hSliderQ, 'Value', 'PreSet', @(src, event) update_plot(hAxesMag, hAxesPhase, hSliderFc, hSliderQ, f_s, hTextFc, hTextQ)); +end + +function update_plot(hAxesMag, hAxesPhase, hSliderFc, hSliderQ, f_s, hTextFc, hTextQ) + % Get the current values from the sliders + f_c = get(hSliderFc, 'Value'); + Q = get(hSliderQ, 'Value'); + + % Update the text displays + set(hTextFc, 'String', num2str(f_c, '%.1f')); % Display cutoff frequency + set(hTextQ, 'String', num2str(Q, '%.2f')); % Display quality factor + + % Update the plot with the new values + plot_response(hAxesMag, hAxesPhase, f_c, Q, f_s); +end + +function plot_response(hAxesMag, hAxesPhase, f_c, Q, f_s) + % Design the biquad lowpass filter + w0 = 2 * pi * f_c / f_s; + alpha = sin(w0) / (2 * Q); + + b0 = (1 - cos(w0)) / 2; + b1 = 1 - cos(w0); + b2 = (1 - cos(w0)) / 2; + a0 = 1 + alpha; + a1 = -2 * cos(w0); + a2 = 1 - alpha; + + % Normalize coefficients + b = [b0 / a0, b1 / a0, b2 / a0]; + a = [1, a1 / a0, a2 / a0]; + + % Compute the frequency response + [h, w] = freqz(b, a, 1024, f_s); + + % Clear the axes and plot the new response + cla(hAxesMag); + plot(hAxesMag, w, 20*log10(abs(h))); + title(hAxesMag, 'Magnitude Response'); + xlabel(hAxesMag, 'Frequency (Hz)'); + ylabel(hAxesMag, 'Magnitude (dB)'); + grid(hAxesMag, 'on'); + + cla(hAxesPhase); + plot(hAxesPhase, w, angle(h) * (180/pi)); + title(hAxesPhase, 'Phase Response'); + xlabel(hAxesPhase, 'Frequency (Hz)'); + ylabel(hAxesPhase, 'Phase (degrees)'); + grid(hAxesPhase, 'on'); +end