├── .github └── workflows │ ├── cmake_aax_prerelease.yml │ ├── cmake_full_test.yml │ ├── cmake_heavy_test.yml │ ├── cmake_nightly_release.yml │ ├── cmake_release.yml │ ├── sanitizer.yml │ ├── sync.yml │ └── sync_release.yml ├── .gitignore ├── .gitmodules ├── CHANGELOG.md ├── CMakeLists.txt ├── LICENSE.md ├── README.md ├── assets ├── font │ └── MiSansLatin-Medium.ttf ├── icons │ ├── auto-gain-compensation.svg │ ├── external-side.svg │ ├── fad-modsine.svg │ ├── fad-phase.svg │ ├── fad-powerswitch.svg │ ├── fad-preset-a.svg │ ├── fad-side.svg │ ├── fad-solo.svg │ ├── links-fill.svg │ ├── loop-left-line.svg │ ├── loudness-match.svg │ ├── pause-line.svg │ ├── play-fill.svg │ ├── relative.svg │ ├── right-to-bracket-solid.svg │ ├── save-line.svg │ ├── static-gain-compensation.svg │ ├── swap.svg │ └── xmark.svg ├── logo.svg └── zlaudio.svg ├── cmake-includes ├── Assets.cmake ├── Benchmarks.cmake ├── CHANGELOG.md ├── GitHubENV.cmake ├── GitVersion.cmake ├── JUCEDefaults.cmake ├── PamplejuceIPP.cmake ├── PamplejuceMacOS.cmake ├── PamplejuceVersion.cmake ├── README.md ├── Sanitizer.cmake ├── SharedCodeDefaults.cmake ├── Tests.cmake └── XcodePrettify.cmake ├── docs ├── logo.svg └── zlaudio.svg ├── licenses ├── JUCE_LICENSE.md ├── RemixIcon_License.txt ├── fft_juce_LICENSE.txt ├── fontaudio_LICENSE.txt ├── kfr_LICENSE.txt ├── nlopt_LICENSE.md └── pamplejuce_LICENSE.txt ├── modules └── .gitkeep ├── packaging ├── Readme.rtf ├── check_dependency.py ├── icon.icns ├── icon.ico ├── icon.png ├── packager_Windows.py └── packager_macOS.py ├── renovate.json └── source ├── PluginEditor.cpp ├── PluginEditor.hpp ├── PluginProcessor.cpp ├── PluginProcessor.hpp ├── dsp ├── audio_buffer │ ├── audio_buffer.hpp │ ├── fifo_audio_buffer.cpp │ ├── fifo_audio_buffer.hpp │ ├── fixed_audio_buffer.cpp │ └── fixed_audio_buffer.hpp ├── chore │ ├── chore.hpp │ ├── para_updater.hpp │ └── smoothed_value.hpp ├── chore_attach.cpp ├── chore_attach.hpp ├── compressor │ ├── compressor.hpp │ ├── computer │ │ ├── computer.hpp │ │ └── knee_computer.hpp │ ├── follower │ │ ├── follower.hpp │ │ └── ps_follower.hpp │ └── tracker │ │ ├── rms_tracker.hpp │ │ └── tracker.hpp ├── container │ ├── array.hpp │ ├── circular_buffer.hpp │ └── container.hpp ├── controller.cpp ├── controller.hpp ├── delay │ ├── delay.hpp │ ├── sample_delay.cpp │ └── sample_delay.hpp ├── dsp.hpp ├── dsp_definitions.hpp ├── eq_match │ ├── eq_match.hpp │ ├── eq_match_analyzer.cpp │ ├── eq_match_analyzer.hpp │ └── eq_match_optimizer.hpp ├── fft │ ├── fft.hpp │ ├── kfr_engine.hpp │ ├── kfr_import.hpp │ └── window_function.hpp ├── fft_analyzer │ ├── average_fft_analyzer.hpp │ ├── conflict_analyzer.cpp │ ├── conflict_analyzer.hpp │ ├── fft_analyzer.hpp │ ├── multiple_fft_analyzer.hpp │ ├── pre_post_fft_analyzer.cpp │ └── pre_post_fft_analyzer.hpp ├── filter │ ├── dynamic_filter │ │ ├── dynamic_filter.hpp │ │ └── dynamic_iir_filter.hpp │ ├── filter.hpp │ ├── filter_design │ │ └── filter_design.hpp │ ├── fir_correction │ │ ├── correction_helper.hpp │ │ ├── fir_base.hpp │ │ ├── fir_correction.hpp │ │ ├── fir_filter.hpp │ │ ├── mixed_correction.hpp │ │ └── prototype_correction.hpp │ ├── helpers.hpp │ ├── ideal_filter │ │ ├── coeff │ │ │ ├── ideal_coeff.cpp │ │ │ └── ideal_coeff.hpp │ │ ├── empty_filter.hpp │ │ ├── ideal_base.hpp │ │ ├── ideal_filter.hpp │ │ ├── single_filter.hpp │ │ └── static_gain_compensation.hpp │ ├── iir_filter │ │ ├── coeff │ │ │ ├── analog_func.cpp │ │ │ ├── analog_func.hpp │ │ │ ├── martin_coeff.cpp │ │ │ └── martin_coeff.hpp │ │ ├── iir_base.hpp │ │ ├── iir_filter.hpp │ │ ├── single_filter.hpp │ │ ├── single_idle_filter.hpp │ │ └── svf_base.hpp │ └── static_frequency_array.hpp ├── filters_attach.cpp ├── filters_attach.hpp ├── gain │ ├── auto_gain.hpp │ ├── gain.hpp │ ├── origin_gain.hpp │ └── simple_gain.hpp ├── histogram │ ├── atomic_histogram.hpp │ ├── histogram.hpp │ └── simple_histogram.hpp ├── interpolation │ ├── interpolation.hpp │ └── seq_makima.hpp ├── loudness │ ├── k_weighting_filter.hpp │ ├── loudness.hpp │ ├── lufs_matcher.hpp │ └── lufs_meter.hpp ├── phase │ ├── phase.hpp │ └── phase_flip.hpp ├── solo_attach.cpp ├── solo_attach.hpp ├── splitter │ ├── lr_splitter.cpp │ ├── lr_splitter.hpp │ ├── ms_splitter.cpp │ ├── ms_splitter.hpp │ └── splitter.hpp └── vector │ └── vector.hpp ├── gui ├── button │ ├── button.hpp │ ├── button_attachment.hpp │ ├── click_button │ │ └── click_button.hpp │ └── compact_button │ │ ├── compact_button.cpp │ │ ├── compact_button.hpp │ │ └── compact_button_look_and_feel.hpp ├── calloutbox │ └── call_out_box_laf.hpp ├── colour_selector │ ├── colour_map_selector.cpp │ ├── colour_map_selector.hpp │ ├── colour_opacity_selector.cpp │ ├── colour_opacity_selector.hpp │ ├── colour_selector.cpp │ └── colour_selector.hpp ├── combobox │ ├── click_combobox │ │ ├── click_combobox.cpp │ │ ├── click_combobox.hpp │ │ └── click_combobox_button_look_and_feel.hpp │ ├── combobox.hpp │ ├── compact_combobox │ │ ├── compact_combobox.cpp │ │ ├── compact_combobox.hpp │ │ └── compact_combobox_look_and_feel.hpp │ └── left_right_combobox │ │ ├── left_right_button_look_and_feel.hpp │ │ ├── left_right_combobox.cpp │ │ ├── left_right_combobox.hpp │ │ └── left_right_combobox_look_and_feel.hpp ├── dragger2d │ ├── dragger2d.hpp │ ├── dragger_component.cpp │ ├── dragger_component.hpp │ ├── dragger_look_and_feel.hpp │ ├── dragger_parameter_attach.cpp │ └── dragger_parameter_attach.hpp ├── gui.hpp ├── interface_definitions.hpp ├── interface_definitons.cpp ├── label │ └── name_look_and_feel.hpp ├── multilingual │ ├── de.hpp │ ├── en.hpp │ ├── es.hpp │ ├── it.hpp │ ├── ja.hpp │ ├── labels.hpp │ ├── multilingual.hpp │ ├── zh_Hans.hpp │ └── zh_Hant.hpp ├── slider │ ├── compact_linear_slider │ │ ├── compact_linear_slider.cpp │ │ ├── compact_linear_slider.hpp │ │ └── compact_linear_slider_look_and_feel.hpp │ ├── extra_slider │ │ └── snapping_slider.h │ ├── slider.hpp │ └── two_value_rotary_slider │ │ └── two_value_rotary_slider.hpp └── tooltip │ ├── tooltip.hpp │ ├── tooltip_look_and_feel.hpp │ └── tooltip_window.hpp ├── panel ├── call_out_box │ ├── analyzer_box.hpp │ ├── call_out_box.hpp │ ├── collision_box.hpp │ ├── dynamic_box.hpp │ ├── general_box.hpp │ └── output_box.hpp ├── control_panel │ ├── control_panel.cpp │ ├── control_panel.hpp │ ├── left_control_panel │ │ ├── left_control_panel.cpp │ │ ├── left_control_panel.hpp │ │ ├── reset_component.cpp │ │ └── reset_component.hpp │ ├── match_control_panel │ │ ├── match_control_panel.cpp │ │ ├── match_control_panel.hpp │ │ ├── match_runner.cpp │ │ └── match_runner.hpp │ └── right_control_panel │ │ ├── right_control_panel.cpp │ │ └── right_control_panel.hpp ├── curve_panel │ ├── background_panel │ │ ├── background_panel.cpp │ │ ├── background_panel.hpp │ │ ├── grid_panel.cpp │ │ └── grid_panel.hpp │ ├── button_panel │ │ ├── button_panel.cpp │ │ ├── button_panel.hpp │ │ ├── button_pop_up.cpp │ │ ├── button_pop_up.hpp │ │ ├── button_pop_up_background.cpp │ │ ├── button_pop_up_background.hpp │ │ ├── filter_button_panel.cpp │ │ ├── filter_button_panel.hpp │ │ ├── link_button_panel.cpp │ │ └── link_button_panel.hpp │ ├── conflict_panel │ │ ├── conflict_panel.cpp │ │ └── conflict_panel.hpp │ ├── curve_panel.cpp │ ├── curve_panel.hpp │ ├── fft_panel │ │ ├── fft_panel.cpp │ │ └── fft_panel.hpp │ ├── helpers.hpp │ ├── loudness_display │ │ ├── loudness_display.cpp │ │ └── loudness_display.hpp │ ├── match_panel │ │ ├── match_analyzer_panel.cpp │ │ ├── match_analyzer_panel.hpp │ │ ├── match_label.cpp │ │ ├── match_label.hpp │ │ ├── match_panel.cpp │ │ └── match_panel.hpp │ ├── scale_panel.cpp │ ├── scale_panel.hpp │ ├── single_panel │ │ ├── reset_attach.hpp │ │ ├── side_panel.cpp │ │ ├── side_panel.hpp │ │ ├── single_panel.cpp │ │ └── single_panel.hpp │ └── sum_panel │ │ ├── solo_panel.cpp │ │ ├── solo_panel.hpp │ │ ├── sum_panel.cpp │ │ └── sum_panel.hpp ├── helper │ ├── atomic_bound.hpp │ ├── helper.hpp │ ├── parse_freq_string.hpp │ └── path_minimizer.hpp ├── main_panel.cpp ├── main_panel.hpp ├── panel_definitons.hpp ├── state_panel │ ├── logo_panel.cpp │ ├── logo_panel.hpp │ ├── match_setting_panel.cpp │ ├── match_setting_panel.hpp │ ├── output_value_panel.cpp │ ├── output_value_panel.hpp │ ├── setting_panel.cpp │ ├── setting_panel.hpp │ ├── state_panel.cpp │ └── state_panel.hpp └── ui_setting_panel │ ├── colour_setting_panel.cpp │ ├── colour_setting_panel.hpp │ ├── control_setting_panel.cpp │ ├── control_setting_panel.hpp │ ├── other_ui_setting_panel.cpp │ ├── other_ui_setting_panel.hpp │ ├── ui_setting_panel.cpp │ └── ui_setting_panel.hpp └── state ├── dummy_processor.hpp ├── property.cpp ├── property.hpp ├── state.hpp └── state_definitions.hpp /.github/workflows/sync.yml: -------------------------------------------------------------------------------- 1 | name: Git sync 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | - cron: "0 0 * * 0" 6 | 7 | jobs: 8 | sync: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Sync to Gitee 12 | uses: abersheeran/sync-gitee-mirror@v1-beta 13 | with: 14 | repository: ${{ github.repository }} 15 | username: ${{ github.actor }} 16 | password: ${{ secrets.GITEE_PAT }} -------------------------------------------------------------------------------- /.github/workflows/sync_release.yml: -------------------------------------------------------------------------------- 1 | name: Release Sync 2 | on: 3 | workflow_dispatch: 4 | # workflow_run: 5 | # workflows: [Release] 6 | # types: [completed] 7 | 8 | jobs: 9 | build: 10 | name: Release Sync 11 | if: ${{ github.event.workflow_run.conclusion == 'success' }} || ${{ github.event_name == 'workflow_dispatch' }} 12 | runs-on: ubuntu-24.04 13 | permissions: 14 | contents: write 15 | steps: 16 | - name: Checkout current repo 17 | uses: actions/checkout@v4 18 | with: 19 | submodules: false 20 | path: "current_repo" 21 | - name: Download release repo 22 | uses: actions/checkout@v4 23 | with: 24 | repository: "ZL-Audio/ZLRelease" 25 | fetch-depth: 0 26 | path: "release_repo" 27 | ssh-key: ${{ secrets.SSH_RELEASE_DEPLOY_KEY }} 28 | - name: Download current release assets (macOS) 29 | uses: robinraju/release-downloader@v1.12 30 | with: 31 | latest: true 32 | preRelease: true 33 | fileName: "*dmg" 34 | out-file-path: "current_release" 35 | - name: Download current release assets (Windows) 36 | uses: robinraju/release-downloader@v1.12 37 | with: 38 | latest: true 39 | preRelease: true 40 | fileName: "*exe" 41 | out-file-path: "current_release" 42 | - name: Remove old release assets 43 | run: | 44 | rm -rf "release_repo/${{ github.event.repository.name }}" 45 | mkdir -p "release_repo/${{ github.event.repository.name }}" 46 | ls "current_release/" 47 | - name: Move current release assets 48 | run: | 49 | mv -v "current_release"/* "release_repo/${{ github.event.repository.name }}/" 50 | mv -v "current_repo/CHANGELOG.md" "release_repo/${{ github.event.repository.name }}/README.md" 51 | - name: Commit release repo 52 | run: | 53 | cd "release_repo" 54 | git config user.name github-actions 55 | git config user.email github-actions@github.com 56 | git checkout --orphan newBranch 57 | git add -A 58 | git commit -m "release" 59 | git branch -D main 60 | git branch -m main 61 | git push -f origin main -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | CMakeLists.txt.user 2 | CMakeCache.txt 3 | CMakeFiles 4 | CMakeScripts 5 | Makefile 6 | cmake_install.cmake 7 | install_manifest.txt 8 | compile_commands.json 9 | CTestTestfile.cmake 10 | _deps 11 | **/.DS_Store 12 | VERSION 13 | 14 | # It's nice to have the Builds folder exist, to remind us where it is 15 | Builds/* 16 | !Builds/.gitkeep 17 | 18 | # This should never exist 19 | Install/* 20 | 21 | # Running CTest makes a bunch o junk 22 | Testing 23 | 24 | # IDE config 25 | .idea 26 | 27 | # clion cmake builds 28 | cmake-build-debug 29 | cmake-build-release 30 | cmake-build-relwithdebinfo 31 | packaging/Output/* -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "JUCE"] 2 | path = JUCE 3 | url = https://github.com/ZL-Audio/JUCE 4 | branch = master 5 | [submodule "nlopt"] 6 | path = nlopt 7 | url = https://github.com/ZL-Audio/nlopt 8 | branch = master 9 | [submodule "kfr"] 10 | path = kfr 11 | url = https://github.com/ZL-Audio/kfr 12 | -------------------------------------------------------------------------------- /assets/font/MiSansLatin-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZL-Audio/ZLEqualizer/5570bd23cc30da3f00a182617e39b19ed634a16e/assets/font/MiSansLatin-Medium.ttf -------------------------------------------------------------------------------- /assets/icons/auto-gain-compensation.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/external-side.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /assets/icons/fad-modsine.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/icons/fad-phase.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/icons/fad-powerswitch.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /assets/icons/fad-preset-a.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/icons/fad-side.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/icons/fad-solo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /assets/icons/links-fill.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /assets/icons/loop-left-line.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/loudness-match.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/icons/pause-line.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/play-fill.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/relative.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /assets/icons/right-to-bracket-solid.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/save-line.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/icons/static-gain-compensation.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /assets/icons/swap.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /assets/icons/xmark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /cmake-includes/Assets.cmake: -------------------------------------------------------------------------------- 1 | # HEADS UP: Pamplejuce assumes anything you stick in the assets folder you want to included in your binary! 2 | # This makes life easy, but will bloat your binary needlessly if you include unused files 3 | file(GLOB_RECURSE AssetFiles CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/assets/*") 4 | 5 | # Setup our binary data as a target called Assets 6 | juce_add_binary_data(Assets SOURCES ${AssetFiles}) 7 | 8 | # Required for Linux happiness: 9 | # See https://forum.juce.com/t/loading-pytorch-model-using-binarydata/39997/2 10 | set_target_properties(Assets PROPERTIES POSITION_INDEPENDENT_CODE TRUE) 11 | -------------------------------------------------------------------------------- /cmake-includes/Benchmarks.cmake: -------------------------------------------------------------------------------- 1 | file(GLOB_RECURSE BenchmarkFiles CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/benchmarks/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/Benchmarks/*.h") 2 | 3 | # Organize the test source in the Tests/ folder in the IDE 4 | source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/benchmarks PREFIX "" FILES ${BenchmarkFiles}) 5 | 6 | add_executable(Benchmarks ${BenchmarkFiles}) 7 | target_compile_features(Benchmarks PRIVATE cxx_std_20) 8 | catch_discover_tests(Benchmarks) 9 | 10 | # Our benchmark executable also wants to know about our plugin code... 11 | target_include_directories(Benchmarks PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/source) 12 | 13 | # Copy over compile definitions from our plugin target so it has all the JUCEy goodness 14 | target_compile_definitions(Benchmarks PRIVATE $) 15 | 16 | # And give tests access to our shared code 17 | target_link_libraries(Benchmarks PRIVATE SharedCode Catch2::Catch2WithMain) 18 | 19 | # Make an Xcode Scheme for the test executable so we can run tests in the IDE 20 | set_target_properties(Benchmarks PROPERTIES XCODE_GENERATE_SCHEME ON) 21 | 22 | # When running Tests we have specific needs 23 | target_compile_definitions(Benchmarks PUBLIC 24 | JUCE_MODAL_LOOPS_PERMITTED=1 # let us run Message Manager in tests 25 | RUN_PAMPLEJUCE_TESTS=1 # also run tests in module .cpp files guarded by RUN_PAMPLEJUCE_TESTS 26 | ) 27 | -------------------------------------------------------------------------------- /cmake-includes/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 2023-09-04 2 | 3 | * Added `SharedCodeDefaults.cmake` which handles setting C++20 and fast math on the `SharedCode` Target. 4 | * Modified CTest to report on failure 5 | 6 | ## 2023-09-04 7 | 8 | Initial commit. Added this CHANGELOG. 9 | -------------------------------------------------------------------------------- /cmake-includes/GitHubENV.cmake: -------------------------------------------------------------------------------- 1 | # Write some temp files to make GitHub Actions / packaging easy 2 | 3 | if (DEFINED ENV{CI}) 4 | set (env_file "${PROJECT_SOURCE_DIR}/.env") 5 | message ("Writing ENV file for CI: ${env_file}") 6 | 7 | # the first call truncates, the rest append 8 | file(WRITE "${env_file}" "PROJECT_NAME=${PROJECT_NAME}\n") 9 | file(APPEND "${env_file}" "PRODUCT_NAME=${PRODUCT_NAME}\n") 10 | file(APPEND "${env_file}" "VERSION=${CURRENT_VERSION}\n") 11 | file(APPEND "${env_file}" "BUNDLE_ID=${BUNDLE_ID}\n") 12 | file(APPEND "${env_file}" "COMPANY_NAME=${COMPANY_NAME}\n") 13 | 14 | file(RELATIVE_PATH RELATIVE_BINARY_PATH "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}") 15 | set (ARTIFACTS_PATH "${RELATIVE_BINARY_PATH}/${CMAKE_PROJECT_NAME}_artefacts/${CMAKE_BUILD_TYPE}") 16 | 17 | file(APPEND "${env_file}" "ARTIFACTS_PATH=${ARTIFACTS_PATH}\n") 18 | if ("VST3" IN_LIST FORMATS) 19 | file(APPEND "${env_file}" "VST3_PATH=${ARTIFACTS_PATH}/VST3/${PRODUCT_NAME}.vst3\n") 20 | endif () 21 | if ("AU" IN_LIST FORMATS) 22 | file(APPEND "${env_file}" "AU_PATH=${ARTIFACTS_PATH}/AU/${PRODUCT_NAME}.component\n") 23 | endif () 24 | if ("LV2" IN_LIST FORMATS) 25 | file(APPEND "${env_file}" "LV2_PATH=${ARTIFACTS_PATH}/LV2/${PRODUCT_NAME}.lv2\n") 26 | endif () 27 | if ("Standalone" IN_LIST FORMATS) 28 | if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") 29 | file(APPEND "${env_file}" "Standalone_PATH=${ARTIFACTS_PATH}/Standalone/${PRODUCT_NAME}.app\n") 30 | elseif (CMAKE_SYSTEM_NAME STREQUAL "Windows") 31 | file(APPEND "${env_file}" "Standalone_PATH=${ARTIFACTS_PATH}/Standalone/${PRODUCT_NAME}.exe\n") 32 | else () 33 | file(APPEND "${env_file}" "Standalone_PATH=${ARTIFACTS_PATH}/Standalone/${PRODUCT_NAME}\n") 34 | endif () 35 | endif () 36 | endif () 37 | -------------------------------------------------------------------------------- /cmake-includes/GitVersion.cmake: -------------------------------------------------------------------------------- 1 | # Read version from git tag and write it to VERSION file 2 | find_package(Git) 3 | 4 | if (GIT_EXECUTABLE) 5 | # Generate a git-describe version string from Git repository tags 6 | execute_process( 7 | COMMAND ${GIT_EXECUTABLE} describe --tags --abbrev=0 8 | OUTPUT_VARIABLE GIT_DESCRIBE_VERSION 9 | RESULT_VARIABLE GIT_DESCRIBE_ERROR_CODE 10 | OUTPUT_STRIP_TRAILING_WHITESPACE 11 | ) 12 | if (NOT GIT_DESCRIBE_ERROR_CODE) 13 | set(FOOBAR_VERSION ${GIT_DESCRIBE_VERSION}) 14 | message(STATUS "Using the version \"${FOOBAR_VERSION}\".") 15 | endif () 16 | execute_process( 17 | COMMAND ${GIT_EXECUTABLE} log -1 --format=%h 18 | OUTPUT_VARIABLE GIT_CURRENT_HASH 19 | RESULT_VARIABLE GIT_HASH_ERROR_CODE 20 | OUTPUT_STRIP_TRAILING_WHITESPACE 21 | ) 22 | if (NOT GIT_HASH_ERROR_CODE) 23 | set(FOOBAR_HASH ${GIT_CURRENT_HASH}) 24 | endif () 25 | endif () 26 | 27 | if (NOT DEFINED FOOBAR_VERSION) 28 | set(FOOBAR_VERSION 0.0.0) 29 | message(WARNING "Failed to determine VERSION from Git tags. Using default version \"${FOOBAR_VERSION}\".") 30 | endif () 31 | if (NOT DEFINED FOOBAR_HASH) 32 | set(FOOBAR_HASH "0000000") 33 | message(WARNING "Failed to determine HASH from Git logs. Using default hash \"${FOOBAR_HASH}\".") 34 | endif () 35 | 36 | string(REPLACE "v" "" FOOBAR_VERSION_WITHOUT_V "${FOOBAR_VERSION}") 37 | 38 | file(WRITE VERSION "${FOOBAR_VERSION_WITHOUT_V}") 39 | 40 | add_definitions(-DZLEQUALIZER_CURRENT_VERSION="${FOOBAR_VERSION_WITHOUT_V}") 41 | 42 | add_definitions(-DZLEQUALIZER_CURRENT_HASH="${FOOBAR_HASH}") -------------------------------------------------------------------------------- /cmake-includes/JUCEDefaults.cmake: -------------------------------------------------------------------------------- 1 | # Adds all the module sources so they appear correctly in the IDE 2 | # Must be set before JUCE is added as a sub-dir (or any targets are made) 3 | # https://github.com/juce-framework/JUCE/commit/6b1b4cf7f6b1008db44411f2c8887d71a3348889 4 | set_property(GLOBAL PROPERTY USE_FOLDERS YES) 5 | 6 | # Creates a /Modules directory in the IDE with the JUCE Module code 7 | option(JUCE_ENABLE_MODULE_SOURCE_GROUPS "Show all module sources in IDE projects" ON) 8 | 9 | # Static runtime please 10 | # See https://github.com/sudara/pamplejuce/issues/111 11 | if (WIN32) 12 | set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>" CACHE INTERNAL "") 13 | endif () 14 | 15 | # Color our warnings and errors 16 | if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") 17 | add_compile_options(-fdiagnostics-color=always) 18 | elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") 19 | add_compile_options(-fcolor-diagnostics) 20 | endif () 21 | -------------------------------------------------------------------------------- /cmake-includes/PamplejuceIPP.cmake: -------------------------------------------------------------------------------- 1 | # When present, use Intel IPP for performance on Windows 2 | if (WIN32) # Can't use MSVC here, as it won't catch Clang on Windows 3 | find_package(IPP) 4 | if (IPP_FOUND) 5 | target_link_libraries(SharedCode INTERFACE IPP::ipps IPP::ippcore IPP::ippi IPP::ippcv) 6 | message("IPP LIBRARIES FOUND") 7 | target_compile_definitions(SharedCode INTERFACE PAMPLEJUCE_IPP=1) 8 | else () 9 | message("IPP LIBRARIES *NOT* FOUND") 10 | endif () 11 | endif () 12 | -------------------------------------------------------------------------------- /cmake-includes/PamplejuceMacOS.cmake: -------------------------------------------------------------------------------- 1 | 2 | # This must be set before the project() call 3 | # see: https://cmake.org/cmake/help/latest/variable/CMAKE_OSX_DEPLOYMENT_TARGET.html 4 | set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13" CACHE STRING "Support macOS down to High Sierra") 5 | 6 | # By default we don't want Xcode schemes to be made for modules, etc 7 | set(CMAKE_XCODE_GENERATE_SCHEME OFF) 8 | -------------------------------------------------------------------------------- /cmake-includes/PamplejuceVersion.cmake: -------------------------------------------------------------------------------- 1 | # Reads in our VERSION file and sticks in it CURRENT_VERSION variable 2 | # Be sure the file has no newlines! 3 | # This exposes CURRENT_VERSION to the build system 4 | # And it's later fed to JUCE so it shows up as VERSION in your IDE 5 | file(STRINGS VERSION CURRENT_VERSION) 6 | 7 | # Figure out the major version to append to our PROJECT_NAME 8 | string(REGEX MATCH "([0-9]+)" MAJOR_VERSION ${CURRENT_VERSION}) 9 | message(STATUS "Major version: ${MAJOR_VERSION}") 10 | -------------------------------------------------------------------------------- /cmake-includes/README.md: -------------------------------------------------------------------------------- 1 | # CMake Includes for Pamplejuce 2 | 3 | Hi there! 4 | 5 | ## What is this? 6 | 7 | It's most of the actual CMake functionality used by [Pamplejuce](https://github.com/sudara/pamplejuce), my template repository for plugins in the JUCE framework. 8 | 9 | ## Why is this its own git submodule? 10 | 11 | It's to help projects built by the template pull in the lastest changes. 12 | 13 | [Pamplejuce](https://github.com/sudara/pamplejuce) is a template repository. Unlike most "dependencies," when you hit "Create Template" you are literally copying and pasting the code. Which sorta sucks, as people can't get fixes or updates. 14 | 15 | ## Why would I want updates? 16 | 17 | For at least the gritty CMake details, there are fixes, improvements and additional functionality being added. 18 | 19 | In the best case, as a submodule, you can pull in the fixes and improvements. 20 | 21 | In the worst case, this seperate repo will help you see what exactly changed in Pamplejuce. 22 | 23 | ## Is it risky? 24 | 25 | It could be! 26 | 27 | As of 2023, Pamplejuce is still being changed around a bunch, with the goal of being a better and better ecosystem for developers. 28 | 29 | That means there could be breakage when you pull. 30 | 31 | ## What changed recently tho? 32 | 33 | See [CHANGELOG.md](CHANGELOG.md). 34 | -------------------------------------------------------------------------------- /cmake-includes/Sanitizer.cmake: -------------------------------------------------------------------------------- 1 | option(WITH_ADDRESS_SANITIZER "Enable Address Sanitizer" OFF) 2 | option(WITH_THREAD_SANITIZER "Enable Thread Sanitizer" OFF) 3 | 4 | message(STATUS "Sanitizers: ASan=${WITH_ADDRESS_SANITIZER} TSan=${WITH_THREAD_SANITIZER}") 5 | if (WITH_ADDRESS_SANITIZER) 6 | if (MSVC) 7 | add_compile_options(/fsanitize=address) 8 | elseif (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") 9 | # also enable UndefinedBehaviorSanitizer 10 | # https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html 11 | add_compile_options(-fsanitize=address,undefined -fno-omit-frame-pointer) 12 | link_libraries(-fsanitize=address) 13 | endif () 14 | message("Address Sanitizer enabled") 15 | endif () 16 | 17 | if (WITH_THREAD_SANITIZER) 18 | if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") 19 | add_compile_options(-fsanitize=thread -g -fno-omit-frame-pointer) 20 | link_libraries(-fsanitize=thread) 21 | message("Thread Sanitizer enabled") 22 | endif () 23 | endif () 24 | -------------------------------------------------------------------------------- /cmake-includes/SharedCodeDefaults.cmake: -------------------------------------------------------------------------------- 1 | if (MSVC) 2 | # fast math and better simd support in RELEASE 3 | # https://learn.microsoft.com/en-us/cpp/build/reference/fp-specify-floating-point-behavior?view=msvc-170#fast 4 | target_compile_options(SharedCode INTERFACE $<$:/fp:precise>) 5 | else () 6 | # See the implications here: 7 | # https://stackoverflow.com/q/45685487 8 | target_compile_options(SharedCode INTERFACE $<$:-O3 -ffp-contract=fast -fno-signed-zeros -freciprocal-math>) 9 | target_compile_options(SharedCode INTERFACE $<$:-O3 -ffp-contract=fast -fno-signed-zeros -freciprocal-math>) 10 | endif () 11 | 12 | # Tell MSVC to properly report what c++ version is being used 13 | if (MSVC) 14 | target_compile_options(SharedCode INTERFACE /Zc:__cplusplus) 15 | endif () 16 | 17 | # C++20, please 18 | # Use cxx_std_23 for C++23 (as of CMake v 3.20) 19 | target_compile_features(SharedCode INTERFACE cxx_std_20) -------------------------------------------------------------------------------- /cmake-includes/Tests.cmake: -------------------------------------------------------------------------------- 1 | # Required for ctest (which is just an easier way to run in cross-platform CI) 2 | # include(CTest) could be used too, but adds additional targets we don't care about 3 | # See: https://github.com/catchorg/Catch2/issues/2026 4 | # You can also forgo ctest entirely and call ./Tests directly from the build dir 5 | enable_testing() 6 | 7 | # Go into detail when there's a CTest failure 8 | set(CTEST_OUTPUT_ON_FAILURE ON) 9 | set_property(GLOBAL PROPERTY CTEST_TARGETS_ADDED 1) 10 | 11 | # "GLOBS ARE BAD" is brittle and silly dev UX, sorry CMake! 12 | file(GLOB_RECURSE TestFiles CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/tests/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/tests/*.h") 13 | 14 | # Organize the test source in the Tests/ folder in Xcode 15 | source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/tests PREFIX "" FILES ${TestFiles}) 16 | 17 | # Use Catch2 v3 on the devel branch 18 | Include(FetchContent) 19 | FetchContent_Declare( 20 | Catch2 21 | GIT_REPOSITORY https://github.com/catchorg/Catch2.git 22 | GIT_PROGRESS TRUE 23 | GIT_SHALLOW TRUE 24 | GIT_TAG v3.4.0) 25 | FetchContent_MakeAvailable(Catch2) # find_package equivalent 26 | 27 | # Setup the test executable, again C++20 please 28 | add_executable(Tests ${TestFiles}) 29 | target_compile_features(Tests PRIVATE cxx_std_20) 30 | 31 | # Our test executable also wants to know about our plugin code... 32 | target_include_directories(Tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/source) 33 | 34 | # Copy over compile definitions from our plugin target so it has all the JUCEy goodness 35 | target_compile_definitions(Tests PRIVATE $) 36 | 37 | # And give tests access to our shared code 38 | target_link_libraries(Tests PRIVATE SharedCode Catch2::Catch2WithMain) 39 | 40 | # Make an Xcode Scheme for the test executable so we can run tests in the IDE 41 | set_target_properties(Tests PROPERTIES XCODE_GENERATE_SCHEME ON) 42 | 43 | # When running Tests we have specific needs 44 | target_compile_definitions(Tests PUBLIC 45 | JUCE_MODAL_LOOPS_PERMITTED=1 # let us run Message Manager in tests 46 | RUN_PAMPLEJUCE_TESTS=1 # also run tests in other module .cpp files guarded by RUN_PAMPLEJUCE_TESTS 47 | ) 48 | 49 | # Load and use the .cmake file provided by Catch2 50 | # https://github.com/catchorg/Catch2/blob/devel/docs/cmake-integration.md 51 | # We have to manually provide the source directory here for now 52 | include(${Catch2_SOURCE_DIR}/extras/Catch.cmake) 53 | catch_discover_tests(Tests) 54 | -------------------------------------------------------------------------------- /cmake-includes/XcodePrettify.cmake: -------------------------------------------------------------------------------- 1 | # No, we don't want our source buried in extra nested folders 2 | set_target_properties(SharedCode PROPERTIES FOLDER "") 3 | 4 | # The Xcode source tree should uhhh, still look like the source tree, yo 5 | source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/source PREFIX "" FILES ${SourceFiles}) 6 | 7 | # It tucks the Plugin varieties into a "Targets" folder and generate an Xcode Scheme manually 8 | # Xcode scheme generation is turned off globally to limit noise from other targets 9 | # The non-hacky way of doing this is via the global PREDEFINED_TARGETS_FOLDER property 10 | # However that doesn't seem to be working in Xcode 11 | # Not all plugin types (au, vst) available on each build type (win, macos, linux) 12 | foreach (target ${FORMATS} "All") 13 | if (TARGET ${PROJECT_NAME}_${target}) 14 | set_target_properties(${PROJECT_NAME}_${target} PROPERTIES 15 | # Tuck the actual plugin targets into a folder where they won't bother us 16 | FOLDER "Targets" 17 | # Let us build the target in Xcode 18 | XCODE_GENERATE_SCHEME ON) 19 | 20 | # Set the default executable that Xcode will open on build 21 | # Note: you must manually build the AudioPluginHost.xcodeproj in the JUCE subdir 22 | if ((NOT target STREQUAL "All") AND (NOT target STREQUAL "Standalone")) 23 | set_target_properties(${PROJECT_NAME}_${target} PROPERTIES 24 | XCODE_SCHEME_EXECUTABLE "${CMAKE_CURRENT_SOURCE_DIR}/JUCE/extras/AudioPluginHost/Builds/MacOSX/build/Debug/AudioPluginHost.app") 25 | endif () 26 | endif () 27 | endforeach () 28 | 29 | if (TARGET Assets) 30 | set_target_properties(Assets PROPERTIES FOLDER "Targets") 31 | endif () 32 | -------------------------------------------------------------------------------- /licenses/fft_juce_LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Matthijs Hollemans 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /licenses/fontaudio_LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Michelangelo Nottoli 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /licenses/pamplejuce_LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Sudara Williams 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /modules/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZL-Audio/ZLEqualizer/5570bd23cc30da3f00a182617e39b19ed634a16e/modules/.gitkeep -------------------------------------------------------------------------------- /packaging/check_dependency.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import platform 4 | import subprocess 5 | 6 | 7 | def main(): 8 | # project_name = os.getenv("PROJECT_NAME", "Pamplejuce") 9 | product_name = os.getenv("PRODUCT_NAME", "") 10 | standalone_path = os.getenv("Standalone_PATH", "") 11 | 12 | if platform.system() == 'Linux': 13 | linux_path = os.path.join(standalone_path, product_name) 14 | result = subprocess.run(['ldd', standalone_path], capture_output=True, text=True) 15 | print(result.stdout) 16 | print(result.stderr) 17 | elif platform.system() == 'Windows': 18 | # set-up windows developer prompt 19 | path2022 = 'C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat' 20 | path2025 = 'C:/Program Files/Microsoft Visual Studio/2025/Enterprise/VC/Auxiliary/Build/vcvars64.bat' 21 | for msvc_path in [os.path.abspath(path2022), os.path.abspath(path2025)]: 22 | if os.path.exists(msvc_path): 23 | print(f"Found MSVC at: {msvc_path}") 24 | cmd = f'cmd.exe /c ""{msvc_path}" && set"' 25 | result = subprocess.run(cmd, shell=True, capture_output=True, text=True) 26 | if result.returncode != 0: 27 | print(f"Error running {msvc_path}: {result.stderr}") 28 | return False 29 | for line in result.stdout.splitlines(): 30 | if '=' in line: 31 | key, value = line.split('=', 1) 32 | os.environ[key] = value 33 | 34 | result = subprocess.run(['dumpbin', '/dependents', standalone_path], capture_output=True, text=True) 35 | print(result.stdout) 36 | print(result.stderr) 37 | elif platform.system() == 'Darwin': 38 | macos_path = os.path.join(standalone_path, 'Contents', 'MacOS', product_name) 39 | result = subprocess.run(['otool', '-L', macos_path], capture_output=True, text=True) 40 | print(result.stdout) 41 | print(result.stderr) 42 | 43 | if __name__ == '__main__': 44 | sys.exit(main()) 45 | -------------------------------------------------------------------------------- /packaging/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZL-Audio/ZLEqualizer/5570bd23cc30da3f00a182617e39b19ed634a16e/packaging/icon.icns -------------------------------------------------------------------------------- /packaging/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZL-Audio/ZLEqualizer/5570bd23cc30da3f00a182617e39b19ed634a16e/packaging/icon.ico -------------------------------------------------------------------------------- /packaging/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ZL-Audio/ZLEqualizer/5570bd23cc30da3f00a182617e39b19ed634a16e/packaging/icon.png -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:recommended" 5 | ], 6 | "git-submodules": { 7 | "enabled": true 8 | }, 9 | "schedule": "after 5am on Friday" 10 | } 11 | -------------------------------------------------------------------------------- /source/dsp/audio_buffer/audio_buffer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "fifo_audio_buffer.hpp" 13 | #include "fixed_audio_buffer.hpp" 14 | -------------------------------------------------------------------------------- /source/dsp/audio_buffer/fifo_audio_buffer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | 15 | namespace zldsp::buffer { 16 | template 17 | class FIFOAudioBuffer { 18 | public: 19 | explicit FIFOAudioBuffer(int channels = 2, int buffer_size = 441); 20 | 21 | void clear(); 22 | 23 | void setSize(int channels, int buffer_size); 24 | 25 | void push(const FloatType **samples, int num_samples); 26 | 27 | void push(const juce::AudioBuffer &samples, int num_samples = -1); 28 | 29 | void push(juce::dsp::AudioBlock block, int num_samples = -1); 30 | 31 | void pop(int num_samples); 32 | 33 | void pop(FloatType **samples, int num_samples); 34 | 35 | void pop(juce::AudioBuffer &samples, int num_samples = -1); 36 | 37 | void pop(juce::dsp::AudioBlock block, int num_samples = -1); 38 | 39 | inline auto getNumChannels() const { return buffer.getNumChannels(); } 40 | 41 | inline auto getNumSamples() const { return fifo_.getTotalSize() - 1; } 42 | 43 | inline auto getNumReady() const { return fifo_.getNumReady(); } 44 | 45 | inline auto getFreeSpace() const { return fifo_.getFreeSpace(); } 46 | 47 | inline auto isFull() const { return fifo_.getFreeSpace() == 0; } 48 | 49 | private: 50 | juce::AbstractFifo fifo_; 51 | 52 | /*< The actual audio buffer */ 53 | juce::AudioBuffer buffer; 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /source/dsp/audio_buffer/fixed_audio_buffer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include "fifo_audio_buffer.hpp" 15 | 16 | namespace zldsp::buffer { 17 | template 18 | class FixedAudioBuffer { 19 | public: 20 | juce::AudioBuffer sub_buffer_; 21 | 22 | explicit FixedAudioBuffer(int subBufferSize = 1); 23 | 24 | void clear(); 25 | 26 | void setSubBufferSize(int subBufferSize); 27 | 28 | void prepare(juce::dsp::ProcessSpec spec); 29 | 30 | void pushBuffer(juce::AudioBuffer &buffer); 31 | 32 | void pushBlock(juce::dsp::AudioBlock block); 33 | 34 | void popSubBuffer(); 35 | 36 | void pushSubBuffer(); 37 | 38 | void popBuffer(juce::AudioBuffer &buffer, bool write = true); 39 | 40 | void popBlock(juce::dsp::AudioBlock block, bool write = true); 41 | 42 | juce::AudioBuffer getSubBufferChannels(int channelOffset, int numChannels); 43 | 44 | juce::dsp::AudioBlock getSubBlockChannels(int channelOffset, int numChannels); 45 | 46 | inline auto isSubReady() { 47 | return input_buffer_.getNumReady() >= sub_buffer_.getNumSamples(); 48 | } 49 | 50 | inline auto getMainSpec() { return main_spec_; } 51 | 52 | inline auto getSubSpec() { return sub_spec_; } 53 | 54 | inline juce::uint32 getLatencySamples() const { 55 | return static_cast(latency_in_samples_.load()); 56 | } 57 | 58 | private: 59 | FIFOAudioBuffer input_buffer_, output_buffer_; 60 | juce::dsp::ProcessSpec sub_spec_, main_spec_; 61 | std::atomic latency_in_samples_{0}; 62 | }; 63 | } 64 | -------------------------------------------------------------------------------- /source/dsp/chore/chore.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "para_updater.hpp" 13 | #include "smoothed_value.hpp" 14 | -------------------------------------------------------------------------------- /source/dsp/chore/para_updater.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | namespace zldsp::chore { 15 | class ParaUpdater final : private juce::AsyncUpdater { 16 | public: 17 | explicit ParaUpdater(const juce::AudioProcessorValueTreeState ¶meter, 18 | const std::string ¶meter_idx) { 19 | para_ = parameter.getParameter(parameter_idx); 20 | } 21 | 22 | void update(const float para_value) { 23 | value_.store(para_value); 24 | triggerAsyncUpdate(); 25 | } 26 | 27 | void updateSync(const float para_value) { 28 | para_->beginChangeGesture(); 29 | para_->setValueNotifyingHost(para_value); 30 | para_->endChangeGesture(); 31 | } 32 | 33 | juce::RangedAudioParameter *getPara() const { return para_; } 34 | 35 | private: 36 | juce::RangedAudioParameter *para_; 37 | std::atomic value_{}; 38 | 39 | void handleAsyncUpdate() override { 40 | para_->beginChangeGesture(); 41 | para_->setValueNotifyingHost(value_.load()); 42 | para_->endChangeGesture(); 43 | } 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /source/dsp/compressor/compressor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "tracker/tracker.hpp" 13 | #include "computer/computer.hpp" 14 | #include "follower/follower.hpp" 15 | -------------------------------------------------------------------------------- /source/dsp/compressor/computer/computer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLCompressor 3 | // 4 | // ZLCompressor is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLCompressor is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLCompressor. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "knee_computer.hpp" 13 | -------------------------------------------------------------------------------- /source/dsp/compressor/follower/follower.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLCompressor 3 | // 4 | // ZLCompressor is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLCompressor is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLCompressor. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "ps_follower.hpp" 13 | -------------------------------------------------------------------------------- /source/dsp/compressor/tracker/tracker.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLCompressor 3 | // 4 | // ZLCompressor is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLCompressor is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLCompressor. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "rms_tracker.hpp" 13 | -------------------------------------------------------------------------------- /source/dsp/container/array.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | namespace zldsp::container { 15 | /** 16 | * an array which has a fixed maximum size (capacity) 17 | * @tparam T the type of elements 18 | * @tparam N the capacity of array 19 | */ 20 | template 21 | class FixedMaxSizeArray { 22 | public: 23 | FixedMaxSizeArray() = default; 24 | 25 | FixedMaxSizeArray &operator =(const FixedMaxSizeArray &that) { 26 | for (size_t i = 0; i < size_; ++i) { 27 | data[i] = that.data[i]; 28 | } 29 | return *this; 30 | } 31 | 32 | T operator [](const size_t idx) const { 33 | return data[idx]; 34 | } 35 | 36 | void push(const T x) { 37 | if (size_ == N) { 38 | size_ = 0; 39 | } 40 | data[size_] = x; 41 | size_++; 42 | } 43 | 44 | void clear() { 45 | size_ = 0; 46 | } 47 | 48 | [[nodiscard]] size_t size() const { 49 | return size_; 50 | } 51 | 52 | [[nodiscard]] static size_t capacity() { 53 | return N; 54 | } 55 | 56 | private: 57 | std::array data{}; 58 | size_t size_ = 0; 59 | }; 60 | } 61 | -------------------------------------------------------------------------------- /source/dsp/container/circular_buffer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | namespace zldsp::container { 15 | /** 16 | * a circular buffer 17 | * @tparam T the type of elements 18 | */ 19 | template 20 | class CircularBuffer { 21 | public: 22 | explicit CircularBuffer(const size_t capacity) { 23 | data_.resize(capacity); 24 | } 25 | 26 | [[nodiscard]] size_t capacity() const { return data_.size(); } 27 | 28 | [[nodiscard]] size_t size() const { return static_cast(c_num_); } 29 | 30 | void setCapacity(const size_t capacity) { 31 | data_.resize(capacity); 32 | } 33 | 34 | void clear() { 35 | std::fill(data_.begin(), data_.end(), T()); 36 | pos_ = 0; 37 | c_num_ = 0; 38 | } 39 | 40 | void pushBack(T x) { 41 | data_[static_cast(pos_)] = x; 42 | pos_ = (pos_ + 1) % static_cast(data_.size()); 43 | c_num_ = std::min(c_num_ + 1, static_cast(data_.size())); 44 | } 45 | 46 | T popFront() { 47 | const auto front_pos = (pos_ - c_num_ + static_cast(data_.size())) % static_cast(data_.size()); 48 | c_num_ -= 1; 49 | return data_[static_cast(front_pos)]; 50 | } 51 | 52 | private: 53 | std::vector data_; 54 | int pos_ = 0, c_num_ = 0; 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /source/dsp/container/container.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "array.hpp" 13 | #include "circular_buffer.hpp" 14 | -------------------------------------------------------------------------------- /source/dsp/delay/delay.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "sample_delay.hpp" 13 | -------------------------------------------------------------------------------- /source/dsp/delay/sample_delay.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #include "sample_delay.hpp" 11 | 12 | namespace zldsp::delay { 13 | template 14 | void SampleDelay::prepare(const juce::dsp::ProcessSpec &spec) { 15 | delay_dsp_.prepare(spec); 16 | sample_rate_.store(spec.sampleRate); 17 | delay_samples_.store(static_cast(static_cast(delay_seconds_.load()) * spec.sampleRate)); 18 | to_update_delay_.store(true); 19 | } 20 | 21 | template 22 | void SampleDelay::process(juce::AudioBuffer &buffer) { 23 | if (to_update_delay_.exchange(false)) { 24 | c_delay_samples_ = delay_samples_.load(); 25 | delay_dsp_.setDelay(static_cast(c_delay_samples_)); 26 | } 27 | if (c_delay_samples_ == 0) { return; } 28 | auto block = juce::dsp::AudioBlock(buffer); 29 | juce::dsp::ProcessContextReplacing context(block); 30 | delay_dsp_.process(context); 31 | } 32 | 33 | template 34 | void SampleDelay::process(juce::dsp::AudioBlock block) { 35 | if (to_update_delay_.exchange(false)) { 36 | c_delay_samples_ = delay_samples_.load(); 37 | delay_dsp_.setDelay(static_cast(c_delay_samples_)); 38 | } 39 | if (c_delay_samples_ == 0) { return; } 40 | juce::dsp::ProcessContextReplacing context(block); 41 | delay_dsp_.process(context); 42 | } 43 | 44 | template 45 | class SampleDelay; 46 | 47 | template 48 | class SampleDelay; 49 | } // zldsp::delay 50 | -------------------------------------------------------------------------------- /source/dsp/delay/sample_delay.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | namespace zldsp::delay { 15 | /** 16 | * a lock free, thread safe integer delay class 17 | * the delay in samples is set to be an integer 18 | * it will not process the signal if the delay is equal to 0 19 | * @tparam FloatType 20 | */ 21 | template 22 | class SampleDelay { 23 | public: 24 | SampleDelay() = default; 25 | 26 | void prepare(const juce::dsp::ProcessSpec &spec); 27 | 28 | void reset() { delay_dsp_.reset(); } 29 | 30 | void setMaximumDelayInSamples(const int maxDelayInSamples) { 31 | delay_dsp_.setMaximumDelayInSamples(maxDelayInSamples); 32 | } 33 | 34 | void process(juce::AudioBuffer &buffer); 35 | 36 | void process(juce::dsp::AudioBlock block); 37 | 38 | void setDelaySeconds(const FloatType x) { 39 | delay_seconds_.store(x); 40 | delay_samples_.store(static_cast(static_cast(x) * sample_rate_.load())); 41 | to_update_delay_.store(true); 42 | } 43 | 44 | int getDelaySamples() const { 45 | return delay_samples_.load(); 46 | } 47 | 48 | private: 49 | std::atomic sample_rate_{44100.0}; 50 | std::atomic delay_seconds_{0}; 51 | std::atomic delay_samples_{0}; 52 | int c_delay_samples_{0}; 53 | std::atomic to_update_delay_{false}; 54 | juce::dsp::DelayLine delay_dsp_; 55 | }; 56 | } // zldsp::delay 57 | -------------------------------------------------------------------------------- /source/dsp/dsp.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "dsp_definitions.hpp" 13 | #include "controller.hpp" 14 | #include "filters_attach.hpp" 15 | #include "solo_attach.hpp" 16 | #include "chore_attach.hpp" 17 | -------------------------------------------------------------------------------- /source/dsp/eq_match/eq_match.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "eq_match_analyzer.hpp" 13 | #include "eq_match_optimizer.hpp" 14 | -------------------------------------------------------------------------------- /source/dsp/fft/fft.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "kfr_engine.hpp" 13 | #include "window_function.hpp" 14 | -------------------------------------------------------------------------------- /source/dsp/fft/kfr_engine.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | #include "kfr_import.hpp" 12 | 13 | namespace zldsp::fft { 14 | template 15 | class KFREngine { 16 | public: 17 | KFREngine() = default; 18 | 19 | void setOrder(const size_t order) { 20 | fft_size_ = static_cast(1) << order; 21 | fft_plan_ = std::make_unique >(fft_size_); 22 | temp_buffer_.resize(fft_plan_->temp_size); 23 | } 24 | 25 | void forward(FloatType *in_buffer, std::complex *out_buffer) { 26 | fft_plan_->execute(out_buffer, in_buffer, temp_buffer_.data()); 27 | } 28 | 29 | void forward(FloatType *in_buffer, FloatType *float_out_buffer) { 30 | auto out_buffer = reinterpret_cast *>(float_out_buffer); 31 | forward(in_buffer, out_buffer); 32 | } 33 | 34 | void backward(std::complex *out_buffer, FloatType *in_buffer) { 35 | fft_plan_->execute(in_buffer, out_buffer, temp_buffer_.data()); 36 | } 37 | 38 | void backward(FloatType *float_out_buffer, FloatType *in_buffer) { 39 | auto out_buffer = reinterpret_cast *>(float_out_buffer); 40 | backward(out_buffer, in_buffer); 41 | } 42 | 43 | void forwardMagnitudeOnly(FloatType *buffer) { 44 | forward(buffer, buffer); 45 | auto *out = reinterpret_cast *>(buffer); 46 | for (size_t i = 0; i < (fft_size_ / 2) + 1; ++i) { 47 | buffer[i] = std::abs(out[i]); 48 | } 49 | } 50 | 51 | [[nodiscard]] size_t getSize() const { return fft_size_; } 52 | 53 | private: 54 | size_t fft_size_{0}; 55 | std::unique_ptr > fft_plan_; 56 | kfr::univector temp_buffer_; 57 | }; 58 | } 59 | -------------------------------------------------------------------------------- /source/dsp/fft/kfr_import.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | #pragma clang diagnostic push 12 | #pragma clang diagnostic ignored "-Wall" 13 | #pragma clang diagnostic ignored "-Weverything" 14 | #include 15 | #include 16 | #pragma clang diagnostic pop 17 | -------------------------------------------------------------------------------- /source/dsp/fft/window_function.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | #include "../vector/vector.hpp" 14 | 15 | namespace zldsp::fft { 16 | template 17 | class WindowFunction { 18 | public: 19 | WindowFunction() = default; 20 | 21 | void setWindow(size_t size, 22 | typename juce::dsp::WindowingFunction::WindowingMethod method, 23 | const FloatType scale = FloatType(1), 24 | const bool normalise = true, const bool cycle = true, const FloatType beta = 0) { 25 | if (cycle) { 26 | std::vector temp_window; 27 | temp_window.resize(size + 1); 28 | juce::dsp::WindowingFunction::fillWindowingTables( 29 | temp_window.data(), size + 1, method, normalise, beta); 30 | window_.resize(size); 31 | zldsp::vector::copy(window_.data(), temp_window.data(), size); 32 | } else { 33 | window_.resize(size); 34 | juce::dsp::WindowingFunction::fillWindowingTables( 35 | window_.data(), size, method, normalise, beta); 36 | } 37 | window_ = window_ * scale; 38 | } 39 | 40 | void multiply(FloatType *buffer, size_t num_samples) { 41 | auto vector = kfr::make_univector(buffer, num_samples); 42 | auto window_v = kfr::make_univector(window_.data(), num_samples); 43 | vector = vector * window_v; 44 | } 45 | 46 | void multiply(kfr::univector &buffer) { 47 | buffer = buffer * window_; 48 | } 49 | 50 | private: 51 | kfr::univector window_; 52 | }; 53 | } 54 | -------------------------------------------------------------------------------- /source/dsp/fft_analyzer/fft_analyzer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "pre_post_fft_analyzer.hpp" 13 | #include "conflict_analyzer.hpp" 14 | #include "multiple_fft_analyzer.hpp" 15 | #include "average_fft_analyzer.hpp" 16 | -------------------------------------------------------------------------------- /source/dsp/filter/dynamic_filter/dynamic_filter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "dynamic_iir_filter.hpp" 13 | -------------------------------------------------------------------------------- /source/dsp/filter/filter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "iir_filter/iir_filter.hpp" 13 | #include "ideal_filter/ideal_filter.hpp" 14 | #include "dynamic_filter/dynamic_filter.hpp" 15 | #include "filter_design/filter_design.hpp" 16 | #include "static_frequency_array.hpp" 17 | #include "fir_correction/fir_correction.hpp" 18 | -------------------------------------------------------------------------------- /source/dsp/filter/fir_correction/correction_helper.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace zldsp::filter { 18 | template 19 | void calculateWsForPrototype(std::vector > &ws) { 20 | const auto delta = static_cast(pi) / static_cast(ws.size() - 1); 21 | double w = 0.f; 22 | for (size_t i = 0; i < ws.size(); ++i) { 23 | ws[i] = std::complex(0.f, static_cast(w)); 24 | w += delta; 25 | } 26 | } 27 | 28 | template 29 | void calculateWsForBiquad(std::vector > &ws) { 30 | const auto delta = static_cast(pi) / static_cast(ws.size() - 1); 31 | double w = 0.f; 32 | for (size_t i = 0; i < ws.size(); ++i) { 33 | ws[i] = std::exp(std::complex(0.f, -static_cast(w))); 34 | w += delta; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /source/dsp/filter/fir_correction/fir_correction.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "correction_helper.hpp" 13 | #include "prototype_correction.hpp" 14 | #include "mixed_correction.hpp" 15 | #include "fir_filter.hpp" 16 | -------------------------------------------------------------------------------- /source/dsp/filter/helpers.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace zldsp::filter { 18 | constexpr static double pi = std::numbers::pi; 19 | constexpr static double ppi = 2 * std::numbers::pi; 20 | 21 | enum FilterType { 22 | kPeak, kLowShelf, kLowPass, kHighShelf, kHighPass, 23 | kNotch, kBandPass, kTiltShelf, kBandShelf, 24 | }; 25 | 26 | enum FilterStructure { 27 | kIIR, kSVF, kParallel 28 | }; 29 | 30 | inline double dotProduct(const std::array &x, const std::array &y) { 31 | return std::inner_product(x.begin(), x.end(), y.begin(), 0.0); 32 | } 33 | 34 | inline double gainToDB(const double gain) { 35 | return std::log10(std::max(std::abs(gain), 1e-16)) * 20; 36 | } 37 | 38 | inline double dbToGain(const double db) { 39 | return std::pow(10, db * 0.05); 40 | } 41 | 42 | inline std::array getBandwidth(const double w0, const double q) { 43 | const auto bw = 2 * std::asinh(0.5 / q) / std::log(2); 44 | const auto scale = std::pow(2, bw / 2); 45 | return {w0 / scale, w0 * scale}; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /source/dsp/filter/ideal_filter/coeff/ideal_coeff.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | namespace zldsp::filter { 15 | class IdealCoeff { 16 | public: 17 | static std::array get1LowPass(double w0); 18 | 19 | static std::array get1HighPass(double w0); 20 | 21 | static std::array get1TiltShelf(double w0, double g); 22 | 23 | static std::array get1LowShelf(double w0, double g); 24 | 25 | static std::array get1HighShelf(double w0, double g); 26 | 27 | static std::array get2LowPass(double w0, double q); 28 | 29 | static std::array get2HighPass(double w0, double q); 30 | 31 | static std::array get2BandPass(double w0, double q); 32 | 33 | static std::array get2Notch(double w0, double q); 34 | 35 | static std::array get2Peak(double w0, double g, double q); 36 | 37 | static std::array get2TiltShelf(double w0, double g, double q); 38 | 39 | static std::array get2LowShelf(double w0, double g, double q); 40 | 41 | static std::array get2HighShelf(double w0, double g, double q); 42 | }; 43 | } // zldsp::filter 44 | -------------------------------------------------------------------------------- /source/dsp/filter/ideal_filter/ideal_filter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "single_filter.hpp" 13 | #include "empty_filter.hpp" 14 | #include "static_gain_compensation.hpp" 15 | -------------------------------------------------------------------------------- /source/dsp/filter/iir_filter/coeff/analog_func.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #include "analog_func.hpp" 11 | 12 | namespace zldsp::filter { 13 | double AnalogFunc::get2Magnitude2(const std::array &coeff, const double w) { 14 | const auto w_2 = w * w; 15 | const auto t1 = coeff[2] - coeff[0] * w_2; 16 | const auto denominator = coeff[1] * coeff[1] * w_2 + t1 * t1; 17 | const auto t2 = coeff[5] - coeff[3] * w_2; 18 | const auto numerator = coeff[4] * coeff[4] * w_2 + t2 * t2; 19 | return numerator / denominator; 20 | } 21 | 22 | double AnalogFunc::get2LowPassMagnitude2(double w0, double q, double w) { 23 | return get2Magnitude2({1, w0 / q, w0 * w0, 0, 0, w0 * w0}, w); 24 | } 25 | 26 | double AnalogFunc::get2HighPassMagnitude2(double w0, double q, double w) { 27 | return get2Magnitude2({1, w0 / q, w0 * w0, 1, 0, 0}, w); 28 | } 29 | 30 | double AnalogFunc::get2BandPassMagnitude2(double w0, double q, double w) { 31 | return get2Magnitude2({1, w0 / q, w0 * w0, 0, w0 / q, 0}, w); 32 | } 33 | 34 | double AnalogFunc::get2NotchMagnitude2(double w0, double q, double w) { 35 | return get2Magnitude2({1, w0 / q, w0 * w0, 1, 0, w0 * w0}, w); 36 | } 37 | 38 | double AnalogFunc::get2PeakMagnitude2(double w0, double g, double q, double w) { 39 | return get2Magnitude2({1, w0 / std::sqrt(g) / q, w0 * w0, 1, w0 * std::sqrt(g) / q, w0 * w0}, w); 40 | } 41 | 42 | double AnalogFunc::get2TiltShelfMagnitude2(double w0, double g, double q, double w) { 43 | const auto A = std::sqrt(g); 44 | return get2Magnitude2({1, std::sqrt(A) * w0 / q, A * w0 * w0, A, std::sqrt(A) * w0 / q, w0 * w0}, w); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /source/dsp/filter/iir_filter/coeff/analog_func.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include "../../helpers.hpp" 15 | 16 | namespace zldsp::filter { 17 | class AnalogFunc { 18 | public: 19 | static double get2LowPassMagnitude2(double w0, double q, double w); 20 | 21 | static double get2HighPassMagnitude2(double w0, double q, double w); 22 | 23 | static double get2BandPassMagnitude2(double w0, double q, double w); 24 | 25 | static double get2NotchMagnitude2(double w0, double q, double w); 26 | 27 | static double get2PeakMagnitude2(double w0, double g, double q, double w); 28 | 29 | static double get2TiltShelfMagnitude2(double w0, double g, double q, double w); 30 | 31 | static double get2LowShelfMagnitude2(double w0, double g, double q, double w); 32 | 33 | static double get2HighShelfMagnitude2(double w0, double g, double q, double w); 34 | 35 | private: 36 | static double get2Magnitude2(const std::array &coeff, double w); 37 | }; 38 | } 39 | -------------------------------------------------------------------------------- /source/dsp/filter/iir_filter/iir_filter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "single_filter.hpp" 13 | #include "single_idle_filter.hpp" 14 | -------------------------------------------------------------------------------- /source/dsp/gain/gain.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "origin_gain.hpp" 13 | #include "simple_gain.hpp" 14 | #include "auto_gain.hpp" 15 | -------------------------------------------------------------------------------- /source/dsp/gain/simple_gain.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "origin_gain.hpp" 13 | 14 | namespace zldsp::gain { 15 | /** 16 | * a lock free, thread safe gain class 17 | * it will not process the signal if the gain is equal to 1 18 | * @tparam FloatType 19 | */ 20 | template 21 | class SimpleGain { 22 | public: 23 | SimpleGain() = default; 24 | 25 | void prepare(const juce::dsp::ProcessSpec &spec) { 26 | gain_dsp_.prepare(spec, 1.0); 27 | } 28 | 29 | template 30 | void process(juce::AudioBuffer &buffer) { 31 | if (IsBypassed) { return; } 32 | if (std::abs(gain_.load() - 1) <= FloatType(1e-6)) { return; } 33 | gain_dsp_.setGainLinear(gain_.load()); 34 | gain_dsp_.template process(buffer); 35 | } 36 | 37 | template 38 | void process(juce::dsp::AudioBlock block) { 39 | if (isBypassed) { return; } 40 | if (std::abs(gain_.load() - 1) <= FloatType(1e-6)) { return; } 41 | gain_dsp_.setGainLinear(gain_.load()); 42 | gain_dsp_.template process(block); 43 | } 44 | 45 | void setGainLinear(const FloatType x) { gain_.store(x); } 46 | 47 | void setGainDecibels(const FloatType x) { 48 | gain_.store(juce::Decibels::decibelsToGain(x, FloatType(-240))); 49 | } 50 | 51 | FloatType getGainDecibels() const { 52 | return juce::Decibels::gainToDecibels(gain_.load()); 53 | } 54 | 55 | private: 56 | std::atomic gain_{FloatType(1)}; 57 | Gain gain_dsp_; 58 | }; 59 | } // zldsp::gain 60 | -------------------------------------------------------------------------------- /source/dsp/histogram/histogram.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "atomic_histogram.hpp" 13 | #include "simple_histogram.hpp" 14 | 15 | 16 | -------------------------------------------------------------------------------- /source/dsp/interpolation/interpolation.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "seq_makima.hpp" 13 | -------------------------------------------------------------------------------- /source/dsp/loudness/loudness.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "k_weighting_filter.hpp" 13 | #include "lufs_meter.hpp" 14 | #include "lufs_matcher.hpp" 15 | -------------------------------------------------------------------------------- /source/dsp/loudness/lufs_matcher.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "lufs_meter.hpp" 13 | 14 | namespace zldsp::loudness { 15 | template 16 | class LUFSMatcher { 17 | public: 18 | LUFSMatcher() = default; 19 | 20 | void prepare(const juce::dsp::ProcessSpec &spec) { 21 | pre_loudness_meter_.prepare(spec); 22 | post_loudness_meter_.prepare(spec); 23 | sample_rate_ = spec.sampleRate; 24 | reset(); 25 | } 26 | 27 | void reset() { 28 | pre_loudness_meter_.reset(); 29 | post_loudness_meter_.reset(); 30 | loudness_diff_.store(FloatType(0)); 31 | current_count_ = 0.0; 32 | } 33 | 34 | void process(juce::AudioBuffer &pre, juce::AudioBuffer &post) { 35 | pre_loudness_meter_.process(pre); 36 | post_loudness_meter_.process(post); 37 | current_count_ += static_cast(pre.getNumSamples()); 38 | if (current_count_ >= sample_rate_) { 39 | current_count_ -= sample_rate_; 40 | const auto pre_loudness = pre_loudness_meter_.getIntegratedLoudness(); 41 | const auto post_loudness = post_loudness_meter_.getIntegratedLoudness(); 42 | loudness_diff_.store(post_loudness - pre_loudness); 43 | } 44 | } 45 | 46 | FloatType getDiff() const { 47 | return loudness_diff_.load(); 48 | } 49 | 50 | private: 51 | LUFSMeter pre_loudness_meter_, post_loudness_meter_; 52 | std::atomic loudness_diff_{FloatType(0)}; 53 | double sample_rate_{48000}, current_count_{0}; 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /source/dsp/phase/phase.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "phase_flip.hpp" 13 | -------------------------------------------------------------------------------- /source/dsp/phase/phase_flip.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #include "../vector/vector.hpp" 15 | 16 | namespace zldsp::phase { 17 | /** 18 | * phase-flip the input audio buffer 19 | * @tparam FloatType the float type of input audio buffer 20 | */ 21 | template 22 | class PhaseFlip { 23 | public: 24 | void process(juce::AudioBuffer &buffer) { 25 | if (is_on_.load()) { 26 | const auto num_samples = static_cast(buffer.getNumSamples()); 27 | const auto num_channels = buffer.getNumChannels(); 28 | for (int chan = 0; chan < num_channels; ++chan) { 29 | zldsp::vector::multiply(buffer.getWritePointer(chan), FloatType(-1.f), num_samples); 30 | } 31 | } 32 | } 33 | 34 | void process(juce::dsp::AudioBlock block) { 35 | if (is_on_.load()) { 36 | const auto num_samples = block.getNumSamples(); 37 | const auto num_channels = block.getNumChannels(); 38 | for (size_t chan = 0; chan < num_channels; ++chan) { 39 | zldsp::vector::multiply(block.getChannelPointer(chan), FloatType(-1.f), num_samples); 40 | } 41 | } 42 | } 43 | 44 | void setON(const bool f) { is_on_.store(f); } 45 | 46 | private: 47 | std::atomic is_on_; 48 | }; 49 | } // zldsp::phase 50 | -------------------------------------------------------------------------------- /source/dsp/solo_attach.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "controller.hpp" 13 | #include "chore/chore.hpp" 14 | 15 | namespace zlp { 16 | template 17 | class SoloAttach final : private juce::AudioProcessorValueTreeState::Listener { 18 | public: 19 | explicit SoloAttach(juce::AudioProcessor &processor, 20 | juce::AudioProcessorValueTreeState ¶meters, 21 | Controller &controller); 22 | 23 | ~SoloAttach() override; 24 | 25 | void addListeners(); 26 | 27 | private: 28 | juce::AudioProcessor &processor_ref_; 29 | juce::AudioProcessorValueTreeState ¶meters_ref_; 30 | Controller &controller_ref_; 31 | 32 | std::array, zlp::kBandNUM> main_solo_updater_, side_solo_updater_; 33 | 34 | constexpr static std::array kIDs{ 35 | fType::ID, 36 | freq::ID, Q::ID, sideFreq::ID, sideQ::ID, 37 | solo::ID, sideSolo::ID 38 | }; 39 | 40 | std::atomic solo_idx_{0}; 41 | std::atomic solo_is_side_{false}; 42 | 43 | constexpr static std::array kInitIDs{ 44 | solo::ID, sideSolo::ID 45 | }; 46 | 47 | constexpr static std::array kDefaultVs{ 48 | static_cast(solo::defaultV), 49 | static_cast(sideSolo::defaultV) 50 | }; 51 | 52 | void parameterChanged(const juce::String ¶meter_id, float new_value) override; 53 | 54 | void initDefaultValues(); 55 | }; 56 | } 57 | -------------------------------------------------------------------------------- /source/dsp/splitter/lr_splitter.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #include "lr_splitter.hpp" 11 | 12 | namespace zldsp::splitter { 13 | template 14 | void LRSplitter::reset() { 15 | } 16 | 17 | template 18 | void LRSplitter::prepare(const juce::dsp::ProcessSpec &spec) { 19 | juce::ignoreUnused(spec); 20 | } 21 | 22 | template 23 | void LRSplitter::split(juce::AudioBuffer &buffer) { 24 | l_buffer_.setDataToReferTo(buffer.getArrayOfWritePointers(), 1, 0, buffer.getNumSamples()); 25 | r_buffer_.setDataToReferTo(buffer.getArrayOfWritePointers() + 1, 1, 0, buffer.getNumSamples()); 26 | } 27 | 28 | template 29 | void LRSplitter::combine(juce::AudioBuffer &buffer) { 30 | juce::ignoreUnused(buffer); 31 | } 32 | 33 | template 34 | class LRSplitter; 35 | 36 | template 37 | class LRSplitter; 38 | } 39 | -------------------------------------------------------------------------------- /source/dsp/splitter/lr_splitter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | 15 | namespace zldsp::splitter { 16 | /** 17 | * a splitter that splits the stereo audio signal input left signal and right signal 18 | * @tparam FloatType 19 | */ 20 | template 21 | class LRSplitter { 22 | public: 23 | LRSplitter() = default; 24 | 25 | void reset(); 26 | 27 | void prepare(const juce::dsp::ProcessSpec &spec); 28 | 29 | /** 30 | * split the audio buffer into internal left buffer and right buffer 31 | * @param buffer 32 | */ 33 | void split(juce::AudioBuffer &buffer); 34 | 35 | /** 36 | * combine the internal left buffer and right buffer into the audio buffer 37 | * @param buffer 38 | */ 39 | void combine(juce::AudioBuffer &buffer); 40 | 41 | inline juce::AudioBuffer &getLBuffer() { return l_buffer_; } 42 | 43 | inline juce::AudioBuffer &getRBuffer() { return r_buffer_; } 44 | 45 | private: 46 | juce::AudioBuffer l_buffer_, r_buffer_; 47 | }; 48 | } 49 | -------------------------------------------------------------------------------- /source/dsp/splitter/ms_splitter.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #include "ms_splitter.hpp" 11 | 12 | namespace zldsp::splitter { 13 | template 14 | void MSSplitter::reset() { 15 | } 16 | 17 | template 18 | void MSSplitter::prepare(const juce::dsp::ProcessSpec &spec) { 19 | juce::ignoreUnused(spec); 20 | } 21 | 22 | template 23 | void MSSplitter::split(juce::AudioBuffer &buffer) { 24 | auto l_vector = kfr::make_univector(buffer.getWritePointer(0), 25 | static_cast(buffer.getNumSamples())); 26 | auto r_vector = kfr::make_univector(buffer.getWritePointer(1), 27 | static_cast(buffer.getNumSamples())); 28 | 29 | l_vector = FloatType(0.5) * (l_vector + r_vector); 30 | r_vector = l_vector - r_vector; 31 | 32 | m_buffer_.setDataToReferTo(buffer.getArrayOfWritePointers(), 1, 0, buffer.getNumSamples()); 33 | s_buffer_.setDataToReferTo(buffer.getArrayOfWritePointers() + 1, 1, 0, buffer.getNumSamples()); 34 | } 35 | 36 | template 37 | void MSSplitter::combine(juce::AudioBuffer &buffer) { 38 | auto m_vector = kfr::make_univector(buffer.getWritePointer(0), 39 | static_cast(buffer.getNumSamples())); 40 | auto s_vector = kfr::make_univector(buffer.getWritePointer(1), 41 | static_cast(buffer.getNumSamples())); 42 | m_vector = m_vector + s_vector; 43 | s_vector = m_vector - s_vector - s_vector; 44 | } 45 | 46 | template 47 | class MSSplitter; 48 | 49 | template 50 | class MSSplitter; 51 | } 52 | -------------------------------------------------------------------------------- /source/dsp/splitter/ms_splitter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #include "../vector/vector.hpp" 15 | 16 | namespace zldsp::splitter { 17 | /** 18 | * a splitter that splits the stereo audio signal input mid signal and side signal 19 | * @tparam FloatType 20 | */ 21 | template 22 | class MSSplitter { 23 | public: 24 | MSSplitter() = default; 25 | 26 | void reset(); 27 | 28 | void prepare(const juce::dsp::ProcessSpec &spec); 29 | 30 | /** 31 | * split the audio buffer into internal mid buffer and side buffer 32 | * @param buffer 33 | */ 34 | void split(juce::AudioBuffer &buffer); 35 | 36 | /** 37 | * combine the internal mid buffer and side buffer into the audio buffer 38 | * @param buffer 39 | */ 40 | void combine(juce::AudioBuffer &buffer); 41 | 42 | inline juce::AudioBuffer &getMBuffer() { return m_buffer_; } 43 | 44 | inline juce::AudioBuffer &getSBuffer() { return s_buffer_; } 45 | 46 | private: 47 | juce::AudioBuffer m_buffer_, s_buffer_; 48 | }; 49 | } 50 | -------------------------------------------------------------------------------- /source/dsp/splitter/splitter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "lr_splitter.hpp" 13 | #include "ms_splitter.hpp" 14 | -------------------------------------------------------------------------------- /source/gui/button/button.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "compact_button/compact_button.hpp" 13 | #include "click_button/click_button.hpp" 14 | #include "button_attachment.hpp" 15 | -------------------------------------------------------------------------------- /source/gui/button/compact_button/compact_button.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #include "compact_button.hpp" 11 | 12 | namespace zlgui { 13 | CompactButton::CompactButton(const juce::String &labelText, UIBase &base, const multilingual::Labels labelIdx) 14 | : ui_base_(base), laf_(ui_base_) { 15 | button_.setClickingTogglesState(true); 16 | button_.setButtonText(labelText); 17 | button_.setLookAndFeel(&laf_); 18 | button_.onClick = [this]() { this->buttonDownAnimation(); }; 19 | addAndMakeVisible(button_); 20 | 21 | setEditable(true); 22 | if (labelIdx != multilingual::Labels::kLabelNum) { 23 | button_.setTooltip(ui_base_.getToolTipText(labelIdx)); 24 | } 25 | } 26 | 27 | CompactButton::~CompactButton() { 28 | button_.setLookAndFeel(nullptr); 29 | } 30 | 31 | void CompactButton::resized() { 32 | auto bound = getLocalBounds().toFloat(); 33 | const auto radius = juce::jmin(bound.getHeight(), bound.getWidth()); 34 | bound = bound.withSizeKeepingCentre(radius, radius); 35 | button_.setBounds(bound.toNearestInt()); 36 | } 37 | 38 | void CompactButton::buttonDownAnimation() { 39 | if (button_.getToggleState() && laf_.getDepth() < 0.1f) { 40 | laf_.setDepth(1.f); 41 | button_.repaint(); 42 | } else if (!button_.getToggleState()) { 43 | laf_.setDepth(0.f); 44 | button_.repaint(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /source/gui/button/compact_button/compact_button.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #include "../../interface_definitions.hpp" 15 | #include "compact_button_look_and_feel.hpp" 16 | 17 | namespace zlgui { 18 | class CompactButton final : public juce::Component { 19 | public: 20 | explicit CompactButton(const juce::String &labelText, UIBase &base, 21 | multilingual::Labels labelIdx = multilingual::Labels::kLabelNum); 22 | 23 | ~CompactButton() override; 24 | 25 | void resized() override; 26 | 27 | void buttonDownAnimation(); 28 | 29 | inline juce::ToggleButton &getButton() { return button_; } 30 | 31 | inline void setEditable(const bool x) { 32 | laf_.setEditable(x); 33 | button_.setInterceptsMouseClicks(x, false); 34 | repaint(); 35 | } 36 | 37 | inline void setDrawable(juce::Drawable *x) { laf_.setDrawable(x); } 38 | 39 | CompactButtonLookAndFeel &getLAF() { return laf_; } 40 | 41 | void lookAndFeelChanged() override { 42 | laf_.updateImages(); 43 | } 44 | 45 | void visibilityChanged() override { 46 | laf_.updateImages(); 47 | } 48 | 49 | private: 50 | UIBase &ui_base_; 51 | 52 | juce::ToggleButton button_; 53 | CompactButtonLookAndFeel laf_; 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /source/gui/calloutbox/call_out_box_laf.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #include "../interface_definitions.hpp" 15 | 16 | namespace zlgui { 17 | class CallOutBoxLAF final : public juce::LookAndFeel_V4 { 18 | public: 19 | explicit CallOutBoxLAF(UIBase &base) : ui_base_(base) { 20 | } 21 | 22 | void drawCallOutBoxBackground(juce::CallOutBox &box, juce::Graphics &g, 23 | const juce::Path &, 24 | juce::Image &) override { 25 | g.setColour(ui_base_.getBackgroundColor()); 26 | g.fillRoundedRectangle(box.getLocalBounds().toFloat(), ui_base_.getFontSize() * .5f); 27 | } 28 | 29 | int getCallOutBoxBorderSize(const juce::CallOutBox &) override { 30 | return 0; 31 | } 32 | 33 | float getCallOutBoxCornerSize(const juce::CallOutBox &) override { 34 | return 0.f; 35 | } 36 | 37 | private: 38 | UIBase &ui_base_; 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /source/gui/colour_selector/colour_map_selector.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | #include "../interface_definitions.hpp" 14 | #include "../combobox/combobox.hpp" 15 | 16 | namespace zlgui { 17 | class ColourMapSelector final : public juce::Component, 18 | private juce::ComboBox::Listener { 19 | public: 20 | explicit ColourMapSelector(zlgui::UIBase &base, float box_width = .5f); 21 | 22 | void paint(juce::Graphics &g) override; 23 | 24 | void resized() override; 25 | 26 | juce::ComboBox &getBox() { return map_box_.getBox(); } 27 | 28 | private: 29 | zlgui::UIBase &ui_base_; 30 | zlgui::CompactCombobox map_box_; 31 | float map_box_width_p_{.5f}; 32 | 33 | void comboBoxChanged(juce::ComboBox *combo_box_that_has_changed) override; 34 | }; 35 | } // zlgui 36 | -------------------------------------------------------------------------------- /source/gui/colour_selector/colour_opacity_selector.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "colour_selector.hpp" 13 | #include "../slider/slider.hpp" 14 | 15 | namespace zlgui { 16 | class ColourOpacitySelector final : public juce::Component, 17 | private juce::Slider::Listener { 18 | public: 19 | explicit ColourOpacitySelector(zlgui::UIBase &base, juce::Component &parent, 20 | bool use_opacity = true, 21 | float width_s = 12.f, float height_s = 10.f, 22 | float w1 = 0.3f, float w2 = 0.3f); 23 | 24 | ~ColourOpacitySelector() override; 25 | 26 | void resized() override; 27 | 28 | juce::Colour getColour() const { 29 | return selector_.getColour(); 30 | } 31 | 32 | void setColour(const juce::Colour c) { 33 | selector_.setColour(c); 34 | slider_.getSlider().setValue(static_cast(c.getFloatAlpha())); 35 | } 36 | 37 | private: 38 | zlgui::UIBase &ui_base_; 39 | ColourSelector selector_; 40 | zlgui::CompactLinearSlider slider_; 41 | bool opacity_on_; 42 | std::array weights_{}; 43 | 44 | void sliderValueChanged(juce::Slider *s) override; 45 | }; 46 | } // zlgui 47 | -------------------------------------------------------------------------------- /source/gui/colour_selector/colour_selector.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | #include "../interface_definitions.hpp" 15 | #include "../calloutbox/call_out_box_laf.hpp" 16 | 17 | namespace zlgui { 18 | class ColourSelector final : public juce::Component, 19 | private juce::ChangeListener { 20 | public: 21 | explicit ColourSelector(zlgui::UIBase &base, juce::Component &parent, 22 | float width_s = 12.f, float height_s = 10.f); 23 | 24 | void paint(juce::Graphics &g) override; 25 | 26 | void mouseDown(const juce::MouseEvent &event) override; 27 | 28 | void setColour(const juce::Colour c) { 29 | colour_ = c; 30 | repaint(); 31 | } 32 | 33 | void setOpacity(const float x) { 34 | colour_ = colour_.withAlpha(x); 35 | repaint(); 36 | } 37 | 38 | [[nodiscard]] juce::Colour getColour() const { 39 | return colour_; 40 | } 41 | 42 | private: 43 | zlgui::UIBase &ui_base_; 44 | zlgui::CallOutBoxLAF laf_; 45 | juce::Component &parent_ref_; 46 | float selector_width_s_, selector_height_s_; 47 | 48 | void changeListenerCallback(juce::ChangeBroadcaster *source) override; 49 | 50 | juce::Colour colour_ = juce::Colours::red; 51 | }; 52 | } // zlgui 53 | -------------------------------------------------------------------------------- /source/gui/combobox/click_combobox/click_combobox.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "../compact_combobox/compact_combobox.hpp" 13 | #include "../../label/name_look_and_feel.hpp" 14 | #include "click_combobox_button_look_and_feel.hpp" 15 | 16 | namespace zlgui { 17 | class ClickCombobox final : public juce::Component { 18 | public: 19 | enum LabelPos { 20 | kLeft, kRight, kTop, kBottom 21 | }; 22 | 23 | ClickCombobox(const juce::String &label_text, const juce::StringArray &choices, UIBase &base, 24 | multilingual::Labels label_idx = multilingual::Labels::kLabelNum); 25 | 26 | ~ClickCombobox() override; 27 | 28 | void resized() override; 29 | 30 | void setLabelScale(const float x) { l_scale_.store(x); } 31 | 32 | void setLabelPos(const LabelPos x) { l_pos_.store(x); } 33 | 34 | ClickComboboxButtonLookAndFeel &getLabelLAF() { return label_laf_; } 35 | 36 | CompactCombobox &getCompactBox() { return compact_box_; } 37 | 38 | private: 39 | CompactCombobox compact_box_; 40 | juce::DrawableButton label_; 41 | ClickComboboxButtonLookAndFeel label_laf_; 42 | std::atomic l_scale_{0.f}; 43 | std::atomic l_pos_{kLeft}; 44 | 45 | void selectRight(); 46 | }; 47 | } // zlgui 48 | -------------------------------------------------------------------------------- /source/gui/combobox/combobox.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "compact_combobox/compact_combobox.hpp" 13 | #include "left_right_combobox/left_right_combobox.hpp" 14 | #include "click_combobox/click_combobox.hpp" 15 | -------------------------------------------------------------------------------- /source/gui/combobox/compact_combobox/compact_combobox.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "compact_combobox_look_and_feel.hpp" 13 | 14 | namespace zlgui { 15 | class CompactCombobox final : public juce::Component, 16 | public juce::SettableTooltipClient { 17 | public: 18 | CompactCombobox(const juce::String &label_text, const juce::StringArray &choices, UIBase &base, 19 | multilingual::Labels label_idx = multilingual::Labels::kLabelNum, 20 | const std::vector &item_label_indices = {}); 21 | 22 | ~CompactCombobox() override; 23 | 24 | void resized() override; 25 | 26 | void mouseUp(const juce::MouseEvent &event) override; 27 | 28 | void mouseDown(const juce::MouseEvent &event) override; 29 | 30 | void mouseDrag(const juce::MouseEvent &event) override; 31 | 32 | void mouseEnter(const juce::MouseEvent &event) override; 33 | 34 | void mouseExit(const juce::MouseEvent &event) override; 35 | 36 | void mouseMove(const juce::MouseEvent &event) override; 37 | 38 | inline void setEditable(const bool x) { 39 | box_laf_.setEditable(x); 40 | setInterceptsMouseClicks(x, false); 41 | } 42 | 43 | inline juce::ComboBox &getBox() { return combo_box_; } 44 | 45 | inline CompactComboboxLookAndFeel &getLAF() { return box_laf_; } 46 | 47 | private: 48 | zlgui::UIBase &ui_base_; 49 | CompactComboboxLookAndFeel box_laf_; 50 | juce::ComboBox combo_box_; 51 | }; 52 | } 53 | -------------------------------------------------------------------------------- /source/gui/combobox/left_right_combobox/left_right_combobox.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "left_right_combobox_look_and_feel.hpp" 13 | #include "left_right_button_look_and_feel.hpp" 14 | 15 | namespace zlgui { 16 | class LeftRightCombobox final : public juce::Component, 17 | public juce::SettableTooltipClient { 18 | public: 19 | explicit LeftRightCombobox(const juce::StringArray &choices, UIBase &base, 20 | multilingual::Labels label_idx = multilingual::Labels::kLabelNum); 21 | 22 | ~LeftRightCombobox() override; 23 | 24 | void resized() override; 25 | 26 | inline juce::ComboBox &getBox() { return box_; } 27 | 28 | inline void setPadding(const float lr, const float ub) { 29 | lr_pad_ = lr; 30 | ub_pad_ = ub; 31 | } 32 | 33 | void selectLeft(); 34 | 35 | void selectRight(); 36 | 37 | private: 38 | UIBase &ui_base_; 39 | juce::DrawableButton left_button_, right_button_; 40 | LeftRightButtonLookAndFeel l_button_laf_, r_button_laf_; 41 | juce::ComboBox box_; 42 | LeftRightComboboxLookAndFeel laf_; 43 | 44 | float lr_pad_{0.f}, ub_pad_{0.f}; 45 | }; 46 | } // zlgui 47 | -------------------------------------------------------------------------------- /source/gui/combobox/left_right_combobox/left_right_combobox_look_and_feel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #include "../../interface_definitions.hpp" 15 | 16 | namespace zlgui { 17 | class LeftRightComboboxLookAndFeel : public juce::LookAndFeel_V4 { 18 | public: 19 | // rounded menu box 20 | explicit LeftRightComboboxLookAndFeel(UIBase &base) { 21 | ui_base_ = &base; 22 | } 23 | 24 | void drawComboBox(juce::Graphics &g, int width, int height, bool, int, int, int, int, 25 | juce::ComboBox &box) override { 26 | juce::ignoreUnused(g, width, height, box); 27 | } 28 | 29 | void positionComboBoxText(juce::ComboBox &box, juce::Label &label) override { 30 | label.setBounds(box.getLocalBounds()); 31 | } 32 | 33 | void drawLabel(juce::Graphics &g, juce::Label &label) override { 34 | if (editable_) { 35 | g.setColour(ui_base_->getTextColor()); 36 | } else { 37 | g.setColour(ui_base_->getTextInactiveColor()); 38 | } 39 | g.setFont(ui_base_->getFontSize() * kFontScale); 40 | g.drawText(label.getText(), label.getLocalBounds(), juce::Justification::centred); 41 | } 42 | 43 | int getMenuWindowFlags() override { 44 | return 1; 45 | } 46 | 47 | inline void setEditable(bool f) { editable_ = f; } 48 | 49 | private: 50 | bool editable_{true}; 51 | static constexpr float kFontScale = 1.5f; 52 | 53 | UIBase *ui_base_; 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /source/gui/dragger2d/dragger2d.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "dragger_component.hpp" 13 | #include "dragger_parameter_attach.hpp" 14 | -------------------------------------------------------------------------------- /source/gui/dragger2d/dragger_parameter_attach.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | 15 | #include "dragger_component.hpp" 16 | 17 | namespace zlgui { 18 | class DraggerParameterAttach final : private Dragger::Listener { 19 | public: 20 | DraggerParameterAttach(juce::RangedAudioParameter ¶meter_x, 21 | juce::NormalisableRange n_range_x, 22 | juce::RangedAudioParameter ¶meter_y, 23 | juce::NormalisableRange n_range_y, 24 | Dragger &dragger_c, 25 | juce::UndoManager *undo_manager = nullptr); 26 | 27 | ~DraggerParameterAttach() override; 28 | 29 | void sendInitialUpdate(); 30 | 31 | void enableX(const bool f) { is_x_attached_.store(f); } 32 | 33 | void enableY(const bool f) { is_y_attached_.store(f); } 34 | 35 | void setX(float new_value) const; 36 | 37 | void setY(float new_value) const; 38 | 39 | private: 40 | void draggerValueChanged(Dragger *dragger) override; 41 | 42 | void dragStarted(Dragger *dragger) override; 43 | 44 | void dragEnded(Dragger *dragger) override; 45 | 46 | Dragger &dragger_; 47 | juce::ParameterAttachment attachment_x_, attachment_y_; 48 | juce::NormalisableRange range_x_, range_y_; 49 | std::atomic is_x_attached_{true}, is_y_attached_{true}; 50 | }; 51 | } // zlgui 52 | -------------------------------------------------------------------------------- /source/gui/gui.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "interface_definitions.hpp" 13 | #include "button/button.hpp" 14 | #include "combobox/combobox.hpp" 15 | #include "slider/slider.hpp" 16 | #include "dragger2d/dragger2d.hpp" 17 | #include "calloutbox/call_out_box_laf.hpp" 18 | #include "colour_selector/colour_selector.hpp" 19 | #include "colour_selector/colour_opacity_selector.hpp" 20 | #include "colour_selector/colour_map_selector.hpp" 21 | #include "tooltip/tooltip.hpp" 22 | -------------------------------------------------------------------------------- /source/gui/label/name_look_and_feel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #include "../interface_definitions.hpp" 15 | 16 | namespace zlgui { 17 | class NameLookAndFeel final : public juce::LookAndFeel_V4 { 18 | public: 19 | explicit NameLookAndFeel(UIBase &base) : ui_base_(base) { 20 | } 21 | 22 | void drawLabel(juce::Graphics &g, juce::Label &label) override { 23 | if (label.isBeingEdited()) { 24 | return; 25 | } 26 | if (editable_) { 27 | g.setColour(ui_base_.getTextColor().withMultipliedAlpha(alpha_)); 28 | } else { 29 | g.setColour(ui_base_.getTextInactiveColor().withMultipliedAlpha(alpha_)); 30 | } 31 | g.setFont(ui_base_.getFontSize() * font_scale_); 32 | g.drawText(label.getText(), label.getLocalBounds().toFloat(), label.getJustificationType()); 33 | } 34 | 35 | inline void setEditable(const bool f) { editable_ = f; } 36 | 37 | inline void setAlpha(const float x) { alpha_ = x; } 38 | 39 | inline void setFontScale(const float x) { font_scale_ = x; } 40 | 41 | private: 42 | bool editable_{true}; 43 | float alpha_{1.f}; 44 | float font_scale_{kFontNormal}; 45 | 46 | UIBase &ui_base_; 47 | }; 48 | } 49 | -------------------------------------------------------------------------------- /source/gui/multilingual/labels.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | namespace zlgui::multilingual { 13 | enum Labels { 14 | kBandBypass, 15 | kBandSolo, 16 | kBandType, 17 | kBandSlope, 18 | kBandStereoMode, 19 | kBandFreq, 20 | kBandGain, 21 | kBandQ, 22 | kBandSelector, 23 | kBandDynamic, 24 | kBandDynamicAuto, 25 | kBandOff, 26 | kBandDynamicBypass, 27 | kBandDynamicSolo, 28 | kBandDynamicRelative, 29 | kBandSideSwap, 30 | kBandDynamicThreshold, 31 | kBandDynamicKnee, 32 | kBandDynamicAttack, 33 | kBandDynamicRelease, 34 | kBandDynamicSideFreq, 35 | kBandDynamicSideQ, 36 | kExternalSideChain, 37 | kStaticGC, 38 | kBypass, 39 | kScale, 40 | kPhaseFlip, 41 | kAutoGC, 42 | kLoudnessMatch, 43 | kOutputGain, 44 | kFFTPre, 45 | kFFTPost, 46 | kFFTSide, 47 | kFFTDecay, 48 | kFFTSlope, 49 | kLookahead, 50 | kRMS, 51 | kSmooth, 52 | kHighQuality, 53 | kCollisionDET, 54 | kCollisionStrength, 55 | kCollisionScale, 56 | kFilterStructure, 57 | kZeroLatency, 58 | kMatchTarget, 59 | kMatchWeight, 60 | kMatchStartLearn, 61 | kMatchSave, 62 | kMatchSmooth, 63 | kMatchSlope, 64 | kMatchAlgo, 65 | kMatchStartFit, 66 | kMatchNumBand, 67 | kDBScale, 68 | kEQMatch, 69 | kMinimumPhase, 70 | kStateVariable, 71 | kParallelPhase, 72 | kMatchedPhase, 73 | kMixedPhase, 74 | kLinearPhase, 75 | kPluginLogo, 76 | kLabelNum 77 | }; 78 | } 79 | -------------------------------------------------------------------------------- /source/gui/multilingual/multilingual.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "labels.hpp" 13 | #include "en.hpp" 14 | #include "zh_Hans.hpp" 15 | #include "zh_Hant.hpp" 16 | #include "it.hpp" 17 | #include "ja.hpp" 18 | #include "de.hpp" 19 | #include "es.hpp" 20 | 21 | namespace zlgui::multilingual { 22 | enum Languages { 23 | kLang_system, 24 | kLang_en, 25 | kLang_zh_Hans, 26 | kLang_zh_Hant, 27 | kLang_it, 28 | kLang_ja, 29 | kLang_de, 30 | kLang_es, 31 | kLangNum 32 | }; 33 | } 34 | -------------------------------------------------------------------------------- /source/gui/slider/extra_slider/snapping_slider.h: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | namespace zlgui { 15 | class SnappingSlider final : public juce::Slider { 16 | public: 17 | explicit SnappingSlider(UIBase &base, const juce::String &name = "") : juce::Slider(name), ui_base_(base) { 18 | } 19 | 20 | void mouseWheelMove(const juce::MouseEvent &e, const juce::MouseWheelDetails &wheel) override { 21 | juce::MouseWheelDetails w = wheel; 22 | w.deltaX *= ui_base_.getSensitivity(kMouseWheel); 23 | w.deltaY *= ui_base_.getSensitivity(kMouseWheel); 24 | if (e.mods.isShiftDown()) { 25 | const auto dir = ui_base_.getIsMouseWheelShiftReverse() ? -1.f : 1.f; 26 | w.deltaX *= ui_base_.getSensitivity(kMouseWheelFine) * dir; 27 | w.deltaY *= ui_base_.getSensitivity(kMouseWheelFine) * dir; 28 | } 29 | Slider::mouseWheelMove(e, w); 30 | } 31 | 32 | private: 33 | UIBase &ui_base_; 34 | 35 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SnappingSlider) 36 | }; 37 | } 38 | -------------------------------------------------------------------------------- /source/gui/slider/slider.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "compact_linear_slider/compact_linear_slider.hpp" 13 | #include "two_value_rotary_slider/two_value_rotary_slider.hpp" 14 | #include "extra_slider/snapping_slider.h" 15 | -------------------------------------------------------------------------------- /source/gui/tooltip/tooltip.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "tooltip_window.hpp" 13 | #include "tooltip_look_and_feel.hpp" 14 | -------------------------------------------------------------------------------- /source/gui/tooltip/tooltip_window.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | namespace zlgui { 15 | class TooltipWindow final : public juce::TooltipWindow { 16 | public: 17 | explicit TooltipWindow(Component *parentComponent, const int millisecondsBeforeTipAppears = 700) 18 | : juce::TooltipWindow(parentComponent, millisecondsBeforeTipAppears) { 19 | } 20 | 21 | juce::String getTipFor(Component &c) override { 22 | return is_on_ ? juce::TooltipWindow::getTipFor(c) : juce::String(); 23 | } 24 | 25 | void setON(const bool x) { is_on_ = x; } 26 | 27 | private: 28 | bool is_on_{true}; 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /source/panel/call_out_box/call_out_box.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "output_box.hpp" 13 | #include "analyzer_box.hpp" 14 | #include "dynamic_box.hpp" 15 | #include "collision_box.hpp" 16 | #include "general_box.hpp" 17 | -------------------------------------------------------------------------------- /source/panel/control_panel/control_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "../../PluginProcessor.hpp" 13 | #include "../../gui/gui.hpp" 14 | #include "left_control_panel/left_control_panel.hpp" 15 | #include "right_control_panel/right_control_panel.hpp" 16 | #include "match_control_panel/match_control_panel.hpp" 17 | 18 | namespace zlpanel { 19 | class ControlPanel final : public juce::Component, 20 | private juce::AudioProcessorValueTreeState::Listener, 21 | private juce::AsyncUpdater { 22 | public: 23 | explicit ControlPanel(PluginProcessor &p, 24 | zlgui::UIBase &base); 25 | 26 | ~ControlPanel() override; 27 | 28 | void resized() override; 29 | 30 | void paint(juce::Graphics &g) override; 31 | 32 | private: 33 | juce::AudioProcessorValueTreeState ¶meters_ref_; 34 | juce::AudioProcessorValueTreeState ¶meters_NA_ref_; 35 | zlgui::UIBase &ui_base_; 36 | std::atomic band_idx_{0}; 37 | std::array, zlstate::kBandNUM> dynamic_on_{}; 38 | LeftControlPanel left_control_panel_; 39 | RightControlPanel right_control_panel_; 40 | MatchControlPanel match_control_panel_; 41 | 42 | void parameterChanged(const juce::String ¶meter_id, float new_value) override; 43 | 44 | void handleAsyncUpdate() override; 45 | }; 46 | } // zlpanel 47 | -------------------------------------------------------------------------------- /source/panel/control_panel/left_control_panel/reset_component.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "BinaryData.h" 13 | 14 | #include "../../../dsp/dsp.hpp" 15 | #include "../../../gui/gui.hpp" 16 | 17 | namespace zlpanel { 18 | class ResetComponent final : public juce::Component { 19 | public: 20 | explicit ResetComponent(juce::AudioProcessorValueTreeState ¶meters, 21 | juce::AudioProcessorValueTreeState ¶meters_NA, 22 | zlgui::UIBase &base); 23 | 24 | ~ResetComponent() override; 25 | 26 | void resized() override; 27 | 28 | void attachGroup(size_t idx); 29 | 30 | private: 31 | juce::AudioProcessorValueTreeState ¶meters_ref_, ¶meters_NA_ref_; 32 | zlgui::UIBase &ui_base_; 33 | const std::unique_ptr drawable_; 34 | zlgui::ClickButton button_; 35 | std::atomic band_idx_; 36 | }; 37 | } // zlpanel 38 | -------------------------------------------------------------------------------- /source/panel/curve_panel/background_panel/background_panel.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #include "background_panel.hpp" 11 | 12 | namespace zlpanel { 13 | BackgroundPanel::BackgroundPanel(juce::AudioProcessorValueTreeState ¶meters, 14 | juce::AudioProcessorValueTreeState ¶meters_NA, 15 | zlgui::UIBase &base) 16 | : ui_base_(base), 17 | grid_panel_(base) { 18 | juce::ignoreUnused(parameters, parameters_NA); 19 | setInterceptsMouseClicks(false, true); 20 | setOpaque(true); 21 | addAndMakeVisible(grid_panel_); 22 | setBufferedToImage(true); 23 | } 24 | 25 | BackgroundPanel::~BackgroundPanel() = default; 26 | 27 | void BackgroundPanel::paint(juce::Graphics &g) { 28 | g.fillAll(ui_base_.getBackgroundColor()); 29 | } 30 | 31 | void BackgroundPanel::resized() { 32 | grid_panel_.setBounds(getLocalBounds()); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /source/panel/curve_panel/background_panel/background_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #include "../../../gui/gui.hpp" 15 | #include "grid_panel.hpp" 16 | 17 | namespace zlpanel { 18 | class BackgroundPanel final : public juce::Component { 19 | public: 20 | explicit BackgroundPanel(juce::AudioProcessorValueTreeState ¶meters, 21 | juce::AudioProcessorValueTreeState ¶meters_NA, 22 | zlgui::UIBase &base); 23 | 24 | ~BackgroundPanel() override; 25 | 26 | void paint(juce::Graphics &g) override; 27 | 28 | void resized() override; 29 | 30 | private: 31 | zlgui::UIBase &ui_base_; 32 | GridPanel grid_panel_; 33 | }; 34 | } 35 | -------------------------------------------------------------------------------- /source/panel/curve_panel/background_panel/grid_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #include "../../../gui/gui.hpp" 15 | 16 | namespace zlpanel { 17 | class GridPanel final : public juce::Component { 18 | public: 19 | /** stl does not support constexpr log/pow, 20 | * (np.log([20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000]) - np.log(10)) / (np.log(22000) - np.log(10)) */ 21 | static constexpr std::array kBackgroundFreqs = { 22 | 0.09006341f, 0.20912077f, 0.29918418f, 0.3892476f, 0.50830495f, 23 | 0.59836837f, 0.68843178f, 0.80748914f, 0.89755255f, 0.98761596f 24 | }; 25 | 26 | static constexpr std::array kBackgroundFreqsNames = { 27 | "20", "50", "100", "200", "500", "1k", "2k", "5k", "10k", "20k" 28 | }; 29 | 30 | static constexpr std::array kBackgroundDBs = { 31 | 0.f, 1.f / 6.f, 2.f / 6.f, 0.5, 4.f / 6.f, 5.f / 6.f 32 | }; 33 | 34 | explicit GridPanel(zlgui::UIBase &base); 35 | 36 | ~GridPanel() override; 37 | 38 | void paint(juce::Graphics &g) override; 39 | 40 | void resized() override; 41 | 42 | private: 43 | zlgui::UIBase &ui_base_; 44 | juce::RectangleList rect_list_; 45 | std::array, 10> text_bounds_; 46 | }; 47 | } 48 | -------------------------------------------------------------------------------- /source/panel/curve_panel/button_panel/button_pop_up_background.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "../../../dsp/dsp.hpp" 13 | #include "../../../gui/gui.hpp" 14 | #include "../../../state/state.hpp" 15 | #include "../../panel_definitons.hpp" 16 | 17 | namespace zlpanel { 18 | 19 | class ButtonPopUpBackground: public juce::Component { 20 | public: 21 | explicit ButtonPopUpBackground(size_t bandIdx, 22 | juce::AudioProcessorValueTreeState ¶meters, 23 | juce::AudioProcessorValueTreeState ¶meters_NA, 24 | zlgui::UIBase &base); 25 | 26 | ~ButtonPopUpBackground() override = default; 27 | 28 | void paint(juce::Graphics &g) override; 29 | 30 | void resized() override; 31 | 32 | private: 33 | size_t band_idx_; 34 | juce::AudioProcessorValueTreeState ¶meters_ref_, ¶meters_NA_ref_; 35 | zlgui::UIBase &ui_base_; 36 | 37 | std::atomic width_{7.7916666f}, height_{4.16667f}; 38 | std::atomic f_type_; 39 | 40 | zlgui::CompactButton bypass_c_, solo_c_; 41 | juce::OwnedArray > button_attachments_; 42 | const std::unique_ptr bypass_drawable_, solo_drawable_; 43 | 44 | zlgui::CompactCombobox ftype_c_; 45 | juce::OwnedArray box_attachments_; 46 | 47 | const std::unique_ptr close_drawable_; 48 | zlgui::ClickButton close_c_; 49 | }; 50 | 51 | } // zlpanel 52 | -------------------------------------------------------------------------------- /source/panel/curve_panel/button_panel/link_button_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "../../../dsp/dsp.hpp" 13 | #include "../../../gui/gui.hpp" 14 | #include "../../../state/state.hpp" 15 | #include "../../panel_definitons.hpp" 16 | 17 | namespace zlpanel { 18 | class LinkButtonPanel final : public juce::Component, 19 | private juce::AudioProcessorValueTreeState::Listener { 20 | public: 21 | explicit LinkButtonPanel(size_t idx, 22 | juce::AudioProcessorValueTreeState ¶meters, 23 | juce::AudioProcessorValueTreeState ¶meters_NA, 24 | zlgui::UIBase &base, 25 | zlgui::Dragger &side_dragger); 26 | 27 | ~LinkButtonPanel() override; 28 | 29 | zlgui::CompactButton &getButton() { return dyn_link_c_; } 30 | 31 | void updateBound(); 32 | 33 | void mouseDoubleClick(const juce::MouseEvent &event) override; 34 | 35 | void resized() override; 36 | 37 | private: 38 | juce::AudioProcessorValueTreeState ¶meters_ref_, ¶meters_NA_ref_; 39 | zlgui::UIBase &ui_base_; 40 | zlgui::Dragger &side_dragger_ref_; 41 | zlgui::CompactButton dyn_link_c_; 42 | float button_size_{}, button_bottom_{}; 43 | std::atomic button_changed_{false}; 44 | juce::OwnedArray > button_attachments_; 45 | const std::unique_ptr link_drawable_; 46 | 47 | std::atomic band_idx_; 48 | std::atomic is_dynamic_on_{false}, is_selected_{false}; 49 | 50 | constexpr static std::array kIDs{zlp::dynamicON::ID}; 51 | constexpr static std::array kNAIDs{zlstate::selectedBandIdx::ID}; 52 | 53 | void parameterChanged(const juce::String ¶meter_id, float new_value) override; 54 | }; 55 | } // zlpanel 56 | -------------------------------------------------------------------------------- /source/panel/curve_panel/conflict_panel/conflict_panel.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #include "conflict_panel.hpp" 11 | 12 | namespace zlpanel { 13 | ConflictPanel::ConflictPanel(zldsp::analyzer::ConflictAnalyzer &conflictAnalyzer, zlgui::UIBase &base) 14 | : analyzer_ref_(conflictAnalyzer), ui_base_(base) { 15 | analyzer_ref_.start(); 16 | setInterceptsMouseClicks(false, false); 17 | juce::ignoreUnused(ui_base_); 18 | } 19 | 20 | ConflictPanel::~ConflictPanel() { 21 | analyzer_ref_.stop(); 22 | } 23 | 24 | void ConflictPanel::paint(juce::Graphics &g) { 25 | g.setGradientFill(gradient_); 26 | g.fillRect(getLocalBounds()); 27 | } 28 | 29 | void ConflictPanel::resized() { 30 | analyzer_ref_.setLeftRight(0.f, static_cast(getRight())); 31 | } 32 | } // zlpanel 33 | -------------------------------------------------------------------------------- /source/panel/curve_panel/conflict_panel/conflict_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #include "../../../dsp/dsp.hpp" 15 | #include "../../../gui/gui.hpp" 16 | 17 | namespace zlpanel { 18 | class ConflictPanel final : public juce::Component { 19 | public: 20 | explicit ConflictPanel(zldsp::analyzer::ConflictAnalyzer &conflictAnalyzer, 21 | zlgui::UIBase &base); 22 | 23 | ~ConflictPanel() override; 24 | 25 | void paint(juce::Graphics &g) override; 26 | 27 | void resized() override; 28 | 29 | void updateGradient() { 30 | if (analyzer_ref_.getON()) { 31 | analyzer_ref_.updateGradient(gradient_); 32 | setVisible(true); 33 | } else { 34 | setVisible(false); 35 | } 36 | } 37 | 38 | private: 39 | zldsp::analyzer::ConflictAnalyzer &analyzer_ref_; 40 | zlgui::UIBase &ui_base_; 41 | juce::Path path_; 42 | juce::ColourGradient gradient_; 43 | }; 44 | } // zlpanel 45 | -------------------------------------------------------------------------------- /source/panel/curve_panel/fft_panel/fft_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "../../../dsp/dsp.hpp" 13 | #include "../../../gui/gui.hpp" 14 | #include "../helpers.hpp" 15 | 16 | namespace zlpanel { 17 | class FFTPanel final : public juce::Component { 18 | public: 19 | explicit FFTPanel(zldsp::analyzer::PrePostFFTAnalyzer &analyzer, 20 | zlgui::UIBase &base); 21 | 22 | ~FFTPanel() override; 23 | 24 | void paint(juce::Graphics &g) override; 25 | 26 | void resized() override; 27 | 28 | void updatePaths(float physicalPixelScaleFactor); 29 | 30 | void visibilityChanged() override; 31 | 32 | void setMinimumFFTDB(const float x) { 33 | minimum_fft_db_.store(x); 34 | } 35 | 36 | private: 37 | zldsp::analyzer::PrePostFFTAnalyzer &analyzer_ref_; 38 | zlgui::UIBase &ui_base_; 39 | juce::Path pre_path_{}, post_path_{}, post_stroke_path_{}, side_path_{}; 40 | juce::Path recent_pre_path_{}, recent_post_path_{}, recent_post_stroke_path_{}, recent_side_path_{}; 41 | juce::SpinLock path_lock_; 42 | AtomicPoint left_corner_, right_corner_; 43 | AtomicBound atomic_bound_; 44 | std::atomic curve_thickness_{0.f}; 45 | std::atomic first_path_ = true; 46 | std::atomic minimum_fft_db_{-72.f}; 47 | }; 48 | } // zlpanel 49 | -------------------------------------------------------------------------------- /source/panel/curve_panel/loudness_display/loudness_display.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #include "loudness_display.hpp" 11 | 12 | namespace zlpanel { 13 | LoudnessDisplay::LoudnessDisplay(PluginProcessor &p, zlgui::UIBase &base) 14 | : processor_ref_(p), ui_base_(base) { 15 | for (size_t i = 0; i < zlstate::kBandNUM; ++i) { 16 | const auto suffix = zlp::appendSuffix("", i); 17 | is_threshold_auto_paras_[i] = processor_ref_.parameters_.getParameter(zlp::dynamicLearn::ID + suffix); 18 | is_dynamic_on_paras_[i] = processor_ref_.parameters_.getParameter(zlp::dynamicON::ID + suffix); 19 | } 20 | band_idx_para_ = processor_ref_.parameters_NA_.getParameter(zlstate::selectedBandIdx::ID); 21 | lookAndFeelChanged(); 22 | } 23 | 24 | void LoudnessDisplay::paint(juce::Graphics &g) { 25 | const auto loudness = processor_ref_.getController().getSideLoudness(band_idx_); 26 | const auto p = 1. + std::clamp(loudness, -80.0, 0.0) / 80; 27 | auto bound = getLocalBounds().toFloat(); 28 | bound = bound.withWidth(bound.getWidth() * static_cast(p)); 29 | g.setColour(colour_); 30 | g.fillRect(bound); 31 | } 32 | 33 | void LoudnessDisplay::checkVisible() { 34 | band_idx_ = static_cast(band_idx_para_->convertFrom0to1(band_idx_para_->getValue())); 35 | const auto f = (is_threshold_auto_paras_[band_idx_]->getValue() < 0.5f) 36 | && (is_dynamic_on_paras_[band_idx_]->getValue() > 0.5f); 37 | setVisible(f && should_visible_ && colour_.getFloatAlpha() > 0.005f); 38 | } 39 | 40 | void LoudnessDisplay::lookAndFeelChanged() { 41 | colour_ = ui_base_.getColourByIdx(zlgui::kSideLoudnessColour); 42 | } 43 | 44 | void LoudnessDisplay::updateVisible(const bool x) { 45 | should_visible_ = x; 46 | } 47 | } // zlpanel 48 | -------------------------------------------------------------------------------- /source/panel/curve_panel/loudness_display/loudness_display.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "../../../PluginProcessor.hpp" 13 | #include "../../../gui/gui.hpp" 14 | #include "../../panel_definitons.hpp" 15 | 16 | namespace zlpanel { 17 | class LoudnessDisplay final : public juce::Component { 18 | public: 19 | explicit LoudnessDisplay(PluginProcessor &p, zlgui::UIBase &base); 20 | 21 | void paint(juce::Graphics &g) override; 22 | 23 | void checkVisible(); 24 | 25 | void lookAndFeelChanged() override; 26 | 27 | void updateVisible(bool x); 28 | 29 | private: 30 | PluginProcessor &processor_ref_; 31 | zlgui::UIBase &ui_base_; 32 | juce::Time previous_time_{}; 33 | 34 | size_t band_idx_{0}; 35 | std::array is_dynamic_on_paras_{}; 36 | std::array is_threshold_auto_paras_{}; 37 | juce::RangedAudioParameter *band_idx_para_; 38 | juce::Colour colour_; 39 | bool should_visible_{false}; 40 | }; 41 | } // zlpanel 42 | -------------------------------------------------------------------------------- /source/panel/curve_panel/match_panel/match_label.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #include "match_label.hpp" 11 | 12 | namespace zlpanel { 13 | MatchLabel::MatchLabel(zlgui::UIBase &base) 14 | : ui_base_(base), label_laf_(base) { 15 | running_label_.setText("Running", juce::dontSendNotification); 16 | running_label_.setJustificationType(juce::Justification::centred); 17 | label_laf_.setFontScale(5.f); 18 | running_label_.setLookAndFeel(&label_laf_); 19 | addAndMakeVisible(running_label_); 20 | setBufferedToImage(true); 21 | } 22 | 23 | void MatchLabel::paint(juce::Graphics &g) { 24 | g.fillAll(ui_base_.getColourByIdx(zlgui::kBackgroundColour).withAlpha(.75f)); 25 | } 26 | 27 | void MatchLabel::resized() { 28 | const auto bound = getLocalBounds().toFloat(); 29 | running_label_.setBounds(bound.withSizeKeepingCentre( 30 | bound.getWidth() * .5f, ui_base_.getFontSize() * 5.f).toNearestInt()); 31 | } 32 | } // zlpanel 33 | -------------------------------------------------------------------------------- /source/panel/curve_panel/match_panel/match_label.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "../../../gui/gui.hpp" 13 | 14 | namespace zlpanel { 15 | class MatchLabel : public juce::Component { 16 | public: 17 | explicit MatchLabel(zlgui::UIBase &base); 18 | 19 | void paint(juce::Graphics &g) override; 20 | 21 | void resized() override; 22 | 23 | private: 24 | zlgui::UIBase &ui_base_; 25 | zlgui::NameLookAndFeel label_laf_; 26 | juce::Label running_label_; 27 | }; 28 | } // zlpanel 29 | -------------------------------------------------------------------------------- /source/panel/curve_panel/match_panel/match_panel.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #include "match_panel.hpp" 11 | 12 | namespace zlpanel { 13 | MatchPanel::MatchPanel(zldsp::eq_match::EqMatchAnalyzer &analyzer, 14 | juce::AudioProcessorValueTreeState ¶meters_NA, zlgui::UIBase &base) 15 | : ui_base_(base), match_analyzer_panel_(analyzer, parameters_NA, base) { 16 | juce::ignoreUnused(analyzer, ui_base_); 17 | setInterceptsMouseClicks(true, false); 18 | addChildComponent(match_analyzer_panel_); 19 | } 20 | 21 | MatchPanel::~MatchPanel() = default; 22 | 23 | void MatchPanel::resized() { 24 | match_analyzer_panel_.setBounds(getLocalBounds()); 25 | } 26 | } // zlpanel 27 | -------------------------------------------------------------------------------- /source/panel/curve_panel/match_panel/match_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "match_analyzer_panel.hpp" 13 | 14 | namespace zlpanel { 15 | class MatchPanel final : public juce::Component { 16 | public: 17 | explicit MatchPanel(zldsp::eq_match::EqMatchAnalyzer &analyzer, 18 | juce::AudioProcessorValueTreeState ¶meters_NA, 19 | zlgui::UIBase &base); 20 | 21 | ~MatchPanel() override; 22 | 23 | void resized() override; 24 | 25 | void updatePaths() { 26 | match_analyzer_panel_.updatePaths(); 27 | } 28 | 29 | void updateDraggers() { 30 | match_analyzer_panel_.updateDraggers(); 31 | } 32 | 33 | void visibilityChanged() override { 34 | match_analyzer_panel_.setVisible(isVisible()); 35 | } 36 | 37 | private: 38 | zlgui::UIBase &ui_base_; 39 | MatchAnalyzerPanel match_analyzer_panel_; 40 | }; 41 | } // zlpanel 42 | -------------------------------------------------------------------------------- /source/panel/curve_panel/scale_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | #include "../../PluginProcessor.hpp" 15 | #include "../../gui/gui.hpp" 16 | #include "../../state/state.hpp" 17 | 18 | namespace zlpanel { 19 | class ScalePanel final : public juce::Component, 20 | public juce::SettableTooltipClient, 21 | private juce::AsyncUpdater { 22 | public: 23 | ScalePanel(PluginProcessor &processor, 24 | zlgui::UIBase &base); 25 | 26 | ~ScalePanel() override; 27 | 28 | void paint(juce::Graphics &g) override; 29 | 30 | void resized() override; 31 | 32 | void setMaximumDB(const float x) { 33 | maximum_db_.store(x); 34 | triggerAsyncUpdate(); 35 | } 36 | 37 | void setMinimumFFTDB(const float x) { 38 | minimum_fft_db_.store(x); 39 | triggerAsyncUpdate(); 40 | } 41 | 42 | private: 43 | juce::AudioProcessorValueTreeState ¶meters_NA_ref_; 44 | zlgui::UIBase &ui_base_; 45 | 46 | zlgui::CompactCombobox scale_box_, min_fft_box_; 47 | juce::OwnedArray box_attachments_; 48 | std::atomic maximum_db_{12.f}, minimum_fft_db_{-72.f}; 49 | 50 | static constexpr std::array kScaleDBs = { 51 | 1.f / 6.f, 2.f / 6.f, 0.5, 4.f / 6.f, 5.f / 6.f 52 | }; 53 | 54 | void handleAsyncUpdate() override; 55 | }; 56 | } // zlpanel 57 | -------------------------------------------------------------------------------- /source/panel/curve_panel/single_panel/side_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "../../../dsp/dsp.hpp" 13 | #include "../../../gui/gui.hpp" 14 | #include 15 | 16 | #include "../../../state/state_definitions.hpp" 17 | 18 | namespace zlpanel { 19 | class SidePanel final : public juce::Component, 20 | private juce::AudioProcessorValueTreeState::Listener { 21 | public: 22 | explicit SidePanel(size_t band_idx, 23 | juce::AudioProcessorValueTreeState ¶meters, 24 | juce::AudioProcessorValueTreeState ¶meters_NA, 25 | zlgui::UIBase &base, 26 | zlp::Controller &controller, 27 | zlgui::Dragger &side_dragger); 28 | 29 | ~SidePanel() override; 30 | 31 | void paint(juce::Graphics &g) override; 32 | 33 | void lookAndFeelChanged() override; 34 | 35 | void updateDragger(); 36 | 37 | private: 38 | size_t band_idx_; 39 | juce::AudioProcessorValueTreeState ¶meters_ref_, ¶meters_NA_ref_; 40 | zlgui::UIBase &ui_base_; 41 | zldsp::filter::IIR::kFilterSize> &side_f_; 42 | zlgui::Dragger &side_dragger_ref_; 43 | std::atomic dyn_on_, selected_, active_; 44 | 45 | static constexpr std::array kChangeIDs{ 46 | zlp::dynamicON::ID, zlp::sideQ::ID 47 | }; 48 | 49 | juce::Colour colour_; 50 | 51 | std::atomic side_q_{0.707}; 52 | std::atomic to_update_{false}; 53 | float current_bw_{0.f}; 54 | 55 | void parameterChanged(const juce::String ¶meter_id, float new_value) override; 56 | }; 57 | } // zlpanel 58 | -------------------------------------------------------------------------------- /source/panel/curve_panel/sum_panel/solo_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "../../../dsp/dsp.hpp" 13 | #include "../../../gui/gui.hpp" 14 | #include "../button_panel/button_panel.hpp" 15 | 16 | namespace zlpanel { 17 | class SoloPanel final : public juce::Component, 18 | private juce::AudioProcessorValueTreeState::Listener { 19 | public: 20 | SoloPanel(juce::AudioProcessorValueTreeState ¶meters, 21 | juce::AudioProcessorValueTreeState ¶meters_NA, 22 | zlgui::UIBase &base, 23 | zlp::Controller &controller, 24 | ButtonPanel &button_panel); 25 | 26 | ~SoloPanel() override; 27 | 28 | void paint(juce::Graphics &g) override; 29 | 30 | void checkVisible() { 31 | setVisible(controller_ref_.getSolo()); 32 | } 33 | 34 | void turnOffSolo() const; 35 | 36 | private: 37 | juce::AudioProcessorValueTreeState ¶meters_ref_, ¶meters_NA_ref_; 38 | zlgui::UIBase &ui_base_; 39 | zldsp::filter::IIR::kFilterSize> &soloF; 40 | zlp::Controller &controller_ref_; 41 | ButtonPanel &button_panel_ref_; 42 | float current_x_{0.}, current_bw_{0.}; 43 | double solo_q_{0.}; 44 | std::atomic band_idx_{0}; 45 | std::vector > solo_updaters_, side_solo_updaters_; 46 | 47 | void handleAsyncUpdate(); 48 | 49 | void parameterChanged(const juce::String ¶meter_id, float new_value) override; 50 | }; 51 | } // zlpanel 52 | -------------------------------------------------------------------------------- /source/panel/helper/atomic_bound.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | namespace zlpanel { 15 | template 16 | class AtomicBound { 17 | public: 18 | AtomicBound() = default; 19 | 20 | void store(const juce::Rectangle &bound) { 21 | x_.store(bound.getX()); 22 | y_.store(bound.getY()); 23 | width_.store(bound.getWidth()); 24 | height_.store(bound.getHeight()); 25 | } 26 | 27 | juce::Rectangle load() const { 28 | return {x_.load(), y_.load(), width_.load(), height_.load()}; 29 | } 30 | 31 | FloatType getX() const { return x_.load(); } 32 | 33 | FloatType getY() const { return y_.load(); } 34 | 35 | FloatType getWidth() const { return width_.load(); } 36 | 37 | FloatType getHeight() const { return height_.load(); } 38 | 39 | private: 40 | std::atomic x_{}, y_{}, width_{}, height_{}; 41 | }; 42 | 43 | template 44 | class AtomicPoint { 45 | public: 46 | AtomicPoint() = default; 47 | 48 | void store(const juce::Point &p) { 49 | x_.store(p.getX()); 50 | y_.store(p.getY()); 51 | } 52 | 53 | juce::Point load() const { 54 | return {x_.load(), y_.load()}; 55 | } 56 | 57 | FloatType getX() const { return x_.load(); } 58 | 59 | FloatType getY() const { return y_.load(); } 60 | 61 | private: 62 | std::atomic x_{}, y_{}; 63 | }; 64 | } 65 | -------------------------------------------------------------------------------- /source/panel/helper/helper.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "path_minimizer.hpp" 13 | #include "atomic_bound.hpp" 14 | #include "parse_freq_string.hpp" 15 | -------------------------------------------------------------------------------- /source/panel/helper/parse_freq_string.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | inline std::optional parseFreqPitchString(juce::String s) { 15 | static constexpr std::array kPitchLookUp{ 16 | "A", "A#", "B", "C", 17 | "C#", "D", "D#", "E", 18 | "F", "F#", "G", "G#" 19 | }; 20 | for (size_t i = 0; i < kPitchLookUp.size(); ++i) { 21 | if (s.startsWithIgnoreCase(kPitchLookUp[11 - i])) { 22 | auto shift = static_cast(11 - i) / 12.0; 23 | s = s.substring(static_cast(kPitchLookUp[11 - i].length())); 24 | shift += s.getDoubleValue(); 25 | return 27.5 * std::pow(2.0, shift); 26 | } 27 | } 28 | return std::nullopt; 29 | } 30 | 31 | inline double parseFreqValueString(const juce::String &s) { 32 | const auto k = (s.contains("k") || s.contains("K")) ? 1000.0 : 1.0; 33 | return s.getDoubleValue() * k; 34 | } 35 | -------------------------------------------------------------------------------- /source/panel/helper/path_minimizer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | namespace zlpanel { 15 | class PathMinimizer { 16 | public: 17 | static constexpr float kTol = 0.01f; 18 | 19 | explicit PathMinimizer(juce::Path &path) : path_ref_(path) { 20 | } 21 | 22 | template 23 | void startNewSubPath(const float x, const float y) { 24 | if (start) { 25 | path_ref_.startNewSubPath(x, y); 26 | } else { 27 | path_ref_.lineTo(x, y); 28 | } 29 | start_x_ = x; 30 | start_y_ = y; 31 | current_x_ = x; 32 | current_y_ = y; 33 | } 34 | 35 | void lineTo(const float x, const float y) { 36 | const auto w = (current_x_ - start_x_) / (x - start_x_); 37 | if (std::abs(w * start_y_ + (1.f - w) * y - current_y_) > kTol) { 38 | path_ref_.lineTo(current_x_, current_y_); 39 | start_x_ = x; 40 | start_y_ = y; 41 | } 42 | current_x_ = x; 43 | current_y_ = y; 44 | } 45 | 46 | void finish() const { 47 | path_ref_.lineTo(current_x_, current_y_); 48 | } 49 | 50 | private: 51 | juce::Path &path_ref_; 52 | float start_x_{0.}, start_y_{0.}; 53 | float current_x_{0.}, current_y_{0.}; 54 | }; 55 | } 56 | -------------------------------------------------------------------------------- /source/panel/main_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "../PluginProcessor.hpp" 13 | #include "control_panel/control_panel.hpp" 14 | #include "curve_panel/curve_panel.hpp" 15 | #include "curve_panel/scale_panel.hpp" 16 | #include "state_panel/state_panel.hpp" 17 | #include "ui_setting_panel/ui_setting_panel.hpp" 18 | #include "call_out_box/call_out_box.hpp" 19 | 20 | namespace zlpanel { 21 | class MainPanel final : public juce::Component, 22 | private juce::AudioProcessorValueTreeState::Listener, 23 | private juce::AsyncUpdater { 24 | public: 25 | explicit MainPanel(PluginProcessor &p, zlgui::UIBase &base); 26 | 27 | ~MainPanel() override; 28 | 29 | void paint(juce::Graphics &g) override; 30 | 31 | void resized() override; 32 | 33 | void parentHierarchyChanged() override; 34 | 35 | void lookAndFeelChanged() override; 36 | 37 | void repaintCallBack(const double nowT) { 38 | curvePanel.repaintCallBack(nowT); 39 | } 40 | 41 | private: 42 | PluginProcessor &processor_ref_; 43 | juce::AudioProcessorValueTreeState &state; 44 | zlgui::UIBase &ui_base_; 45 | ControlPanel controlPanel; 46 | CurvePanel curvePanel; 47 | ScalePanel scalePanel; 48 | StatePanel statePanel; 49 | UISettingPanel uiSettingPanel; 50 | 51 | OutputBox outputBox; 52 | AnalyzerBox analyzerBox; 53 | DynamicBox dynamicBox; 54 | CollisionBox collisionBox; 55 | GeneralBox generalBox; 56 | 57 | zlgui::TooltipLookAndFeel tooltipLAF; 58 | zlgui::TooltipWindow tooltipWindow; 59 | 60 | void parameterChanged(const juce::String ¶meter_id, float new_value) override; 61 | 62 | void handleAsyncUpdate() override; 63 | 64 | void updateFFTs(); 65 | }; 66 | } 67 | -------------------------------------------------------------------------------- /source/panel/state_panel/logo_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "../../gui/gui.hpp" 13 | #include "../../PluginProcessor.hpp" 14 | #include "../ui_setting_panel/ui_setting_panel.hpp" 15 | 16 | namespace zlpanel { 17 | class LogoPanel final : public juce::Component, public juce::SettableTooltipClient { 18 | public: 19 | explicit LogoPanel(PluginProcessor &p, 20 | zlgui::UIBase &base, 21 | UISettingPanel &uiSettingPanel); 22 | 23 | void paint(juce::Graphics &g) override; 24 | 25 | void setJustification(int justificationFlags); 26 | 27 | void mouseDoubleClick(const juce::MouseEvent &event) override; 28 | 29 | private: 30 | juce::AudioProcessorValueTreeState &state_ref_; 31 | zlgui::UIBase &ui_base_; 32 | UISettingPanel &panel_to_show_; 33 | const std::unique_ptr brand_drawable_, logo_drawable_; 34 | juce::Justification justification_{juce::Justification::topLeft}; 35 | }; 36 | } // zlpanel 37 | -------------------------------------------------------------------------------- /source/panel/state_panel/match_setting_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "../../gui/gui.hpp" 13 | 14 | namespace zlpanel { 15 | class MatchSettingPanel final : public juce::Component, 16 | public juce::SettableTooltipClient, 17 | private juce::ValueTree::Listener { 18 | public: 19 | explicit MatchSettingPanel(zlgui::UIBase &base); 20 | 21 | ~MatchSettingPanel() override; 22 | 23 | void paint(juce::Graphics &g) override; 24 | 25 | void mouseDown(const juce::MouseEvent &event) override; 26 | 27 | void mouseEnter(const juce::MouseEvent &event) override; 28 | 29 | private: 30 | zlgui::UIBase &ui_base_; 31 | juce::Identifier identifier_{"match_panel"}; 32 | 33 | void valueTreePropertyChanged(juce::ValueTree &tree_whose_property_has_changed, 34 | const juce::Identifier &property) override; 35 | }; 36 | } // zlpanel 37 | -------------------------------------------------------------------------------- /source/panel/state_panel/output_value_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "../../state/state.hpp" 13 | #include "../../gui/gui.hpp" 14 | #include "../../PluginProcessor.hpp" 15 | #include "../panel_definitons.hpp" 16 | 17 | namespace zlpanel { 18 | class OutputValuePanel final : public juce::Component, 19 | private juce::MultiTimer, 20 | private juce::ValueTree::Listener { 21 | public: 22 | explicit OutputValuePanel(PluginProcessor &p, 23 | zlgui::UIBase &base); 24 | 25 | ~OutputValuePanel() override; 26 | 27 | void paint(juce::Graphics &g) override; 28 | 29 | void resized() override; 30 | 31 | private: 32 | PluginProcessor &processor_ref_; 33 | juce::AudioProcessorValueTreeState ¶meters_ref_, ¶meters_NA_ref_; 34 | zlgui::UIBase &ui_base_; 35 | juce::RangedAudioParameter *lm_para_; 36 | std::atomic &scale_; 37 | float c_gain_{0.f}, c_scale_{100.f}; 38 | bool c_learning_{false}; 39 | juce::String gain_string_{"0.0"}, scale_string_{"100%"}; 40 | bool show_gain_{false}; 41 | juce::Rectangle gain_bound_, scale_bound_; 42 | juce::Path background_path_; 43 | 44 | void timerCallback(int timerID) override; 45 | 46 | void lookAndFeelChanged() override; 47 | 48 | void updateGainValue(); 49 | 50 | void valueTreePropertyChanged(juce::ValueTree &tree_whose_property_has_changed, 51 | const juce::Identifier &property) override; 52 | }; 53 | } // zlpanel 54 | -------------------------------------------------------------------------------- /source/panel/state_panel/setting_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "../../gui/gui.hpp" 13 | #include "../../PluginProcessor.hpp" 14 | 15 | namespace zlpanel { 16 | class SettingPanel final : public juce::Component, 17 | private juce::MultiTimer, private juce::ValueTree::Listener { 18 | public: 19 | explicit SettingPanel(PluginProcessor &p, zlgui::UIBase &base, 20 | const juce::String &label, zlgui::BoxIdx idx); 21 | 22 | ~SettingPanel() override; 23 | 24 | void paint(juce::Graphics &g) override; 25 | 26 | void mouseDown(const juce::MouseEvent &event) override; 27 | 28 | void mouseEnter(const juce::MouseEvent &event) override; 29 | 30 | void mouseExit(const juce::MouseEvent &event) override; 31 | 32 | private: 33 | juce::AudioProcessorValueTreeState ¶meters_ref_, ¶meters_NA_ref_; 34 | zlgui::UIBase &ui_base_; 35 | juce::String setting_name_; 36 | zlgui::BoxIdx box_idx_; 37 | 38 | void timerCallback(int timerID) override; 39 | 40 | void valueTreePropertyChanged(juce::ValueTree &tree_whose_property_has_changed, 41 | const juce::Identifier &property) override; 42 | }; 43 | } // zlpanel 44 | -------------------------------------------------------------------------------- /source/panel/state_panel/state_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "../../PluginProcessor.hpp" 13 | #include "../ui_setting_panel/ui_setting_panel.hpp" 14 | #include "logo_panel.hpp" 15 | #include "output_value_panel.hpp" 16 | #include "setting_panel.hpp" 17 | #include "match_setting_panel.hpp" 18 | 19 | namespace zlpanel { 20 | class StatePanel final : public juce::Component { 21 | public: 22 | explicit StatePanel(PluginProcessor &p, 23 | zlgui::UIBase &base, 24 | UISettingPanel &uiSettingPanel); 25 | 26 | void resized() override; 27 | 28 | private: 29 | constexpr static float kLabelSize = 2.75f; 30 | zlgui::UIBase &ui_base_; 31 | juce::AudioProcessorValueTreeState ¶meters_NA_ref_; 32 | 33 | OutputValuePanel output_value_panel_; 34 | SettingPanel output_setting_panel_; 35 | SettingPanel analyzer_setting_panel_; 36 | SettingPanel dynamic_setting_panel_; 37 | SettingPanel collision_setting_panel_; 38 | SettingPanel general_setting_panel_; 39 | MatchSettingPanel match_setting_panel_; 40 | LogoPanel logo_panel_; 41 | 42 | zlgui::CompactButton effect_c_, side_c_, sgc_c_; 43 | juce::OwnedArray > button_attachments_{}; 44 | const std::unique_ptr effect_drawable_; 45 | const std::unique_ptr side_drawable_; 46 | const std::unique_ptr sgc_drawable_; 47 | }; 48 | } // zlpanel 49 | -------------------------------------------------------------------------------- /source/panel/ui_setting_panel/control_setting_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "../../gui/gui.hpp" 13 | #include "../../PluginProcessor.hpp" 14 | 15 | namespace zlpanel { 16 | class ControlSettingPanel final : public juce::Component { 17 | public: 18 | static constexpr float kHeightP = 20.f; 19 | 20 | explicit ControlSettingPanel(PluginProcessor &p, zlgui::UIBase &base); 21 | 22 | ~ControlSettingPanel() override; 23 | 24 | void loadSetting(); 25 | 26 | void saveSetting(); 27 | 28 | void resetSetting(); 29 | 30 | void resized() override; 31 | 32 | void mouseDown(const juce::MouseEvent &event) override; 33 | 34 | private: 35 | PluginProcessor &processor_ref_; 36 | zlgui::UIBase &ui_base_; 37 | zlgui::NameLookAndFeel name_laf_; 38 | 39 | juce::Label wheel_label_; 40 | juce::Label drag_label_; 41 | std::array sensitivity_sliders_; 42 | zlgui::CompactCombobox wheel_reverse_box_; 43 | juce::Label rotary_style_label_; 44 | zlgui::CompactCombobox rotary_style_box_; 45 | zlgui::CompactLinearSlider rotary_drag_sensitivity_slider_; 46 | juce::Label slider_double_click_label_; 47 | zlgui::CompactCombobox slider_double_click_box_; 48 | 49 | juce::Label import_label_, export_label_; 50 | std::unique_ptr chooser_; 51 | inline auto static const kSettingDirectory = 52 | juce::File::getSpecialLocation(juce::File::userApplicationDataDirectory) 53 | .getChildFile("Audio") 54 | .getChildFile("Presets") 55 | .getChildFile(JucePlugin_Manufacturer) 56 | .getChildFile("Shared Settings"); 57 | 58 | void importControls(); 59 | 60 | void exportControls(); 61 | }; 62 | } // zlpanel 63 | -------------------------------------------------------------------------------- /source/panel/ui_setting_panel/other_ui_setting_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "../../gui/gui.hpp" 13 | #include "../../PluginProcessor.hpp" 14 | 15 | namespace zlpanel { 16 | class OtherUISettingPanel final : public juce::Component { 17 | public: 18 | static constexpr float kHeightP = 4.f * 7.f; 19 | 20 | explicit OtherUISettingPanel(PluginProcessor &p, zlgui::UIBase &base); 21 | 22 | void loadSetting(); 23 | 24 | void saveSetting(); 25 | 26 | void resetSetting(); 27 | 28 | void resized() override; 29 | 30 | void setRendererList(const juce::StringArray &rendererList); 31 | 32 | private: 33 | PluginProcessor &pRef; 34 | zlgui::UIBase &ui_base_; 35 | zlgui::NameLookAndFeel name_laf_; 36 | 37 | juce::Label rendering_engine_label_; 38 | zlgui::CompactCombobox rendering_engine_box_; 39 | juce::Label refresh_rate_label_; 40 | zlgui::CompactCombobox refresh_rate_box_; 41 | juce::Label fft_label_; 42 | zlgui::CompactLinearSlider fft_tilt_slider_, fft_speed_slider_; 43 | zlgui::CompactCombobox fft_order_box_; 44 | juce::Label curve_thick_label_; 45 | zlgui::CompactLinearSlider single_curve_slider_, sum_curve_slider_; 46 | juce::Label default_pass_filter_slope_label_; 47 | zlgui::CompactCombobox default_pass_filter_slope_box_; 48 | juce::Label dyn_link_label_; 49 | zlgui::CompactCombobox dyn_link_box_; 50 | juce::Label tooltip_label_; 51 | zlgui::CompactCombobox tooltip_on_box_, tooltip_lang_box_; 52 | }; 53 | } // zlpanel 54 | -------------------------------------------------------------------------------- /source/panel/ui_setting_panel/ui_setting_panel.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "../../PluginProcessor.hpp" 13 | #include "colour_setting_panel.hpp" 14 | #include "control_setting_panel.hpp" 15 | #include "other_ui_setting_panel.hpp" 16 | 17 | namespace zlpanel { 18 | class UISettingPanel final : public juce::Component { 19 | public: 20 | explicit UISettingPanel(PluginProcessor &p, zlgui::UIBase &base); 21 | 22 | ~UISettingPanel() override; 23 | 24 | void paint(juce::Graphics &g) override; 25 | 26 | void resized() override; 27 | 28 | void loadSetting(); 29 | 30 | void mouseDown(const juce::MouseEvent &event) override; 31 | 32 | void visibilityChanged() override; 33 | 34 | void setRendererList(const juce::StringArray &rendererList); 35 | 36 | private: 37 | PluginProcessor &processor_ref_; 38 | zlgui::UIBase &ui_base_; 39 | juce::Viewport view_port_; 40 | ColourSettingPanel colour_panel_; 41 | ControlSettingPanel control_panel_; 42 | OtherUISettingPanel other_panel_; 43 | const std::unique_ptr save_drawable_, close_drawable_, reset_drawable_; 44 | zlgui::ClickButton save_button_, close_button_, reset_button_; 45 | 46 | zlgui::NameLookAndFeel panel_name_laf_; 47 | std::array panel_labels_; 48 | 49 | juce::Label version_label_; 50 | zlgui::NameLookAndFeel label_laf_; 51 | 52 | enum PanelIdx { 53 | kColourP, 54 | kControlP, 55 | kOtherP 56 | }; 57 | 58 | PanelIdx current_panel_idx_ = kColourP; 59 | 60 | void changeDisplayPanel(); 61 | }; 62 | } // zlpanel 63 | -------------------------------------------------------------------------------- /source/state/dummy_processor.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | 14 | namespace zlstate { 15 | class DummyProcessor : public juce::AudioProcessor { 16 | public: 17 | DummyProcessor() = default; 18 | 19 | ~DummyProcessor() override = default; 20 | 21 | void prepareToPlay(double, int) override { 22 | } 23 | 24 | void releaseResources() override { 25 | } 26 | 27 | bool isBusesLayoutSupported(const BusesLayout &) const override { return true; } 28 | 29 | void processBlock(juce::AudioBuffer &, juce::MidiBuffer &) override { 30 | } 31 | 32 | void processBlock(juce::AudioBuffer &, juce::MidiBuffer &) override { 33 | } 34 | 35 | juce::AudioProcessorEditor *createEditor() override { return nullptr; } 36 | 37 | bool hasEditor() const override { return false; } 38 | 39 | const juce::String getName() const override { return {}; } 40 | 41 | bool acceptsMidi() const override { return false; } 42 | 43 | bool producesMidi() const override { return false; } 44 | 45 | bool isMidiEffect() const override { return false; } 46 | 47 | double getTailLengthSeconds() const override { return 0; } 48 | 49 | int getNumPrograms() override { return 1; } 50 | 51 | int getCurrentProgram() override { return 0; } 52 | 53 | void setCurrentProgram(int) override { 54 | } 55 | 56 | const juce::String getProgramName(int) override { return {}; } 57 | 58 | void changeProgramName(int, const juce::String &) override { 59 | } 60 | 61 | void getStateInformation(juce::MemoryBlock &) override { 62 | } 63 | 64 | void setStateInformation(const void *, int) override { 65 | } 66 | 67 | JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(DummyProcessor) 68 | }; 69 | } 70 | -------------------------------------------------------------------------------- /source/state/property.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #include "property.hpp" 11 | 12 | namespace zlstate { 13 | Property::Property() { 14 | if (!kPath.isDirectory()) { 15 | if (!kPath.createDirectory()) return; 16 | } 17 | ui_file_ = std::make_unique(kUIPath, juce::PropertiesFile::Options()); 18 | } 19 | 20 | Property::Property(juce::AudioProcessorValueTreeState &apvts) { 21 | if (!kPath.isDirectory()) { 22 | if (!kPath.createDirectory()) return; 23 | } 24 | ui_file_ = std::make_unique(kUIPath, juce::PropertiesFile::Options()); 25 | loadAPVTS(apvts); 26 | } 27 | 28 | void Property::loadAPVTS(juce::AudioProcessorValueTreeState &apvts) { 29 | const juce::ScopedReadLock scoped_lock(read_write_lock_); 30 | const auto file = ui_file_->getFile(); 31 | if (const auto xml = juce::XmlDocument::parse(file)) { 32 | apvts.replaceState(juce::ValueTree::fromXml(*xml)); 33 | } 34 | } 35 | 36 | void Property::saveAPVTS(juce::AudioProcessorValueTreeState &apvts) { 37 | const juce::ScopedWriteLock scoped_lock(read_write_lock_); 38 | const auto file = ui_file_->getFile(); 39 | if (const auto xml = apvts.copyState().createXml()) { 40 | if (!xml->writeTo(file)) return; 41 | } 42 | } 43 | } // namespace zlstate 44 | -------------------------------------------------------------------------------- /source/state/property.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include 13 | #include 14 | 15 | namespace zlstate { 16 | class Property { 17 | public: 18 | Property(); 19 | 20 | explicit Property(juce::AudioProcessorValueTreeState &apvts); 21 | 22 | void loadAPVTS(juce::AudioProcessorValueTreeState &apvts); 23 | 24 | void saveAPVTS(juce::AudioProcessorValueTreeState &apvts); 25 | 26 | private: 27 | std::unique_ptr ui_file_; 28 | juce::ReadWriteLock read_write_lock_; 29 | 30 | inline auto static const kPath = 31 | juce::File::getSpecialLocation(juce::File::userApplicationDataDirectory) 32 | .getChildFile("Audio") 33 | .getChildFile("Presets") 34 | .getChildFile(JucePlugin_Manufacturer) 35 | .getChildFile(JucePlugin_Name); 36 | inline auto static const kUIPath = 37 | kPath.getChildFile("ui.xml"); 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /source/state/state.hpp: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2025 - zsliu98 2 | // This file is part of ZLEqualizer 3 | // 4 | // ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation. 5 | // 6 | // ZLEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 7 | // 8 | // You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see . 9 | 10 | #pragma once 11 | 12 | #include "dummy_processor.hpp" 13 | #include "property.hpp" 14 | #include "state_definitions.hpp" 15 | 16 | 17 | --------------------------------------------------------------------------------