diff --git a/.clang-tidy b/.clang-tidy
index aff46bba6..5de9376e5 100644
--- a/.clang-tidy
+++ b/.clang-tidy
@@ -2,17 +2,22 @@
Checks: >
bugprone-macro-parentheses,
bugprone-macro-repeated-side-effects,
+ modernize-avoid-c-arrays,
+ modernize-loop-convert,
modernize-redundant-void-arg,
+ modernize-use-auto,
modernize-use-bool-literals,
modernize-use-emplace,
modernize-use-equals-default,
modernize-use-equals-delete,
modernize-use-override,
+ modernize-use-using,
performance-trivially-destructible,
+ readability-braces-around-statements,
+ readability-const-return-type,
readability-identifier-naming,
readability-misleading-indentation,
- readability-simplify-boolean-expr,
- readability-braces-around-statements
+ readability-simplify-boolean-expr
WarningsAsErrors: ''
HeaderFilterRegex: '' # don't show errors from headers
AnalyzeTemporaryDtors: false
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
deleted file mode 100644
index fcc875601..000000000
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ /dev/null
@@ -1,36 +0,0 @@
----
-name: Bug report
-about: Create a report to help us improve
-title: ''
-labels: bug
-assignees: ''
-
----
-
-# Please search the issue tracker for existing bug reports before submitting your own. Delete this line to confirm no similar report has been posted yet.
-
-### Bug Summary
-
-#### Steps to reproduce
-
-#### Expected behavior
-
-#### Actual behavior
-
-#### Screenshot
-
-#### Affected LMMS versions
-
-
-
-#### Logs
-
- Click to expand
-
-
-
-
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 000000000..4cd1464d6
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,90 @@
+# yamllint disable-file rule:line-length
+name: Bug Report
+description: File a bug report to help us improve
+labels:
+ - bug
+body:
+ - type: input
+ id: system-information
+ attributes:
+ label: System Information
+ description: |
+ - The operating system you use to run LMMS.
+ - When relevant, also include your hardware information.
+ placeholder: ex. Fedora Linux 39, KDE Plasma 5.27.10 - 13th Gen Intel® Core™ i9-13950HX, 32GB RAM
+ validations:
+ required: true
+ - type: input
+ id: affected-version
+ attributes:
+ label: LMMS Version(s)
+ description: |
+ - The version of LMMS affected by the bug.
+ - Can be an official version number, nightly release identifier, or commit hash.
+ - The version number can be found under the Help > About menu.
+ placeholder: ex. 1.2.2, 1.3.0-alpha.1.518+gdd53bec31, 2d185df
+ validations:
+ required: true
+ - type: input
+ id: working-version
+ attributes:
+ label: Most Recent Working Version
+ description: |
+ - If there is a previous version of LMMS that did not exhibit the bug, include it here.
+ placeholder: ex. 1.2.2, 1.3.0-alpha.1.518+gdd53bec31, 2d185df
+ validations:
+ required: false
+ - type: textarea
+ id: bug-summary
+ attributes:
+ label: Bug Summary
+ description: Briefly describe the bug.
+ validations:
+ required: true
+ - type: textarea
+ id: expected-behaviour
+ attributes:
+ label: Expected Behaviour
+ description: Describe what should have happened.
+ validations:
+ required: true
+ - type: textarea
+ id: steps-to-reproduce
+ attributes:
+ label: Steps To Reproduce
+ description: |
+ - Describe the minimum set of steps required to reproduce this bug.
+ - If you included a minimum reproducible project below, you can describe here how it should be used.
+ validations:
+ required: true
+ - type: textarea
+ id: logs
+ attributes:
+ label: Logs
+ description: |
+ - Copy and paste any relevant log output here.
+ value: |
+
+ Click to expand
+
+
+
+
+ validations:
+ required: false
+ - type: textarea
+ id: supporting-files
+ attributes:
+ label: Screenshots / Minimum Reproducible Project
+ description: |
+ - Upload any screenshots showing the bug in action.
+ - If possible, also include a .mmp/.mmpz project containing the simplest possible setup needed to reproduce the bug.
+
+ ***Note:** To upload a project file to GitHub, it will need to be placed in a .zip archive.*
+ - type: checkboxes
+ id: search-for-existing
+ attributes:
+ label: Please search the issue tracker for existing bug reports before submitting your own.
+ options:
+ - label: I have searched all existing issues and confirmed that this is not a duplicate.
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
deleted file mode 100644
index f9a0ae192..000000000
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ /dev/null
@@ -1,18 +0,0 @@
----
-name: Feature request
-about: Suggest an idea for this project
-title: ''
-labels: enhancement
-assignees: ''
-
----
-
-# Please search the issue tracker for existing feature requests before submitting your own. Delete this line to confirm no similar request has been posted yet.
-
-### Enhancement Summary
-
-#### Justification
-
-#### Mockup
-
-
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 000000000..1f11b4eb3
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,31 @@
+# yamllint disable-file rule:line-length
+name: Feature Request
+description: Suggest an idea for the project
+labels:
+ - "enhancement"
+body:
+ - type: textarea
+ id: enhancement-summary
+ attributes:
+ label: Enhancement Summary
+ description: |
+ - Briefly describe the enhancement.
+ - Explain why you believe the proposed enhancement to be a good idea, and (if applicable) how it helps overcome a limitation of LMMS you are currently facing.
+ validations:
+ required: true
+ - type: textarea
+ id: mockup
+ attributes:
+ label: Implementation Details / Mockup
+ description: |
+ - Explain how you believe this enhancement should be implemented.
+ - If your proposal encompasses changes to the user interface, include diagrams displaying your intent.
+ validations:
+ required: true
+ - type: checkboxes
+ id: search-for-existing
+ attributes:
+ label: Please search the issue tracker for existing feature requests before submitting your own.
+ options:
+ - label: I have searched all existing issues and confirmed that this is not a duplicate.
+ required: true
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 007842b82..b08c3ba20 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -14,7 +14,8 @@ jobs:
-DUSE_WERROR=ON
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DUSE_COMPILE_CACHE=ON
- CCACHE_MAXSIZE: 500M
+ CCACHE_MAXSIZE: 0
+ CCACHE_NOCOMPRESS: 1
MAKEFLAGS: -j2
steps:
- name: Update and configure Git
@@ -38,15 +39,16 @@ jobs:
path: ~/.ccache
- name: Configure
run: |
+ ccache --zero-stats
source /opt/qt5*/bin/qt5*-env.sh || true
mkdir build && cd build
cmake .. $CMAKE_OPTS -DCMAKE_INSTALL_PREFIX=./install
- name: Build
run: cmake --build build
- - name: Build tests
- run: cmake --build build --target tests
- name: Run tests
- run: build/tests/tests
+ run: |
+ cd build/tests
+ ctest --output-on-failure -j2
- name: Package
run: |
cmake --build build --target install
@@ -56,29 +58,42 @@ jobs:
with:
name: linux
path: build/lmms-*.AppImage
- - name: Print ccache statistics
+ - name: Trim ccache and print statistics
run: |
+ ccache --cleanup
echo "[ccache config]"
- ccache -p
+ ccache --print-config
echo "[ccache stats]"
- ccache -s
+ ccache --show-stats
+ env:
+ CCACHE_MAXSIZE: 500M
macos:
name: macos
- runs-on: macos-11
+ runs-on: macos-12
env:
CMAKE_OPTS: >-
-DUSE_WERROR=ON
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DUSE_COMPILE_CACHE=ON
- CCACHE_MAXSIZE: 500M
+ CCACHE_MAXSIZE: 0
+ CCACHE_NOCOMPRESS: 1
MAKEFLAGS: -j3
- DEVELOPER_DIR: /Applications/Xcode_11.7.app/Contents/Developer
+ DEVELOPER_DIR: /Applications/Xcode_13.1.app/Contents/Developer
steps:
- name: Check out
uses: actions/checkout@v3
with:
fetch-depth: 0
submodules: recursive
+ - name: Clean up Homebrew download cache
+ run: rm -rf ~/Library/Caches/Homebrew/downloads
+ - name: Restore Homebrew download cache
+ uses: actions/cache/restore@v3
+ with:
+ key: n/a - only restore from restore-keys
+ restore-keys: |
+ homebrew-
+ path: ~/Library/Caches/Homebrew/downloads
- name: Cache ccache data
uses: actions/cache@v3
with:
@@ -89,12 +104,16 @@ jobs:
path: ~/Library/Caches/ccache
- name: Install dependencies
run: |
- brew install ccache fftw pkg-config libogg libvorbis lame libsndfile \
- libsamplerate jack sdl libgig libsoundio lilv lv2 stk \
- fluid-synth portaudio fltk qt@5 carla
+ brew bundle install --verbose
+ npm update -g npm
npm install --location=global appdmg
+ env:
+ HOMEBREW_NO_AUTO_UPDATE: 1
+ HOMEBREW_NO_INSTALL_UPGRADE: 1
+ HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK: 1
- name: Configure
run: |
+ ccache --zero-stats
mkdir build
cmake -S . \
-B build \
@@ -104,10 +123,10 @@ jobs:
-DUSE_WERROR=OFF
- name: Build
run: cmake --build build
- - name: Build tests
- run: cmake --build build --target tests
- name: Run tests
- run: build/tests/tests
+ run: |
+ cd build/tests
+ ctest --output-on-failure -j3
- name: Package
run: |
cmake --build build --target install
@@ -117,12 +136,20 @@ jobs:
with:
name: macos
path: build/lmms-*.dmg
- - name: Print ccache statistics
+ - name: Trim ccache and print statistics
run: |
+ ccache --cleanup
echo "[ccache config]"
- ccache -p
+ ccache --show-config
echo "[ccache stats]"
- ccache -s
+ ccache --show-stats --verbose
+ env:
+ CCACHE_MAXSIZE: 500MB
+ - name: Save Homebrew download cache
+ uses: actions/cache/save@v3
+ with:
+ key: homebrew-${{ hashFiles('Brewfile.lock.json') }}
+ path: ~/Library/Caches/Homebrew/downloads
mingw:
strategy:
fail-fast: false
@@ -136,7 +163,8 @@ jobs:
-DUSE_WERROR=ON
-DCMAKE_BUILD_TYPE=RelWithDebInfo
-DUSE_COMPILE_CACHE=ON
- CCACHE_MAXSIZE: 500M
+ CCACHE_MAXSIZE: 0
+ CCACHE_NOCOMPRESS: 1
MAKEFLAGS: -j2
steps:
- name: Update and configure Git
@@ -161,12 +189,11 @@ jobs:
path: ~/.ccache
- name: Configure
run: |
+ ccache --zero-stats
mkdir build && cd build
../cmake/build_win${{ matrix.arch }}.sh
- name: Build
run: cmake --build build
- - name: Build tests
- run: cmake --build build --target tests
- name: Package
run: cmake --build build --target package
- name: Upload artifacts
@@ -174,12 +201,15 @@ jobs:
with:
name: mingw${{ matrix.arch }}
path: build/lmms-*.exe
- - name: Print ccache statistics
+ - name: Trim ccache and print statistics
run: |
+ ccache --cleanup
echo "[ccache config]"
- ccache -p
+ ccache --print-config
echo "[ccache stats]"
- ccache -s
+ ccache --show-stats
+ env:
+ CCACHE_MAXSIZE: 500M
msvc:
strategy:
fail-fast: false
@@ -189,6 +219,8 @@ jobs:
runs-on: windows-2019
env:
qt-version: '5.15.2'
+ CCACHE_MAXSIZE: 0
+ CCACHE_NOCOMPRESS: 1
steps:
- name: Check out
uses: actions/checkout@v3
@@ -196,53 +228,66 @@ jobs:
fetch-depth: 0
submodules: recursive
- name: Cache vcpkg dependencies
+ id: cache-deps
uses: actions/cache@v3
with:
- key: vcpkg-${{ matrix.arch }}-${{ github.ref }}-${{ github.run_id }}
+ key: vcpkg-${{ matrix.arch }}-${{ hashFiles('vcpkg.json') }}
restore-keys: |
- vcpkg-${{ matrix.arch }}-${{ github.ref }}-
vcpkg-${{ matrix.arch }}-
- path: C:\vcpkg\installed
+ path: build\vcpkg_installed
+ - name: Cache ccache data
+ uses: actions/cache@v3
+ with:
+ key: "ccache-${{ github.job }}-${{ matrix.arch }}-${{ github.ref }}\
+ -${{ github.run_id }}"
+ restore-keys: |
+ ccache-${{ github.job }}-${{ matrix.arch }}-${{ github.ref }}-
+ ccache-${{ github.job }}-${{ matrix.arch }}-
+ path: ~\AppData\Local\ccache
+ - name: Install tools
+ run: choco install ccache
- name: Install 64-bit Qt
if: matrix.arch == 'x64'
- uses: jurplel/install-qt-action@64bdb64f2c14311d23733a8463e5fcbc65e8775e
+ uses: jurplel/install-qt-action@b3ea5275e37b734d027040e2c7fe7a10ea2ef946
with:
version: ${{ env.qt-version }}
arch: win64_msvc2019_64
archives: qtbase qtsvg qttools
cache: true
- name: Install 32-bit Qt
- uses: jurplel/install-qt-action@64bdb64f2c14311d23733a8463e5fcbc65e8775e
+ uses: jurplel/install-qt-action@b3ea5275e37b734d027040e2c7fe7a10ea2ef946
with:
version: ${{ env.qt-version }}
arch: win32_msvc2019
archives: qtbase qtsvg qttools
cache: true
set-env: ${{ matrix.arch == 'x86' }}
- - name: Install dependencies
- run: |
- vcpkg install `
- --triplet=${{ matrix.arch }}-windows `
- --host-triplet=${{ matrix.arch }}-windows `
- --recurse `
- fftw3 fltk fluidsynth[sndfile] libsamplerate libsndfile libstk `
- lilv lv2 portaudio sdl2
- name: Set up build environment
- uses: ilammy/msvc-dev-cmd@d8610e2b41c6d0f0c3b4c46dad8df0fd826c68e1
+ uses: ilammy/msvc-dev-cmd@cec98b9d092141f74527d0afa6feb2af698cfe89
with:
arch: ${{ matrix.arch }}
- name: Configure
run: |
- mkdir build
+ ccache --zero-stats
+ mkdir build -Force
cmake -S . `
-B build `
-G Ninja `
--toolchain C:/vcpkg/scripts/buildsystems/vcpkg.cmake `
- -DCMAKE_BUILD_TYPE=RelWithDebInfo
+ -DCMAKE_BUILD_TYPE=RelWithDebInfo `
+ -DUSE_COMPILE_CACHE=ON `
+ -DVCPKG_TARGET_TRIPLET="${{ matrix.arch }}-windows" `
+ -DVCPKG_HOST_TRIPLET="${{ matrix.arch }}-windows" `
+ -DVCPKG_MANIFEST_INSTALL="${{ env.should_install_manifest }}"
+ env:
+ should_install_manifest:
+ ${{ steps.cache-deps.outputs.cache-hit == 'true' && 'NO' || 'YES' }}
- name: Build
run: cmake --build build
- - name: Build tests
- run: cmake --build build --target tests
+ - name: Run tests
+ run: |
+ cd build/tests
+ ctest --output-on-failure -j2
- name: Package
run: cmake --build build --target package
- name: Upload artifacts
@@ -250,3 +295,12 @@ jobs:
with:
name: msvc-${{ matrix.arch }}
path: build\lmms-*.exe
+ - name: Trim ccache and print statistics
+ run: |
+ ccache --cleanup
+ echo "[ccache config]"
+ ccache --show-config
+ echo "[ccache stats]"
+ ccache --show-stats --verbose
+ env:
+ CCACHE_MAXSIZE: 500MB
diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml
index 1d893989e..3f7700674 100644
--- a/.github/workflows/checks.yml
+++ b/.github/workflows/checks.yml
@@ -21,7 +21,7 @@ jobs:
run: tests/scripted/check-namespace
shellcheck:
runs-on: ubuntu-latest
- container: koalaman/shellcheck-alpine:v0.4.6
+ container: koalaman/shellcheck-alpine:v0.9.0
steps:
- name: Check out
uses: actions/checkout@v3
diff --git a/.gitignore b/.gitignore
index ee289379f..cc2823ba0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
-/build
-/target
+/build/
+/target/
.*.sw?
.DS_Store
*~
@@ -9,3 +9,4 @@
/plugins/ZynAddSubFx/zynaddsubfx/doc/Makefile
/plugins/ZynAddSubFx/zynaddsubfx/doc/gen/Makefile
/data/locale/*.qm
+Brewfile.lock.json
diff --git a/.gitmodules b/.gitmodules
index 2ccfcbcdf..1c43fd1b3 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,15 +1,12 @@
[submodule "src/3rdparty/qt5-x11embed"]
path = src/3rdparty/qt5-x11embed
url = https://github.com/Lukas-W/qt5-x11embed.git
-[submodule "src/3rdparty/rpmalloc/rpmalloc"]
- path = src/3rdparty/rpmalloc/rpmalloc
- url = https://github.com/mjansson/rpmalloc.git
[submodule "plugins/ZynAddSubFx/zynaddsubfx"]
path = plugins/ZynAddSubFx/zynaddsubfx
url = https://github.com/lmms/zynaddsubfx.git
[submodule "plugins/FreeBoy/game-music-emu"]
path = plugins/FreeBoy/game-music-emu
- url = https://bitbucket.org/mpyne/game-music-emu.git
+ url = https://github.com/libgme/game-music-emu.git
[submodule "plugins/OpulenZ/adplug"]
path = plugins/OpulenZ/adplug
url = https://github.com/adplug/adplug.git
@@ -24,7 +21,7 @@
url = https://github.com/swh/ladspa
[submodule "plugins/LadspaEffect/tap/tap-plugins"]
path = plugins/LadspaEffect/tap/tap-plugins
- url = https://github.com/tomszilagyi/tap-plugins
+ url = https://github.com/lmms/tap-plugins
[submodule "src/3rdparty/weakjack/weakjack"]
path = src/3rdparty/weakjack/weakjack
url = https://github.com/x42/weakjack.git
@@ -40,12 +37,15 @@
[submodule "plugins/CarlaBase/carla"]
path = plugins/CarlaBase/carla
url = https://github.com/falktx/carla
-[submodule "plugins/Sid/resid"]
- path = plugins/Sid/resid
- url = https://github.com/simonowen/resid
+[submodule "plugins/Sid/resid/resid"]
+ path = plugins/Sid/resid/resid
+ url = https://github.com/libsidplayfp/resid
[submodule "src/3rdparty/jack2"]
path = src/3rdparty/jack2
url = https://github.com/jackaudio/jack2
[submodule "plugins/LadspaEffect/cmt/cmt"]
path = plugins/LadspaEffect/cmt/cmt
url = https://github.com/lmms/cmt
+[submodule "src/3rdparty/hiir/hiir"]
+ path = src/3rdparty/hiir/hiir
+ url = https://github.com/LostRobotMusic/hiir
diff --git a/Brewfile b/Brewfile
new file mode 100644
index 000000000..1bfbd7b01
--- /dev/null
+++ b/Brewfile
@@ -0,0 +1,20 @@
+brew "carla"
+brew "ccache"
+brew "fftw"
+brew "fltk"
+brew "fluid-synth"
+brew "jack"
+brew "lame"
+brew "libgig"
+brew "libogg"
+brew "libsamplerate"
+brew "libsndfile"
+brew "libsoundio"
+brew "libvorbis"
+brew "lilv"
+brew "lv2"
+brew "pkg-config"
+brew "portaudio"
+brew "qt@5"
+brew "sdl2"
+brew "stk"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c5de064a5..8401c3c41 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,24 +1,31 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.9)
+# Set the given policy to NEW. If it does not exist, it will not be set. If it
+# is already set to NEW (most likely due to predating the minimum required CMake
+# version), a developer warning is emitted indicating that the policy need no
+# longer be explicitly set.
+function(enable_policy_if_exists id)
+ if(POLICY "${id}")
+ cmake_policy(GET "${id}" current_value)
+ if(current_value STREQUAL "NEW")
+ message(AUTHOR_WARNING "${id} is now set to NEW by default, and no longer needs to be explicitly set.")
+ else()
+ cmake_policy(SET "${id}" NEW)
+ endif()
+ endif()
+endfunction()
+
+# Needed for the SWH Ladspa plugins. See below.
+enable_policy_if_exists(CMP0074) # find_package() uses _ROOT variables.
+# Needed for ccache support with MSVC
+enable_policy_if_exists(CMP0141) # MSVC debug information format flags are selected by an abstraction.
+
PROJECT(lmms)
SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules" ${CMAKE_MODULE_PATH})
SET(LMMS_BINARY_DIR ${CMAKE_BINARY_DIR})
SET(LMMS_SOURCE_DIR ${CMAKE_SOURCE_DIR})
-IF(COMMAND CMAKE_POLICY)
- CMAKE_POLICY(SET CMP0005 NEW)
- CMAKE_POLICY(SET CMP0003 NEW)
- IF (CMAKE_MAJOR_VERSION GREATER 2)
- CMAKE_POLICY(SET CMP0026 NEW)
- CMAKE_POLICY(SET CMP0045 NEW)
- CMAKE_POLICY(SET CMP0050 OLD)
- ENDIF()
- CMAKE_POLICY(SET CMP0020 NEW)
- CMAKE_POLICY(SET CMP0057 NEW)
-ENDIF(COMMAND CMAKE_POLICY)
-
-
# Import of windows.h breaks min()/max()
ADD_DEFINITIONS(-DNOMINMAX)
@@ -39,7 +46,7 @@ INCLUDE(GenerateExportHeader)
STRING(TOUPPER "${CMAKE_PROJECT_NAME}" PROJECT_NAME_UCASE)
-SET(PROJECT_YEAR 2020)
+SET(PROJECT_YEAR 2024)
SET(PROJECT_AUTHOR "LMMS Developers")
SET(PROJECT_URL "https://lmms.io")
@@ -64,6 +71,7 @@ INCLUDE(VersionInfo)
INCLUDE(DetectMachine)
OPTION(WANT_ALSA "Include ALSA (Advanced Linux Sound Architecture) support" ON)
+OPTION(WANT_OSS "Include Open Sound System support" ON)
OPTION(WANT_CALF "Include CALF LADSPA plugins" ON)
OPTION(WANT_CAPS "Include C* Audio Plugin Suite (LADSPA plugins)" ON)
OPTION(WANT_CARLA "Include Carla plugin" ON)
@@ -81,14 +89,19 @@ OPTION(WANT_SOUNDIO "Include libsoundio support" ON)
OPTION(WANT_SDL "Include SDL (Simple DirectMedia Layer) support" ON)
OPTION(WANT_SF2 "Include SoundFont2 player plugin" ON)
OPTION(WANT_GIG "Include GIG player plugin" ON)
+option(WANT_SID "Include Sid instrument" ON)
OPTION(WANT_STK "Include Stk (Synthesis Toolkit) support" ON)
OPTION(WANT_SWH "Include Steve Harris's LADSPA plugins" ON)
OPTION(WANT_TAP "Include Tom's Audio Processing LADSPA plugins" ON)
OPTION(WANT_VST "Include VST support" ON)
-OPTION(WANT_VST_32 "Include 32-bit VST support" ON)
-OPTION(WANT_VST_64 "Include 64-bit VST support" ON)
+OPTION(WANT_VST_32 "Include 32-bit Windows VST support" ON)
+OPTION(WANT_VST_64 "Include 64-bit Windows VST support" ON)
OPTION(WANT_WINMM "Include WinMM MIDI support" OFF)
OPTION(WANT_DEBUG_FPE "Debug floating point exceptions" OFF)
+option(WANT_DEBUG_ASAN "Enable AddressSanitizer" OFF)
+option(WANT_DEBUG_TSAN "Enable ThreadSanitizer" OFF)
+option(WANT_DEBUG_MSAN "Enable MemorySanitizer" OFF)
+option(WANT_DEBUG_UBSAN "Enable UndefinedBehaviorSanitizer" OFF)
OPTION(BUNDLE_QT_TRANSLATIONS "Install Qt translation files for LMMS" OFF)
@@ -97,9 +110,11 @@ IF(LMMS_BUILD_APPLE)
LINK_DIRECTORIES("${APPLE_PREFIX}/lib")
SET(WANT_SOUNDIO OFF)
SET(WANT_ALSA OFF)
+ SET(WANT_OSS OFF)
SET(WANT_PULSEAUDIO OFF)
SET(WANT_VST OFF)
SET(STATUS_ALSA "")
+ SET(STATUS_OSS "")
SET(STATUS_PULSEAUDIO "")
SET(STATUS_APPLEMIDI "OK")
ELSE(LMMS_BUILD_APPLE)
@@ -109,13 +124,18 @@ ENDIF(LMMS_BUILD_APPLE)
IF(LMMS_BUILD_WIN32)
SET(WANT_ALSA OFF)
+ SET(WANT_OSS OFF)
SET(WANT_PULSEAUDIO OFF)
SET(WANT_SNDIO OFF)
SET(WANT_SOUNDIO OFF)
SET(WANT_WINMM ON)
SET(BUNDLE_QT_TRANSLATIONS ON)
SET(LMMS_HAVE_WINMM TRUE)
+ if(NOT LMMS_BUILD_WIN64)
+ set(WANT_VST_64 OFF)
+ endif()
SET(STATUS_ALSA "")
+ SET(STATUS_OSS "")
SET(STATUS_PULSEAUDIO "")
SET(STATUS_SOUNDIO "")
SET(STATUS_SNDIO "")
@@ -200,7 +220,14 @@ SET(QT_QTTEST_LIBRARY Qt5::Test)
# check for libsndfile
FIND_PACKAGE(SndFile REQUIRED)
-IF(NOT SNDFILE_FOUND)
+IF(SNDFILE_FOUND)
+ IF(SndFile_VERSION VERSION_GREATER_EQUAL "1.1.0")
+ SET(LMMS_HAVE_SNDFILE_MP3 TRUE)
+ ELSE()
+ MESSAGE("libsndfile version is < 1.1.0; MP3 import disabled")
+ SET(LMMS_HAVE_SNDFILE_MP3 FALSE)
+ ENDIF()
+ELSE()
MESSAGE(FATAL_ERROR "LMMS requires libsndfile1 and libsndfile1-dev >= 1.0.18 - please install, remove CMakeCache.txt and try again!")
ENDIF()
# check if we can use SFC_SET_COMPRESSION_LEVEL
@@ -211,6 +238,13 @@ CHECK_CXX_SOURCE_COMPILES(
LMMS_HAVE_SF_COMPLEVEL
)
+# check for perl
+if(LMMS_BUILD_APPLE)
+ # Prefer system perl over Homebrew, MacPorts, etc
+ set(Perl_ROOT "/usr/bin")
+endif()
+find_package(Perl)
+
IF(WANT_LV2)
IF(PKG_CONFIG_FOUND)
PKG_CHECK_MODULES(LV2 lv2)
@@ -273,8 +307,12 @@ ELSE(WANT_CMT)
ENDIF(WANT_CMT)
IF(WANT_SWH)
- SET(LMMS_HAVE_SWH TRUE)
- SET(STATUS_SWH "OK")
+ IF(PERL_FOUND)
+ SET(LMMS_HAVE_SWH TRUE)
+ SET(STATUS_SWH "OK")
+ ELSE()
+ SET(STATUS_SWH "Skipping, perl is missing")
+ ENDIF()
ELSE(WANT_SWH)
SET(STATUS_SWH "not built as requested")
ENDIF(WANT_SWH)
@@ -340,6 +378,16 @@ IF(WANT_SDL AND NOT LMMS_HAVE_SDL2)
ENDIF()
ENDIF()
+# check for Sid
+if(WANT_SID)
+ if(PERL_FOUND)
+ set(LMMS_HAVE_SID TRUE)
+ set(STATUS_SID "OK")
+ else()
+ set(STATUS_SID "not found, please install perl if you require the Sid instrument")
+ endif()
+endif()
+
# check for Stk
IF(WANT_STK)
FIND_PACKAGE(STK)
@@ -406,8 +454,6 @@ IF(WANT_MP3LAME)
SET(STATUS_MP3LAME "OK")
ELSE(LAME_FOUND)
SET(STATUS_MP3LAME "not found, please install libmp3lame-dev (or similar)")
- SET(LAME_LIBRARIES "")
- SET(LAME_INCLUDE_DIRS "")
ENDIF(LAME_FOUND)
ELSE(WANT_MP3LAME)
SET(STATUS_MP3LAME "Disabled for build")
@@ -426,13 +472,13 @@ IF(WANT_OGGVORBIS)
ENDIF(WANT_OGGVORBIS)
-# check whether to enable OSS-support
-IF(LMMS_HAVE_SOUNDCARD_H OR LMMS_HAVE_SYS_SOUNDCARD_H)
+# check for OSS
+IF(WANT_OSS AND (LMMS_HAVE_SOUNDCARD_H OR LMMS_HAVE_SYS_SOUNDCARD_H))
SET(LMMS_HAVE_OSS TRUE)
SET(STATUS_OSS "OK")
-ELSE(LMMS_HAVE_SOUNDCARD_H OR LMMS_HAVE_SYS_SOUNDCARD_H)
+ELSEIF(WANT_OSS)
SET(STATUS_OSS "")
-ENDIF(LMMS_HAVE_SOUNDCARD_H OR LMMS_HAVE_SYS_SOUNDCARD_H)
+ENDIF()
# check for ALSA
@@ -502,10 +548,14 @@ ENDIF()
# check for Fluidsynth
IF(WANT_SF2)
- find_package(FluidSynth 1.1.0)
+ find_package(FluidSynth 1.1.7)
if(FluidSynth_FOUND)
SET(LMMS_HAVE_FLUIDSYNTH TRUE)
- SET(STATUS_FLUIDSYNTH "OK")
+ if(FluidSynth_VERSION_STRING VERSION_GREATER_EQUAL 2)
+ set(STATUS_FLUIDSYNTH "OK")
+ else()
+ set(STATUS_FLUIDSYNTH "OK (FluidSynth version < 2: per-note panning unsupported)")
+ endif()
else()
SET(STATUS_FLUIDSYNTH "not found, libfluidsynth-dev (or similar)"
"is highly recommended")
@@ -540,26 +590,42 @@ IF(WANT_SNDIO)
ENDIF(WANT_SNDIO)
# check for WINE
-IF(WANT_VST)
- FIND_PACKAGE(Wine)
- IF(WINE_FOUND)
- SET(LMMS_SUPPORT_VST TRUE)
- IF(WINE_LIBRARY_FIX)
- SET(STATUS_VST "OK, with workaround linking ${WINE_LIBRARY_FIX}")
- ELSE()
- SET(STATUS_VST "OK")
- ENDIF()
- ELSEIF(WANT_VST_NOWINE)
- SET(LMMS_SUPPORT_VST TRUE)
- SET(STATUS_VST "OK")
- ELSE(WINE_FOUND)
- SET(STATUS_VST "not found, please install (lib)wine-dev (or similar) - 64 bit systems additionally need gcc-multilib and g++-multilib")
- ENDIF(WINE_FOUND)
-ENDIF(WANT_VST)
-IF(LMMS_BUILD_WIN32)
- SET(LMMS_SUPPORT_VST TRUE)
- SET(STATUS_VST "OK")
-ENDIF(LMMS_BUILD_WIN32)
+if(WANT_VST)
+ if((WANT_VST_32 OR WANT_VST_64) AND NOT LMMS_BUILD_WIN32)
+ find_package(Wine)
+ include(CheckWineGcc)
+ endif()
+ macro(check_vst bits)
+ if(NOT WANT_VST_${bits})
+ set(STATUS_VST_${bits} "Not built, as requested")
+ elseif(LMMS_BUILD_WIN32)
+ set(STATUS_VST_${bits} "OK")
+ set(LMMS_HAVE_VST_${bits} TRUE)
+ elseif(NOT WINE_FOUND)
+ set(STATUS_VST_${bits} "not found, please install (lib)wine-dev (or similar) - 64 bit systems additionally need gcc-multilib and g++-multilib")
+ else()
+ CheckWineGcc("${bits}" "${WINEGCC}" WINEGCC_WORKING)
+ if(WINEGCC_WORKING)
+ set(LMMS_HAVE_VST_${bits} TRUE)
+ if(WINE_LIBRARY_FIX)
+ set(STATUS_VST_${bits} "OK, with workaround linking ${WINE_LIBRARY_FIX}")
+ else()
+ set(STATUS_VST_${bits} "OK")
+ endif()
+ else()
+ set(STATUS_VST_${bits} "winegcc fails to compile ${bits}-bit binaries, please make sure you have ${bits}-bit GCC libraries")
+ endif()
+ endif()
+ endmacro()
+ check_vst(32)
+ check_vst(64)
+ if(LMMS_HAVE_VST_32 OR LMMS_HAVE_VST_64 OR LMMS_BUILD_LINUX)
+ set(LMMS_HAVE_VST TRUE)
+ set(STATUS_VST "OK")
+ else()
+ set(STATUS_VST "No hosts selected and available")
+ endif()
+endif()
IF(WANT_DEBUG_FPE)
IF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE)
@@ -616,7 +682,9 @@ else()
set(NOOP_COMMAND "${CMAKE_COMMAND}" "-E" "echo")
endif()
if(STRIP)
- set(STRIP_COMMAND "$,${NOOP_COMMAND},${STRIP}>")
+ # TODO CMake 3.19: Now that CONFIG generator expressions support testing for
+ # multiple configurations, combine the OR into a single CONFIG expression.
+ set(STRIP_COMMAND "$,$>,${NOOP_COMMAND},${STRIP}>")
else()
set(STRIP_COMMAND "${NOOP_COMMAND}")
endif()
@@ -652,8 +720,36 @@ IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
ELSE(WIN32)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -DPIC")
ENDIF(WIN32)
+elseif(MSVC)
+ # Use UTF-8 as the source and execution character set
+ add_compile_options("/utf-8")
ENDIF()
+# add enabled sanitizers
+function(add_sanitizer sanitizer supported_compilers want_flag status_flag)
+ if(${want_flag})
+ if(CMAKE_CXX_COMPILER_ID MATCHES "${supported_compilers}")
+ set("${status_flag}" "Enabled" PARENT_SCOPE)
+ string(REPLACE ";" " " additional_flags "${ARGN}")
+ # todo CMake 3.13: use add_compile_options/add_link_options instead
+ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fsanitize=${sanitizer} ${additional_flags}" PARENT_SCOPE)
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=${sanitizer} ${additional_flags}" PARENT_SCOPE)
+ else()
+ set("${status_flag}" "Wanted but disabled due to unsupported compiler" PARENT_SCOPE)
+ endif()
+ else()
+ set("${status_flag}" "Disabled" PARENT_SCOPE)
+ endif()
+endfunction()
+
+add_sanitizer(address "GNU|Clang|MSVC" WANT_DEBUG_ASAN STATUS_DEBUG_ASAN)
+add_sanitizer(thread "GNU|Clang" WANT_DEBUG_TSAN STATUS_DEBUG_TSAN)
+add_sanitizer(memory "Clang" WANT_DEBUG_MSAN STATUS_DEBUG_MSAN -fno-omit-frame-pointer)
+# UBSan does not link with vptr enabled due to a problem with references from PeakControllerEffect
+# not being found by PeakController
+add_sanitizer(undefined "GNU|Clang" WANT_DEBUG_UBSAN STATUS_DEBUG_UBSAN -fno-sanitize=vptr)
+
+
# use ccache
include(CompileCache)
@@ -722,7 +818,6 @@ ADD_CUSTOM_TARGET(uninstall
COMMAND ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}" -P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/uninstall.cmake"
)
-
#
# display configuration information
#
@@ -774,9 +869,11 @@ MESSAGE(
"* ZynAddSubFX instrument : ${STATUS_ZYN}\n"
"* Carla Patchbay & Rack : ${STATUS_CARLA}\n"
"* SoundFont2 player : ${STATUS_FLUIDSYNTH}\n"
+"* Sid instrument : ${STATUS_SID}\n"
"* Stk Mallets : ${STATUS_STK}\n"
-"* VST-instrument hoster : ${STATUS_VST}\n"
-"* VST-effect hoster : ${STATUS_VST}\n"
+"* VST plugin host : ${STATUS_VST}\n"
+" * 32-bit Windows host : ${STATUS_VST_32}\n"
+" * 64-bit Windows host : ${STATUS_VST_64}\n"
"* CALF LADSPA plugins : ${STATUS_CALF}\n"
"* CAPS LADSPA plugins : ${STATUS_CAPS}\n"
"* CMT LADSPA plugins : ${STATUS_CMT}\n"
@@ -788,7 +885,11 @@ MESSAGE(
MESSAGE(
"Developer options\n"
"-----------------------------------------\n"
-"* Debug FP exceptions : ${STATUS_DEBUG_FPE}\n"
+"* Debug FP exceptions : ${STATUS_DEBUG_FPE}\n"
+"* Debug using AddressSanitizer : ${STATUS_DEBUG_ASAN}\n"
+"* Debug using ThreadSanitizer : ${STATUS_DEBUG_TSAN}\n"
+"* Debug using MemorySanitizer : ${STATUS_DEBUG_MSAN}\n"
+"* Debug using UBSanitizer : ${STATUS_DEBUG_UBSAN}\n"
)
MESSAGE(
diff --git a/README.md b/README.md
index 7090a6a15..c8324226e 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,11 @@
#  LMMS
-[](https://circleci.com/gh/LMMS/lmms)
+[](https://github.com/LMMS/lmms/actions/workflows/build.yml)
[](https://lmms.io/download)
[](https://github.com/LMMS/lmms/releases)
[](https://discord.gg/3sc5su7)
[](https://www.transifex.com/lmms/lmms/)
-**New PRs may be affected by ongoing reorganization ([#5592](https://github.com/LMMS/lmms/issues/5592)). Please be prepared to rebase your PR as necessary.**
-
What is LMMS?
--------------
diff --git a/cmake/apple/install_apple.sh.in b/cmake/apple/install_apple.sh.in
index e1921b1a5..fc27d78b3 100644
--- a/cmake/apple/install_apple.sh.in
+++ b/cmake/apple/install_apple.sh.in
@@ -6,9 +6,6 @@
set -e
-# STK rawwaves directory
-STK_RAWWAVE=$(brew --prefix stk)/share/stk/rawwaves
-
# Place to create ".app" bundle
APP="@CMAKE_BINARY_DIR@/@PROJECT_NAME_UCASE@.app"
@@ -29,19 +26,15 @@ command cp "@CMAKE_BINARY_DIR@/Info.plist" "@CMAKE_INSTALL_PREFIX@/"
mkdir -p "$APP/Contents/MacOS"
mkdir -p "$APP/Contents/Frameworks"
mkdir -p "$APP/Contents/Resources"
-mkdir -p "$APP/Contents/share/stk/rawwaves"
cd "@CMAKE_INSTALL_PREFIX@"
cp -R ./* "$APP/Contents"
cp "@CMAKE_SOURCE_DIR@/cmake/apple/"*.icns "$APP/Contents/Resources/"
-cp "$STK_RAWWAVE"/*.raw "$APP/Contents/share/stk/rawwaves" > /dev/null 2>&1
# Make all libraries writable for macdeployqt
cd "$APP"
find . -type f -print0 | xargs -0 chmod u+w
lmmsbin="MacOS/@CMAKE_PROJECT_NAME@"
-zynlib="lib/lmms/libzynaddsubfx.so"
-zynfmk="Frameworks/libZynAddSubFxCore.dylib"
zynbin="MacOS/RemoteZynAddSubFx"
# Move lmms binary
@@ -49,15 +42,6 @@ mv "$APP/Contents/bin/@CMAKE_PROJECT_NAME@" "$APP/Contents/$lmmsbin"
# Fix zyn linking
mv "$APP/Contents/lib/lmms/RemoteZynAddSubFx" "$APP/Contents/$zynbin"
-mv "$APP/Contents/lib/lmms/libZynAddSubFxCore.dylib" "$APP/Contents/$zynfmk"
-
-install_name_tool -change @rpath/libZynAddSubFxCore.dylib \
- @loader_path/../$zynfmk \
- "$APP/Contents/$zynbin"
-
-install_name_tool -change @rpath/libZynAddSubFxCore.dylib \
- @loader_path/../../$zynfmk \
- "$APP/Contents/$zynlib"
# Replace @rpath with @loader_path for Carla
# See also plugins/CarlaBase/CMakeLists.txt
@@ -72,7 +56,6 @@ install_name_tool -change @rpath/libcarlabase.dylib \
# Link lmms binary
_executables="${_executables} -executable=$APP/Contents/$zynbin"
-_executables="${_executables} -executable=$APP/Contents/$zynfmk"
# Build a list of shared objects in target/lib/lmms
for file in "$APP/Contents/lib/lmms/"*.so; do
@@ -114,4 +97,8 @@ done
# Cleanup
rm -rf "$APP/Contents/bin"
+
+# Codesign
+codesign --force --deep --sign - "$APP"
+
echo -e "\nFinished.\n\n"
diff --git a/cmake/install/CMakeLists.txt b/cmake/install/CMakeLists.txt
index cd4100c9b..3f6e3624e 100644
--- a/cmake/install/CMakeLists.txt
+++ b/cmake/install/CMakeLists.txt
@@ -36,7 +36,21 @@ IF(LMMS_BUILD_WIN32 OR LMMS_INSTALL_DEPENDENCIES)
)
ENDIF()
+# Install STK rawwaves
+if(LMMS_HAVE_STK AND (LMMS_BUILD_WIN32 OR LMMS_BUILD_APPLE))
+ if(STK_RAWWAVE_ROOT)
+ file(GLOB RAWWAVES "${STK_RAWWAVE_ROOT}/*.raw")
+ install(FILES ${RAWWAVES} DESTINATION "${DATA_DIR}/stk/rawwaves")
+ else()
+ message(WARNING "Can't find STK rawwave root!")
+ endif()
+endif()
+
IF(LMMS_BUILD_APPLE)
INSTALL(CODE "EXECUTE_PROCESS(COMMAND chmod u+x ${CMAKE_BINARY_DIR}/install_apple.sh)")
- INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${CMAKE_BINARY_DIR}/install_apple.sh)")
+ INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${CMAKE_BINARY_DIR}/install_apple.sh RESULT_VARIABLE EXIT_CODE)
+ IF(NOT EXIT_CODE EQUAL 0)
+ MESSAGE(FATAL_ERROR \"Execution of install_apple.sh failed\")
+ ENDIF()
+ ")
ENDIF()
diff --git a/cmake/linux/package_linux.sh.in b/cmake/linux/package_linux.sh.in
index 89e500060..16cd5719b 100644
--- a/cmake/linux/package_linux.sh.in
+++ b/cmake/linux/package_linux.sh.in
@@ -149,6 +149,7 @@ fi
# Patch the desktop file
sed -i 's/.*Exec=.*/Exec=lmms.real/' "$DESKTOPFILE"
+echo "X-AppImage-Version=@VERSION@" >> "$DESKTOPFILE"
# Fix linking for soft-linked plugins
for file in "${APPDIR}usr/lib/lmms/"*.so; do
@@ -201,6 +202,9 @@ fi
rm -f "${APPDIR}/AppRun"
ln -sr "${APPDIR}/usr/bin/lmms" "${APPDIR}/AppRun"
+# Add icon
+ln -srf "${APPDIR}/lmms.png" "${APPDIR}/.DirIcon"
+
# Create AppImage
echo -e "\nFinishing the AppImage..."
run_and_log "$APPIMAGETOOL" "${APPDIR}" "@APPIMAGE_FILE@"
diff --git a/cmake/modules/BashCompletion.cmake b/cmake/modules/BashCompletion.cmake
index c3916f201..7301e82aa 100644
--- a/cmake/modules/BashCompletion.cmake
+++ b/cmake/modules/BashCompletion.cmake
@@ -24,7 +24,7 @@
# - Windows does not support bash completion
# - macOS support should eventually be added for Homebrew (TODO)
IF(WIN32)
- MESSAGE(STATUS "Bash competion is not supported on this platform.")
+ MESSAGE(STATUS "Bash completion is not supported on this platform.")
ELSEIF(APPLE)
MESSAGE(STATUS "Bash completion is not yet implemented for this platform.")
ELSE()
diff --git a/cmake/modules/BuildPlugin.cmake b/cmake/modules/BuildPlugin.cmake
index f8b3d3153..70e518c93 100644
--- a/cmake/modules/BuildPlugin.cmake
+++ b/cmake/modules/BuildPlugin.cmake
@@ -56,11 +56,7 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME)
ADD_LIBRARY(${PLUGIN_NAME} ${PLUGIN_LINK} ${PLUGIN_SOURCES} ${plugin_MOC_out} ${RCC_OUT})
- TARGET_LINK_LIBRARIES(${PLUGIN_NAME} Qt5::Widgets Qt5::Xml)
-
- IF(LMMS_BUILD_WIN32)
- TARGET_LINK_LIBRARIES(${PLUGIN_NAME} lmms)
- ENDIF(LMMS_BUILD_WIN32)
+ target_link_libraries("${PLUGIN_NAME}" lmms Qt5::Widgets Qt5::Xml)
INSTALL(TARGETS ${PLUGIN_NAME}
LIBRARY DESTINATION "${PLUGIN_DIR}"
@@ -70,10 +66,7 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME)
IF(LMMS_BUILD_APPLE)
IF ("${PLUGIN_LINK}" STREQUAL "SHARED")
SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
- ELSE()
- SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES LINK_FLAGS "-bundle_loader \"${CMAKE_BINARY_DIR}/lmms\"")
ENDIF()
- ADD_DEPENDENCIES(${PLUGIN_NAME} lmms)
ENDIF(LMMS_BUILD_APPLE)
IF(LMMS_BUILD_WIN32)
add_custom_command(
diff --git a/cmake/modules/CheckSubmodules.cmake b/cmake/modules/CheckSubmodules.cmake
index f36189c38..b9ea20778 100644
--- a/cmake/modules/CheckSubmodules.cmake
+++ b/cmake/modules/CheckSubmodules.cmake
@@ -18,7 +18,7 @@
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
# Files which confirm a successful clone
-SET(VALID_CRUMBS "CMakeLists.txt;Makefile;Makefile.in;Makefile.am;configure.ac;configure.py;autogen.sh;.gitignore;LICENSE;Home.md")
+SET(VALID_CRUMBS "CMakeLists.txt;Makefile;Makefile.in;Makefile.am;configure.ac;configure.py;autogen.sh;.gitignore;LICENSE;Home.md;license.txt")
OPTION(NO_SHALLOW_CLONE "Disable shallow cloning of submodules" OFF)
diff --git a/cmake/modules/CompileCache.cmake b/cmake/modules/CompileCache.cmake
index ed4622bd9..56486e24f 100644
--- a/cmake/modules/CompileCache.cmake
+++ b/cmake/modules/CompileCache.cmake
@@ -1,25 +1,40 @@
-option(USE_COMPILE_CACHE "Use ccache or clcache for compilation" OFF)
+option(USE_COMPILE_CACHE "Use a compiler cache for compilation" OFF)
# Compatibility for old option name
if(USE_CCACHE)
set(USE_COMPILE_CACHE ON)
endif()
-if(USE_COMPILE_CACHE)
- if(MSVC)
- set(CACHE_TOOL_NAME clcache)
- elseif(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|AppleClang|Clang)")
- set(CACHE_TOOL_NAME ccache)
- else()
- message(WARNING "Compile cache only available with MSVC or GNU")
+if(NOT USE_COMPILE_CACHE)
+ return()
+endif()
+
+if(NOT CMAKE_CXX_COMPILER_ID MATCHES "(GNU|AppleClang|Clang|MSVC)")
+ message(WARNING "Compiler cache only available with MSVC or GNU")
+ return()
+endif()
+
+set(CACHE_TOOL_NAME ccache)
+find_program(CACHE_TOOL "${CACHE_TOOL_NAME}")
+if(NOT CACHE_TOOL)
+ message(WARNING "USE_COMPILE_CACHE enabled, but no ${CACHE_TOOL_NAME} found")
+ return()
+endif()
+
+if(MSVC)
+ # ccache doesn't support debug information in the PDB format. Setting the
+ # debug information format requires CMP0141, introduced with CMake 3.25, to
+ # be set to NEW prior to the initial `project` command.
+ if(CMAKE_VERSION VERSION_LESS "3.25")
+ message(WARNING "Use of compiler cache with MSVC requires at least CMake 3.25")
+ return()
endif()
- find_program(CACHE_TOOL ${CACHE_TOOL_NAME})
- if (CACHE_TOOL)
- message(STATUS "Using ${CACHE_TOOL} found for caching")
- set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CACHE_TOOL})
- set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CACHE_TOOL})
- else()
- message(WARNING "USE_COMPILE_CACHE enabled, but no ${CACHE_TOOL_NAME} found")
- endif()
+ set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<$:Embedded>")
endif()
+
+message(STATUS "Using ${CACHE_TOOL} for compiler caching")
+
+# TODO CMake 3.21: Use CMAKE___LAUNCHER variables instead
+set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CACHE_TOOL}")
+set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CACHE_TOOL}")
diff --git a/cmake/modules/DefineInstallVar.cmake b/cmake/modules/DefineInstallVar.cmake
index b13cb1d52..0ca8fa429 100644
--- a/cmake/modules/DefineInstallVar.cmake
+++ b/cmake/modules/DefineInstallVar.cmake
@@ -24,7 +24,7 @@ function(DEFINE_INSTALL_VAR)
endif()
else()
if(VAR_GENERATOR_EXPRESSION)
- cmake_policy(SET CMP0087 NEW)
+ cmake_policy(SET CMP0087 NEW) # install(CODE) and install(SCRIPT) support generator expressions.
endif()
install(CODE "set(\"${VAR_NAME}\" \"${VAR_CONTENT}\")")
endif()
diff --git a/cmake/modules/DetectMachine.cmake b/cmake/modules/DetectMachine.cmake
index 388efeb82..65bc6d2b7 100644
--- a/cmake/modules/DetectMachine.cmake
+++ b/cmake/modules/DetectMachine.cmake
@@ -92,7 +92,7 @@ IF(WIN32)
endif()
ELSE()
# Detect target architecture based on compiler target triple e.g. "x86_64-pc-linux"
- EXEC_PROGRAM( ${CMAKE_C_COMPILER} ARGS "-dumpmachine ${CMAKE_C_FLAGS}" OUTPUT_VARIABLE Machine )
+ execute_process(COMMAND ${CMAKE_C_COMPILER} -dumpmachine ${CMAKE_C_FLAGS} OUTPUT_VARIABLE Machine)
MESSAGE("Machine: ${Machine}")
STRING(REGEX MATCH "i.86" IS_X86 "${Machine}")
STRING(REGEX MATCH "86_64|amd64" IS_X86_64 "${Machine}")
diff --git a/cmake/modules/FindFluidSynth.cmake b/cmake/modules/FindFluidSynth.cmake
index fcc00cd7d..70c40b8d8 100644
--- a/cmake/modules/FindFluidSynth.cmake
+++ b/cmake/modules/FindFluidSynth.cmake
@@ -34,7 +34,7 @@ if(FluidSynth_INCLUDE_DIR AND FluidSynth_LIBRARY)
if(VCPKG_INSTALLED_DIR)
include(ImportedTargetHelpers)
- _get_vcpkg_library_configs(FluidSynth_IMPLIB_RELEASE FluidSynth_IMPLIB_DEBUG "${FluidSynth_LIBRARY}")
+ get_vcpkg_library_configs(FluidSynth_IMPLIB_RELEASE FluidSynth_IMPLIB_DEBUG "${FluidSynth_LIBRARY}")
else()
set(FluidSynth_IMPLIB_RELEASE "${FluidSynth_LIBRARY}")
endif()
diff --git a/cmake/modules/FindLame.cmake b/cmake/modules/FindLame.cmake
index c3fb09c5b..3017dc5aa 100644
--- a/cmake/modules/FindLame.cmake
+++ b/cmake/modules/FindLame.cmake
@@ -1,37 +1,31 @@
-# - Try to find LAME
-# Once done this will define
+# Copyright (c) 2023 Dominic Clark
#
-# Lame_FOUND - system has liblame
-# Lame_INCLUDE_DIRS - the liblame include directory
-# Lame_LIBRARIES - The liblame libraries
-# mp3lame::mp3lame - an imported target providing lame
+# Redistribution and use is allowed according to the terms of the New BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
-find_package(mp3lame CONFIG QUIET)
+include(ImportedTargetHelpers)
-if(TARGET mp3lame::mp3lame)
- # Extract details for find_package_handle_standard_args
- get_target_property(Lame_LIBRARIES mp3lame::mp3lame LOCATION)
- get_target_property(Lame_INCLUDE_DIRS mp3lame::mp3lame INTERFACE_INCLUDE_DIRECTORIES)
-else()
- find_path(Lame_INCLUDE_DIRS lame/lame.h)
- find_library(Lame_LIBRARIES mp3lame)
+find_package_config_mode_with_fallback(mp3lame mp3lame::mp3lame
+ LIBRARY_NAMES "mp3lame"
+ INCLUDE_NAMES "lame/lame.h"
+ PREFIX Lame
+)
- list(APPEND Lame_DEFINITIONS HAVE_LIBMP3LAME=1)
+determine_version_from_source(Lame_VERSION mp3lame::mp3lame [[
+ #include
+ #include
- mark_as_advanced(Lame_INCLUDE_DIRS Lame_LIBRARIES Lame_DEFINITIONS)
-
- if(Lame_LIBRARIES AND Lame_INCLUDE_DIRS)
- add_library(mp3lame::mp3lame UNKNOWN IMPORTED)
-
- set_target_properties(mp3lame::mp3lame PROPERTIES
- INTERFACE_INCLUDE_DIRECTORIES "${Lame_INCLUDE_DIRS}"
- INTERFACE_COMPILE_DEFINITIONS "${Lame_DEFINITIONS}"
- IMPORTED_LOCATION "${Lame_LIBRARIES}"
- )
- endif()
-endif()
+ auto main() -> int
+ {
+ auto version = lame_version_t{};
+ get_lame_version_numerical(&version);
+ std::cout << version.major << "." << version.minor;
+ }
+]])
include(FindPackageHandleStandardArgs)
+
find_package_handle_standard_args(Lame
- REQUIRED_VARS Lame_LIBRARIES Lame_INCLUDE_DIRS
+ REQUIRED_VARS Lame_LIBRARY Lame_INCLUDE_DIRS
+ VERSION_VAR Lame_VERSION
)
diff --git a/cmake/modules/FindOggVorbis.cmake b/cmake/modules/FindOggVorbis.cmake
index 79a9ab406..cfbd73256 100644
--- a/cmake/modules/FindOggVorbis.cmake
+++ b/cmake/modules/FindOggVorbis.cmake
@@ -1,86 +1,68 @@
-# - Try to find the OggVorbis libraries
-# Once done this will define
+# Copyright (c) 2023 Dominic Clark
#
-# OGGVORBIS_FOUND - system has OggVorbis
-# OGGVORBIS_VERSION - set either to 1 or 2
-# OGGVORBIS_INCLUDE_DIR - the OggVorbis include directory
-# OGGVORBIS_LIBRARIES - The libraries needed to use OggVorbis
-# OGG_LIBRARY - The Ogg library
-# VORBIS_LIBRARY - The Vorbis library
-# VORBISFILE_LIBRARY - The VorbisFile library
-# VORBISENC_LIBRARY - The VorbisEnc library
-
-# Copyright (c) 2006, Richard Laerkaeng,
-#
-# Redistribution and use is allowed according to the terms of the BSD license.
+# Redistribution and use is allowed according to the terms of the New BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+include(ImportedTargetHelpers)
-include (CheckLibraryExists)
+find_package_config_mode_with_fallback(Ogg Ogg::ogg
+ LIBRARY_NAMES "ogg"
+ INCLUDE_NAMES "ogg/ogg.h"
+ PKG_CONFIG ogg
+)
-find_path(VORBIS_INCLUDE_DIR vorbis/vorbisfile.h)
-find_path(OGG_INCLUDE_DIR ogg/ogg.h)
+find_package_config_mode_with_fallback(Vorbis Vorbis::vorbis
+ LIBRARY_NAMES "vorbis"
+ INCLUDE_NAMES "vorbis/codec.h"
+ PKG_CONFIG vorbis
+ DEPENDS Ogg::ogg
+)
-find_library(OGG_LIBRARY NAMES ogg)
-find_library(VORBIS_LIBRARY NAMES vorbis)
-find_library(VORBISFILE_LIBRARY NAMES vorbisfile)
-find_library(VORBISENC_LIBRARY NAMES vorbisenc)
+find_package_config_mode_with_fallback(Vorbis Vorbis::vorbisfile
+ LIBRARY_NAMES "vorbisfile"
+ INCLUDE_NAMES "vorbis/vorbisfile.h"
+ PKG_CONFIG vorbisfile
+ DEPENDS Vorbis::vorbis
+ PREFIX VorbisFile
+)
+find_package_config_mode_with_fallback(Vorbis Vorbis::vorbisenc
+ LIBRARY_NAMES "vorbisenc"
+ INCLUDE_NAMES "vorbis/vorbisenc.h"
+ PKG_CONFIG vorbisenc
+ DEPENDS Vorbis::vorbis
+ PREFIX VorbisEnc
+)
-if (VORBIS_INCLUDE_DIR AND VORBIS_LIBRARY AND VORBISFILE_LIBRARY AND VORBISENC_LIBRARY)
- set(OGGVORBIS_FOUND TRUE)
+determine_version_from_source(Vorbis_VERSION Vorbis::vorbis [[
+ #include
+ #include
+ #include
- set(OGGVORBIS_LIBRARIES ${OGG_LIBRARY} ${VORBIS_LIBRARY} ${VORBISFILE_LIBRARY} ${VORBISENC_LIBRARY})
+ auto main() -> int
+ {
+ // Version string has the format "org name version"
+ const auto version = std::string_view{vorbis_version_string()};
+ const auto nameBegin = version.find(' ') + 1;
+ const auto versionBegin = version.find(' ', nameBegin) + 1;
+ std::cout << version.substr(versionBegin);
+ }
+]])
- set(_CMAKE_REQUIRED_LIBRARIES_TMP ${CMAKE_REQUIRED_LIBRARIES})
- set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${OGGVORBIS_LIBRARIES})
- check_library_exists(vorbis vorbis_bitrate_addblock "" HAVE_LIBVORBISENC2)
- set(CMAKE_REQUIRED_LIBRARIES ${_CMAKE_REQUIRED_LIBRARIES_TMP})
-
- if (HAVE_LIBVORBISENC2)
- set (OGGVORBIS_VERSION 2)
- else (HAVE_LIBVORBISENC2)
- set (OGGVORBIS_VERSION 1)
- endif (HAVE_LIBVORBISENC2)
-
-else (VORBIS_INCLUDE_DIR AND VORBIS_LIBRARY AND VORBISFILE_LIBRARY AND VORBISENC_LIBRARY)
- set (OGGVORBIS_VERSION)
- set(OGGVORBIS_FOUND FALSE)
-endif (VORBIS_INCLUDE_DIR AND VORBIS_LIBRARY AND VORBISFILE_LIBRARY AND VORBISENC_LIBRARY)
-
-
-if (OGGVORBIS_FOUND)
- if (NOT OggVorbis_FIND_QUIETLY)
- message(STATUS "Found OggVorbis: ${OGGVORBIS_LIBRARIES}")
- endif (NOT OggVorbis_FIND_QUIETLY)
-else (OGGVORBIS_FOUND)
- if (OggVorbis_FIND_REQUIRED)
- message(FATAL_ERROR "Could NOT find OggVorbis libraries")
- endif (OggVorbis_FIND_REQUIRED)
- if (NOT OggVorbis_FIND_QUITELY)
- message(STATUS "Could NOT find OggVorbis libraries")
- endif (NOT OggVorbis_FIND_QUITELY)
-endif (OGGVORBIS_FOUND)
-
-#check_include_files(vorbis/vorbisfile.h HAVE_VORBISFILE_H)
-#check_library_exists(ogg ogg_page_version "" HAVE_LIBOGG)
-#check_library_exists(vorbis vorbis_info_init "" HAVE_LIBVORBIS)
-#check_library_exists(vorbisfile ov_open "" HAVE_LIBVORBISFILE)
-#check_library_exists(vorbisenc vorbis_info_clear "" HAVE_LIBVORBISENC)
-#check_library_exists(vorbis vorbis_bitrate_addblock "" HAVE_LIBVORBISENC2)
-
-#if (HAVE_LIBOGG AND HAVE_VORBISFILE_H AND HAVE_LIBVORBIS AND HAVE_LIBVORBISFILE AND HAVE_LIBVORBISENC)
-# message(STATUS "Ogg/Vorbis found")
-# set (VORBIS_LIBS "-lvorbis -logg")
-# set (VORBISFILE_LIBS "-lvorbisfile")
-# set (VORBISENC_LIBS "-lvorbisenc")
-# set (OGGVORBIS_FOUND TRUE)
-# if (HAVE_LIBVORBISENC2)
-# set (HAVE_VORBIS 2)
-# else (HAVE_LIBVORBISENC2)
-# set (HAVE_VORBIS 1)
-# endif (HAVE_LIBVORBISENC2)
-#else (HAVE_LIBOGG AND HAVE_VORBISFILE_H AND HAVE_LIBVORBIS AND HAVE_LIBVORBISFILE AND HAVE_LIBVORBISENC)
-# message(STATUS "Ogg/Vorbis not found")
-#endif (HAVE_LIBOGG AND HAVE_VORBISFILE_H AND HAVE_LIBVORBIS AND HAVE_LIBVORBISFILE AND HAVE_LIBVORBISENC)
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(OggVorbis
+ REQUIRED_VARS
+ Ogg_LIBRARY
+ Ogg_INCLUDE_DIRS
+ Vorbis_LIBRARY
+ Vorbis_INCLUDE_DIRS
+ VorbisFile_LIBRARY
+ VorbisFile_INCLUDE_DIRS
+ VorbisEnc_LIBRARY
+ VorbisEnc_INCLUDE_DIRS
+ # This only reports the Vorbis version - Ogg can have a different version,
+ # so if we ever care about that, it should be split off into a different
+ # find module.
+ VERSION_VAR Vorbis_VERSION
+)
diff --git a/cmake/modules/FindPortaudio.cmake b/cmake/modules/FindPortaudio.cmake
index f9c7699f4..e7cfa1383 100644
--- a/cmake/modules/FindPortaudio.cmake
+++ b/cmake/modules/FindPortaudio.cmake
@@ -1,44 +1,34 @@
-# Copyright (c) 2022 Dominic Clark
+# Copyright (c) 2023 Dominic Clark
#
# Redistribution and use is allowed according to the terms of the New BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
-# Try config mode if possible
-find_package(portaudio CONFIG QUIET)
+include(ImportedTargetHelpers)
-if(TARGET portaudio)
- # Extract details for find_package_handle_standard_args
- get_target_property(Portaudio_LIBRARY portaudio LOCATION)
- get_target_property(Portaudio_INCLUDE_DIR portaudio INTERFACE_INCLUDE_DIRECTORIES)
-else()
- # Attempt to find PortAudio using PkgConfig, if we have it
- find_package(PkgConfig QUIET)
- if(PKG_CONFIG_FOUND)
- pkg_check_modules(PORTAUDIO_PKG portaudio-2.0)
- endif()
+find_package_config_mode_with_fallback(portaudio portaudio
+ LIBRARY_NAMES "portaudio"
+ INCLUDE_NAMES "portaudio.h"
+ PKG_CONFIG portaudio-2.0
+ PREFIX Portaudio
+)
- # Find the library and headers using the results from PkgConfig as a guide
- find_library(Portaudio_LIBRARY
- NAMES "portaudio"
- HINTS ${PORTAUDIO_PKG_LIBRARY_DIRS}
- )
+determine_version_from_source(Portaudio_VERSION portaudio [[
+ #include
+ #include "portaudio.h"
- find_path(Portaudio_INCLUDE_DIR
- NAMES "portaudio.h"
- HINTS ${PORTAUDIO_PKG_INCLUDE_DIRS}
- )
-
- # Create an imported target for PortAudio if we succeeded in finding it.
- if(Portaudio_LIBRARY AND Portaudio_INCLUDE_DIR)
- add_library(portaudio UNKNOWN IMPORTED)
- set_target_properties(portaudio PROPERTIES
- INTERFACE_INCLUDE_DIRECTORIES "${Portaudio_INCLUDE_DIR}"
- IMPORTED_LOCATION "${Portaudio_LIBRARY}"
- )
- endif()
-endif()
+ auto main() -> int
+ {
+ // Version number has the format 0xMMmmpp
+ const auto version = Pa_GetVersion();
+ std::cout << ((version >> 16) & 0xff)
+ << "." << ((version >> 8) & 0xff)
+ << "." << ((version >> 0) & 0xff);
+ }
+]])
include(FindPackageHandleStandardArgs)
+
find_package_handle_standard_args(Portaudio
- REQUIRED_VARS Portaudio_LIBRARY Portaudio_INCLUDE_DIR
+ REQUIRED_VARS Portaudio_LIBRARY Portaudio_INCLUDE_DIRS
+ VERSION_VAR Portaudio_VERSION
)
diff --git a/cmake/modules/FindSTK.cmake b/cmake/modules/FindSTK.cmake
index 80ed0da42..5564d24f8 100644
--- a/cmake/modules/FindSTK.cmake
+++ b/cmake/modules/FindSTK.cmake
@@ -1,32 +1,27 @@
-# Try config mode first
-find_package(unofficial-libstk CONFIG QUIET)
+include(ImportedTargetHelpers)
-if(TARGET unofficial::libstk::libstk)
- # Extract details for find_package_handle_standard_args
- get_target_property(STK_LIBRARY unofficial::libstk::libstk LOCATION)
- get_target_property(STK_INCLUDE_DIR unofficial::libstk::libstk INTERFACE_INCLUDE_DIRECTORIES)
-else()
- find_path(STK_INCLUDE_DIR
- NAMES stk/Stk.h
- PATH /usr/include /usr/local/include "${CMAKE_INSTALL_PREFIX}/include" "${CMAKE_FIND_ROOT_PATH}/include"
+# TODO CMake 3.18: Alias this target to something less hideous
+find_package_config_mode_with_fallback(unofficial-libstk unofficial::libstk::libstk
+ LIBRARY_NAMES "stk"
+ INCLUDE_NAMES "stk/Stk.h"
+ LIBRARY_HINTS "/usr/lib" "/usr/local/lib" "${CMAKE_INSTALL_PREFIX}/lib" "${CMAKE_FIND_ROOT_PATH}/lib"
+ INCLUDE_HINTS "/usr/include" "/usr/local/include" "${CMAKE_INSTALL_PREFIX}/include" "${CMAKE_FIND_ROOT_PATH}/include"
+ PREFIX STK
+)
+
+# Find STK rawwave path
+if(STK_INCLUDE_DIRS)
+ list(GET STK_INCLUDE_DIRS 0 STK_INCLUDE_DIR)
+ find_path(STK_RAWWAVE_ROOT
+ NAMES silence.raw sinewave.raw
+ HINTS "${STK_INCLUDE_DIR}/.."
+ PATH_SUFFIXES share/stk/rawwaves share/libstk/rawwaves
)
-
- find_library(STK_LIBRARY
- NAMES stk
- PATH /usr/lib /usr/local/lib "${CMAKE_INSTALL_PREFIX}/lib" "${CMAKE_FIND_ROOT_PATH}/lib"
- )
-
- if(STK_INCLUDE_DIR AND STK_LIBRARY)
- # Yes, this target name is hideous, but it matches that provided by vcpkg
- add_library(unofficial::libstk::libstk UNKNOWN IMPORTED)
- set_target_properties(unofficial::libstk::libstk PROPERTIES
- INTERFACE_INCLUDE_DIRECTORIES "${STK_INCLUDE_DIR}"
- IMPORTED_LOCATION "${STK_LIBRARY}"
- )
- endif()
endif()
include(FindPackageHandleStandardArgs)
+
find_package_handle_standard_args(STK
REQUIRED_VARS STK_LIBRARY STK_INCLUDE_DIR
+ # STK doesn't appear to expose its version, so we can't pass it here
)
diff --git a/cmake/modules/FindSamplerate.cmake b/cmake/modules/FindSamplerate.cmake
index 53b69f6c7..683748c59 100644
--- a/cmake/modules/FindSamplerate.cmake
+++ b/cmake/modules/FindSamplerate.cmake
@@ -1,34 +1,35 @@
-# FindFFTW.cmake - Try to find FFTW3
-# Copyright (c) 2018 Lukas W
-# This file is MIT licensed.
-# See http://opensource.org/licenses/MIT
+# Copyright (c) 2023 Dominic Clark
+#
+# Redistribution and use is allowed according to the terms of the New BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
-find_package(PkgConfig QUIET)
-if(PKG_CONFIG_FOUND)
- pkg_check_modules(SAMPLERATE_PKG samplerate)
-endif()
+include(ImportedTargetHelpers)
-find_path(SAMPLERATE_INCLUDE_DIR
- NAMES samplerate.h
- PATHS ${SAMPLERATE_PKG_INCLUDE_DIRS}
+find_package_config_mode_with_fallback(SampleRate SampleRate::samplerate
+ LIBRARY_NAMES "samplerate" "libsamplerate" "libsamplerate-0"
+ INCLUDE_NAMES "samplerate.h"
+ PKG_CONFIG samplerate
+ PREFIX Samplerate
)
-set(SAMPLERATE_NAMES samplerate libsamplerate)
-if(Samplerate_FIND_VERSION_MAJOR)
- list(APPEND SAMPLERATE_NAMES libsamplerate-${Samplerate_FIND_VERSION_MAJOR})
-else()
- list(APPEND SAMPLERATE_NAMES libsamplerate-0)
-endif()
+determine_version_from_source(Samplerate_VERSION SampleRate::samplerate [[
+ #include
+ #include
+ #include
-find_library(SAMPLERATE_LIBRARY
- NAMES ${SAMPLERATE_NAMES}
- PATHS ${SAMPLERATE_PKG_LIBRARY_DIRS}
-)
+ auto main() -> int
+ {
+ // Version string has the format "name-version copyright"
+ const auto version = std::string_view{src_get_version()};
+ const auto begin = version.find('-') + 1;
+ const auto end = version.find(' ', begin);
+ std::cout << version.substr(begin, end - begin);
+ }
+]])
include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(SAMPLERATE DEFAULT_MSG SAMPLERATE_LIBRARY SAMPLERATE_INCLUDE_DIR)
-mark_as_advanced(SAMPLERATE_INCLUDE_DIR SAMPLERATE_LIBRARY )
-
-set(SAMPLERATE_LIBRARIES ${SAMPLERATE_LIBRARY} )
-set(SAMPLERATE_INCLUDE_DIRS ${SAMPLERATE_INCLUDE_DIR})
+find_package_handle_standard_args(Samplerate
+ REQUIRED_VARS Samplerate_LIBRARY Samplerate_INCLUDE_DIRS
+ VERSION_VAR Samplerate_VERSION
+)
diff --git a/cmake/modules/FindSndFile.cmake b/cmake/modules/FindSndFile.cmake
index 28ebb7bb7..d69fa6331 100644
--- a/cmake/modules/FindSndFile.cmake
+++ b/cmake/modules/FindSndFile.cmake
@@ -1,39 +1,34 @@
-# FindSndFile.cmake - Try to find libsndfile
-# Copyright (c) 2018 Lukas W
-# This file is MIT licensed.
-# See http://opensource.org/licenses/MIT
+# Copyright (c) 2023 Dominic Clark
+#
+# Redistribution and use is allowed according to the terms of the New BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
-# Try pkgconfig for hints
-find_package(PkgConfig QUIET)
-if(PKG_CONFIG_FOUND)
- pkg_check_modules(SNDFILE_PKG sndfile)
-endif(PKG_CONFIG_FOUND)
-set(SndFile_DEFINITIONS ${SNDFILE_PKG_CFLAGS_OTHER})
+include(ImportedTargetHelpers)
-if(WIN32)
- # Try Vcpkg
- find_package(LibSndFile ${SndFile_FIND_VERSION} CONFIG QUIET)
- if(LibSndFile_FOUND)
- get_target_property(LibSndFile_Location sndfile-shared LOCATION)
- get_target_property(LibSndFile_Include_Path sndfile-shared INTERFACE_INCLUDE_DIRECTORIES)
- get_filename_component(LibSndFile_Path LibSndFile_Location PATH)
- endif()
-endif()
-
-find_path(SNDFILE_INCLUDE_DIR
- NAMES sndfile.h
- PATHS ${SNDFILE_PKG_INCLUDE_DIRS} ${LibSndFile_Include_Path}
+find_package_config_mode_with_fallback(SndFile SndFile::sndfile
+ LIBRARY_NAMES "sndfile" "libsndfile" "libsndfile-1"
+ INCLUDE_NAMES "sndfile.h"
+ PKG_CONFIG sndfile
)
-find_library(SNDFILE_LIBRARY
- NAMES sndfile libsndfile libsndfile-1
- PATHS ${SNDFILE_PKG_LIBRARY_DIRS} ${LibSndFile_Path}
+determine_version_from_source(SndFile_VERSION SndFile::sndfile [[
+ #include
+ #include
+ #include
+
+ auto main() -> int
+ {
+ // Version string has the format "name-version", optionally followed by "-exp"
+ const auto version = std::string_view{sf_version_string()};
+ const auto begin = version.find('-') + 1;
+ const auto end = version.find('-', begin);
+ std::cout << version.substr(begin, end - begin);
+ }
+]])
+
+include(FindPackageHandleStandardArgs)
+
+find_package_handle_standard_args(SndFile
+ REQUIRED_VARS SndFile_LIBRARY SndFile_INCLUDE_DIRS
+ VERSION_VAR SndFile_VERSION
)
-
-find_package(PackageHandleStandardArgs)
-find_package_handle_standard_args(SndFile DEFAULT_MSG SNDFILE_LIBRARY SNDFILE_INCLUDE_DIR)
-
-set(SNDFILE_LIBRARIES ${SNDFILE_LIBRARY})
-set(SNDFILE_INCLUDE_DIRS ${SNDFILE_INCLUDE_DIR})
-
-mark_as_advanced(SNDFILE_LIBRARY SNDFILE_LIBRARIES SNDFILE_INCLUDE_DIR SNDFILE_INCLUDE_DIRS)
diff --git a/cmake/modules/FindWine.cmake b/cmake/modules/FindWine.cmake
index 024dac1ea..aabb5ef78 100644
--- a/cmake/modules/FindWine.cmake
+++ b/cmake/modules/FindWine.cmake
@@ -32,8 +32,8 @@ FIND_PROGRAM(WINE_CXX
FIND_PROGRAM(WINE_BUILD NAMES winebuild)
# Detect wine paths and handle linking problems
IF(WINE_CXX)
- EXEC_PROGRAM(${WINE_CXX} ARGS "-m32 -v /dev/zero" OUTPUT_VARIABLE WINEBUILD_OUTPUT_32)
- EXEC_PROGRAM(${WINE_CXX} ARGS "-m64 -v /dev/zero" OUTPUT_VARIABLE WINEBUILD_OUTPUT_64)
+ execute_process(COMMAND ${WINE_CXX} -m32 -v /dev/zero OUTPUT_VARIABLE WINEBUILD_OUTPUT_32)
+ execute_process(COMMAND ${WINE_CXX} -m64 -v /dev/zero OUTPUT_VARIABLE WINEBUILD_OUTPUT_64)
_findwine_find_flags("${WINEBUILD_OUTPUT_32}" "^-isystem/usr/include$" BUGGED_WINEGCC)
_findwine_find_flags("${WINEBUILD_OUTPUT_32}" "^-isystem" WINEGCC_INCLUDE_DIR)
_findwine_find_flags("${WINEBUILD_OUTPUT_32}" "libwinecrt0\\.a.*" WINECRT_32)
diff --git a/cmake/modules/ImportedTargetHelpers.cmake b/cmake/modules/ImportedTargetHelpers.cmake
index 87b3aeedc..d3d979901 100644
--- a/cmake/modules/ImportedTargetHelpers.cmake
+++ b/cmake/modules/ImportedTargetHelpers.cmake
@@ -1,7 +1,178 @@
+# ImportedTargetHelpers.cmake - various helper functions for use in find modules.
+#
+# Copyright (c) 2022-2023 Dominic Clark
+#
+# Redistribution and use is allowed according to the terms of the New BSD license.
+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
+
+# If the version variable is not yet set, build the source linked to the target,
+# run it, and set the version variable to the output. Useful for libraries which
+# do not expose the version information in a header where it can be extracted
+# with regular expressions, but do provide a function to get the version.
+#
+# Usage:
+# determine_version_from_source(
+# # The cache variable in which to store the computed version
+# # The target which the source will link to
+# # The source code to determine the version
+# )
+function(determine_version_from_source _version_out _target _source)
+ # Return if we already know the version, or the target was not found
+ if(NOT "${${_version_out}}" STREQUAL "" OR NOT TARGET "${_target}")
+ return()
+ endif()
+
+ # Return with a notice if cross-compiling, since we are unlikely to be able
+ # to run the compiled source
+ if(CMAKE_CROSSCOMPILING)
+ message(
+ "${_target} was found but the version could not be determined automatically.\n"
+ "Set the cache variable `${_version_out}` to the version you have installed."
+ )
+ return()
+ endif()
+
+ # Write the source code to a temporary file
+ string(SHA1 _source_hash "${_source}")
+ set(_source_file "${CMAKE_CURRENT_BINARY_DIR}/${_source_hash}.cpp")
+ file(WRITE "${_source_file}" "${_source}")
+
+ # Build and run the temporary file to get the version
+ # TODO CMake 3.25: Use the new signature for try_run which has a NO_CACHE
+ # option and doesn't require separate file management.
+ try_run(
+ _dvfs_run_result _dvfs_compile_result "${CMAKE_CURRENT_BINARY_DIR}"
+ SOURCES "${_source_file}"
+ LINK_LIBRARIES "${_target}"
+ CXX_STANDARD 17
+ RUN_OUTPUT_VARIABLE _run_output
+ COMPILE_OUTPUT_VARIABLE _compile_output
+ )
+
+ # Clean up the temporary file
+ file(REMOVE "${_source_file}")
+
+ # Set the version if the run was successful, using a cache variable since
+ # this version check may be relatively expensive. Otherwise, log the error
+ # and inform the user.
+ if(_dvfs_run_result EQUAL "0")
+ set("${_version_out}" "${_run_output}" CACHE INTERNAL "Version of ${_target}")
+ else()
+ message(DEBUG "${_compile_output}")
+ message(
+ "${_target} was found but the version could not be determined automatically.\n"
+ "Set the cache variable `${_version_out}` to the version you have installed."
+ )
+ endif()
+endfunction()
+
+# Search for a package using config mode. If this fails to find the desired
+# target, use the specified fallbacks and add the target if they succeed. Set
+# the variables `prefix_LIBRARY`, `prefix_INCLUDE_DIRS`, and `prefix_VERSION`
+# if found for the caller to pass to `find_package_handle_standard_args`.
+#
+# Usage:
+# find_package_config_mode_with_fallback(
+# # The package to search for with config mode
+# # The target to expect from config mode, or define if not found
+# LIBRARY_NAMES names... # Possible library names to search for as a fallback
+# INCLUDE_NAMES names... # Possible header names to search for as a fallback
+# [PKG_CONFIG ] # The pkg-config name to search for as a fallback
+# [LIBRARY_HINTS hints...] # Locations to look for libraries
+# [INCLUDE_HINTS hints...] # Locations to look for headers
+# [DEPENDS dependencies...] # Dependencies of the target - added to INTERFACE_LINK_LIBRARIES, and will fail if not found
+# [PREFIX ] # The prefix for result variables - defaults to the package name
+# )
+function(find_package_config_mode_with_fallback _fpcmwf_PACKAGE_NAME _fpcmwf_TARGET_NAME)
+ # Parse remaining arguments
+ set(_options "")
+ set(_one_value_args "PKG_CONFIG" "PREFIX")
+ set(_multi_value_args "LIBRARY_NAMES" "LIBRARY_HINTS" "INCLUDE_NAMES" "INCLUDE_HINTS" "DEPENDS")
+ cmake_parse_arguments(PARSE_ARGV 2 _fpcmwf "${_options}" "${_one_value_args}" "${_multi_value_args}")
+
+ # Compute result variable names
+ if(NOT DEFINED _fpcmwf_PREFIX)
+ set(_fpcmwf_PREFIX "${_fpcmwf_PACKAGE_NAME}")
+ endif()
+ set(_version_var "${_fpcmwf_PREFIX}_VERSION")
+ set(_library_var "${_fpcmwf_PREFIX}_LIBRARY")
+ set(_include_var "${_fpcmwf_PREFIX}_INCLUDE_DIRS")
+
+ # Try config mode if possible
+ find_package("${_fpcmwf_PACKAGE_NAME}" CONFIG QUIET)
+
+ if(TARGET "${_fpcmwf_TARGET_NAME}")
+ # Extract package details from existing target
+ get_target_property("${_library_var}" "${_fpcmwf_TARGET_NAME}" LOCATION)
+ get_target_property("${_include_var}" "${_fpcmwf_TARGET_NAME}" INTERFACE_INCLUDE_DIRECTORIES)
+ if(DEFINED "${_fpcmwf_PACKAGE_NAME}_VERSION")
+ set("${_version_var}" "${${_fpcmwf_PACKAGE_NAME}_VERSION}")
+ endif()
+ else()
+ # Check whether the dependencies exist
+ foreach(_dependency IN LISTS _fpcmwf_DEPENDS)
+ if(NOT TARGET "${_dependency}")
+ return()
+ endif()
+ endforeach()
+
+ # Attempt to find the package using pkg-config, if we have it and it was requested
+ set(_pkg_config_prefix "${_fpcmwf_PKG_CONFIG}_PKG")
+ if(DEFINED _fpcmwf_PKG_CONFIG)
+ find_package(PkgConfig QUIET)
+ if(PKG_CONFIG_FOUND)
+ pkg_check_modules("${_pkg_config_prefix}" QUIET "${_fpcmwf_PKG_CONFIG}")
+ if("${${_pkg_config_prefix}_FOUND}")
+ set("${_version_var}" "${${_pkg_config_prefix}_VERSION}")
+ endif()
+ endif()
+ endif()
+
+ # Find the library and headers using the results from pkg-config as a guide
+ find_library("${_library_var}"
+ NAMES ${_fpcmwf_LIBRARY_NAMES}
+ HINTS ${${_pkg_config_prefix}_LIBRARY_DIRS} ${_fpcmwf_LIBRARY_HINTS}
+ )
+
+ find_path("${_include_var}"
+ NAMES ${_fpcmwf_INCLUDE_NAMES}
+ HINTS ${${_pkg_config_prefix}_INCLUDE_DIRS} ${_fpcmwf_INCLUDE_HINTS}
+ )
+
+ # Create an imported target if we succeeded in finding the package
+ if(${_library_var} AND ${_include_var})
+ add_library("${_fpcmwf_TARGET_NAME}" UNKNOWN IMPORTED)
+ set_target_properties("${_fpcmwf_TARGET_NAME}" PROPERTIES
+ IMPORTED_LOCATION "${${_library_var}}"
+ INTERFACE_INCLUDE_DIRECTORIES "${${_include_var}}"
+ INTERFACE_LINK_LIBRARIES "${_fpcmwf_DEPENDS}"
+ )
+ endif()
+
+ mark_as_advanced("${_library_var}" "${_include_var}")
+ endif()
+
+ # Return results to caller
+ if(DEFINED "${_version_var}")
+ set("${_version_var}" "${${_version_var}}" PARENT_SCOPE)
+ else()
+ unset("${_version_var}" PARENT_SCOPE)
+ endif()
+ set("${_library_var}" "${${_library_var}}" PARENT_SCOPE)
+ set("${_include_var}" "${${_include_var}}" PARENT_SCOPE)
+endfunction()
+
# Given a library in vcpkg, find appropriate debug and release versions. If only
-# one version exists, it is used as the release version, and the debug version
-# is not set.
-function(_get_vcpkg_library_configs _release_out _debug_out _library)
+# one version exists, use it as the release version, and do not set the debug
+# version.
+#
+# Usage:
+# get_vcpkg_library_configs(
+# # Variable in which to store the path to the release version of the library
+# # Variable in which to store the path to the debug version of the library
+# # Known path to some version of the library
+# )
+function(get_vcpkg_library_configs _release_out _debug_out _library)
# We want to do all operations within the vcpkg directory
file(RELATIVE_PATH _lib_relative "${VCPKG_INSTALLED_DIR}" "${_library}")
diff --git a/cmake/modules/InstallDependencies.cmake b/cmake/modules/InstallDependencies.cmake
index 791041bb2..29e5b207c 100644
--- a/cmake/modules/InstallDependencies.cmake
+++ b/cmake/modules/InstallDependencies.cmake
@@ -1,8 +1,9 @@
include(GetPrerequisites)
include(CMakeParseArguments)
-CMAKE_POLICY(SET CMP0011 NEW)
-CMAKE_POLICY(SET CMP0057 NEW)
+# Project's cmake_minimum_required doesn't propagate to install scripts
+cmake_policy(PUSH)
+cmake_policy(SET CMP0057 NEW) # Support new if() IN_LIST operator.
function(make_absolute var)
get_filename_component(abs "${${var}}" ABSOLUTE BASE_DIR "${CMAKE_INSTALL_PREFIX}")
@@ -182,3 +183,5 @@ function(FIND_PREREQUISITES target RESULT_VAR exclude_system recurse
set(${RESULT_VAR} ${RESULTS} PARENT_SCOPE)
endfunction()
+
+cmake_policy(POP)
diff --git a/cmake/modules/PluginList.cmake b/cmake/modules/PluginList.cmake
index fe98a64b4..8c444aca2 100644
--- a/cmake/modules/PluginList.cmake
+++ b/cmake/modules/PluginList.cmake
@@ -33,6 +33,7 @@ SET(LMMS_PLUGIN_LIST
Compressor
CrossoverEQ
Delay
+ Dispersion
DualFilter
DynamicsProcessor
Eq
@@ -40,6 +41,7 @@ SET(LMMS_PLUGIN_LIST
HydrogenImport
LadspaBrowser
LadspaEffect
+ LOMM
Lv2Effect
Lv2Instrument
Lb302
@@ -58,10 +60,12 @@ SET(LMMS_PLUGIN_LIST
Sf2Player
Sfxr
Sid
+ SlicerT
SpectrumAnalyzer
StereoEnhancer
StereoMatrix
Stk
+ TapTempo
VstBase
Vestige
VstEffect
diff --git a/cmake/nsis/CMakeLists.txt b/cmake/nsis/CMakeLists.txt
index 9dca3495d..ee1bd45c3 100644
--- a/cmake/nsis/CMakeLists.txt
+++ b/cmake/nsis/CMakeLists.txt
@@ -73,12 +73,6 @@ SET(CPACK_NSIS_MUI_ICON "${CPACK_NSIS_MUI_ICON}" PARENT_SCOPE)
CONFIGURE_FILE("lmms.rc.in" "${CMAKE_BINARY_DIR}/lmms.rc")
CONFIGURE_FILE("zynaddsubfx.rc.in" "${CMAKE_BINARY_DIR}/plugins/ZynAddSubFx/zynaddsubfx.rc")
-IF(LMMS_HAVE_STK)
- FILE(GLOB RAWWAVES "${MINGW_PREFIX}/share/stk/rawwaves/*.raw")
- LIST(SORT RAWWAVES)
- INSTALL(FILES ${RAWWAVES} DESTINATION "${DATA_DIR}/stk/rawwaves")
-ENDIF()
-
INSTALL(FILES "lmms.exe.manifest" DESTINATION .)
INSTALL(FILES "lmms.VisualElementsManifest.xml" DESTINATION .)
INSTALL(DIRECTORY "assets" DESTINATION .)
diff --git a/data/locale/ar.ts b/data/locale/ar.ts
index 1f159c42a..4aca06e51 100644
--- a/data/locale/ar.ts
+++ b/data/locale/ar.ts
@@ -5334,62 +5334,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
-
+
Move &right
-
+
Rename &channel
-
+
R&emove channel
-
+
Remove &unused channels
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
-
+
New Mixer Channel
@@ -6361,7 +6361,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/bs.ts b/data/locale/bs.ts
index 506b401bd..8050af8c2 100644
--- a/data/locale/bs.ts
+++ b/data/locale/bs.ts
@@ -2698,14 +2698,14 @@ Please make sure you have write-permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
The Mixer channel receives input from one or more instrument tracks.
It in turn can be routed to multiple other mixer channels. LMMS automatically takes care of preventing infinite loops for you and doesn't allow making a connection that would result in an infinite loop.
@@ -2716,27 +2716,27 @@ You can remove and move mixer channels in the context menu, which is accessed by
-
+
Move &left
-
+
Move &right
-
+
Rename &channel
-
+
R&emove channel
-
+
Remove &unused channels
@@ -2789,12 +2789,12 @@ You can remove and move mixer channels in the context menu, which is accessed by
-
+
Rename mixer channel
-
+
Enter the new name for this mixer channel
@@ -3677,7 +3677,7 @@ You can remove and move mixer channels in the context menu, which is accessed by
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
@@ -9752,7 +9752,7 @@ Please make sure you have read-permission to the file and the directory containi
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
Assign to:
diff --git a/data/locale/ca.ts b/data/locale/ca.ts
index 765cf3b60..2b06d0754 100644
--- a/data/locale/ca.ts
+++ b/data/locale/ca.ts
@@ -5333,62 +5333,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
-
+
Move &right
-
+
Rename &channel
-
+
R&emove channel
-
+
Remove &unused channels
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
-
+
New mixer Channel
@@ -6360,7 +6360,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/cs.ts b/data/locale/cs.ts
index 0ed175022..16982e4ae 100644
--- a/data/locale/cs.ts
+++ b/data/locale/cs.ts
@@ -5334,62 +5334,62 @@ Ověřte si prosím, zda máte povolen zápis do souboru a do složky, ve které
- MixerLine
+ MixerChannelView
-
+
Channel send amount
Množství odeslaného kanálu
-
+
Move &left
Přesunout do&leva
-
+
Move &right
Přesun dop&rava
-
+
Rename &channel
Přejmenovat &kanál
-
+
R&emove channel
Př&esunout kanál
-
+
Remove &unused channels
Odstranit nepo&užívané kanály
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
Přiřadit k:
-
+
New mixer Channel
Nový efektový kanál
@@ -6361,7 +6361,7 @@ Ověřte si prosím, zda máte povolen zápis do souboru a do složky, ve které
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/de.ts b/data/locale/de.ts
index 51ca7d562..d5d0625c2 100644
--- a/data/locale/de.ts
+++ b/data/locale/de.ts
@@ -5334,62 +5334,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
Kanal Sendemenge
-
+
Move &left
Nach &links verschieben
-
+
Move &right
Nach &rechts verschieben
-
+
Rename &channel
&Kanal umbenennen
-
+
R&emove channel
Kanal &Entfernen
-
+
Remove &unused channels
Entferne &unbenutzte Kanäle
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
Weise hinzu:
-
+
New mixer Channel
Neuer FX-Kanal
@@ -6361,7 +6361,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/el.ts b/data/locale/el.ts
index 320a6657f..130d5c63e 100644
--- a/data/locale/el.ts
+++ b/data/locale/el.ts
@@ -5333,62 +5333,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
-
+
Move &right
-
+
Rename &channel
-
+
R&emove channel
-
+
Remove &unused channels
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
-
+
New mixer Channel
@@ -6360,7 +6360,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/en.ts b/data/locale/en.ts
index e52ae39ab..246311921 100644
--- a/data/locale/en.ts
+++ b/data/locale/en.ts
@@ -5335,62 +5335,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
-
+
Move &right
-
+
Rename &channel
-
+
R&emove channel
-
+
Remove &unused channels
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
-
+
New mixer Channel
@@ -6362,7 +6362,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/eo.ts b/data/locale/eo.ts
index 005ee8100..88e92cda8 100644
--- a/data/locale/eo.ts
+++ b/data/locale/eo.ts
@@ -5333,62 +5333,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
-
+
Move &right
-
+
Rename &channel
-
+
R&emove channel
-
+
Remove &unused channels
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
-
+
New mixer Channel
@@ -6360,7 +6360,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/es.ts b/data/locale/es.ts
index 4fc4951ef..26c743784 100644
--- a/data/locale/es.ts
+++ b/data/locale/es.ts
@@ -5334,62 +5334,62 @@ Asegúrate de tener permisos de escritura tanto del archivo como del directorio
- MixerLine
+ MixerChannelView
-
+
Channel send amount
Cantidad de envío del canal
-
+
Move &left
Mover a la Izquierda (&L)
-
+
Move &right
Mover a la Derecha (&R)
-
+
Rename &channel
Renombrar &Canal
-
+
R&emove channel
Borrar canal (&E)
-
+
Remove &unused channels
Quitar los canales que no esten en &uso
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
Asignar a:
-
+
New mixer Channel
Nuevo Canal FX
@@ -6361,7 +6361,7 @@ Asegúrate de tener permisos de escritura tanto del archivo como del directorio
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/eu.ts b/data/locale/eu.ts
index 25c165f81..7e815a261 100644
--- a/data/locale/eu.ts
+++ b/data/locale/eu.ts
@@ -5614,62 +5614,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
-
+
Move &right
-
+
Rename &channel
-
+
R&emove channel
-
+
Remove &unused channels
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
-
+
New mixer Channel
@@ -6641,7 +6641,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/fa.ts b/data/locale/fa.ts
index 181ca0ca1..b167716fd 100644
--- a/data/locale/fa.ts
+++ b/data/locale/fa.ts
@@ -5333,62 +5333,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
-
+
Move &right
-
+
Rename &channel
-
+
R&emove channel
-
+
Remove &unused channels
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
-
+
New mixer Channel
@@ -6360,7 +6360,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/fr.ts b/data/locale/fr.ts
index 2c65444a8..0386fb4c6 100644
--- a/data/locale/fr.ts
+++ b/data/locale/fr.ts
@@ -5618,62 +5618,62 @@ Veuillez vous assurez que vous avez les droits d'écriture sur le fichier e
- MixerLine
+ MixerChannelView
-
+
Channel send amount
Quantité de signal envoyé du canal
-
+
Move &left
Déplacer à &gauche
-
+
Move &right
Déplacer à &droite
-
+
Rename &channel
&Renommer le canal
-
+
R&emove channel
&Supprimer le canal
-
+
Remove &unused channels
Supprimer les canaux &inutilisés
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
Assigner à :
-
+
New mixer Channel
Nouveau canal d'effet
@@ -6645,7 +6645,7 @@ Veuillez vous assurez que vous avez les droits d'écriture sur le fichier e
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/gl.ts b/data/locale/gl.ts
index cf04fd5d4..01cd54322 100644
--- a/data/locale/gl.ts
+++ b/data/locale/gl.ts
@@ -5333,62 +5333,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
-
+
Move &right
-
+
Rename &channel
-
+
R&emove channel
-
+
Remove &unused channels
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
-
+
New mixer Channel
@@ -6360,7 +6360,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/he.ts b/data/locale/he.ts
index ee5a23613..2699b7e1a 100644
--- a/data/locale/he.ts
+++ b/data/locale/he.ts
@@ -5334,62 +5334,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
-
+
Move &right
-
+
Rename &channel
-
+
R&emove channel
-
+
Remove &unused channels
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
-
+
New mixer Channel
@@ -6361,7 +6361,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/hi_IN.ts b/data/locale/hi_IN.ts
index 15550231f..5b2eeebf5 100644
--- a/data/locale/hi_IN.ts
+++ b/data/locale/hi_IN.ts
@@ -5335,62 +5335,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
-
+
Move &right
-
+
Rename &channel
-
+
R&emove channel
-
+
Remove &unused channels
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
-
+
New mixer Channel
@@ -6362,7 +6362,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/hu_HU.ts b/data/locale/hu_HU.ts
index 836059946..88ef6a431 100644
--- a/data/locale/hu_HU.ts
+++ b/data/locale/hu_HU.ts
@@ -5339,62 +5339,62 @@ Ellenőrizd, hogy rendelkezel-e a szükséges engedélyekkel és próbáld újra
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
Mozgatás &balra
-
+
Move &right
Mozgatás &jobbra
-
+
Rename &channel
Csatorna át&nevezése
-
+
R&emove channel
Csatorna &eltávolítása
-
+
Remove &unused channels
&Nem használt csatornák eltávolítása
-
+
Set channel color
Szín módosítása
-
+
Remove channel color
Szín eltávolítása
-
+
Pick random channel color
Véletlenszerű szín
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
Hozzárendelés:
-
+
New mixer Channel
Új csatorna
@@ -6366,7 +6366,7 @@ Ellenőrizd, hogy rendelkezel-e a szükséges engedélyekkel és próbáld újra
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/id.ts b/data/locale/id.ts
index e381ea726..4adeb9b22 100644
--- a/data/locale/id.ts
+++ b/data/locale/id.ts
@@ -5335,62 +5335,62 @@ Pastikan Anda memiliki izin menulis ke file dan direktori yang berisi berkas ter
- MixerLine
+ MixerChannelView
-
+
Channel send amount
Jumlah kirim saluran
-
+
Move &left
Pindah ke &kiri
-
+
Move &right
Pindah ke &kanan
-
+
Rename &channel
Ganti nama &saluran
-
+
R&emove channel
H&apus saluran
-
+
Remove &unused channels
Hapus &saluran yang tak terpakai
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
-
+
New mixer Channel
Saluran FX Baru
@@ -6362,7 +6362,7 @@ Pastikan Anda memiliki izin menulis ke file dan direktori yang berisi berkas ter
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/it.ts b/data/locale/it.ts
index ff146d471..104a3bdbc 100644
--- a/data/locale/it.ts
+++ b/data/locale/it.ts
@@ -5339,62 +5339,62 @@ Si prega di controllare i permessi di scrittura sul file e la cartella che lo co
- MixerLine
+ MixerChannelView
-
+
Channel send amount
Quantità di segnale inviata dal canale
-
+
Move &left
Sposta a &sinistra
-
+
Move &right
Sposta a $destra
-
+
Rename &channel
Rinomina &canale
-
+
R&emove channel
R&imuovi canale
-
+
Remove &unused channels
Rimuovi canali in&utilizzati
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
Assegna a:
-
+
New mixer Channel
Nuovo canale FX
@@ -6366,7 +6366,7 @@ Si prega di controllare i permessi di scrittura sul file e la cartella che lo co
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/ja.ts b/data/locale/ja.ts
index e10ca5118..84c5c8a6a 100644
--- a/data/locale/ja.ts
+++ b/data/locale/ja.ts
@@ -5335,62 +5335,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
一つ左へ (&l)
-
+
Move &right
一つ右へ (&r)
-
+
Rename &channel
チャンネル名を変更 (&c)
-
+
R&emove channel
チャンネルを削除 (&e)
-
+
Remove &unused channels
使用していないチャンネルを削除 (&u)
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
-
+
New mixer Channel
@@ -6362,7 +6362,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/ka.ts b/data/locale/ka.ts
index 1956d8d04..bd7890457 100644
--- a/data/locale/ka.ts
+++ b/data/locale/ka.ts
@@ -5333,62 +5333,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
-
+
Move &right
-
+
Rename &channel
-
+
R&emove channel
-
+
Remove &unused channels
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
-
+
New mixer Channel
@@ -6360,7 +6360,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/ko.ts b/data/locale/ko.ts
index 7373b5ca9..036c73231 100644
--- a/data/locale/ko.ts
+++ b/data/locale/ko.ts
@@ -5337,62 +5337,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
왼쪽으로 이동(&L)
-
+
Move &right
오른쪽으로 이동(&R)
-
+
Rename &channel
채널 이름 바꾸기(&C)
-
+
R&emove channel
채널 제거(&R)
-
+
Remove &unused channels
사용하지 않는 채널 제거(&U)
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
채널 할당:
-
+
New mixer Channel
새 FX 채널
@@ -6364,7 +6364,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/ms_MY.ts b/data/locale/ms_MY.ts
index 209d51d10..dc3561ea2 100644
--- a/data/locale/ms_MY.ts
+++ b/data/locale/ms_MY.ts
@@ -5333,62 +5333,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
-
+
Move &right
-
+
Rename &channel
-
+
R&emove channel
-
+
Remove &unused channels
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
-
+
New mixer Channel
@@ -6360,7 +6360,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/nb.ts b/data/locale/nb.ts
index 3675b7f58..adfc6d856 100644
--- a/data/locale/nb.ts
+++ b/data/locale/nb.ts
@@ -5333,62 +5333,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
-
+
Move &right
-
+
Rename &channel
-
+
R&emove channel
-
+
Remove &unused channels
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
-
+
New mixer Channel
@@ -6360,7 +6360,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/nl.ts b/data/locale/nl.ts
index ad630a249..8d1304135 100644
--- a/data/locale/nl.ts
+++ b/data/locale/nl.ts
@@ -5335,62 +5335,62 @@ Zorg ervoor dat u schrijfbevoegdheid heeft voor het bestand en voor de map die h
- MixerLine
+ MixerChannelView
-
+
Channel send amount
Hoeveelheid kanaal-send
-
+
Move &left
&Links verplaatsen
-
+
Move &right
&Rechts verplaatsen
-
+
Rename &channel
&Kanaal hernoemen
-
+
R&emove channel
Kanaal v&erwijderen
-
+
Remove &unused channels
Ongebr&uikte kanalen verwijderen
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
Toewijzen aan:
-
+
New mixer Channel
Nieuw FX-kanaal
@@ -6362,7 +6362,7 @@ Zorg ervoor dat u schrijfbevoegdheid heeft voor het bestand en voor de map die h
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/oc.ts b/data/locale/oc.ts
index 58c81c964..be804cfca 100644
--- a/data/locale/oc.ts
+++ b/data/locale/oc.ts
@@ -5333,62 +5333,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
-
+
Move &right
-
+
Rename &channel
-
+
R&emove channel
-
+
Remove &unused channels
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
-
+
New mixer Channel
@@ -6360,7 +6360,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/pl.ts b/data/locale/pl.ts
index bb0c64ede..3a12f0815 100644
--- a/data/locale/pl.ts
+++ b/data/locale/pl.ts
@@ -5619,62 +5619,62 @@ Upewnij się, że masz uprawnienia do zapisu do pliku i katalogu zawierającego
- MixerLine
+ MixerChannelView
-
+
Channel send amount
Ilość wysyłania kanału
-
+
Move &left
Przesuń w &lewo
-
+
Move &right
Przesuń w p&rawo
-
+
Rename &channel
Zmień nazwę &kanału
-
+
R&emove channel
Usuń k&anał
-
+
Remove &unused channels
&Usuń nieużywane kanały
-
+
Set channel color
Ustaw kolor kanału
-
+
Remove channel color
Usuń kolor kanału
-
+
Pick random channel color
Ustaw losowy kolor kanału
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
Przypisz do:
-
+
New mixer Channel
Nowy kanał efektów
@@ -6646,7 +6646,7 @@ Upewnij się, że masz uprawnienia do zapisu do pliku i katalogu zawierającego
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/pt.ts b/data/locale/pt.ts
index b375e289f..d88d0fa24 100644
--- a/data/locale/pt.ts
+++ b/data/locale/pt.ts
@@ -5336,62 +5336,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
Quantidade de envio de canal
-
+
Move &left
-
+
Move &right
-
+
Rename &channel
Renomear canal
-
+
R&emove channel
Remover canal
-
+
Remove &unused channels
Remover canais não utilizados
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
Atribuir a:
-
+
New mixer Channel
Novo Canal FX
@@ -6363,7 +6363,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/ro.ts b/data/locale/ro.ts
index eceb45a64..4823ca57e 100644
--- a/data/locale/ro.ts
+++ b/data/locale/ro.ts
@@ -5334,62 +5334,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
-
+
Move &right
-
+
Rename &channel
-
+
R&emove channel
-
+
Remove &unused channels
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
-
+
New mixer Channel
@@ -6361,7 +6361,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/ru.ts b/data/locale/ru.ts
index 8235f291f..dee2b8482 100644
--- a/data/locale/ru.ts
+++ b/data/locale/ru.ts
@@ -5348,62 +5348,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
Величина отправки канала
-
+
Move &left
Подвинуть в&лево
-
+
Move &right
Подвинуть в&право
-
+
Rename &channel
Пере&именовать канал
-
+
R&emove channel
&Удалить канал
-
+
Remove &unused channels
Удалить &неиспользуемые каналы
-
+
Set channel color
Установить цвет канала
-
+
Remove channel color
Удалить цвет канала
-
+
Pick random channel color
Выбрать случайный цвет канала
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
Назначить на:
-
+
New mixer Channel
Новый канал ЭФ
@@ -6375,7 +6375,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/sl.ts b/data/locale/sl.ts
index 3ad55a4c0..1aa67d54d 100644
--- a/data/locale/sl.ts
+++ b/data/locale/sl.ts
@@ -5333,62 +5333,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
-
+
Move &left
-
+
Move &right
-
+
Rename &channel
-
+
R&emove channel
-
+
Remove &unused channels
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
-
+
New mixer Channel
@@ -6360,7 +6360,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/sr.ts b/data/locale/sr.ts
index 9b90164ab..557890f35 100644
--- a/data/locale/sr.ts
+++ b/data/locale/sr.ts
@@ -2178,7 +2178,7 @@ Please make sure you have write-permission to the file and the directory contain
- MixerLine
+ MixerChannelView
Channel send amount
@@ -2956,7 +2956,7 @@ You can remove and move mixer channels in the context menu, which is accessed by
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
@@ -7752,7 +7752,7 @@ Please make sure you have read-permission to the file and the directory containi
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
Assign to:
diff --git a/data/locale/sv.ts b/data/locale/sv.ts
index 4963b07a9..b40306cac 100644
--- a/data/locale/sv.ts
+++ b/data/locale/sv.ts
@@ -5617,62 +5617,62 @@ Se till att du har skrivbehörighet till filen och mappen som innehåller filen
- MixerLine
+ MixerChannelView
-
+
Channel send amount
Kanalsändningsbelopp
-
+
Move &left
Flytta &vänster
-
+
Move &right
Flytta &höger
-
+
Rename &channel
Byt namn på &kanal
-
+
R&emove channel
T&a bort kanal
-
+
Remove &unused channels
Ta bort &oanvända kanaler
-
+
Set channel color
Ställ in kanalfärg
-
+
Remove channel color
Ta bort kanalfärg
-
+
Pick random channel color
Välj slumpmässig kanalfärg
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
Tilldela till:
-
+
New mixer Channel
Ny FX-kanal
@@ -6644,7 +6644,7 @@ Se till att du har skrivbehörighet till filen och mappen som innehåller filen
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/tr.ts b/data/locale/tr.ts
index 387be6d8b..bd469667f 100644
--- a/data/locale/tr.ts
+++ b/data/locale/tr.ts
@@ -5619,62 +5619,62 @@ Lütfen dosyaya ve dosyayı içeren dizine yazma izniniz olduğundan emin olun v
- MixerLine
+ MixerChannelView
-
+
Channel send amount
Kanal gönderme miktarı
-
+
Move &left
Sol&a taşı
-
+
Move &right
&Sağa taşı
-
+
Rename &channel
&Kanalı yeniden adlandır
-
+
R&emove channel
Kanalı k&aldır
-
+
Remove &unused channels
&Kullanılmayan kanalları kaldırın
-
+
Set channel color
Kanal rengini ayarla
-
+
Remove channel color
Kanal rengini kaldır
-
+
Pick random channel color
Rastgele kanal rengi seçin
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
Ata:
-
+
New mixer Channel
Yeni FX Kanalı
@@ -6646,7 +6646,7 @@ Lütfen dosyaya ve dosyayı içeren dizine yazma izniniz olduğundan emin olun v
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/uk.ts b/data/locale/uk.ts
index 50df10e4b..245c433a1 100644
--- a/data/locale/uk.ts
+++ b/data/locale/uk.ts
@@ -5334,62 +5334,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
Величина відправки каналу
-
+
Move &left
Рухати вліво &L
-
+
Move &right
Рухати вправо &R
-
+
Rename &channel
Перейменувати канал &C
-
+
R&emove channel
Видалити канал &e
-
+
Remove &unused channels
Видалити канали які &не використовуються
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
Призначити до:
-
+
New mixer Channel
Новий ефект каналу
@@ -6361,7 +6361,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/zh_CN.ts b/data/locale/zh_CN.ts
index 63b22df99..57c080341 100644
--- a/data/locale/zh_CN.ts
+++ b/data/locale/zh_CN.ts
@@ -5343,62 +5343,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
通道发送的数量
-
+
Move &left
向左移(&L)
-
+
Move &right
向右移(&R)
-
+
Rename &channel
重命名通道(&C)
-
+
R&emove channel
删除通道(&E)
-
+
Remove &unused channels
移除所有未用通道(&U)
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
分配给:
-
+
New mixer Channel
新的效果通道
@@ -6370,7 +6370,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/locale/zh_TW.ts b/data/locale/zh_TW.ts
index 791a45599..9348dfb32 100644
--- a/data/locale/zh_TW.ts
+++ b/data/locale/zh_TW.ts
@@ -5334,62 +5334,62 @@ Please make sure you have write permission to the file and the directory contain
- MixerLine
+ MixerChannelView
-
+
Channel send amount
通道發送的數量
-
+
Move &left
向左移(&L)
-
+
Move &right
向右移(&R)
-
+
Rename &channel
重命名通道(&C)
-
+
R&emove channel
刪除通道(&E)
-
+
Remove &unused channels
移除所有未用通道(&U)
-
+
Set channel color
-
+
Remove channel color
-
+
Pick random channel color
- MixerLineLcdSpinBox
+ MixerChannelLcdSpinBox
-
+
Assign to:
分配給:
-
+
New mixer Channel
新的效果通道
@@ -6361,7 +6361,7 @@ Please make sure you have write permission to the file and the directory contain
- InstrumentMiscView
+ InstrumentTuningView
MASTER PITCH
diff --git a/data/samples/bassloops/briff01.ogg b/data/samples/bassloops/briff01 - 140 BPM.ogg
similarity index 98%
rename from data/samples/bassloops/briff01.ogg
rename to data/samples/bassloops/briff01 - 140 BPM.ogg
index a307df85f..0b9cc32f7 100644
Binary files a/data/samples/bassloops/briff01.ogg and b/data/samples/bassloops/briff01 - 140 BPM.ogg differ
diff --git a/data/samples/bassloops/rave_bass01.ogg b/data/samples/bassloops/rave_bass01 - 180 BPM.ogg
similarity index 98%
rename from data/samples/bassloops/rave_bass01.ogg
rename to data/samples/bassloops/rave_bass01 - 180 BPM.ogg
index 920ff4a74..335195747 100644
Binary files a/data/samples/bassloops/rave_bass01.ogg and b/data/samples/bassloops/rave_bass01 - 180 BPM.ogg differ
diff --git a/data/samples/bassloops/rave_bass02.ogg b/data/samples/bassloops/rave_bass02 - 180 BPM.ogg
similarity index 98%
rename from data/samples/bassloops/rave_bass02.ogg
rename to data/samples/bassloops/rave_bass02 - 180 BPM.ogg
index ff38123df..230d99d2e 100644
Binary files a/data/samples/bassloops/rave_bass02.ogg and b/data/samples/bassloops/rave_bass02 - 180 BPM.ogg differ
diff --git a/data/samples/bassloops/tb303_01.ogg b/data/samples/bassloops/tb303_01 - 123 BPM.ogg
similarity index 98%
rename from data/samples/bassloops/tb303_01.ogg
rename to data/samples/bassloops/tb303_01 - 123 BPM.ogg
index 41e1b1fc4..105720175 100644
Binary files a/data/samples/bassloops/tb303_01.ogg and b/data/samples/bassloops/tb303_01 - 123 BPM.ogg differ
diff --git a/data/samples/bassloops/techno_bass01.ogg b/data/samples/bassloops/techno_bass01 - 140 BPM.ogg
similarity index 92%
rename from data/samples/bassloops/techno_bass01.ogg
rename to data/samples/bassloops/techno_bass01 - 140 BPM.ogg
index 15c2c8e32..55cd204dd 100644
Binary files a/data/samples/bassloops/techno_bass01.ogg and b/data/samples/bassloops/techno_bass01 - 140 BPM.ogg differ
diff --git a/data/samples/bassloops/techno_bass02.ogg b/data/samples/bassloops/techno_bass02 - 140 BPM.ogg
similarity index 93%
rename from data/samples/bassloops/techno_bass02.ogg
rename to data/samples/bassloops/techno_bass02 - 140 BPM.ogg
index 08691f435..c1f3e8637 100644
Binary files a/data/samples/bassloops/techno_bass02.ogg and b/data/samples/bassloops/techno_bass02 - 140 BPM.ogg differ
diff --git a/data/samples/bassloops/techno_synth01.ogg b/data/samples/bassloops/techno_synth01 - 140 BPM.ogg
similarity index 86%
rename from data/samples/bassloops/techno_synth01.ogg
rename to data/samples/bassloops/techno_synth01 - 140 BPM.ogg
index 95c3d96ae..1086bb0c8 100644
Binary files a/data/samples/bassloops/techno_synth01.ogg and b/data/samples/bassloops/techno_synth01 - 140 BPM.ogg differ
diff --git a/data/samples/bassloops/techno_synth02.ogg b/data/samples/bassloops/techno_synth02 - 140 BPM.ogg
similarity index 87%
rename from data/samples/bassloops/techno_synth02.ogg
rename to data/samples/bassloops/techno_synth02 - 140 BPM.ogg
index dfa972e1d..afb27172b 100644
Binary files a/data/samples/bassloops/techno_synth02.ogg and b/data/samples/bassloops/techno_synth02 - 140 BPM.ogg differ
diff --git a/data/samples/bassloops/techno_synth03.ogg b/data/samples/bassloops/techno_synth03 - 130 BPM.ogg
similarity index 92%
rename from data/samples/bassloops/techno_synth03.ogg
rename to data/samples/bassloops/techno_synth03 - 130 BPM.ogg
index c27cda653..bffff9517 100644
Binary files a/data/samples/bassloops/techno_synth03.ogg and b/data/samples/bassloops/techno_synth03 - 130 BPM.ogg differ
diff --git a/data/samples/bassloops/techno_synth04.ogg b/data/samples/bassloops/techno_synth04 - 140 BPM.ogg
similarity index 99%
rename from data/samples/bassloops/techno_synth04.ogg
rename to data/samples/bassloops/techno_synth04 - 140 BPM.ogg
index 0e9a37398..9dd34f33a 100644
Binary files a/data/samples/bassloops/techno_synth04.ogg and b/data/samples/bassloops/techno_synth04 - 140 BPM.ogg differ
diff --git a/data/samples/beats/909beat01.ogg b/data/samples/beats/909beat01 - 122 BPM.ogg
similarity index 99%
rename from data/samples/beats/909beat01.ogg
rename to data/samples/beats/909beat01 - 122 BPM.ogg
index 1892eb91b..2bae51357 100644
Binary files a/data/samples/beats/909beat01.ogg and b/data/samples/beats/909beat01 - 122 BPM.ogg differ
diff --git a/data/samples/beats/break01.ogg b/data/samples/beats/break01 - 168 BPM.ogg
similarity index 94%
rename from data/samples/beats/break01.ogg
rename to data/samples/beats/break01 - 168 BPM.ogg
index d1f5769bd..5d9bd2f4b 100644
Binary files a/data/samples/beats/break01.ogg and b/data/samples/beats/break01 - 168 BPM.ogg differ
diff --git a/data/samples/beats/break02.ogg b/data/samples/beats/break02 - 141 BPM.ogg
similarity index 89%
rename from data/samples/beats/break02.ogg
rename to data/samples/beats/break02 - 141 BPM.ogg
index 17243cd9e..653662c75 100644
Binary files a/data/samples/beats/break02.ogg and b/data/samples/beats/break02 - 141 BPM.ogg differ
diff --git a/data/samples/beats/break03.ogg b/data/samples/beats/break03 - 168 BPM.ogg
similarity index 95%
rename from data/samples/beats/break03.ogg
rename to data/samples/beats/break03 - 168 BPM.ogg
index f806be70a..3b3a4b346 100644
Binary files a/data/samples/beats/break03.ogg and b/data/samples/beats/break03 - 168 BPM.ogg differ
diff --git a/data/samples/beats/electro_beat01.ogg b/data/samples/beats/electro_beat01 - 120 BPM.ogg
similarity index 99%
rename from data/samples/beats/electro_beat01.ogg
rename to data/samples/beats/electro_beat01 - 120 BPM.ogg
index 57cd690fc..29352b683 100644
Binary files a/data/samples/beats/electro_beat01.ogg and b/data/samples/beats/electro_beat01 - 120 BPM.ogg differ
diff --git a/data/samples/beats/electro_beat02.ogg b/data/samples/beats/electro_beat02 - 119 BPM.ogg
similarity index 98%
rename from data/samples/beats/electro_beat02.ogg
rename to data/samples/beats/electro_beat02 - 119 BPM.ogg
index b89260bab..775b64d88 100644
Binary files a/data/samples/beats/electro_beat02.ogg and b/data/samples/beats/electro_beat02 - 119 BPM.ogg differ
diff --git a/data/samples/beats/house_loop01.ogg b/data/samples/beats/house_loop01 - 142 BPM.ogg
similarity index 98%
rename from data/samples/beats/house_loop01.ogg
rename to data/samples/beats/house_loop01 - 142 BPM.ogg
index 09f3a260b..9f04d1deb 100644
Binary files a/data/samples/beats/house_loop01.ogg and b/data/samples/beats/house_loop01 - 142 BPM.ogg differ
diff --git a/data/samples/beats/jungle01.ogg b/data/samples/beats/jungle01 - 168 BPM.ogg
similarity index 98%
rename from data/samples/beats/jungle01.ogg
rename to data/samples/beats/jungle01 - 168 BPM.ogg
index 9662e4514..b7196044f 100644
Binary files a/data/samples/beats/jungle01.ogg and b/data/samples/beats/jungle01 - 168 BPM.ogg differ
diff --git a/data/samples/beats/rave_hihat01.ogg b/data/samples/beats/rave_hihat01 - 180 BPM.ogg
similarity index 98%
rename from data/samples/beats/rave_hihat01.ogg
rename to data/samples/beats/rave_hihat01 - 180 BPM.ogg
index 236f447a8..632bb0bec 100644
Binary files a/data/samples/beats/rave_hihat01.ogg and b/data/samples/beats/rave_hihat01 - 180 BPM.ogg differ
diff --git a/data/samples/beats/rave_hihat02.ogg b/data/samples/beats/rave_hihat02 - 180 BPM.ogg
similarity index 98%
rename from data/samples/beats/rave_hihat02.ogg
rename to data/samples/beats/rave_hihat02 - 180 BPM.ogg
index 33329bd55..a6e5426f4 100644
Binary files a/data/samples/beats/rave_hihat02.ogg and b/data/samples/beats/rave_hihat02 - 180 BPM.ogg differ
diff --git a/data/samples/beats/rave_kick01.ogg b/data/samples/beats/rave_kick01 - 180 BPM.ogg
similarity index 98%
rename from data/samples/beats/rave_kick01.ogg
rename to data/samples/beats/rave_kick01 - 180 BPM.ogg
index 79f99ffb8..5633f6e1c 100644
Binary files a/data/samples/beats/rave_kick01.ogg and b/data/samples/beats/rave_kick01 - 180 BPM.ogg differ
diff --git a/data/samples/beats/rave_kick02.ogg b/data/samples/beats/rave_kick02 - 180 BPM.ogg
similarity index 98%
rename from data/samples/beats/rave_kick02.ogg
rename to data/samples/beats/rave_kick02 - 180 BPM.ogg
index 463112869..c57cfc0d9 100644
Binary files a/data/samples/beats/rave_kick02.ogg and b/data/samples/beats/rave_kick02 - 180 BPM.ogg differ
diff --git a/data/samples/beats/rave_snare01.ogg b/data/samples/beats/rave_snare01 - 180 BPM.ogg
similarity index 98%
rename from data/samples/beats/rave_snare01.ogg
rename to data/samples/beats/rave_snare01 - 180 BPM.ogg
index ceec2d6e0..6e17a6af3 100644
Binary files a/data/samples/beats/rave_snare01.ogg and b/data/samples/beats/rave_snare01 - 180 BPM.ogg differ
diff --git a/data/samples/drums/kick04.ogg b/data/samples/drums/kick04.ogg
index 567480abd..8f7dce527 100644
Binary files a/data/samples/drums/kick04.ogg and b/data/samples/drums/kick04.ogg differ
diff --git a/data/samples/effects/scratch01.ogg b/data/samples/effects/scratch01.ogg
index 9f216038d..0b05505cd 100644
Binary files a/data/samples/effects/scratch01.ogg and b/data/samples/effects/scratch01.ogg differ
diff --git a/data/samples/effects/wind_chimes01.ogg b/data/samples/effects/wind_chimes01.ogg
index 35d3374a2..7fb3c441a 100644
Binary files a/data/samples/effects/wind_chimes01.ogg and b/data/samples/effects/wind_chimes01.ogg differ
diff --git a/data/samples/instruments/harpsichord01.ogg b/data/samples/instruments/harpsichord01.ogg
index 028bbd912..c84ffd7df 100644
Binary files a/data/samples/instruments/harpsichord01.ogg and b/data/samples/instruments/harpsichord01.ogg differ
diff --git a/data/samples/latin/latin_brass01.ogg b/data/samples/latin/latin_brass01 - 140 BPM.ogg
similarity index 95%
rename from data/samples/latin/latin_brass01.ogg
rename to data/samples/latin/latin_brass01 - 140 BPM.ogg
index 3bf7dcd27..ac9a2c59b 100644
Binary files a/data/samples/latin/latin_brass01.ogg and b/data/samples/latin/latin_brass01 - 140 BPM.ogg differ
diff --git a/data/samples/latin/latin_guitar01.ogg b/data/samples/latin/latin_guitar01 - 126 BPM.ogg
similarity index 95%
rename from data/samples/latin/latin_guitar01.ogg
rename to data/samples/latin/latin_guitar01 - 126 BPM.ogg
index 25685013d..3c316ec3b 100644
Binary files a/data/samples/latin/latin_guitar01.ogg and b/data/samples/latin/latin_guitar01 - 126 BPM.ogg differ
diff --git a/data/samples/latin/latin_guitar02.ogg b/data/samples/latin/latin_guitar02 - 140 BPM.ogg
similarity index 92%
rename from data/samples/latin/latin_guitar02.ogg
rename to data/samples/latin/latin_guitar02 - 140 BPM.ogg
index 3fe4269a2..55b218d98 100644
Binary files a/data/samples/latin/latin_guitar02.ogg and b/data/samples/latin/latin_guitar02 - 140 BPM.ogg differ
diff --git a/data/samples/latin/latin_guitar03.ogg b/data/samples/latin/latin_guitar03 - 120 BPM.ogg
similarity index 90%
rename from data/samples/latin/latin_guitar03.ogg
rename to data/samples/latin/latin_guitar03 - 120 BPM.ogg
index 0ae9bb3f7..1f6a9275e 100644
Binary files a/data/samples/latin/latin_guitar03.ogg and b/data/samples/latin/latin_guitar03 - 120 BPM.ogg differ
diff --git a/data/samples/misc/hit01.ogg b/data/samples/misc/hit01.ogg
index d5e93633e..30dd86135 100644
Binary files a/data/samples/misc/hit01.ogg and b/data/samples/misc/hit01.ogg differ
diff --git a/data/themes/classic/automation_ghost_note.png b/data/themes/classic/automation_ghost_note.png
new file mode 100644
index 000000000..d14c047d7
Binary files /dev/null and b/data/themes/classic/automation_ghost_note.png differ
diff --git a/data/themes/classic/cursor_select_left.png b/data/themes/classic/cursor_select_left.png
new file mode 100644
index 000000000..eaa80e0bb
Binary files /dev/null and b/data/themes/classic/cursor_select_left.png differ
diff --git a/data/themes/classic/cursor_select_right.png b/data/themes/classic/cursor_select_right.png
new file mode 100644
index 000000000..abd4aecfb
Binary files /dev/null and b/data/themes/classic/cursor_select_right.png differ
diff --git a/data/themes/classic/edit_tangent.png b/data/themes/classic/edit_tangent.png
new file mode 100644
index 000000000..438673b33
Binary files /dev/null and b/data/themes/classic/edit_tangent.png differ
diff --git a/data/themes/classic/fader_background.png b/data/themes/classic/fader_background.png
deleted file mode 100644
index 682ff4c92..000000000
Binary files a/data/themes/classic/fader_background.png and /dev/null differ
diff --git a/data/themes/classic/fader_leds.png b/data/themes/classic/fader_leds.png
deleted file mode 100644
index 6c673cf36..000000000
Binary files a/data/themes/classic/fader_leds.png and /dev/null differ
diff --git a/data/themes/classic/horizontal_slider.png b/data/themes/classic/horizontal_slider.png
new file mode 100644
index 000000000..49d16b9d8
Binary files /dev/null and b/data/themes/classic/horizontal_slider.png differ
diff --git a/data/themes/classic/lcd_11green.png b/data/themes/classic/lcd_11green.png
new file mode 100644
index 000000000..32e923fe8
Binary files /dev/null and b/data/themes/classic/lcd_11green.png differ
diff --git a/data/themes/classic/lcd_11green_dot.png b/data/themes/classic/lcd_11green_dot.png
new file mode 100644
index 000000000..9f5a660d3
Binary files /dev/null and b/data/themes/classic/lcd_11green_dot.png differ
diff --git a/data/themes/classic/style.css b/data/themes/classic/style.css
index 58ec5dc09..dfaee134d 100644
--- a/data/themes/classic/style.css
+++ b/data/themes/classic/style.css
@@ -8,7 +8,7 @@ QLabel, QTreeWidget, QListWidget, QGroupBox, QMenuBar {
}
QMdiArea {
- background-image: url(resources:background_artwork.png);
+ background-image: url("resources:background_artwork.png");
}
lmms--gui--Knob {
@@ -22,6 +22,7 @@ lmms--gui--AutomationEditor {
qproperty-backgroundShade: rgba(255, 255, 255, 15);
qproperty-nodeInValueColor: rgba(255, 119, 175, 150);
qproperty-nodeOutValueColor: rgba(129, 231, 181, 150);
+ qproperty-nodeTangentLineColor: rgba(200, 200, 200, 255);
qproperty-crossColor: rgb( 255, 51, 51 );
/* Grid colors */
qproperty-lineColor: rgba(128, 128, 128, 80);
@@ -32,6 +33,10 @@ lmms--gui--AutomationEditor {
qproperty-scaleColor: qlineargradient(spread:reflect,
x1:0, y1:0.5, x2:1, y2:0.5,
stop:0 #333, stop:1 #202020);
+
+ qproperty-ghostNoteColor: rgba(248, 248, 255, 125);
+ qproperty-detuningNoteColor: rgba(248, 11, 11, 125);
+ qproperty-ghostSampleColor: rgba(125, 125, 125, 125);
}
/* text box */
@@ -70,7 +75,7 @@ QToolTip {
color: #4afd85;
}
-lmms--gui--TextFloat {
+lmms--gui--TextFloat, lmms--gui--SimpleTextFloat {
border-radius: 4px;
background: qlineargradient(spread:reflect, x1:0.5, y1:0.5, x2:0.5, y2:0, stop:0 rgba(0, 0, 0, 255), stop:1 rgba(50, 50, 50, 220));
opacity: 175;
@@ -82,7 +87,6 @@ lmms--gui--TextFloat {
QMenu {
border:1px solid #747474;
background-color: #c9c9c9;
- font-size:11px;
}
QMenu::separator {
@@ -98,15 +102,12 @@ QMenu::item {
QMenu::item:selected {
color: white;
- font-weight:bold;
background-color: #747474;
}
QMenu::item:disabled {
color: #747474;
background-color: #c9c9c9;
- font-size:12px;
- font-weight: normal;
padding: 4px 32px 4px 20px;
}
@@ -132,7 +133,7 @@ QMenu::indicator:selected {
lmms--gui--FileBrowser QCheckBox
{
- font-size: 10px;
+ font-size: 8pt;
color: white;
}
@@ -146,6 +147,7 @@ lmms--gui--PianoRoll {
qproperty-backgroundShade: rgba( 255, 255, 255, 10 );
qproperty-noteModeColor: rgb( 255, 255, 255 );
qproperty-noteColor: rgb( 119, 199, 216 );
+ qproperty-stepNoteColor: #9b1313;
qproperty-noteTextColor: rgb( 255, 255, 255 );
qproperty-noteOpacity: 128;
qproperty-noteBorders: true; /* boolean property, set false to have borderless notes */
@@ -187,6 +189,7 @@ lmms--gui--TabWidget {
qproperty-tabText: rgba(255, 255, 255, 180);
qproperty-tabTitleText: #fff;
qproperty-tabSelected: #61666b;
+ qproperty-tabTextSelected: rgba(255, 255, 255, 180);
qproperty-tabBackground: #3c434b;
qproperty-tabBorder: #3c434b;
}
@@ -200,7 +203,9 @@ lmms--gui--GroupBox {
lmms--gui--Oscilloscope {
background: none;
border: none;
- qproperty-normalColor: rgb(71, 253, 133);
+ qproperty-leftChannelColor: rgb(71, 253, 133);
+ qproperty-rightChannelColor: rgb(238, 253, 71);
+ qproperty-otherChannelsColor: rgb(71, 235, 253);
qproperty-clippingColor: rgb(255, 64, 64);
}
@@ -208,7 +213,8 @@ lmms--gui--Oscilloscope {
lmms--gui--CPULoadWidget {
border: none;
- background: url(resources:cpuload_bg.png);
+ background: url("resources:cpuload_bg.png");
+ qproperty-stepSize: 4;
}
/* scrollbar: trough */
@@ -324,14 +330,14 @@ QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical {
height: 5px;
}
-QScrollBar::left-arrow:horizontal { background-image: url(resources:sbarrow_left.png);}
-QScrollBar::right-arrow:horizontal { background-image: url(resources:sbarrow_right.png);}
-QScrollBar::up-arrow:vertical { background-image: url(resources:sbarrow_up.png);}
-QScrollBar::down-arrow:vertical { background-image: url(resources:sbarrow_down.png);}
-QScrollBar::left-arrow:horizontal:disabled { background-image: url(resources:sbarrow_left_d.png);}
-QScrollBar::right-arrow:horizontal:disabled { background-image: url(resources:sbarrow_right_d.png);}
-QScrollBar::up-arrow:vertical:disabled { background-image: url(resources:sbarrow_up_d.png);}
-QScrollBar::down-arrow:vertical:disabled { background-image: url(resources:sbarrow_down_d.png);}
+QScrollBar::left-arrow:horizontal { background-image: url("resources:sbarrow_left.png");}
+QScrollBar::right-arrow:horizontal { background-image: url("resources:sbarrow_right.png");}
+QScrollBar::up-arrow:vertical { background-image: url("resources:sbarrow_up.png");}
+QScrollBar::down-arrow:vertical { background-image: url("resources:sbarrow_down.png");}
+QScrollBar::left-arrow:horizontal:disabled { background-image: url("resources:sbarrow_left_d.png");}
+QScrollBar::right-arrow:horizontal:disabled { background-image: url("resources:sbarrow_right_d.png");}
+QScrollBar::up-arrow:vertical:disabled { background-image: url("resources:sbarrow_up_d.png");}
+QScrollBar::down-arrow:vertical:disabled { background-image: url("resources:sbarrow_down_d.png");}
/* background for song editor and pattern editor */
@@ -369,7 +375,7 @@ lmms--gui--TrackOperationsWidget > QPushButton {
}
lmms--gui--TrackOperationsWidget > QPushButton::menu-indicator {
- image: url(resources:trackop.png);
+ image: url("resources:trackop.png");
subcontrol-origin: padding;
subcontrol-position: center;
position: relative;
@@ -377,12 +383,12 @@ lmms--gui--TrackOperationsWidget > QPushButton::menu-indicator {
}
lmms--gui--TrackOperationsWidget > QPushButton::menu-indicator:hover {
- image: url(resources:trackop_h.png);
+ image: url("resources:trackop_h.png");
}
lmms--gui--TrackOperationsWidget > QPushButton::menu-indicator:pressed,
lmms--gui--TrackOperationsWidget > QPushButton::menu-indicator:checked {
- image: url(resources:trackop_c.png);
+ image: url("resources:trackop_c.png");
position: relative;
top: 2px;
}
@@ -411,13 +417,32 @@ lmms--gui--AutomatableSlider::groove:vertical {
lmms--gui--AutomatableSlider::handle:vertical {
background: none;
- border-image: url(resources:main_slider.png);
+ border-image: url("resources:main_slider.png");
width: 26px;
height: 10px;
border-radius: 2px;
margin: -4px -12px -2px;
}
+/* main horizontal sliders (zoom) */
+
+lmms--gui--AutomatableSlider::groove:horizontal {
+ background: rgba(0,0,0, 128);
+ border: 1px inset rgba(100,100,100, 64);
+ border-radius: 2px;
+ height: 2px;
+ margin: 2px;
+}
+
+lmms--gui--AutomatableSlider::handle:horizontal {
+ background: none;
+ border-image: url("resources:horizontal_slider.png");
+ width: 10px;
+ height: 26px;
+ border-radius: 2px;
+ margin: -12px -2px;
+}
+
/* about dialog */
QTabWidget, QTabWidget QWidget {
background: #5b6571;
@@ -610,7 +635,7 @@ lmms--gui--ControllerRackView QPushButton {
font-size: 10px;
}
-lmms--gui--MixerLine {
+lmms--gui--MixerChannelView {
background: #5b6571;
color: #e0e0e0;
qproperty-backgroundActive: qlineargradient(spread:reflect, x1:0, y1:0, x2:1, y2:0,
@@ -621,11 +646,16 @@ lmms--gui--MixerLine {
qproperty-strokeInnerInactive: rgba( 255, 255, 255, 50 );
}
+lmms--gui--MixerChannelView QGraphicsView {
+ background: transparent;
+ border-style: none;
+}
+
/* persistent peak markers for fx peak meters */
lmms--gui--Fader {
- qproperty-peakGreen: rgb( 74, 253, 133);
- qproperty-peakYellow: rgb(224, 222, 18);
- qproperty-peakRed: rgb( 255, 100, 100);
+ qproperty-peakOk: rgb( 74, 253, 133);
+ qproperty-peakWarn: rgb(224, 222, 18);
+ qproperty-peakClip: rgb( 255, 100, 100);
}
lmms--gui--TimeLineWidget {
@@ -641,15 +671,25 @@ lmms--gui--TimeLineWidget {
background-color: qlineargradient( x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #8796a7, stop: 1.0 #3e454e );
- qproperty-inactiveLoopColor: rgba( 52, 63, 53, 64 );
+ qproperty-inactiveLoopColor: rgba( 52, 63, 53, 64 );
qproperty-inactiveLoopBrush: rgba( 255, 255, 255, 32 );
qproperty-inactiveLoopInnerColor: rgba( 255, 255, 255, 32 );
+ qproperty-inactiveLoopHandleColor: rgba( 192, 192, 192, 100 );
qproperty-activeLoopColor: rgba( 52, 63, 53, 255 );
qproperty-activeLoopBrush: qlineargradient( x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #378d59, stop: 1.0 #297e36 );
qproperty-activeLoopInnerColor: rgba( 74, 155, 100, 255 );
+ qproperty-activeLoopHandleColor: rgba( 192, 192, 192, 200 );
+
+ /* Width of loop marker handles (when handle mode is active) */
+ qproperty-loopHandleWidth: 8;
+
qproperty-barLineColor: rgb( 192, 192, 192 );
qproperty-barNumberColor: rgb( 192, 192, 192 );
+
+ /* Cursor hotspots for loop marker adjustment */
+ qproperty-mouseHotspotSelLeft: 0px 16px;
+ qproperty-mouseHotspotSelRight: 32px 16px;
}
QTreeView {
@@ -882,6 +922,14 @@ lmms--gui--SidInstrumentView lmms--gui--Knob {
qproperty-lineWidth: 2;
}
+lmms--gui--SlicerTView lmms--gui--Knob {
+ color: rgb(162, 128, 226);
+ qproperty-outerColor: rgb( 162, 128, 226 );
+ qproperty-innerRadius: 1;
+ qproperty-outerRadius: 11;
+ qproperty-lineWidth: 3;
+}
+
lmms--gui--WatsynView lmms--gui--Knob {
qproperty-innerRadius: 1;
qproperty-outerRadius: 7;
@@ -950,6 +998,7 @@ lmms--gui--CompressorControlDialog {
qproperty-textColor: rgba(209, 216, 228, 50);
qproperty-graphColor: rgba(209, 216, 228, 50);
qproperty-resetColor: rgba(200, 100, 15, 200);
+ qproperty-backgroundColor: rgba(7, 8, 9, 255);
}
lmms--gui--CompressorControlDialog lmms--gui--Knob {
@@ -958,6 +1007,11 @@ lmms--gui--CompressorControlDialog lmms--gui--Knob {
qproperty-lineWidth: 2;
}
+lmms--gui--BarModelEditor {
+ qproperty-backgroundBrush: rgba(28, 73, 51, 255);
+ qproperty-barBrush: rgba(17, 136, 71, 255);
+}
+
/* palette information */
lmms--gui--LmmsPalette {
diff --git a/data/themes/default/automation_ghost_note.png b/data/themes/default/automation_ghost_note.png
new file mode 100644
index 000000000..d14c047d7
Binary files /dev/null and b/data/themes/default/automation_ghost_note.png differ
diff --git a/data/themes/default/cursor_select_left.png b/data/themes/default/cursor_select_left.png
new file mode 100644
index 000000000..eaa80e0bb
Binary files /dev/null and b/data/themes/default/cursor_select_left.png differ
diff --git a/data/themes/default/cursor_select_right.png b/data/themes/default/cursor_select_right.png
new file mode 100644
index 000000000..abd4aecfb
Binary files /dev/null and b/data/themes/default/cursor_select_right.png differ
diff --git a/data/themes/default/edit_draw_small.png b/data/themes/default/edit_draw_small.png
new file mode 100644
index 000000000..9979c8223
Binary files /dev/null and b/data/themes/default/edit_draw_small.png differ
diff --git a/data/themes/default/edit_tangent.png b/data/themes/default/edit_tangent.png
new file mode 100644
index 000000000..7bc400094
Binary files /dev/null and b/data/themes/default/edit_tangent.png differ
diff --git a/data/themes/default/fader_background.png b/data/themes/default/fader_background.png
deleted file mode 100644
index 7d6b59e35..000000000
Binary files a/data/themes/default/fader_background.png and /dev/null differ
diff --git a/data/themes/default/fader_leds.png b/data/themes/default/fader_leds.png
deleted file mode 100644
index 707902e04..000000000
Binary files a/data/themes/default/fader_leds.png and /dev/null differ
diff --git a/data/themes/default/horizontal_slider.png b/data/themes/default/horizontal_slider.png
new file mode 100644
index 000000000..24f6098e5
Binary files /dev/null and b/data/themes/default/horizontal_slider.png differ
diff --git a/data/themes/default/lcd_11green.png b/data/themes/default/lcd_11green.png
new file mode 100644
index 000000000..32e923fe8
Binary files /dev/null and b/data/themes/default/lcd_11green.png differ
diff --git a/data/themes/default/lcd_11green_dot.png b/data/themes/default/lcd_11green_dot.png
new file mode 100644
index 000000000..9f5a660d3
Binary files /dev/null and b/data/themes/default/lcd_11green_dot.png differ
diff --git a/data/themes/default/lcd_19purple.png b/data/themes/default/lcd_19purple.png
new file mode 100644
index 000000000..35ecc4ace
Binary files /dev/null and b/data/themes/default/lcd_19purple.png differ
diff --git a/data/themes/default/lcd_19purple_dot.png b/data/themes/default/lcd_19purple_dot.png
new file mode 100644
index 000000000..6582d8c20
Binary files /dev/null and b/data/themes/default/lcd_19purple_dot.png differ
diff --git a/data/themes/default/lcd_21pink.png b/data/themes/default/lcd_21pink.png
index c2009eeda..719730427 100644
Binary files a/data/themes/default/lcd_21pink.png and b/data/themes/default/lcd_21pink.png differ
diff --git a/data/themes/default/receive_bg_arrow.png b/data/themes/default/receive_bg_arrow.png
index d4961540a..368a1bf15 100644
Binary files a/data/themes/default/receive_bg_arrow.png and b/data/themes/default/receive_bg_arrow.png differ
diff --git a/data/themes/default/send_bg_arrow.png b/data/themes/default/send_bg_arrow.png
index 05a8c7366..311505b68 100644
Binary files a/data/themes/default/send_bg_arrow.png and b/data/themes/default/send_bg_arrow.png differ
diff --git a/data/themes/default/style.css b/data/themes/default/style.css
index f4c651c9e..f13ec09d8 100644
--- a/data/themes/default/style.css
+++ b/data/themes/default/style.css
@@ -3,13 +3,13 @@
********************/
/* most foreground text items */
-QLabel, QTreeWidget, QListWidget, QGroupBox, QMenuBar {
+QLabel, QTreeWidget, QListWidget, QGroupBox, QMenuBar, QCheckBox {
color: #d1d8e4;
}
QTreeView {
outline: none;
- font-size: 12px;
+ alternate-background-color: #111314;
}
QTreeWidget::item {
@@ -42,7 +42,7 @@ QMdiArea {
lmms--gui--FileBrowser QCheckBox
{
- font-size: 10px;
+ font-size: 8pt;
color: white;
}
@@ -57,6 +57,7 @@ lmms--gui--AutomationEditor {
qproperty-backgroundShade: rgba(255, 255, 255, 15);
qproperty-nodeInValueColor: rgba(103, 73, 194, 150);
qproperty-nodeOutValueColor: rgba(125, 40, 40, 150);
+ qproperty-nodeTangentLineColor: rgba(200, 200, 200, 255);
qproperty-crossColor: rgba(215, 210, 254, 150);
/* Grid colors */
qproperty-lineColor: #292929;
@@ -65,6 +66,9 @@ lmms--gui--AutomationEditor {
qproperty-graphColor: rgba(69,42,153,180);
qproperty-scaleColor: #262b30;
+ qproperty-ghostNoteColor: rgba(248, 248, 255, 125);
+ qproperty-detuningNoteColor: rgba(248, 11, 11, 125);
+ qproperty-ghostSampleColor: rgba(125, 125, 125, 125);
}
/* text box */
@@ -100,7 +104,7 @@ QToolTip {
color: #d1d8e4;
}
-lmms--gui--TextFloat {
+lmms--gui--TextFloat, lmms--gui--SimpleTextFloat {
background: #040506;
color: #d1d8e4;
}
@@ -115,7 +119,6 @@ QSplashScreen QLabel {
QMenu {
border-top: 2px solid #08993E;
background-color: #15191c;
- font-size: 11px;
}
QMenu::separator {
@@ -133,15 +136,12 @@ QMenu::item {
QMenu::item:selected {
color: #d1d8e4;
- font-weight: normal;
background-color: #21272b;
}
QMenu::item:disabled {
color: #515459;
background-color: #262b30;
- font-size: 12px;
- font-weight: normal;
padding: 4px 32px 4px 20px;
}
@@ -178,6 +178,7 @@ lmms--gui--PianoRoll {
qproperty-backgroundShade: rgba(255, 255, 255, 10);
qproperty-noteModeColor: #0bd556;
qproperty-noteColor: #0bd556;
+ qproperty-stepNoteColor: #9b1313;
qproperty-noteTextColor: #ffffff;
qproperty-noteOpacity: 165;
qproperty-noteBorders: false; /* boolean property, set false to have borderless notes */
@@ -218,7 +219,8 @@ lmms--gui--TabWidget {
background-color: #262b30;
qproperty-tabText: rgba(255, 255, 255, 180);
qproperty-tabTitleText: #fff;
- qproperty-tabSelected: #323940;
+ qproperty-tabSelected: #1c4933;
+ qproperty-tabTextSelected: rgba(255, 255, 255, 255);
qproperty-tabBackground: #181b1f;
qproperty-tabBorder: #181b1f;
}
@@ -232,7 +234,9 @@ lmms--gui--GroupBox {
lmms--gui--Oscilloscope {
background: none;
border: none;
- qproperty-normalColor: rgb(71, 253, 133);
+ qproperty-leftChannelColor: rgb(71, 253, 133);
+ qproperty-rightChannelColor: rgb(238, 253, 71);
+ qproperty-otherChannelsColor: rgb(71, 235, 253);
qproperty-clippingColor: rgb(255, 64, 64);
}
@@ -240,7 +244,8 @@ lmms--gui--Oscilloscope {
lmms--gui--CPULoadWidget {
border: none;
- background: url(resources:cpuload_bg.png);
+ background: url("resources:cpuload_bg.png");
+ qproperty-stepSize: 1;
}
/* scrollbar: trough */
@@ -358,16 +363,16 @@ QScrollBar::up-arrow:vertical, QScrollBar::down-arrow:vertical {
margin-left: 3px;
}
-QScrollBar::left-arrow:horizontal { background-image: url(resources:sbarrow_left.png);}
-QScrollBar::right-arrow:horizontal { background-image: url(resources:sbarrow_right.png);}
-QScrollBar::up-arrow:vertical { background-image: url(resources:sbarrow_up.png);}
-QScrollBar::down-arrow:vertical { background-image: url(resources:sbarrow_down.png);}
-QScrollBar::left-arrow:horizontal:disabled { background-image: url(resources:sbarrow_left_d.png);}
-QScrollBar::right-arrow:horizontal:disabled { background-image: url(resources:sbarrow_right_d.png);}
-QScrollBar::up-arrow:vertical:disabled { background-image: url(resources:sbarrow_up_d.png);}
-QScrollBar::down-arrow:vertical:disabled { background-image: url(resources:sbarrow_down_d.png);}
-lmms--gui--EffectRackView QScrollBar::up-arrow:vertical:disabled { background-image: url(resources:sbarrow_up.png);}
-lmms--gui--EffectRackView QScrollBar::down-arrow:vertical:disabled { background-image: url(resources:sbarrow_down.png);}
+QScrollBar::left-arrow:horizontal { background-image: url("resources:sbarrow_left.png");}
+QScrollBar::right-arrow:horizontal { background-image: url("resources:sbarrow_right.png");}
+QScrollBar::up-arrow:vertical { background-image: url("resources:sbarrow_up.png");}
+QScrollBar::down-arrow:vertical { background-image: url("resources:sbarrow_down.png");}
+QScrollBar::left-arrow:horizontal:disabled { background-image: url("resources:sbarrow_left_d.png");}
+QScrollBar::right-arrow:horizontal:disabled { background-image: url("resources:sbarrow_right_d.png");}
+QScrollBar::up-arrow:vertical:disabled { background-image: url("resources:sbarrow_up_d.png");}
+QScrollBar::down-arrow:vertical:disabled { background-image: url("resources:sbarrow_down_d.png");}
+lmms--gui--EffectRackView QScrollBar::up-arrow:vertical:disabled { background-image: url("resources:sbarrow_up.png");}
+lmms--gui--EffectRackView QScrollBar::down-arrow:vertical:disabled { background-image: url("resources:sbarrow_down.png");}
/* background for song editor and pattern editor */
@@ -404,7 +409,7 @@ lmms--gui--TrackOperationsWidget > QPushButton {
}
lmms--gui--TrackOperationsWidget > QPushButton::menu-indicator {
- image: url(resources:trackop.png);
+ image: url("resources:trackop.png");
subcontrol-origin: padding;
subcontrol-position: center;
position: relative;
@@ -413,7 +418,7 @@ lmms--gui--TrackOperationsWidget > QPushButton::menu-indicator {
lmms--gui--TrackOperationsWidget > QPushButton::menu-indicator:pressed,
lmms--gui--TrackOperationsWidget > QPushButton::menu-indicator:checked {
- image: url(resources:trackop.png);
+ image: url("resources:trackop.png");
position: relative;
top: 2px;
}
@@ -436,19 +441,42 @@ lmms--gui--AutomatableSlider::groove:vertical {
lmms--gui--AutomatableSlider::handle:vertical {
background: none;
- border-image: url(resources:main_slider.png);
+ border-image: url("resources:main_slider.png");
width: 26px;
height: 10px;
border-radius: 2px;
margin: -4px -12px -2px;
}
+/* main horizontal sliders (zoom) */
+
+lmms--gui--AutomatableSlider::groove:horizontal {
+ background: #040506;
+ border: none;
+ border-radius: 2px;
+ height: 2px;
+ margin: 2px;
+}
+
+lmms--gui--AutomatableSlider::handle:horizontal {
+ background: none;
+ border-image: url("resources:horizontal_slider.png");
+ width: 10px;
+ height: 26px;
+ border-radius: 2px;
+ margin: -12px -2px;
+}
+
/* window that shows up when you add effects */
lmms--gui--EffectSelectDialog QScrollArea {
background: #262b30;
}
+lmms--gui--SetupDialog QScrollArea {
+ border: 0px;
+}
+
/* the inner boxes in LADSPA effect windows */
lmms--gui--EffectControlDialog QGroupBox {
@@ -522,7 +550,7 @@ QToolButton:checked {
border-top: 1px solid #1b1f22;
border-bottom: 1px solid #4a515e;
background: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1, stop:0 #1b1f22, stop:1 #13161a);
- background-image: url(resources:shadow_p.png);
+ background-image: url("resources:shadow_p.png");
}
/* buttons with combined menu */
@@ -571,7 +599,7 @@ lmms--gui--TrackLabelButton:pressed {
lmms--gui--TrackLabelButton:checked {
border: 1px solid #485059;
background: #1C1F24;
- background-image: url(resources:track_shadow_p.png);
+ background-image: url("resources:track_shadow_p.png");
border-radius: none;
font-size: 11px;
font-weight: normal;
@@ -581,7 +609,7 @@ lmms--gui--TrackLabelButton:checked {
lmms--gui--TrackLabelButton:checked:pressed {
border: 1px solid #2f353b;
background: #0e1012;
- background-image: url(resources:track_shadow_p.png);
+ background-image: url("resources:track_shadow_p.png");
font-size: 11px;
padding: 2px 1px;
font-weight: solid;
@@ -649,7 +677,7 @@ lmms--gui--ControllerRackView QPushButton {
font-size: 10px;
}
-lmms--gui--MixerLine {
+lmms--gui--MixerChannelView {
background: #14161A;
color: #d1d8e4;
qproperty-backgroundActive: #3B424A;
@@ -659,11 +687,16 @@ lmms--gui--MixerLine {
qproperty-strokeInnerInactive: #0C0D0F;
}
+lmms--gui--MixerChannelView QGraphicsView {
+ background: transparent;
+ border-style: none;
+}
+
/* persistent peak markers for fx peak meters */
lmms--gui--Fader {
- qproperty-peakGreen: #0ad45c;
- qproperty-peakYellow: #d6ec52;
- qproperty-peakRed: #c12038;
+ qproperty-peakOk: #0ad45c;
+ qproperty-peakWarn: #d6ec52;
+ qproperty-peakClip: #c12038;
}
lmms--gui--TimeLineWidget {
@@ -679,27 +712,32 @@ lmms--gui--TimeLineWidget {
/* Properties for the loop indicator rectangle in inactive state:
- LoopColor: Color of the outermost border
- LoopBrush: Brush to paint the main portion of the rectangle
- - LoopInnerColor: Color used to paint the inlayed border */
+ - LoopInnerColor: Color used to paint the inlayed border
+ - LoopHandleColor: Color used to paint loop marker handles */
qproperty-inactiveLoopColor: #3B424A;
qproperty-inactiveLoopBrush: #3B424A;
qproperty-inactiveLoopInnerColor: #3B424A;
+ qproperty-inactiveLoopHandleColor: rgba( 192, 192, 192, 100 );
/* Properties for the loop indicator rectangle in active state.
See above for detailed description. */
qproperty-activeLoopColor: #21A14F;
qproperty-activeLoopBrush: #21A14F;
qproperty-activeLoopInnerColor: #21A14F;
+ qproperty-activeLoopHandleColor: rgba( 192, 192, 192, 200 );
/* Vertical padding for the loop indicator rectangle.
A value of zero draws the rectangle at the full height of the widget. */
qproperty-loopRectangleVerticalPadding: 1;
+ /* Width of loop marker handles (when handle mode is active) */
+ qproperty-loopHandleWidth: 8;
qproperty-barLineColor: rgb( 192, 192, 192 );
qproperty-barNumberColor: rgb( 192, 192, 192 );
-}
-QTreeView {
- alternate-background-color: #111314;
+ /* Cursor hotspots for loop marker adjustment */
+ qproperty-mouseHotspotSelLeft: 0px 16px;
+ qproperty-mouseHotspotSelRight: 32px 16px;
}
lmms--gui--TrackContainerView QLabel
@@ -926,6 +964,14 @@ lmms--gui--SidInstrumentView lmms--gui--Knob {
qproperty-lineWidth: 2;
}
+lmms--gui--SlicerTView lmms--gui--Knob {
+ color: rgb(162, 128, 226);
+ qproperty-outerColor: rgb( 162, 128, 226 );
+ qproperty-innerRadius: 1;
+ qproperty-outerRadius: 11;
+ qproperty-lineWidth: 3;
+}
+
lmms--gui--WatsynView lmms--gui--Knob {
qproperty-innerRadius: 1;
qproperty-outerRadius: 7;
@@ -994,6 +1040,7 @@ lmms--gui--CompressorControlDialog {
qproperty-textColor: rgba(209, 216, 228, 50);
qproperty-graphColor: rgba(209, 216, 228, 50);
qproperty-resetColor: rgba(200, 100, 15, 200);
+ qproperty-backgroundColor: rgba(7, 8, 9, 255);
}
lmms--gui--CompressorControlDialog lmms--gui--Knob {
@@ -1002,6 +1049,11 @@ lmms--gui--CompressorControlDialog lmms--gui--Knob {
qproperty-lineWidth: 2;
}
+lmms--gui--BarModelEditor {
+ qproperty-backgroundBrush: rgba(28, 73, 51, 255);
+ qproperty-barBrush: rgba(17, 136, 71, 255);
+}
+
/* palette information */
lmms--gui--LmmsPalette {
diff --git a/data/themes/default/tuning_tab.png b/data/themes/default/tuning_tab.png
new file mode 100644
index 000000000..41c4f2d9f
Binary files /dev/null and b/data/themes/default/tuning_tab.png differ
diff --git a/include/AboutDialog.h b/include/AboutDialog.h
index c7d65023f..2fd01faf5 100644
--- a/include/AboutDialog.h
+++ b/include/AboutDialog.h
@@ -22,9 +22,8 @@
*
*/
-
-#ifndef ABOUT_DIALOG_H
-#define ABOUT_DIALOG_H
+#ifndef LMMS_GUI_ABOUT_DIALOG_H
+#define LMMS_GUI_ABOUT_DIALOG_H
#include
@@ -42,5 +41,4 @@ public:
} // namespace lmms::gui
-#endif
-
+#endif // LMMS_GUI_ABOUT_DIALOG_H
diff --git a/include/ActionGroup.h b/include/ActionGroup.h
index 0fe9d78ed..e18f6fb23 100644
--- a/include/ActionGroup.h
+++ b/include/ActionGroup.h
@@ -22,9 +22,8 @@
*
*/
-
-#ifndef ACTION_GROUP_H
-#define ACTION_GROUP_H
+#ifndef LMMS_GUI_ACTION_GROUP_H
+#define LMMS_GUI_ACTION_GROUP_H
#include
@@ -59,4 +58,4 @@ private:
} // namespace lmms::gui
-#endif
+#endif // LMMS_GUI_ACTION_GROUP_H
diff --git a/include/ArrayVector.h b/include/ArrayVector.h
new file mode 100644
index 000000000..06e09226c
--- /dev/null
+++ b/include/ArrayVector.h
@@ -0,0 +1,388 @@
+/*
+ * ArrayVector.h
+ *
+ * Copyright (c) 2023 Dominic Clark
+ *
+ * This file is part of LMMS - https://lmms.io
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program (see COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef LMMS_ARRAY_VECTOR_H
+#define LMMS_ARRAY_VECTOR_H
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace lmms {
+
+namespace detail {
+
+template
+constexpr bool is_input_iterator_v = false;
+
+template
+constexpr bool is_input_iterator_v::iterator_category>> =
+ std::is_convertible_v::iterator_category, std::input_iterator_tag>;
+
+} // namespace detail
+
+/**
+ * A container that stores up to a maximum of `N` elements of type `T` directly
+ * within itself, rather than separately on the heap. Useful when a dynamically
+ * resizeable container is needed for use in real-time code. Can be thought of
+ * as a hybrid between `std::array` and `std::vector`. The interface follows
+ * that of `std::vector` - see standard C++ documentation.
+ */
+template
+class ArrayVector
+{
+public:
+ using size_type = std::size_t;
+ using difference_type = std::ptrdiff_t;
+ using value_type = T;
+ using reference = T&;
+ using const_reference = const T&;
+ using pointer = T*;
+ using const_pointer = const T*;
+ using iterator = pointer;
+ using const_iterator = const_pointer;
+ using reverse_iterator = std::reverse_iterator;
+ using const_reverse_iterator = std::reverse_iterator;
+
+ ArrayVector() = default;
+
+ ArrayVector(const ArrayVector& other) noexcept(std::is_nothrow_copy_constructible_v) :
+ m_size{other.m_size}
+ {
+ std::uninitialized_copy(other.begin(), other.end(), begin());
+ }
+
+ ArrayVector(ArrayVector&& other) noexcept(std::is_nothrow_move_constructible_v) :
+ m_size{other.m_size}
+ {
+ std::uninitialized_move(other.begin(), other.end(), begin());
+ other.clear();
+ }
+
+ ArrayVector(size_type count, const T& value) noexcept(std::is_nothrow_copy_constructible_v) :
+ m_size{count}
+ {
+ assert(count <= N);
+ std::uninitialized_fill_n(begin(), count, value);
+ }
+
+ explicit ArrayVector(size_type count) noexcept(std::is_nothrow_default_constructible_v) :
+ m_size{count}
+ {
+ assert(count <= N);
+ std::uninitialized_value_construct_n(begin(), count);
+ }
+
+ template, int> = 0>
+ ArrayVector(It first, It last)
+ {
+ // Can't check the size first as the iterator may not be multipass
+ const auto end = std::uninitialized_copy(first, last, begin());
+ m_size = end - begin();
+ assert(m_size <= N);
+ }
+
+ ArrayVector(std::initializer_list il) noexcept(std::is_nothrow_copy_constructible_v) :
+ m_size{il.size()}
+ {
+ assert(il.size() <= N);
+ std::uninitialized_copy(il.begin(), il.end(), begin());
+ }
+
+ ~ArrayVector() { std::destroy(begin(), end()); }
+
+ ArrayVector& operator=(const ArrayVector& other)
+ noexcept(std::is_nothrow_copy_assignable_v && std::is_nothrow_copy_constructible_v)
+ {
+ if (this != &other) {
+ const auto toAssign = std::min(other.size(), size());
+ const auto assignedFromEnd = other.begin() + toAssign;
+ const auto assignedToEnd = std::copy(other.begin(), other.begin() + toAssign, begin());
+ std::destroy(assignedToEnd, end());
+ std::uninitialized_copy(assignedFromEnd, other.end(), end());
+ m_size = other.size();
+ }
+ return *this;
+ }
+
+ ArrayVector& operator=(ArrayVector&& other)
+ noexcept(std::is_nothrow_move_assignable_v && std::is_nothrow_move_constructible_v)
+ {
+ if (this != &other) {
+ const auto toAssign = std::min(other.size(), size());
+ const auto assignedFromEnd = other.begin() + toAssign;
+ const auto assignedToEnd = std::move(other.begin(), other.begin() + toAssign, begin());
+ std::destroy(assignedToEnd, end());
+ std::uninitialized_move(assignedFromEnd, other.end(), end());
+ m_size = other.size();
+ other.clear();
+ }
+ return *this;
+ }
+
+ ArrayVector& operator=(std::initializer_list il)
+ noexcept(std::is_nothrow_copy_assignable_v && std::is_nothrow_copy_constructible_v)
+ {
+ assert(il.size() <= N);
+ const auto toAssign = std::min(il.size(), size());
+ const auto assignedFromEnd = il.begin() + toAssign;
+ const auto assignedToEnd = std::copy(il.begin(), assignedFromEnd, begin());
+ std::destroy(assignedToEnd, end());
+ std::uninitialized_copy(assignedFromEnd, il.end(), end());
+ m_size = il.size();
+ return *this;
+ }
+
+ void assign(size_type count, const T& value)
+ noexcept(std::is_nothrow_copy_assignable_v && std::is_nothrow_copy_constructible_v)
+ {
+ assert(count <= N);
+ const auto temp = value;
+ const auto toAssign = std::min(count, size());
+ const auto toConstruct = count - toAssign;
+ const auto assignedToEnd = std::fill_n(begin(), toAssign, temp);
+ std::destroy(assignedToEnd, end());
+ std::uninitialized_fill_n(assignedToEnd, toConstruct, temp);
+ m_size = count;
+ }
+
+ template, int> = 0>
+ void assign(It first, It last)
+ {
+ // Can't check the size first as the iterator may not be multipass
+ auto pos = begin();
+ for (; first != last && pos != end(); ++pos, ++first) {
+ *pos = *first;
+ }
+ std::destroy(pos, end());
+ pos = std::uninitialized_copy(first, last, pos);
+ m_size = pos - begin();
+ assert(m_size <= N);
+ }
+
+ reference at(size_type index)
+ {
+ if (index >= m_size) { throw std::out_of_range{"index out of range"}; }
+ return data()[index];
+ }
+
+ const_reference at(size_type index) const
+ {
+ if (index >= m_size) { throw std::out_of_range{"index out of range"}; }
+ return data()[index];
+ }
+
+ reference operator[](size_type index) noexcept
+ {
+ assert(index < m_size);
+ return data()[index];
+ }
+
+ const_reference operator[](size_type index) const noexcept
+ {
+ assert(index < m_size);
+ return data()[index];
+ }
+
+ reference front() noexcept { return operator[](0); }
+ const_reference front() const noexcept { return operator[](0); }
+
+ reference back() noexcept { return operator[](m_size - 1); }
+ const_reference back() const noexcept { return operator[](m_size - 1); }
+
+ pointer data() noexcept { return *std::launder(reinterpret_cast(m_data)); }
+ const_pointer data() const noexcept { return *std::launder(reinterpret_cast(m_data)); }
+
+ iterator begin() noexcept { return data(); }
+ const_iterator begin() const noexcept { return data(); }
+ const_iterator cbegin() const noexcept { return data(); }
+
+ iterator end() noexcept { return data() + m_size; }
+ const_iterator end() const noexcept { return data() + m_size; }
+ const_iterator cend() const noexcept { return data() + m_size; }
+
+ reverse_iterator rbegin() noexcept { return std::reverse_iterator{end()}; }
+ const_reverse_iterator rbegin() const noexcept { return std::reverse_iterator{end()}; }
+ const_reverse_iterator crbegin() const noexcept { return std::reverse_iterator{cend()}; }
+
+ reverse_iterator rend() noexcept { return std::reverse_iterator{begin()}; }
+ const_reverse_iterator rend() const noexcept { return std::reverse_iterator{begin()}; }
+ const_reverse_iterator crend() const noexcept { return std::reverse_iterator{cbegin()}; }
+
+ bool empty() const noexcept { return m_size == 0; }
+ bool full() const noexcept { return m_size == N; }
+ size_type size() const noexcept { return m_size; }
+ size_type max_size() const noexcept { return N; }
+ size_type capacity() const noexcept { return N; }
+
+ void clear() noexcept
+ {
+ std::destroy(begin(), end());
+ m_size = 0;
+ }
+
+ iterator insert(const_iterator pos, const T& value) { return emplace(pos, value); }
+ iterator insert(const_iterator pos, T&& value) { return emplace(pos, std::move(value)); }
+
+ iterator insert(const_iterator pos, size_type count, const T& value)
+ {
+ assert(m_size + count <= N);
+ assert(cbegin() <= pos && pos <= cend());
+ const auto mutPos = begin() + (pos - cbegin());
+ const auto newEnd = std::uninitialized_fill_n(end(), count, value);
+ std::rotate(mutPos, end(), newEnd);
+ m_size += count;
+ return mutPos;
+ }
+
+ template, int> = 0>
+ iterator insert(const_iterator pos, It first, It last)
+ {
+ // Can't check the size first as the iterator may not be multipass
+ assert(cbegin() <= pos && pos <= cend());
+ const auto mutPos = begin() + (pos - cbegin());
+ const auto newEnd = std::uninitialized_copy(first, last, end());
+ std::rotate(mutPos, end(), newEnd);
+ m_size = newEnd - begin();
+ assert(m_size <= N);
+ return mutPos;
+ }
+
+ iterator insert(const_iterator pos, std::initializer_list il) { return insert(pos, il.begin(), il.end()); }
+
+ template
+ iterator emplace(const_iterator pos, Args&&... args)
+ {
+ assert(cbegin() <= pos && pos <= cend());
+ const auto mutPos = begin() + (pos - cbegin());
+ emplace_back(std::forward(args)...);
+ std::rotate(mutPos, end() - 1, end());
+ return mutPos;
+ }
+
+ iterator erase(const_iterator pos) { return erase(pos, pos + 1); }
+ iterator erase(const_iterator first, const_iterator last)
+ {
+ assert(cbegin() <= first && first <= last && last <= cend());
+ const auto mutFirst = begin() + (first - cbegin());
+ const auto mutLast = begin() + (last - cbegin());
+ const auto newEnd = std::move(mutLast, end(), mutFirst);
+ std::destroy(newEnd, end());
+ m_size = newEnd - begin();
+ return mutFirst;
+ }
+
+ void push_back(const T& value) { emplace_back(value); }
+ void push_back(T&& value) { emplace_back(std::move(value)); }
+
+ template
+ reference emplace_back(Args&&... args)
+ {
+ assert(!full());
+ // TODO C++20: Use std::construct_at
+ const auto result = new(static_cast(end())) T(std::forward(args)...);
+ ++m_size;
+ return *result;
+ }
+
+ void pop_back()
+ {
+ assert(!empty());
+ --m_size;
+ std::destroy_at(end());
+ }
+
+ void resize(size_type size)
+ {
+ if (size > N) { throw std::length_error{"size exceeds maximum size"}; }
+ if (size < m_size) {
+ std::destroy(begin() + size, end());
+ } else {
+ std::uninitialized_value_construct(end(), begin() + size);
+ }
+ m_size = size;
+ }
+
+ void resize(size_type size, const value_type& value)
+ {
+ if (size > N) { throw std::length_error{"size exceeds maximum size"}; }
+ if (size < m_size) {
+ std::destroy(begin() + size, end());
+ } else {
+ std::uninitialized_fill(end(), begin() + size, value);
+ }
+ m_size = size;
+ }
+
+ void swap(ArrayVector& other)
+ noexcept(std::is_nothrow_swappable_v && std::is_nothrow_move_constructible_v)
+ {
+ using std::swap;
+ swap(*this, other);
+ }
+
+ friend void swap(ArrayVector& a, ArrayVector& b)
+ noexcept(std::is_nothrow_swappable_v && std::is_nothrow_move_constructible_v)
+ {
+ const auto toSwap = std::min(a.size(), b.size());
+ const auto aSwapEnd = a.begin() + toSwap;
+ const auto bSwapEnd = b.begin() + toSwap;
+ std::swap_ranges(a.begin(), aSwapEnd, b.begin());
+ std::uninitialized_move(aSwapEnd, a.end(), bSwapEnd);
+ std::uninitialized_move(bSwapEnd, b.end(), aSwapEnd);
+ std::destroy(aSwapEnd, a.end());
+ std::destroy(bSwapEnd, b.end());
+ std::swap(a.m_size, b.m_size);
+ }
+
+ // TODO C++20: Replace with operator<=>
+ friend bool operator<(const ArrayVector& l, const ArrayVector& r)
+ {
+ return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
+ }
+ friend bool operator<=(const ArrayVector& l, const ArrayVector& r) { return !(r < l); }
+ friend bool operator>(const ArrayVector& l, const ArrayVector& r) { return r < l; }
+ friend bool operator>=(const ArrayVector& l, const ArrayVector& r) { return !(l < r); }
+
+ friend bool operator==(const ArrayVector& l, const ArrayVector& r)
+ {
+ return std::equal(l.begin(), l.end(), r.begin(), r.end());
+ }
+ // TODO C++20: Remove
+ friend bool operator!=(const ArrayVector& l, const ArrayVector& r) { return !(l == r); }
+
+private:
+ alignas(T) std::byte m_data[std::max(N * sizeof(T), std::size_t{1})]; // Intentionally a raw array
+ size_type m_size = 0;
+};
+
+} // namespace lmms
+
+#endif // LMMS_ARRAY_VECTOR_H
diff --git a/include/AudioAlsa.h b/include/AudioAlsa.h
index f96dd01c9..975532071 100644
--- a/include/AudioAlsa.h
+++ b/include/AudioAlsa.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef AUDIO_ALSA_H
-#define AUDIO_ALSA_H
+#ifndef LMMS_AUDIO_ALSA_H
+#define LMMS_AUDIO_ALSA_H
#include "lmmsconfig.h"
@@ -108,4 +108,4 @@ private:
#endif // LMMS_HAVE_ALSA
-#endif
+#endif // LMMS_AUDIO_ALSA_H
diff --git a/include/AudioAlsaSetupWidget.h b/include/AudioAlsaSetupWidget.h
index f68d71e8a..cbe99ba01 100644
--- a/include/AudioAlsaSetupWidget.h
+++ b/include/AudioAlsaSetupWidget.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef AUDIO_ALSA_SETUP_WIDGET_H
-#define AUDIO_ALSA_SETUP_WIDGET_H
+#ifndef LMMS_GUI_AUDIO_ALSA_SETUP_WIDGET_H
+#define LMMS_GUI_AUDIO_ALSA_SETUP_WIDGET_H
#include "lmmsconfig.h"
@@ -66,4 +66,4 @@ private:
#endif // LMMS_HAVE_ALSA
-#endif
+#endif // LMMS_GUI_AUDIO_ALSA_SETUP_WIDGET_H
diff --git a/include/AudioDevice.h b/include/AudioDevice.h
index 6b4e9939a..c6ee46efc 100644
--- a/include/AudioDevice.h
+++ b/include/AudioDevice.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef AUDIO_DEVICE_H
-#define AUDIO_DEVICE_H
+#ifndef LMMS_AUDIO_DEVICE_H
+#define LMMS_AUDIO_DEVICE_H
#include
#include
@@ -96,11 +96,7 @@ public:
protected:
// subclasses can re-implement this for being used in conjunction with
// processNextBuffer()
- virtual void writeBuffer( const surroundSampleFrame * /* _buf*/,
- const fpp_t /*_frames*/,
- const float /*_master_gain*/ )
- {
- }
+ virtual void writeBuffer(const surroundSampleFrame* /* _buf*/, const fpp_t /*_frames*/) {}
// called by according driver for fetching new sound-data
fpp_t getNextBuffer( surroundSampleFrame * _ab );
@@ -109,7 +105,6 @@ protected:
// returns num of bytes in outbuf
int convertToS16( const surroundSampleFrame * _ab,
const fpp_t _frames,
- const float _master_gain,
int_sample_t * _output_buffer,
const bool _convert_endian = false );
@@ -160,4 +155,4 @@ private:
} // namespace lmms
-#endif
+#endif // LMMS_AUDIO_DEVICE_H
diff --git a/include/AudioDeviceSetupWidget.h b/include/AudioDeviceSetupWidget.h
index e984651e4..acc99602d 100644
--- a/include/AudioDeviceSetupWidget.h
+++ b/include/AudioDeviceSetupWidget.h
@@ -2,6 +2,7 @@
* AudioDeviceSetupWidget.h - Base class for audio device setup widgets
*
* Copyright (c) 2004-2015 Tobias Doerffel
+ * Copyright (c) 2023- Michael Gregorius
*
* This file is part of LMMS - https://lmms.io
*
@@ -22,15 +23,15 @@
*
*/
-#ifndef AUDIO_DEVICE_SETUP_WIDGET_H
-#define AUDIO_DEVICE_SETUP_WIDGET_H
+#ifndef LMMS_GUI_AUDIO_DEVICE_SETUP_WIDGET_H
+#define LMMS_GUI_AUDIO_DEVICE_SETUP_WIDGET_H
-#include "TabWidget.h"
+#include
namespace lmms::gui
{
-class AudioDeviceSetupWidget : public TabWidget
+class AudioDeviceSetupWidget : public QGroupBox
{
Q_OBJECT
public:
@@ -45,4 +46,4 @@ public:
} // namespace lmms::gui
-#endif
+#endif // LMMS_GUI_AUDIO_DEVICE_SETUP_WIDGET_H
diff --git a/include/AudioDummy.h b/include/AudioDummy.h
index 30b125b3a..e34260171 100644
--- a/include/AudioDummy.h
+++ b/include/AudioDummy.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef AUDIO_DUMMY_H
-#define AUDIO_DUMMY_H
+#ifndef LMMS_AUDIO_DUMMY_H
+#define LMMS_AUDIO_DUMMY_H
#include "AudioDevice.h"
#include "AudioDeviceSetupWidget.h"
@@ -116,4 +116,4 @@ private:
} // namespace lmms
-#endif
+#endif // LMMS_AUDIO_DUMMY_H
diff --git a/include/AudioEngine.h b/include/AudioEngine.h
index 71751acb8..67c2edd86 100644
--- a/include/AudioEngine.h
+++ b/include/AudioEngine.h
@@ -22,20 +22,19 @@
*
*/
-#ifndef AUDIO_ENGINE_H
-#define AUDIO_ENGINE_H
+#ifndef LMMS_AUDIO_ENGINE_H
+#define LMMS_AUDIO_ENGINE_H
-#include
-
-#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
- #include
+#ifdef __MINGW32__
+#include
+#else
+#include
#endif
#include
-#include
-#include
#include
+#include
#include "lmms_basics.h"
#include "LocklessList.h"
@@ -109,27 +108,27 @@ public:
struct qualitySettings
{
- enum Mode
+ enum class Mode
{
- Mode_Draft,
- Mode_HighQuality,
- Mode_FinalMix
+ Draft,
+ HighQuality,
+ FinalMix
} ;
- enum Interpolation
+ enum class Interpolation
{
- Interpolation_Linear,
- Interpolation_SincFastest,
- Interpolation_SincMedium,
- Interpolation_SincBest
+ Linear,
+ SincFastest,
+ SincMedium,
+ SincBest
} ;
- enum Oversampling
+ enum class Oversampling
{
- Oversampling_None,
- Oversampling_2x,
- Oversampling_4x,
- Oversampling_8x
+ None,
+ X2,
+ X4,
+ X8
} ;
Interpolation interpolation;
@@ -139,18 +138,18 @@ public:
{
switch (m)
{
- case Mode_Draft:
- interpolation = Interpolation_Linear;
- oversampling = Oversampling_None;
+ case Mode::Draft:
+ interpolation = Interpolation::Linear;
+ oversampling = Oversampling::None;
break;
- case Mode_HighQuality:
+ case Mode::HighQuality:
interpolation =
- Interpolation_SincFastest;
- oversampling = Oversampling_2x;
+ Interpolation::SincFastest;
+ oversampling = Oversampling::X2;
break;
- case Mode_FinalMix:
- interpolation = Interpolation_SincBest;
- oversampling = Oversampling_8x;
+ case Mode::FinalMix:
+ interpolation = Interpolation::SincBest;
+ oversampling = Oversampling::X8;
break;
}
}
@@ -165,10 +164,10 @@ public:
{
switch( oversampling )
{
- case Oversampling_None: return 1;
- case Oversampling_2x: return 2;
- case Oversampling_4x: return 4;
- case Oversampling_8x: return 8;
+ case Oversampling::None: return 1;
+ case Oversampling::X2: return 2;
+ case Oversampling::X4: return 4;
+ case Oversampling::X8: return 8;
}
return 1;
}
@@ -177,13 +176,13 @@ public:
{
switch( interpolation )
{
- case Interpolation_Linear:
+ case Interpolation::Linear:
return SRC_ZERO_ORDER_HOLD;
- case Interpolation_SincFastest:
+ case Interpolation::SincFastest:
return SRC_SINC_FASTEST;
- case Interpolation_SincMedium:
+ case Interpolation::SincMedium:
return SRC_SINC_MEDIUM_QUALITY;
- case Interpolation_SincBest:
+ case Interpolation::SincBest:
return SRC_SINC_BEST_QUALITY;
}
return SRC_LINEAR;
@@ -197,6 +196,7 @@ public:
// audio-device-stuff
+ bool renderOnly() const { return m_renderOnly; }
// Returns the current audio device's name. This is not necessarily
// the user's preferred audio device, in case you were thinking that.
inline const QString & audioDevName() const
@@ -255,7 +255,7 @@ public:
return m_playHandles;
}
- void removePlayHandlesOfTypes(Track * track, const quint8 types);
+ void removePlayHandlesOfTypes(Track * track, PlayHandle::Types types);
// methods providing information for other classes
@@ -275,6 +275,11 @@ public:
return m_profiler.cpuLoad();
}
+ int detailLoad(const AudioEngineProfiler::DetailType type) const
+ {
+ return m_profiler.detailLoad(type);
+ }
+
const qualitySettings & currentQualitySettings() const
{
return m_qualitySettings;
@@ -401,6 +406,10 @@ private:
AudioDevice * tryAudioDevices();
MidiClient * tryMidiClients();
+ void renderStageNoteSetup();
+ void renderStageInstruments();
+ void renderStageEffects();
+ void renderStageMix();
const surroundSampleFrame * renderNextBuffer();
@@ -410,13 +419,9 @@ private:
void clearInternal();
- //! Called by the audio thread to give control to other threads,
- //! such that they can do changes in the model (like e.g. removing effects)
- void runChangesInModel();
-
bool m_renderOnly;
- QVector m_audioPorts;
+ std::vector m_audioPorts;
fpp_t m_framesPerPeriod;
@@ -430,7 +435,7 @@ private:
surroundSampleFrame * m_outputBufferWrite;
// worker thread stuff
- QVector m_workers;
+ std::vector m_workers;
int m_numWorkers;
// playhandle stuff
@@ -443,8 +448,6 @@ private:
struct qualitySettings m_qualitySettings;
float m_masterGain;
- bool m_isProcessing;
-
// audio device stuff
void doSetAudioDevice( AudioDevice *_dev );
AudioDevice * m_audioDev;
@@ -466,19 +469,7 @@ private:
bool m_clearSignal;
- bool m_changesSignal;
- unsigned int m_changes;
- QMutex m_changesMutex;
-#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
- QRecursiveMutex m_doChangesMutex;
-#else
- QMutex m_doChangesMutex;
-#endif
- QMutex m_waitChangesMutex;
- QWaitCondition m_changesAudioEngineCondition;
- QWaitCondition m_changesRequestCondition;
-
- bool m_waitingForWrite;
+ std::mutex m_changeMutex;
friend class Engine;
friend class AudioEngineWorkerThread;
@@ -487,4 +478,4 @@ private:
} // namespace lmms
-#endif
+#endif // LMMS_AUDIO_ENGINE_H
diff --git a/include/AudioEngineProfiler.h b/include/AudioEngineProfiler.h
index 38631c6a9..b0d62a1dc 100644
--- a/include/AudioEngineProfiler.h
+++ b/include/AudioEngineProfiler.h
@@ -22,9 +22,11 @@
*
*/
-#ifndef AUDIO_ENGINE_PROFILER_H
-#define AUDIO_ENGINE_PROFILER_H
+#ifndef LMMS_AUDIO_ENGINE_PROFILER_H
+#define LMMS_AUDIO_ENGINE_PROFILER_H
+#include
+#include
#include
#include "lmms_basics.h"
@@ -53,13 +55,57 @@ public:
void setOutputFile( const QString& outputFile );
+ enum class DetailType {
+ NoteSetup,
+ Instruments,
+ Effects,
+ Mixing,
+ Count
+ };
+
+ constexpr static auto DetailCount = static_cast(DetailType::Count);
+
+ int detailLoad(const DetailType type) const
+ {
+ return m_detailLoad[static_cast(type)].load(std::memory_order_relaxed);
+ }
+
+ class Probe
+ {
+ public:
+ Probe(AudioEngineProfiler& profiler, AudioEngineProfiler::DetailType type)
+ : m_profiler(profiler)
+ , m_type(type)
+ {
+ profiler.startDetail(type);
+ }
+ ~Probe() { m_profiler.finishDetail(m_type); }
+ Probe& operator=(const Probe&) = delete;
+ Probe(const Probe&) = delete;
+ Probe(Probe&&) = delete;
+
+ private:
+ AudioEngineProfiler &m_profiler;
+ const AudioEngineProfiler::DetailType m_type;
+ };
private:
+ void startDetail(const DetailType type) { m_detailTimer[static_cast(type)].reset(); }
+ void finishDetail(const DetailType type)
+ {
+ m_detailTime[static_cast(type)] = m_detailTimer[static_cast(type)].elapsed();
+ }
+
MicroTimer m_periodTimer;
- int m_cpuLoad;
+ std::atomic m_cpuLoad;
QFile m_outputFile;
+
+ // Use arrays to avoid dynamic allocations in realtime code
+ std::array m_detailTimer;
+ std::array m_detailTime{0};
+ std::array, DetailCount> m_detailLoad{0};
};
} // namespace lmms
-#endif
+#endif // LMMS_AUDIO_ENGINE_PROFILER_H
diff --git a/include/AudioEngineWorkerThread.h b/include/AudioEngineWorkerThread.h
index 87e2791b1..b76235aa1 100644
--- a/include/AudioEngineWorkerThread.h
+++ b/include/AudioEngineWorkerThread.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef AUDIO_ENGINE_WORKER_THREAD_H
-#define AUDIO_ENGINE_WORKER_THREAD_H
+#ifndef LMMS_AUDIO_ENGINE_WORKER_THREAD_H
+#define LMMS_AUDIO_ENGINE_WORKER_THREAD_H
#include
@@ -45,7 +45,7 @@ public:
class JobQueue
{
public:
- enum OperationMode
+ enum class OperationMode
{
Static, // no jobs added while processing queue
Dynamic // jobs can be added while processing queue
@@ -57,7 +57,7 @@ public:
m_items(),
m_writeIndex( 0 ),
m_itemsDone( 0 ),
- m_opMode( Static )
+ m_opMode( OperationMode::Static )
{
std::fill(m_items, m_items + JOB_QUEUE_SIZE, nullptr);
}
@@ -83,7 +83,7 @@ public:
virtual void quit();
static void resetJobQueue( JobQueue::OperationMode _opMode =
- JobQueue::Static )
+ JobQueue::OperationMode::Static )
{
globalJobQueue.reset( _opMode );
}
@@ -97,12 +97,12 @@ public:
// to ThreadableJob objects
template
static void fillJobQueue( const T & _vec,
- JobQueue::OperationMode _opMode = JobQueue::Static )
+ JobQueue::OperationMode _opMode = JobQueue::OperationMode::Static )
{
resetJobQueue( _opMode );
- for( typename T::ConstIterator it = _vec.begin(); it != _vec.end(); ++it )
+ for (const auto& job : _vec)
{
- addJob( *it );
+ addJob(job);
}
}
@@ -121,4 +121,4 @@ private:
} // namespace lmms
-#endif
+#endif // LMMS_AUDIO_ENGINE_WORKER_THREAD_H
diff --git a/include/AudioFileDevice.h b/include/AudioFileDevice.h
index beee087e7..dc9a786a4 100644
--- a/include/AudioFileDevice.h
+++ b/include/AudioFileDevice.h
@@ -23,8 +23,8 @@
*
*/
-#ifndef AUDIO_FILE_DEVICE_H
-#define AUDIO_FILE_DEVICE_H
+#ifndef LMMS_AUDIO_FILE_DEVICE_H
+#define LMMS_AUDIO_FILE_DEVICE_H
#include
@@ -73,4 +73,4 @@ using AudioFileDeviceInstantiaton
} // namespace lmms
-#endif
+#endif // LMMS_AUDIO_FILE_DEVICE_H
diff --git a/include/AudioFileFlac.h b/include/AudioFileFlac.h
index 542a2e717..9432f4231 100644
--- a/include/AudioFileFlac.h
+++ b/include/AudioFileFlac.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef AUDIO_FILE_FLAC_H
-#define AUDIO_FILE_FLAC_H
+#ifndef LMMS_AUDIO_FILE_FLAC_H
+#define LMMS_AUDIO_FILE_FLAC_H
#include "lmmsconfig.h"
@@ -33,7 +33,7 @@
namespace lmms
{
-class AudioFileFlac: public AudioFileDevice
+class AudioFileFlac : public AudioFileDevice
{
public:
AudioFileFlac(OutputSettings const& outputSettings,
@@ -65,9 +65,7 @@ private:
SF_INFO m_sfinfo;
SNDFILE* m_sf;
- void writeBuffer(surroundSampleFrame const* _ab,
- fpp_t const frames,
- float master_gain) override;
+ void writeBuffer(surroundSampleFrame const* _ab, fpp_t const frames) override;
bool startEncoding();
void finishEncoding();
@@ -77,4 +75,4 @@ private:
} // namespace lmms
-#endif //AUDIO_FILE_FLAC_H
+#endif // LMMS_AUDIO_FILE_FLAC_H
diff --git a/include/AudioFileMP3.h b/include/AudioFileMP3.h
index 290c9ccbf..013c93a3e 100644
--- a/include/AudioFileMP3.h
+++ b/include/AudioFileMP3.h
@@ -23,8 +23,8 @@
*
*/
-#ifndef AUDIO_FILE_MP3_H
-#define AUDIO_FILE_MP3_H
+#ifndef LMMS_AUDIO_FILE_MP3_H
+#define LMMS_AUDIO_FILE_MP3_H
#include "lmmsconfig.h"
@@ -58,9 +58,7 @@ public:
}
protected:
- void writeBuffer( const surroundSampleFrame * /* _buf*/,
- const fpp_t /*_frames*/,
- const float /*_master_gain*/ ) override;
+ void writeBuffer(const surroundSampleFrame* /* _buf*/, const fpp_t /*_frames*/) override;
private:
void flushRemainingBuffers();
@@ -75,4 +73,4 @@ private:
#endif // LMMS_HAVE_MP3LAME
-#endif
+#endif // LMMS_AUDIO_FILE_MP3_H
diff --git a/include/AudioFileOgg.h b/include/AudioFileOgg.h
index 18617fa5f..fc3ce25b4 100644
--- a/include/AudioFileOgg.h
+++ b/include/AudioFileOgg.h
@@ -23,8 +23,8 @@
*
*/
-#ifndef AUDIO_FILE_OGG_H
-#define AUDIO_FILE_OGG_H
+#ifndef LMMS_AUDIO_FILE_OGG_H
+#define LMMS_AUDIO_FILE_OGG_H
#include "lmmsconfig.h"
@@ -58,9 +58,7 @@ public:
private:
- void writeBuffer( const surroundSampleFrame * _ab,
- const fpp_t _frames,
- const float _master_gain ) override;
+ void writeBuffer(const surroundSampleFrame* _ab, const fpp_t _frames) override;
bool startEncoding();
void finishEncoding();
@@ -113,4 +111,4 @@ private:
#endif // LMMS_HAVE_OGGVORBIS
-#endif
+#endif // LMMS_AUDIO_FILE_OGG_H
diff --git a/include/AudioFileWave.h b/include/AudioFileWave.h
index 8dd3566f4..22b124f93 100644
--- a/include/AudioFileWave.h
+++ b/include/AudioFileWave.h
@@ -23,8 +23,8 @@
*
*/
-#ifndef AUDIO_FILE_WAVE_H
-#define AUDIO_FILE_WAVE_H
+#ifndef LMMS_AUDIO_FILE_WAVE_H
+#define LMMS_AUDIO_FILE_WAVE_H
#include "lmmsconfig.h"
#include "AudioFileDevice.h"
@@ -56,9 +56,7 @@ public:
private:
- void writeBuffer( const surroundSampleFrame * _ab,
- const fpp_t _frames,
- float _master_gain ) override;
+ void writeBuffer(const surroundSampleFrame* _ab, const fpp_t _frames) override;
bool startEncoding();
void finishEncoding();
@@ -71,4 +69,4 @@ private:
} // namespace lmms
-#endif
+#endif // LMMS_AUDIO_FILE_WAVE_H
diff --git a/include/AudioJack.h b/include/AudioJack.h
index 263399487..6efb262ed 100644
--- a/include/AudioJack.h
+++ b/include/AudioJack.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef AUDIO_JACK_H
-#define AUDIO_JACK_H
+#ifndef LMMS_AUDIO_JACK_H
+#define LMMS_AUDIO_JACK_H
#include "lmmsconfig.h"
@@ -35,7 +35,7 @@
#endif
#include
-#include
+#include
#include "AudioDevice.h"
#include "AudioDeviceSetupWidget.h"
@@ -57,42 +57,37 @@ class AudioJack : public QObject, public AudioDevice
{
Q_OBJECT
public:
- AudioJack( bool & _success_ful, AudioEngine* audioEngine );
+ AudioJack(bool& successful, AudioEngine* audioEngine);
~AudioJack() override;
// this is to allow the jack midi connection to use the same jack client connection
// the jack callback is handled here, we call the midi client so that it can read
// it's midi data during the callback
- AudioJack * addMidiClient(MidiJack *midiClient);
+ AudioJack* addMidiClient(MidiJack* midiClient);
void removeMidiClient() { m_midiClient = nullptr; }
- jack_client_t * jackClient() {return m_client;};
+ jack_client_t* jackClient() { return m_client; };
inline static QString name()
{
- return QT_TRANSLATE_NOOP( "AudioDeviceSetupWidget",
- "JACK (JACK Audio Connection Kit)" );
+ return QT_TRANSLATE_NOOP("AudioDeviceSetupWidget", "JACK (JACK Audio Connection Kit)");
}
-
-class setupWidget : public gui::AudioDeviceSetupWidget
+ class setupWidget : public gui::AudioDeviceSetupWidget
{
public:
- setupWidget( QWidget * _parent );
+ setupWidget(QWidget* parent);
~setupWidget() override;
void saveSettings() override;
private:
- QLineEdit * m_clientName;
- gui::LcdSpinBox * m_channels;
-
- } ;
-
+ QLineEdit* m_clientName;
+ gui::LcdSpinBox* m_channels;
+ };
private slots:
void restartAfterZombified();
-
private:
bool initJackClient();
@@ -100,48 +95,44 @@ private:
void stopProcessing() override;
void applyQualitySettings() override;
- void registerPort( AudioPort * _port ) override;
- void unregisterPort( AudioPort * _port ) override;
- void renamePort( AudioPort * _port ) override;
+ void registerPort(AudioPort* port) override;
+ void unregisterPort(AudioPort* port) override;
+ void renamePort(AudioPort* port) override;
- int processCallback( jack_nframes_t _nframes, void * _udata );
+ int processCallback(jack_nframes_t nframes);
- static int staticProcessCallback( jack_nframes_t _nframes,
- void * _udata );
- static void shutdownCallback( void * _udata );
+ static int staticProcessCallback(jack_nframes_t nframes, void* udata);
+ static void shutdownCallback(void* _udata);
-
- jack_client_t * m_client;
+ jack_client_t* m_client;
bool m_active;
std::atomic m_stopped;
- std::atomic m_midiClient;
- QVector m_outputPorts;
- jack_default_audio_sample_t * * m_tempOutBufs;
- surroundSampleFrame * m_outBuf;
+ std::atomic m_midiClient;
+ std::vector m_outputPorts;
+ jack_default_audio_sample_t** m_tempOutBufs;
+ surroundSampleFrame* m_outBuf;
f_cnt_t m_framesDoneInCurBuf;
f_cnt_t m_framesToDoInCurBuf;
-
#ifdef AUDIO_PORT_SUPPORT
struct StereoPort
{
- jack_port_t * ports[2];
- } ;
+ jack_port_t* ports[2];
+ };
- using JackPortMap = QMap;
+ using JackPortMap = QMap;
JackPortMap m_portMap;
#endif
signals:
void zombified();
-
-} ;
+};
} // namespace lmms
#endif // LMMS_HAVE_JACK
-#endif
+#endif // LMMS_AUDIO_JACK_H
diff --git a/include/AudioOss.h b/include/AudioOss.h
index 71103586a..55f64de85 100644
--- a/include/AudioOss.h
+++ b/include/AudioOss.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef AUDIO_OSS_H
-#define AUDIO_OSS_H
+#ifndef LMMS_AUDIO_OSS_H
+#define LMMS_AUDIO_OSS_H
#include "lmmsconfig.h"
@@ -92,4 +92,4 @@ private:
#endif // LMMS_HAVE_OSS
-#endif
+#endif // LMMS_AUDIO_OSS_H
diff --git a/include/AudioPort.h b/include/AudioPort.h
index 5a2645784..9e3ce2bd6 100644
--- a/include/AudioPort.h
+++ b/include/AudioPort.h
@@ -22,14 +22,13 @@
*
*/
-#ifndef AUDIO_PORT_H
-#define AUDIO_PORT_H
+#ifndef LMMS_AUDIO_PORT_H
+#define LMMS_AUDIO_PORT_H
#include
#include
#include
-#include "MemoryManager.h"
#include "PlayHandle.h"
namespace lmms
@@ -41,7 +40,6 @@ class BoolModel;
class AudioPort : public ThreadableJob
{
- MM_OPERATORS
public:
AudioPort( const QString & _name, bool _has_effect_chain = true,
FloatModel * volumeModel = nullptr, FloatModel * panningModel = nullptr,
@@ -138,4 +136,4 @@ private:
} // namespace lmms
-#endif
+#endif // LMMS_AUDIO_PORT_H
diff --git a/include/AudioPortAudio.h b/include/AudioPortAudio.h
index 3fd32a7ac..01b8f3fd7 100644
--- a/include/AudioPortAudio.h
+++ b/include/AudioPortAudio.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef AUDIO_PORTAUDIO_H
-#define AUDIO_PORTAUDIO_H
+#ifndef LMMS_AUDIO_PORTAUDIO_H
+#define LMMS_AUDIO_PORTAUDIO_H
#include
@@ -163,4 +163,4 @@ private:
} // namespace lmms
-#endif
+#endif // LMMS_AUDIO_PORTAUDIO_H
diff --git a/include/AudioPulseAudio.h b/include/AudioPulseAudio.h
index 789296e27..b6a998274 100644
--- a/include/AudioPulseAudio.h
+++ b/include/AudioPulseAudio.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef AUDIO_PULSEAUDIO_H
-#define AUDIO_PULSEAUDIO_H
+#ifndef LMMS_AUDIO_PULSEAUDIO_H
+#define LMMS_AUDIO_PULSEAUDIO_H
#include "lmmsconfig.h"
@@ -104,4 +104,4 @@ private:
#endif // LMMS_HAVE_PULSEAUDIO
-#endif
+#endif // LMMS_AUDIO_PULSEAUDIO_H
diff --git a/include/AudioResampler.h b/include/AudioResampler.h
new file mode 100644
index 000000000..379146962
--- /dev/null
+++ b/include/AudioResampler.h
@@ -0,0 +1,64 @@
+/*
+ * AudioResampler.h - wrapper around libsamplerate
+ *
+ * Copyright (c) 2023 saker
+ *
+ * This file is part of LMMS - https://lmms.io
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program (see COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef LMMS_AUDIO_RESAMPLER_H
+#define LMMS_AUDIO_RESAMPLER_H
+
+#include
+
+#include "lmms_export.h"
+
+namespace lmms {
+
+class LMMS_EXPORT AudioResampler
+{
+public:
+ struct ProcessResult
+ {
+ int error;
+ long inputFramesUsed;
+ long outputFramesGenerated;
+ };
+
+ AudioResampler(int interpolationMode, int channels);
+ AudioResampler(const AudioResampler&) = delete;
+ AudioResampler(AudioResampler&&) = delete;
+ ~AudioResampler();
+
+ AudioResampler& operator=(const AudioResampler&) = delete;
+ AudioResampler& operator=(AudioResampler&&) = delete;
+
+ auto resample(const float* in, long inputFrames, float* out, long outputFrames, double ratio) -> ProcessResult;
+ auto interpolationMode() const -> int { return m_interpolationMode; }
+ auto channels() const -> int { return m_channels; }
+
+private:
+ int m_interpolationMode = -1;
+ int m_channels = 0;
+ int m_error = 0;
+ SRC_STATE* m_state = nullptr;
+};
+} // namespace lmms
+
+#endif // LMMS_AUDIO_RESAMPLER_H
diff --git a/include/AudioSampleRecorder.h b/include/AudioSampleRecorder.h
index 7ad551916..a3e776881 100644
--- a/include/AudioSampleRecorder.h
+++ b/include/AudioSampleRecorder.h
@@ -23,11 +23,12 @@
*
*/
-#ifndef AUDIO_SAMPLE_RECORDER_H
-#define AUDIO_SAMPLE_RECORDER_H
+#ifndef LMMS_AUDIO_SAMPLE_RECORDER_H
+#define LMMS_AUDIO_SAMPLE_RECORDER_H
#include
#include
+#include
#include "AudioDevice.h"
@@ -44,13 +45,10 @@ public:
~AudioSampleRecorder() override;
f_cnt_t framesRecorded() const;
- void createSampleBuffer( SampleBuffer** sampleBuffer );
-
+ std::shared_ptr createSampleBuffer();
private:
- void writeBuffer( const surroundSampleFrame * _ab,
- const fpp_t _frames,
- const float _master_gain ) override;
+ void writeBuffer(const surroundSampleFrame* _ab, const fpp_t _frames) override;
using BufferList = QList>;
BufferList m_buffers;
@@ -59,4 +57,4 @@ private:
} // namespace lmms
-#endif
+#endif // LMMS_AUDIO_SAMPLE_RECORDER_H
diff --git a/include/AudioSdl.h b/include/AudioSdl.h
index 7e7710a2f..62db8b68a 100644
--- a/include/AudioSdl.h
+++ b/include/AudioSdl.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef AUDIO_SDL_H
-#define AUDIO_SDL_H
+#ifndef LMMS_AUDIO_SDL_H
+#define LMMS_AUDIO_SDL_H
#include "lmmsconfig.h"
@@ -115,4 +115,4 @@ private:
#endif // LMMS_HAVE_SDL
-#endif
+#endif // LMMS_AUDIO_SDL_H
diff --git a/include/AudioSndio.h b/include/AudioSndio.h
index 606850105..594ca94e7 100644
--- a/include/AudioSndio.h
+++ b/include/AudioSndio.h
@@ -23,8 +23,8 @@
*
*/
-#ifndef _AUDIO_SNDIO_H
-#define _AUDIO_SNDIO_H
+#ifndef LMMS_AUDIO_SNDIO_H
+#define LMMS_AUDIO_SNDIO_H
#include "lmmsconfig.h"
@@ -87,6 +87,6 @@ private:
} // namespace lmms
-#endif // LMMS_HAVE_SNDIO
+#endif // LMMS_HAVE_SNDIO
-#endif // _AUDIO_SNDIO_H
+#endif // LMMS_AUDIO_SNDIO_H
diff --git a/include/AudioSoundIo.h b/include/AudioSoundIo.h
index dc9afe7e4..b327f7d84 100644
--- a/include/AudioSoundIo.h
+++ b/include/AudioSoundIo.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef AUDIO_SOUNDIO_H
-#define AUDIO_SOUNDIO_H
+#ifndef LMMS_AUDIO_SOUNDIO_H
+#define LMMS_AUDIO_SOUNDIO_H
#include
@@ -145,4 +145,4 @@ private:
#endif // LMMS_HAVE_SOUNDIO
-#endif
+#endif // LMMS_AUDIO_SOUNDIO_H
diff --git a/include/AutomatableButton.h b/include/AutomatableButton.h
index d8c58523c..3d78b8e9c 100644
--- a/include/AutomatableButton.h
+++ b/include/AutomatableButton.h
@@ -22,9 +22,8 @@
*
*/
-
-#ifndef AUTOMATABLE_BUTTON_H
-#define AUTOMATABLE_BUTTON_H
+#ifndef LMMS_GUI_AUTOMATABLE_BUTTON_H
+#define LMMS_GUI_AUTOMATABLE_BUTTON_H
#include
@@ -109,4 +108,4 @@ private:
} // namespace lmms::gui
-#endif
+#endif // LMMS_GUI_AUTOMATABLE_BUTTON_H
diff --git a/include/AutomatableModel.h b/include/AutomatableModel.h
index c8f2ab548..15285e17a 100644
--- a/include/AutomatableModel.h
+++ b/include/AutomatableModel.h
@@ -22,17 +22,18 @@
*
*/
-#ifndef AUTOMATABLE_MODEL_H
-#define AUTOMATABLE_MODEL_H
+#ifndef LMMS_AUTOMATABLE_MODEL_H
+#define LMMS_AUTOMATABLE_MODEL_H
+#include
#include
#include
+#include
#include "JournallingObject.h"
#include "Model.h"
#include "TimePos.h"
#include "ValueBuffer.h"
-#include "MemoryManager.h"
#include "ModelVisitor.h"
@@ -76,11 +77,10 @@ class ControllerConnection;
class LMMS_EXPORT AutomatableModel : public Model, public JournallingObject
{
Q_OBJECT
- MM_OPERATORS
public:
- using AutoModelVector = QVector;
+ using AutoModelVector = std::vector;
- enum ScaleType
+ enum class ScaleType
{
Linear,
Logarithmic,
@@ -144,7 +144,7 @@ public:
template
static bool castValue( const float v )
{
- return ( qRound( v ) != 0 );
+ return (std::round(v) != 0);
}
@@ -231,11 +231,11 @@ public:
}
void setScaleLogarithmic( bool setToTrue = true )
{
- setScaleType( setToTrue ? Logarithmic : Linear );
+ setScaleType( setToTrue ? ScaleType::Logarithmic : ScaleType::Linear );
}
bool isScaleLogarithmic() const
{
- return m_scaleType == Logarithmic;
+ return m_scaleType == ScaleType::Logarithmic;
}
void setStep( const float step );
@@ -507,5 +507,4 @@ using AutomatedValueMap = QMap;
} // namespace lmms
-#endif
-
+#endif // LMMS_AUTOMATABLE_MODEL_H
diff --git a/include/AutomatableModelView.h b/include/AutomatableModelView.h
index 1e8ef7398..12b2e4d49 100644
--- a/include/AutomatableModelView.h
+++ b/include/AutomatableModelView.h
@@ -23,8 +23,8 @@
*
*/
-#ifndef AUTOMATABLE_MODEL_VIEW_H
-#define AUTOMATABLE_MODEL_VIEW_H
+#ifndef LMMS_GUI_AUTOMATABLE_MODEL_VIEW_H
+#define LMMS_GUI_AUTOMATABLE_MODEL_VIEW_H
#include "ModelView.h"
#include "AutomatableModel.h"
@@ -137,5 +137,4 @@ using BoolModelView = TypedModelView;
} // namespace lmms::gui
-#endif
-
+#endif // LMMS_GUI_AUTOMATABLE_MODEL_VIEW_H
diff --git a/include/AutomatableSlider.h b/include/AutomatableSlider.h
index ba11741b5..cb1a6965f 100644
--- a/include/AutomatableSlider.h
+++ b/include/AutomatableSlider.h
@@ -22,9 +22,8 @@
*
*/
-
-#ifndef AUTOMATABLE_SLIDER_H
-#define AUTOMATABLE_SLIDER_H
+#ifndef LMMS_GUI_AUTOMATABLE_SLIDER_H
+#define LMMS_GUI_AUTOMATABLE_SLIDER_H
#include
@@ -77,4 +76,4 @@ using sliderModel = IntModel;
} // namespace lmms::gui
-#endif
+#endif // LMMS_GUI_AUTOMATABLE_SLIDER_H
diff --git a/include/AutomationClip.h b/include/AutomationClip.h
index 3e253d85f..0b49978c7 100644
--- a/include/AutomationClip.h
+++ b/include/AutomationClip.h
@@ -24,8 +24,8 @@
*
*/
-#ifndef AUTOMATION_CLIP_H
-#define AUTOMATION_CLIP_H
+#ifndef LMMS_AUTOMATION_CLIP_H
+#define LMMS_AUTOMATION_CLIP_H
#include
#include
@@ -46,6 +46,7 @@ class TimePos;
namespace gui
{
class AutomationClipView;
+class AutomationEditor;
} // namespace gui
@@ -54,15 +55,15 @@ class LMMS_EXPORT AutomationClip : public Clip
{
Q_OBJECT
public:
- enum ProgressionTypes
+ enum class ProgressionType
{
- DiscreteProgression,
- LinearProgression,
- CubicHermiteProgression
+ Discrete,
+ Linear,
+ CubicHermite
} ;
using timeMap = QMap;
- using objectVector = QVector>;
+ using objectVector = std::vector>;
using TimemapIterator = timeMap::const_iterator;
@@ -76,11 +77,11 @@ public:
const objectVector& objects() const;
// progression-type stuff
- inline ProgressionTypes progressionType() const
+ inline ProgressionType progressionType() const
{
return m_progressionType;
}
- void setProgressionType( ProgressionTypes _new_progression_type );
+ void setProgressionType( ProgressionType _new_progression_type );
inline float getTension() const
{
@@ -111,6 +112,13 @@ public:
void resetNodes(const int tick0, const int tick1);
+ /**
+ * @brief Resets the tangents from the nodes between the given ticks
+ * @param Int first tick of the range
+ * @param Int second tick of the range
+ */
+ void resetTangents(const int tick0, const int tick1);
+
void recordValue(TimePos time, float value);
TimePos setDragValue( const TimePos & time,
@@ -151,10 +159,21 @@ public:
return m_timeMap.isEmpty() == false;
}
+ static bool supportsTangentEditing(ProgressionType pType)
+ {
+ // Update function if we have new progression types that support tangent editing
+ return pType == ProgressionType::CubicHermite;
+ }
+
+ inline bool canEditTangents() const
+ {
+ return supportsTangentEditing(m_progressionType);
+ }
+
float valueAt( const TimePos & _time ) const;
float *valuesAfter( const TimePos & _time ) const;
- const QString name() const;
+ QString name() const;
// settings-management
void saveSettings( QDomDocument & _doc, QDomElement & _parent ) override;
@@ -167,7 +186,7 @@ public:
static bool isAutomated( const AutomatableModel * _m );
- static QVector clipsForModel( const AutomatableModel * _m );
+ static std::vector clipsForModel(const AutomatableModel* _m);
static AutomationClip * globalAutomationClip( AutomatableModel * _m );
static void resolveAllIDs();
@@ -190,6 +209,15 @@ private:
void generateTangents(timeMap::iterator it, int numToGenerate);
float valueAt( timeMap::const_iterator v, int offset ) const;
+ /**
+ * @brief
+ * This function combines the song tracks, pattern store tracks,
+ * and the global automation track all in one vector.
+ *
+ * @return std::vector
+ */
+ static std::vector combineAllTracks();
+
// Mutex to make methods involving automation clips thread safe
// Mutable so we can lock it from const objects
#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
@@ -199,17 +227,20 @@ private:
#endif
AutomationTrack * m_autoTrack;
- QVector m_idsToResolve;
+ std::vector m_idsToResolve;
objectVector m_objects;
timeMap m_timeMap; // actual values
timeMap m_oldTimeMap; // old values for storing the values before setDragValue() is called.
float m_tension;
bool m_hasAutomation;
- ProgressionTypes m_progressionType;
+ ProgressionType m_progressionType;
bool m_dragging;
bool m_dragKeepOutValue; // Should we keep the current dragged node's outValue?
float m_dragOutValue; // The outValue of the dragged node's
+ bool m_dragLockedTan; // If the dragged node has it's tangents locked
+ float m_dragInTan; // The dragged node's inTangent
+ float m_dragOutTan; // The dragged node's outTangent
bool m_isRecording;
float m_lastRecordedValue;
@@ -221,6 +252,7 @@ private:
friend class gui::AutomationClipView;
friend class AutomationNode;
+ friend class gui::AutomationEditor;
} ;
@@ -252,6 +284,11 @@ inline float OUTTAN(AutomationClip::TimemapIterator it)
return it->getOutTangent();
}
+inline float LOCKEDTAN(AutomationClip::TimemapIterator it)
+{
+ return it->lockedTangents();
+}
+
inline int POS(AutomationClip::TimemapIterator it)
{
return it.key();
@@ -260,4 +297,4 @@ inline int POS(AutomationClip::TimemapIterator it)
} // namespace lmms
-#endif
+#endif // LMMS_AUTOMATION_CLIP_H
diff --git a/include/AutomationClipView.h b/include/AutomationClipView.h
index b4de7839c..bdd2f0568 100644
--- a/include/AutomationClipView.h
+++ b/include/AutomationClipView.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef AUTOMATION_CLIP_VIEW_H
-#define AUTOMATION_CLIP_VIEW_H
+#ifndef LMMS_GUI_AUTOMATION_CLIP_VIEW_H
+#define LMMS_GUI_AUTOMATION_CLIP_VIEW_H
#include
@@ -74,9 +74,6 @@ private:
QPixmap m_paintPixmap;
QStaticText m_staticTextName;
-
- static QPixmap * s_clip_rec;
-
void scaleTimemapToFit( float oldMin, float oldMax );
} ;
@@ -85,4 +82,4 @@ private:
} // namespace lmms
-#endif
+#endif // LMMS_GUI_AUTOMATION_CLIP_VIEW_H
diff --git a/include/AutomationEditor.h b/include/AutomationEditor.h
index 52609416f..1110e8e4c 100644
--- a/include/AutomationEditor.h
+++ b/include/AutomationEditor.h
@@ -23,18 +23,21 @@
*
*/
-#ifndef AUTOMATION_EDITOR_H
-#define AUTOMATION_EDITOR_H
+#ifndef LMMS_GUI_AUTOMATION_EDITOR_H
+#define LMMS_GUI_AUTOMATION_EDITOR_H
+#include
#include
+#include
-#include "Editor.h"
-
-#include "lmms_basics.h"
-#include "JournallingObject.h"
-#include "TimePos.h"
#include "AutomationClip.h"
#include "ComboBoxModel.h"
+#include "Editor.h"
+#include "JournallingObject.h"
+#include "MidiClip.h"
+#include "SampleClip.h"
+#include "TimePos.h"
+#include "lmms_basics.h"
class QPainter;
class QPixmap;
@@ -62,12 +65,18 @@ class AutomationEditor : public QWidget, public JournallingObject
Q_PROPERTY(QColor lineColor MEMBER m_lineColor)
Q_PROPERTY(QColor nodeInValueColor MEMBER m_nodeInValueColor)
Q_PROPERTY(QColor nodeOutValueColor MEMBER m_nodeOutValueColor)
+ Q_PROPERTY(QColor nodeTangentLineColor MEMBER m_nodeTangentLineColor)
Q_PROPERTY(QBrush scaleColor MEMBER m_scaleColor)
Q_PROPERTY(QBrush graphColor MEMBER m_graphColor)
Q_PROPERTY(QColor crossColor MEMBER m_crossColor)
Q_PROPERTY(QColor backgroundShade MEMBER m_backgroundShade)
+ Q_PROPERTY(QColor ghostNoteColor MEMBER m_ghostNoteColor)
+ Q_PROPERTY(QColor detuningNoteColor MEMBER m_detuningNoteColor)
+ Q_PROPERTY(QColor ghostSampleColor MEMBER m_ghostSampleColor)
public:
void setCurrentClip(AutomationClip * new_clip);
+ void setGhostMidiClip(MidiClip* newMidiClip);
+ void setGhostSample(SampleClip* newSample);
inline const AutomationClip * currentClip() const
{
@@ -86,11 +95,12 @@ public:
return "automationeditor";
}
- enum EditModes
+ enum class EditMode
{
- DRAW,
- ERASE,
- DRAW_OUTVALUES
+ Draw,
+ Erase,
+ DrawOutValues,
+ EditTangents
};
public slots:
@@ -117,6 +127,13 @@ protected:
inline void drawLevelTick(QPainter & p, int tick, float value);
timeMap::iterator getNodeAt(int x, int y, bool outValue = false, int r = 5);
+ /**
+ * @brief Given a mouse X coordinate, returns a timeMap::iterator that points to
+ * the closest node.
+ * @param Int X coordinate
+ * @return timeMap::iterator with the closest node or timeMap.end() if there are no nodes.
+ */
+ timeMap::iterator getClosestNode(int x);
void drawLine( int x0, float y0, int x1, float y1 );
bool fineTuneValue(timeMap::iterator node, bool editingOutValue);
@@ -128,10 +145,16 @@ protected slots:
void horScrolled( int new_pos );
void verScrolled( int new_pos );
- void setEditMode(AutomationEditor::EditModes mode);
+ void setEditMode(AutomationEditor::EditMode mode);
void setEditMode(int mode);
- void setProgressionType(AutomationClip::ProgressionTypes type);
+ void setProgressionType(AutomationClip::ProgressionType type);
+ /**
+ * @brief This method handles the AutomationEditorWindow event of changing
+ * progression types. After that, it calls updateEditTanButton so the edit
+ * tangents button is updated accordingly
+ * @param Int New progression type
+ */
void setProgressionType(int type);
void setTension();
@@ -143,16 +166,25 @@ protected slots:
/// Updates the clip's quantization using the current user selected value.
void setQuantization();
+ void resetGhostNotes()
+ {
+ m_ghostNotes = nullptr;
+ m_ghostSample = nullptr;
+ update();
+ }
+
private:
- enum Actions
+ enum class Action
{
- NONE,
- MOVE_VALUE,
- ERASE_VALUES,
- MOVE_OUTVALUE,
- RESET_OUTVALUES,
- DRAW_LINE
+ None,
+ MoveValue,
+ EraseValues,
+ MoveOutValue,
+ ResetOutValues,
+ DrawLine,
+ MoveTangent,
+ ResetTangents
} ;
// some constants...
@@ -165,22 +197,29 @@ private:
static const int VALUES_WIDTH = 64;
+ static const int NOTE_HEIGHT = 10; // height of individual notes
+ static const int NOTE_MARGIN = 40; // total border margin for notes
+ static const int MIN_NOTE_RANGE = 20; // min number of keys for fixed size
+ static const int SAMPLE_MARGIN = 40;
+ static constexpr int MAX_SAMPLE_HEIGHT = 400; // constexpr for use in min
+
AutomationEditor();
AutomationEditor( const AutomationEditor & );
~AutomationEditor() override;
- static QPixmap * s_toolDraw;
- static QPixmap * s_toolErase;
- static QPixmap * s_toolDrawOut;
- static QPixmap * s_toolMove;
- static QPixmap * s_toolYFlip;
- static QPixmap * s_toolXFlip;
+ QPixmap m_toolDraw = embed::getIconPixmap("edit_draw");
+ QPixmap m_toolErase = embed::getIconPixmap("edit_erase");
+ QPixmap m_toolDrawOut = embed::getIconPixmap("edit_draw_outvalue");
+ QPixmap m_toolEditTangents = embed::getIconPixmap("edit_tangent");
+ QPixmap m_toolMove = embed::getIconPixmap("edit_move");
+ QPixmap m_toolYFlip = embed::getIconPixmap("flip_y");
+ QPixmap m_toolXFlip = embed::getIconPixmap("flip_x");
ComboBoxModel m_zoomingXModel;
ComboBoxModel m_zoomingYModel;
ComboBoxModel m_quantizeModel;
- static const QVector m_zoomXLevels;
+ static const std::array m_zoomXLevels;
FloatModel * m_tensionModel;
@@ -192,6 +231,10 @@ private:
float m_bottomLevel;
float m_topLevel;
+ MidiClip* m_ghostNotes = nullptr;
+ QPointer m_ghostSample = nullptr; // QPointer to set to nullptr on deletion
+ bool m_renderSample = false;
+
void centerTopBottomScroll();
void updateTopBottomLevels();
@@ -200,7 +243,7 @@ private:
TimePos m_currentPosition;
- Actions m_action;
+ Action m_action;
int m_moveXOffset;
@@ -214,7 +257,12 @@ private:
// Time position (key) of automation node whose outValue is being dragged
int m_draggedOutValueKey;
- EditModes m_editMode;
+ // The tick from the node whose tangent is being dragged
+ int m_draggedTangentTick;
+ // Whether the tangent being dragged is the InTangent or OutTangent
+ bool m_draggedOutTangent;
+
+ EditMode m_editMode;
bool m_mouseDownLeft;
bool m_mouseDownRight; //true if right click is being held down
@@ -224,6 +272,7 @@ private:
void drawCross(QPainter & p );
void drawAutomationPoint( QPainter & p, timeMap::iterator it );
+ void drawAutomationTangents(QPainter& p, timeMap::iterator it);
bool inPatternEditor();
QColor m_barLineColor;
@@ -232,9 +281,13 @@ private:
QBrush m_graphColor;
QColor m_nodeInValueColor;
QColor m_nodeOutValueColor;
+ QColor m_nodeTangentLineColor;
QBrush m_scaleColor;
QColor m_crossColor;
QColor m_backgroundShade;
+ QColor m_ghostNoteColor;
+ QColor m_detuningNoteColor;
+ QColor m_ghostSampleColor;
friend class AutomationEditorWindow;
@@ -258,6 +311,9 @@ public:
~AutomationEditorWindow() override = default;
void setCurrentClip(AutomationClip* clip);
+ void setGhostMidiClip(MidiClip* clip) { m_editor->setGhostMidiClip(clip); };
+ void setGhostSample(SampleClip* newSample) { m_editor->setGhostSample(newSample); };
+
const AutomationClip* currentClip();
void dropEvent( QDropEvent * _de ) override;
@@ -284,8 +340,21 @@ protected slots:
private slots:
void updateWindowTitle();
+ void setProgressionType(int progType);
+ /**
+ * @brief The Edit Tangent edit mode should only be available for
+ * Cubic Hermite progressions, so this method is responsable for disabling it
+ * for other edit modes and reenabling it when it changes back to the Edit Tangent
+ * mode.
+ */
+ void updateEditTanButton();
private:
+ QAction* m_drawAction;
+ QAction* m_eraseAction;
+ QAction* m_drawOutAction;
+ QAction* m_editTanAction;
+
QAction* m_discreteAction;
QAction* m_linearAction;
QAction* m_cubicHermiteAction;
@@ -298,10 +367,12 @@ private:
ComboBox * m_zoomingXComboBox;
ComboBox * m_zoomingYComboBox;
ComboBox * m_quantizeComboBox;
+
+ QPushButton* m_resetGhostNotes;
};
} // namespace gui
} // namespace lmms
-#endif
+#endif // LMMS_GUI_AUTOMATION_EDITOR_H
diff --git a/include/AutomationNode.h b/include/AutomationNode.h
index 11bd6d57d..60154332f 100644
--- a/include/AutomationNode.h
+++ b/include/AutomationNode.h
@@ -23,8 +23,8 @@
*
*/
-#ifndef AUTOMATION_NODE_H
-#define AUTOMATION_NODE_H
+#ifndef LMMS_AUTOMATION_NODE_H
+#define LMMS_AUTOMATION_NODE_H
namespace lmms
{
@@ -125,6 +125,22 @@ public:
m_outTangent = tangent;
}
+ /**
+ * @brief Checks if the tangents from the node are locked
+ */
+ inline const bool lockedTangents() const
+ {
+ return m_lockedTangents;
+ }
+
+ /**
+ * @brief Locks or Unlocks the tangents from this node
+ */
+ inline void setLockedTangents(bool b)
+ {
+ m_lockedTangents = b;
+ }
+
/**
* @brief Sets the clip this node belongs to
* @param AutomationClip* clip that m_clip will be
@@ -152,8 +168,13 @@ private:
// outValue are equal, inTangent and outTangent are equal too.
float m_inTangent;
float m_outTangent;
+
+ // If the tangents were edited manually, this will be true. That way
+ // the tangents from this node will not be recalculated. It's set back
+ // to false if the tangents are reset.
+ bool m_lockedTangents;
};
} // namespace lmms
-#endif
+#endif // LMMS_AUTOMATION_NODE_H
diff --git a/include/AutomationTrack.h b/include/AutomationTrack.h
index 1779bf102..64c2cc43a 100644
--- a/include/AutomationTrack.h
+++ b/include/AutomationTrack.h
@@ -24,8 +24,8 @@
*
*/
-#ifndef AUTOMATION_TRACK_H
-#define AUTOMATION_TRACK_H
+#ifndef LMMS_AUTOMATION_TRACK_H
+#define LMMS_AUTOMATION_TRACK_H
#include "Track.h"
@@ -62,4 +62,4 @@ private:
} // namespace lmms
-#endif
+#endif // LMMS_AUTOMATION_TRACK_H
diff --git a/include/AutomationTrackView.h b/include/AutomationTrackView.h
index 18454bec2..449e9bef8 100644
--- a/include/AutomationTrackView.h
+++ b/include/AutomationTrackView.h
@@ -23,8 +23,8 @@
*
*/
-#ifndef AUTOMATION_TRACK_VIEW_H
-#define AUTOMATION_TRACK_VIEW_H
+#ifndef LMMS_GUI_AUTOMATION_TRACK_VIEW_H
+#define LMMS_GUI_AUTOMATION_TRACK_VIEW_H
#include "TrackView.h"
@@ -52,4 +52,4 @@ public:
} // namespace lmms
-#endif
+#endif // LMMS_GUI_AUTOMATION_TRACK_VIEW_H
diff --git a/include/BandLimitedWave.h b/include/BandLimitedWave.h
index 588fc4eea..1f402aa6e 100644
--- a/include/BandLimitedWave.h
+++ b/include/BandLimitedWave.h
@@ -23,8 +23,8 @@
*
*/
-#ifndef BANDLIMITEDWAVE_H
-#define BANDLIMITEDWAVE_H
+#ifndef LMMS_BANDLIMITEDWAVE_H
+#define LMMS_BANDLIMITEDWAVE_H
class QDataStream;
class QString;
@@ -89,14 +89,15 @@ QDataStream& operator>> ( QDataStream &in, WaveMipMap &waveMipMap );
class LMMS_EXPORT BandLimitedWave
{
public:
- enum Waveforms
+ enum class Waveform
{
BLSaw,
BLSquare,
BLTriangle,
BLMoog,
- NumBLWaveforms
+ Count
};
+ constexpr static auto NumWaveforms = static_cast(Waveform::Count);
BandLimitedWave() = default;
virtual ~BandLimitedWave() = default;
@@ -127,7 +128,7 @@ public:
* \param _wavelen The wavelength (length of one cycle, ie. the inverse of frequency) of the wanted oscillation, measured in sample frames
* \param _wave The wanted waveform. Options currently are saw, triangle, square and moog saw.
*/
- static inline sample_t oscillate( float _ph, float _wavelen, Waveforms _wave )
+ static inline sample_t oscillate( float _ph, float _wavelen, Waveform _wave )
{
// get the next higher tlen
int t = 0;
@@ -139,27 +140,28 @@ public:
int lookup = static_cast( lookupf );
const float ip = fraction( lookupf );
- const sample_t s1 = s_waveforms[ _wave ].sampleAt( t, lookup );
- const sample_t s2 = s_waveforms[ _wave ].sampleAt( t, ( lookup + 1 ) % tlen );
+ const sample_t s1 = s_waveforms[ static_cast(_wave) ].sampleAt( t, lookup );
+ const sample_t s2 = s_waveforms[ static_cast(_wave) ].sampleAt( t, ( lookup + 1 ) % tlen );
const int lm = lookup == 0 ? tlen - 1 : lookup - 1;
- const sample_t s0 = s_waveforms[ _wave ].sampleAt( t, lm );
- const sample_t s3 = s_waveforms[ _wave ].sampleAt( t, ( lookup + 2 ) % tlen );
+ const sample_t s0 = s_waveforms[ static_cast(_wave) ].sampleAt( t, lm );
+ const sample_t s3 = s_waveforms[ static_cast(_wave) ].sampleAt( t, ( lookup + 2 ) % tlen );
const sample_t sr = optimal4pInterpolate( s0, s1, s2, s3, ip );
return sr;
-/* lookup = lookup << 1;
+ /*
+ lookup = lookup << 1;
tlen = tlen << 1;
t += 1;
- const sample_t s3 = s_waveforms[ _wave ].sampleAt( t, lookup );
- const sample_t s4 = s_waveforms[ _wave ].sampleAt( t, ( lookup + 1 ) % tlen );
+ const sample_t s3 = s_waveforms[ static_cast(_wave) ].sampleAt( t, lookup );
+ const sample_t s4 = s_waveforms[ static_cast(_wave) ].sampleAt( t, ( lookup + 1 ) % tlen );
const sample_t s34 = linearInterpolate( s3, s4, ip );
const float ip2 = ( ( tlen - _wavelen ) / tlen - 0.5 ) * 2.0;
return linearInterpolate( s12, s34, ip2 );
- */
+ */
};
@@ -167,11 +169,11 @@ public:
static bool s_wavesGenerated;
- static std::array s_waveforms;
+ static std::array s_waveforms;
static QString s_wavetableDir;
};
} // namespace lmms
-#endif
+#endif // LMMS_BANDLIMITEDWAVE_H
diff --git a/include/BarModelEditor.h b/include/BarModelEditor.h
new file mode 100644
index 000000000..79a320a7d
--- /dev/null
+++ b/include/BarModelEditor.h
@@ -0,0 +1,76 @@
+/*
+ * BarModelEditor.h - edit model values using a bar display
+ *
+ * Copyright (c) 2023-now Michael Gregorius
+ *
+ * This file is part of LMMS - https://lmms.io
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program (see COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ */
+
+#pragma once
+
+#ifndef LMMS_GUI_BAR_MODEL_EDITOR_H
+#define LMMS_GUI_BAR_MODEL_EDITOR_H
+
+#include "FloatModelEditorBase.h"
+
+
+namespace lmms::gui
+{
+
+class LMMS_EXPORT BarModelEditor : public FloatModelEditorBase
+{
+ Q_OBJECT
+
+public:
+ Q_PROPERTY(QBrush backgroundBrush READ getBackgroundBrush WRITE setBackgroundBrush)
+ Q_PROPERTY(QBrush barBrush READ getBarBrush WRITE setBarBrush)
+ Q_PROPERTY(QColor textColor READ getTextColor WRITE setTextColor)
+
+ BarModelEditor(QString text, FloatModel * floatModel, QWidget * parent = nullptr);
+
+ // Define how the widget will behave in a layout
+ QSizePolicy sizePolicy() const;
+
+ QSize minimumSizeHint() const override;
+
+ QSize sizeHint() const override;
+
+ QBrush const & getBackgroundBrush() const;
+ void setBackgroundBrush(QBrush const & backgroundBrush);
+
+ QBrush const & getBarBrush() const;
+ void setBarBrush(QBrush const & barBrush);
+
+ QColor const & getTextColor() const;
+ void setTextColor(QColor const & textColor);
+
+protected:
+ void paintEvent(QPaintEvent *event) override;
+
+private:
+ QString const m_text;
+
+ QBrush m_backgroundBrush;
+ QBrush m_barBrush;
+ QColor m_textColor;
+};
+
+} // namespace lmms::gui
+
+#endif // LMMS_GUI_BAR_MODEL_EDITOR_H
diff --git a/include/BasicFilters.h b/include/BasicFilters.h
index 836d758b6..25dcf834c 100644
--- a/include/BasicFilters.h
+++ b/include/BasicFilters.h
@@ -28,9 +28,8 @@
*
*/
-
-#ifndef BASIC_FILTERS_H
-#define BASIC_FILTERS_H
+#ifndef LMMS_BASIC_FILTERS_H
+#define LMMS_BASIC_FILTERS_H
#ifndef __USE_XOPEN
#define __USE_XOPEN
@@ -41,7 +40,6 @@
#include "lmms_basics.h"
#include "lmms_constants.h"
#include "interpolation.h"
-#include "MemoryManager.h"
namespace lmms
{
@@ -51,7 +49,6 @@ template class BasicFilters;
template
class LinkwitzRiley
{
- MM_OPERATORS
public:
LinkwitzRiley( float sampleRate )
{
@@ -146,9 +143,13 @@ using StereoLinkwitzRiley = LinkwitzRiley<2>;
template
class BiQuad
{
- MM_OPERATORS
public:
- BiQuad()
+ BiQuad() :
+ m_a1(0.),
+ m_a2(0.),
+ m_b0(0.),
+ m_b1(0.),
+ m_b2(0.)
{
clearHistory();
}
@@ -189,7 +190,6 @@ using StereoBiQuad = BiQuad<2>;
template
class OnePole
{
- MM_OPERATORS
public:
OnePole()
{
@@ -210,7 +210,7 @@ public:
inline float update( float s, ch_cnt_t ch )
{
- if( qAbs( s ) < 1.0e-10f && qAbs( m_z1[ch] ) < 1.0e-10f ) return 0.0f;
+ if (std::abs(s) < 1.0e-10f && std::abs(m_z1[ch]) < 1.0e-10f) return 0.0f;
return m_z1[ch] = s * m_a0 + m_z1[ch] * m_b1;
}
@@ -223,9 +223,8 @@ using StereoOnePole = OnePole<2>;
template
class BasicFilters
{
- MM_OPERATORS
public:
- enum FilterTypes
+ enum class FilterType
{
LowPass,
HiPass,
@@ -248,8 +247,7 @@ public:
Highpass_SV,
Notch_SV,
FastFormant,
- Tripole,
- NumFilters
+ Tripole
};
static inline float minFreq()
@@ -262,20 +260,20 @@ public:
return( 0.01f );
}
- inline void setFilterType( const int _idx )
+ inline void setFilterType( const FilterType _idx )
{
- m_doubleFilter = _idx == DoubleLowPass || _idx == DoubleMoog;
+ m_doubleFilter = _idx == FilterType::DoubleLowPass || _idx == FilterType::DoubleMoog;
if( !m_doubleFilter )
{
- m_type = static_cast( _idx );
+ m_type = _idx;
return;
}
// Double lowpass mode, backwards-compat for the goofy
// Add-NumFilters to signify doubleFilter stuff
- m_type = _idx == DoubleLowPass
- ? LowPass
- : Moog;
+ m_type = _idx == FilterType::DoubleLowPass
+ ? FilterType::LowPass
+ : FilterType::Moog;
if( m_subFilter == nullptr )
{
m_subFilter = new BasicFilters(
@@ -330,33 +328,39 @@ public:
}
}
+ inline void setSampleRate(const sample_rate_t sampleRate)
+ {
+ m_sampleRate = sampleRate;
+ m_sampleRatio = 1.f / m_sampleRate;
+ if (m_subFilter != nullptr)
+ {
+ m_subFilter->setSampleRate(m_sampleRate);
+ }
+ }
+
inline sample_t update( sample_t _in0, ch_cnt_t _chnl )
{
- sample_t out;
+ sample_t out = 0.0f;
switch( m_type )
{
- case Moog:
+ case FilterType::Moog:
{
sample_t x = _in0 - m_r*m_y4[_chnl];
// four cascaded onepole filters
// (bilinear transform)
- m_y1[_chnl] = qBound( -10.0f,
- ( x + m_oldx[_chnl] ) * m_p
- - m_k * m_y1[_chnl],
- 10.0f );
- m_y2[_chnl] = qBound( -10.0f,
- ( m_y1[_chnl] + m_oldy1[_chnl] ) * m_p
- - m_k * m_y2[_chnl],
- 10.0f );
- m_y3[_chnl] = qBound( -10.0f,
- ( m_y2[_chnl] + m_oldy2[_chnl] ) * m_p
- - m_k * m_y3[_chnl],
- 10.0f );
- m_y4[_chnl] = qBound( -10.0f,
- ( m_y3[_chnl] + m_oldy3[_chnl] ) * m_p
- - m_k * m_y4[_chnl],
+ m_y1[_chnl] = std::clamp((x + m_oldx[_chnl]) * m_p
+ - m_k * m_y1[_chnl], -10.0f,
+ 10.0f);
+ m_y2[_chnl] = std::clamp((m_y1[_chnl] + m_oldy1[_chnl]) * m_p
+ - m_k * m_y2[_chnl], -10.0f,
+ 10.0f);
+ m_y3[_chnl] = std::clamp((m_y2[_chnl] + m_oldy2[_chnl]) * m_p
+ - m_k * m_y3[_chnl], -10.0f,
10.0f );
+ m_y4[_chnl] = std::clamp((m_y3[_chnl] + m_oldy3[_chnl]) * m_p
+ - m_k * m_y4[_chnl], -10.0f,
+ 10.0f);
m_oldx[_chnl] = x;
m_oldy1[_chnl] = m_y1[_chnl];
@@ -369,27 +373,23 @@ public:
// 3x onepole filters with 4x oversampling and interpolation of oversampled signal:
// input signal is linear-interpolated after oversampling, output signal is averaged from oversampled outputs
- case Tripole:
+ case FilterType::Tripole:
{
- out = 0.0f;
float ip = 0.0f;
for( int i = 0; i < 4; ++i )
{
ip += 0.25f;
sample_t x = linearInterpolate( m_last[_chnl], _in0, ip ) - m_r * m_y3[_chnl];
- m_y1[_chnl] = qBound( -10.0f,
- ( x + m_oldx[_chnl] ) * m_p
- - m_k * m_y1[_chnl],
- 10.0f );
- m_y2[_chnl] = qBound( -10.0f,
- ( m_y1[_chnl] + m_oldy1[_chnl] ) * m_p
- - m_k * m_y2[_chnl],
- 10.0f );
- m_y3[_chnl] = qBound( -10.0f,
- ( m_y2[_chnl] + m_oldy2[_chnl] ) * m_p
- - m_k * m_y3[_chnl],
- 10.0f );
+ m_y1[_chnl] = std::clamp((x + m_oldx[_chnl]) * m_p
+ - m_k * m_y1[_chnl], -10.0f,
+ 10.0f);
+ m_y2[_chnl] = std::clamp((m_y1[_chnl] + m_oldy1[_chnl]) * m_p
+ - m_k * m_y2[_chnl], -10.0f,
+ 10.0f);
+ m_y3[_chnl] = std::clamp((m_y2[_chnl] + m_oldy2[_chnl]) * m_p
+ - m_k * m_y3[_chnl], -10.0f,
+ 10.0f);
m_oldx[_chnl] = x;
m_oldy1[_chnl] = m_y1[_chnl];
m_oldy2[_chnl] = m_y2[_chnl];
@@ -405,8 +405,8 @@ public:
// and extended to other SV filter types
// /* Hal Chamberlin's state variable filter */
- case Lowpass_SV:
- case Bandpass_SV:
+ case FilterType::Lowpass_SV:
+ case FilterType::Bandpass_SV:
{
float highpass;
@@ -422,15 +422,14 @@ public:
}
/* mix filter output into output buffer */
- return m_type == Lowpass_SV
+ return m_type == FilterType::Lowpass_SV
? m_delay4[_chnl]
: m_delay3[_chnl];
}
- case Highpass_SV:
+ case FilterType::Highpass_SV:
{
float hp;
-
for( int i = 0; i < 2; ++i ) // 2x oversample
{
m_delay2[_chnl] = m_delay2[_chnl] + m_svf1 * m_delay1[_chnl];
@@ -441,10 +440,9 @@ public:
return hp;
}
- case Notch_SV:
+ case FilterType::Notch_SV:
{
- float hp1, hp2;
-
+ float hp1;
for( int i = 0; i < 2; ++i ) // 2x oversample
{
m_delay2[_chnl] = m_delay2[_chnl] + m_svf1 * m_delay1[_chnl]; /* delay2/4 = lowpass output */
@@ -452,7 +450,7 @@ public:
m_delay1[_chnl] = m_svf1 * hp1 + m_delay1[_chnl]; /* delay1/3 = bandpass output */
m_delay4[_chnl] = m_delay4[_chnl] + m_svf2 * m_delay3[_chnl];
- hp2 = m_delay2[_chnl] - m_delay4[_chnl] - m_svq * m_delay3[_chnl];
+ float hp2 = m_delay2[_chnl] - m_delay4[_chnl] - m_svq * m_delay3[_chnl];
m_delay3[_chnl] = m_svf2 * hp2 + m_delay3[_chnl];
}
@@ -466,22 +464,22 @@ public:
// can be driven up to self-oscillation (BTW: do not remove the limits!!!).
// (C) 1998 ... 2009 S.Fendt. Released under the GPL v2.0 or any later version.
- case Lowpass_RC12:
+ case FilterType::Lowpass_RC12:
{
- sample_t lp, bp, hp, in;
+ sample_t lp = 0.0f;
for( int n = 4; n != 0; --n )
{
- in = _in0 + m_rcbp0[_chnl] * m_rcq;
- in = qBound( -1.0f, in, 1.0f );
+ sample_t in = _in0 + m_rcbp0[_chnl] * m_rcq;
+ in = std::clamp(in, -1.0f, 1.0f);
lp = in * m_rcb + m_rclp0[_chnl] * m_rca;
- lp = qBound( -1.0f, lp, 1.0f );
+ lp = std::clamp(lp, -1.0f, 1.0f);
- hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] );
- hp = qBound( -1.0f, hp, 1.0f );
+ sample_t hp = m_rcc * (m_rchp0[_chnl] + in - m_rclast0[_chnl]);
+ hp = std::clamp(hp, -1.0f, 1.0f);
- bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
- bp = qBound( -1.0f, bp, 1.0f );
+ sample_t bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
+ bp = std::clamp(bp, -1.0f, 1.0f);
m_rclast0[_chnl] = in;
m_rclp0[_chnl] = lp;
@@ -490,45 +488,45 @@ public:
}
return lp;
}
- case Highpass_RC12:
- case Bandpass_RC12:
+ case FilterType::Highpass_RC12:
+ case FilterType::Bandpass_RC12:
{
- sample_t hp, bp, in;
+ sample_t hp, bp;
for( int n = 4; n != 0; --n )
{
- in = _in0 + m_rcbp0[_chnl] * m_rcq;
- in = qBound( -1.0f, in, 1.0f );
+ sample_t in = _in0 + m_rcbp0[_chnl] * m_rcq;
+ in = std::clamp(in, -1.0f, 1.0f);
hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] );
- hp = qBound( -1.0f, hp, 1.0f );
+ hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
- bp = qBound( -1.0f, bp, 1.0f );
+ bp = std::clamp(bp, -1.0f, 1.0f);
m_rclast0[_chnl] = in;
m_rchp0[_chnl] = hp;
m_rcbp0[_chnl] = bp;
}
- return m_type == Highpass_RC12 ? hp : bp;
+ return m_type == FilterType::Highpass_RC12 ? hp : bp;
}
- case Lowpass_RC24:
+ case FilterType::Lowpass_RC24:
{
- sample_t lp, bp, hp, in;
+ sample_t lp;
for( int n = 4; n != 0; --n )
{
// first stage is as for the 12dB case...
- in = _in0 + m_rcbp0[_chnl] * m_rcq;
- in = qBound( -1.0f, in, 1.0f );
+ sample_t in = _in0 + m_rcbp0[_chnl] * m_rcq;
+ in = std::clamp(in, -1.0f, 1.0f);
lp = in * m_rcb + m_rclp0[_chnl] * m_rca;
- lp = qBound( -1.0f, lp, 1.0f );
+ lp = std::clamp(lp, -1.0f, 1.0f);
- hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] );
- hp = qBound( -1.0f, hp, 1.0f );
+ sample_t hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] );
+ hp = std::clamp(hp, -1.0f, 1.0f);
- bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
- bp = qBound( -1.0f, bp, 1.0f );
+ sample_t bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
+ bp = std::clamp(bp, -1.0f, 1.0f);
m_rclast0[_chnl] = in;
m_rclp0[_chnl] = lp;
@@ -537,16 +535,16 @@ public:
// second stage gets the output of the first stage as input...
in = lp + m_rcbp1[_chnl] * m_rcq;
- in = qBound( -1.0f, in, 1.0f );
+ in = std::clamp(in, -1.0f, 1.0f );
lp = in * m_rcb + m_rclp1[_chnl] * m_rca;
- lp = qBound( -1.0f, lp, 1.0f );
+ lp = std::clamp(lp, -1.0f, 1.0f);
hp = m_rcc * ( m_rchp1[_chnl] + in - m_rclast1[_chnl] );
- hp = qBound( -1.0f, hp, 1.0f );
+ hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_rcb + m_rcbp1[_chnl] * m_rca;
- bp = qBound( -1.0f, bp, 1.0f );
+ bp = std::clamp(bp, -1.0f, 1.0f);
m_rclast1[_chnl] = in;
m_rclp1[_chnl] = lp;
@@ -555,91 +553,89 @@ public:
}
return lp;
}
- case Highpass_RC24:
- case Bandpass_RC24:
+ case FilterType::Highpass_RC24:
+ case FilterType::Bandpass_RC24:
{
- sample_t hp, bp, in;
+ sample_t hp, bp;
for( int n = 4; n != 0; --n )
{
// first stage is as for the 12dB case...
- in = _in0 + m_rcbp0[_chnl] * m_rcq;
- in = qBound( -1.0f, in, 1.0f );
+ sample_t in = _in0 + m_rcbp0[_chnl] * m_rcq;
+ in = std::clamp(in, -1.0f, 1.0f);
hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] );
- hp = qBound( -1.0f, hp, 1.0f );
+ hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
- bp = qBound( -1.0f, bp, 1.0f );
+ bp = std::clamp(bp, -1.0f, 1.0f);
m_rclast0[_chnl] = in;
m_rchp0[_chnl] = hp;
m_rcbp0[_chnl] = bp;
// second stage gets the output of the first stage as input...
- in = m_type == Highpass_RC24
+ in = m_type == FilterType::Highpass_RC24
? hp + m_rcbp1[_chnl] * m_rcq
: bp + m_rcbp1[_chnl] * m_rcq;
- in = qBound( -1.0f, in, 1.0f );
+ in = std::clamp(in, -1.0f, 1.0f);
hp = m_rcc * ( m_rchp1[_chnl] + in - m_rclast1[_chnl] );
- hp = qBound( -1.0f, hp, 1.0f );
+ hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_rcb + m_rcbp1[_chnl] * m_rca;
- bp = qBound( -1.0f, bp, 1.0f );
+ bp = std::clamp(bp, -1.0f, 1.0f);
m_rclast1[_chnl] = in;
m_rchp1[_chnl] = hp;
m_rcbp1[_chnl] = bp;
}
- return m_type == Highpass_RC24 ? hp : bp;
+ return m_type == FilterType::Highpass_RC24 ? hp : bp;
}
- case Formantfilter:
- case FastFormant:
+ case FilterType::Formantfilter:
+ case FilterType::FastFormant:
{
- if( qAbs( _in0 ) < 1.0e-10f && qAbs( m_vflast[0][_chnl] ) < 1.0e-10f ) { return 0.0f; } // performance hack - skip processing when the numbers get too small
- sample_t hp, bp, in;
+ if (std::abs(_in0) < 1.0e-10f && std::abs(m_vflast[0][_chnl]) < 1.0e-10f) { return 0.0f; } // performance hack - skip processing when the numbers get too small
- out = 0;
- const int os = m_type == FastFormant ? 1 : 4; // no oversampling for fast formant
+ const int os = m_type == FilterType::FastFormant ? 1 : 4; // no oversampling for fast formant
for( int o = 0; o < os; ++o )
{
// first formant
- in = _in0 + m_vfbp[0][_chnl] * m_vfq;
- in = qBound( -1.0f, in, 1.0f );
+ sample_t in = _in0 + m_vfbp[0][_chnl] * m_vfq;
+ in = std::clamp(in, -1.0f, 1.0f);
- hp = m_vfc[0] * ( m_vfhp[0][_chnl] + in - m_vflast[0][_chnl] );
- hp = qBound( -1.0f, hp, 1.0f );
+ sample_t hp = m_vfc[0] * ( m_vfhp[0][_chnl] + in - m_vflast[0][_chnl] );
+ hp = std::clamp(hp, -1.0f, 1.0f);
- bp = hp * m_vfb[0] + m_vfbp[0][_chnl] * m_vfa[0];
- bp = qBound( -1.0f, bp, 1.0f );
+ sample_t bp = hp * m_vfb[0] + m_vfbp[0][_chnl] * m_vfa[0];
+ bp = std::clamp(bp, -1.0f, 1.0f);
m_vflast[0][_chnl] = in;
m_vfhp[0][_chnl] = hp;
m_vfbp[0][_chnl] = bp;
in = bp + m_vfbp[2][_chnl] * m_vfq;
- in = qBound( -1.0f, in, 1.0f );
+ in = std::clamp(in, -1.0f, 1.0f);
hp = m_vfc[0] * ( m_vfhp[2][_chnl] + in - m_vflast[2][_chnl] );
- hp = qBound( -1.0f, hp, 1.0f );
+ hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_vfb[0] + m_vfbp[2][_chnl] * m_vfa[0];
- bp = qBound( -1.0f, bp, 1.0f );
+ bp = std::clamp(bp, -1.0f, 1.0f);
m_vflast[2][_chnl] = in;
m_vfhp[2][_chnl] = hp;
m_vfbp[2][_chnl] = bp;
in = bp + m_vfbp[4][_chnl] * m_vfq;
- in = qBound( -1.0f, in, 1.0f );
+ in = std::clamp(in, -1.0f, 1.0f);
hp = m_vfc[0] * ( m_vfhp[4][_chnl] + in - m_vflast[4][_chnl] );
- hp = qBound( -1.0f, hp, 1.0f );
+ hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_vfb[0] + m_vfbp[4][_chnl] * m_vfa[0];
- bp = qBound( -1.0f, bp, 1.0f );
+ bp = std::clamp(bp, -1.0f, 1.0f);
m_vflast[4][_chnl] = in;
m_vfhp[4][_chnl] = hp;
@@ -649,39 +645,39 @@ public:
// second formant
in = _in0 + m_vfbp[0][_chnl] * m_vfq;
- in = qBound( -1.0f, in, 1.0f );
+ in = std::clamp(in, -1.0f, 1.0f);
hp = m_vfc[1] * ( m_vfhp[1][_chnl] + in - m_vflast[1][_chnl] );
- hp = qBound( -1.0f, hp, 1.0f );
+ hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_vfb[1] + m_vfbp[1][_chnl] * m_vfa[1];
- bp = qBound( -1.0f, bp, 1.0f );
+ bp = std::clamp(bp, -1.0f, 1.0f);
m_vflast[1][_chnl] = in;
m_vfhp[1][_chnl] = hp;
m_vfbp[1][_chnl] = bp;
in = bp + m_vfbp[3][_chnl] * m_vfq;
- in = qBound( -1.0f, in, 1.0f );
+ in = std::clamp(in, -1.0f, 1.0f);
hp = m_vfc[1] * ( m_vfhp[3][_chnl] + in - m_vflast[3][_chnl] );
- hp = qBound( -1.0f, hp, 1.0f );
+ hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_vfb[1] + m_vfbp[3][_chnl] * m_vfa[1];
- bp = qBound( -1.0f, bp, 1.0f );
+ bp = std::clamp(bp, -1.0f, 1.0f);
m_vflast[3][_chnl] = in;
m_vfhp[3][_chnl] = hp;
m_vfbp[3][_chnl] = bp;
in = bp + m_vfbp[5][_chnl] * m_vfq;
- in = qBound( -1.0f, in, 1.0f );
+ in = std::clamp(in, -1.0f, 1.0f);
hp = m_vfc[1] * ( m_vfhp[5][_chnl] + in - m_vflast[5][_chnl] );
- hp = qBound( -1.0f, hp, 1.0f );
+ hp = std::clamp(hp, -1.0f, 1.0f);
bp = hp * m_vfb[1] + m_vfbp[5][_chnl] * m_vfa[1];
- bp = qBound( -1.0f, bp, 1.0f );
+ bp = std::clamp(bp, -1.0f, 1.0f);
m_vflast[5][_chnl] = in;
m_vfhp[5][_chnl] = hp;
@@ -689,7 +685,7 @@ public:
out += bp;
}
- return m_type == FastFormant ? out * 2.0f : out * 0.5f;
+ return m_type == FilterType::FastFormant ? out * 2.0f : out * 0.5f;
}
default:
@@ -710,16 +706,16 @@ public:
inline void calcFilterCoeffs( float _freq, float _q )
{
// temp coef vars
- _q = qMax( _q, minQ() );
+ _q = std::max(_q, minQ());
- if( m_type == Lowpass_RC12 ||
- m_type == Bandpass_RC12 ||
- m_type == Highpass_RC12 ||
- m_type == Lowpass_RC24 ||
- m_type == Bandpass_RC24 ||
- m_type == Highpass_RC24 )
+ if( m_type == FilterType::Lowpass_RC12 ||
+ m_type == FilterType::Bandpass_RC12 ||
+ m_type == FilterType::Highpass_RC12 ||
+ m_type == FilterType::Lowpass_RC24 ||
+ m_type == FilterType::Bandpass_RC24 ||
+ m_type == FilterType::Highpass_RC24 )
{
- _freq = qBound( 50.0f, _freq, 20000.0f );
+ _freq = std::clamp(_freq, 50.0f, 20000.0f);
const float sr = m_sampleRatio * 0.25f;
const float f = 1.0f / ( _freq * F_2PI );
@@ -732,10 +728,10 @@ public:
return;
}
- if( m_type == Formantfilter ||
- m_type == FastFormant )
+ if( m_type == FilterType::Formantfilter ||
+ m_type == FilterType::FastFormant )
{
- _freq = qBound( minFreq(), _freq, 20000.0f ); // limit freq and q for not getting bad noise out of the filter...
+ _freq = std::clamp(_freq, minFreq(), 20000.0f); // limit freq and q for not getting bad noise out of the filter...
// formats for a, e, i, o, u, a
static const float _f[6][2] = { { 1000, 1400 }, { 500, 2300 },
@@ -758,7 +754,7 @@ public:
const float f1 = 1.0f / ( linearInterpolate( _f[vowel+0][1], _f[vowel+1][1], fract ) * F_2PI );
// samplerate coeff: depends on oversampling
- const float sr = m_type == FastFormant ? m_sampleRatio : m_sampleRatio * 0.25f;
+ const float sr = m_type == FilterType::FastFormant ? m_sampleRatio : m_sampleRatio * 0.25f;
m_vfa[0] = 1.0f - sr / ( f0 + sr );
m_vfb[0] = 1.0f - m_vfa[0];
@@ -769,11 +765,11 @@ public:
return;
}
- if( m_type == Moog ||
- m_type == DoubleMoog )
+ if( m_type == FilterType::Moog ||
+ m_type == FilterType::DoubleMoog )
{
// [ 0 - 0.5 ]
- const float f = qBound( minFreq(), _freq, 20000.0f ) * m_sampleRatio;
+ const float f = std::clamp(_freq, minFreq(), 20000.0f) * m_sampleRatio;
// (Empirical tunning)
m_p = ( 3.6f - 3.2f * f ) * f;
m_k = 2.0f * m_p - 1;
@@ -788,9 +784,9 @@ public:
return;
}
- if( m_type == Tripole )
+ if( m_type == FilterType::Tripole )
{
- const float f = qBound( 20.0f, _freq, 20000.0f ) * m_sampleRatio * 0.25f;
+ const float f = std::clamp(_freq, 20.0f, 20000.0f) * m_sampleRatio * 0.25f;
m_p = ( 3.6f - 3.2f * f ) * f;
m_k = 2.0f * m_p - 1.0f;
@@ -799,20 +795,20 @@ public:
return;
}
- if( m_type == Lowpass_SV ||
- m_type == Bandpass_SV ||
- m_type == Highpass_SV ||
- m_type == Notch_SV )
+ if( m_type == FilterType::Lowpass_SV ||
+ m_type == FilterType::Bandpass_SV ||
+ m_type == FilterType::Highpass_SV ||
+ m_type == FilterType::Notch_SV )
{
- const float f = sinf( qMax( minFreq(), _freq ) * m_sampleRatio * F_PI );
- m_svf1 = qMin( f, 0.825f );
- m_svf2 = qMin( f * 2.0f, 0.825f );
- m_svq = qMax( 0.0001f, 2.0f - ( _q * 0.1995f ) );
+ const float f = sinf(std::max(minFreq(), _freq) * m_sampleRatio * F_PI);
+ m_svf1 = std::min(f, 0.825f);
+ m_svf2 = std::min(f * 2.0f, 0.825f);
+ m_svq = std::max(0.0001f, 2.0f - (_q * 0.1995f));
return;
}
// other filters
- _freq = qBound( minFreq(), _freq, 20000.0f );
+ _freq = std::clamp(_freq, minFreq(), 20000.0f);
const float omega = F_2PI * _freq * m_sampleRatio;
const float tsin = sinf( omega ) * 0.5f;
const float tcos = cosf( omega );
@@ -826,38 +822,38 @@ public:
switch( m_type )
{
- case LowPass:
+ case FilterType::LowPass:
{
const float b1 = ( 1.0f - tcos ) * a0;
const float b0 = b1 * 0.5f;
m_biQuad.setCoeffs( a1, a2, b0, b1, b0 );
break;
}
- case HiPass:
+ case FilterType::HiPass:
{
const float b1 = ( -1.0f - tcos ) * a0;
const float b0 = b1 * -0.5f;
m_biQuad.setCoeffs( a1, a2, b0, b1, b0 );
break;
}
- case BandPass_CSG:
+ case FilterType::BandPass_CSG:
{
const float b0 = tsin * a0;
m_biQuad.setCoeffs( a1, a2, b0, 0.0f, -b0 );
break;
}
- case BandPass_CZPG:
+ case FilterType::BandPass_CZPG:
{
const float b0 = alpha * a0;
m_biQuad.setCoeffs( a1, a2, b0, 0.0f, -b0 );
break;
}
- case Notch:
+ case FilterType::Notch:
{
m_biQuad.setCoeffs( a1, a2, a0, a1, a0 );
break;
}
- case AllPass:
+ case FilterType::AllPass:
{
m_biQuad.setCoeffs( a1, a2, a2, a1, 1.0f );
break;
@@ -906,7 +902,7 @@ private:
// in/out history for Lowpass_SV (state-variant lowpass)
frame m_delay1, m_delay2, m_delay3, m_delay4;
- FilterTypes m_type;
+ FilterType m_type;
bool m_doubleFilter;
float m_sampleRate;
@@ -918,4 +914,4 @@ private:
} // namespace lmms
-#endif
+#endif // LMMS_BASIC_FILTERS_H
diff --git a/include/BufferManager.h b/include/BufferManager.h
index 57729918e..712e420ff 100644
--- a/include/BufferManager.h
+++ b/include/BufferManager.h
@@ -23,8 +23,8 @@
*
*/
-#ifndef BUFFER_MANAGER_H
-#define BUFFER_MANAGER_H
+#ifndef LMMS_BUFFER_MANAGER_H
+#define LMMS_BUFFER_MANAGER_H
#include "lmms_export.h"
#include "lmms_basics.h"
@@ -54,4 +54,4 @@ private:
} // namespace lmms
-#endif
+#endif // LMMS_BUFFER_MANAGER_H
diff --git a/include/CPULoadWidget.h b/include/CPULoadWidget.h
index dd2747ef2..bed10b05e 100644
--- a/include/CPULoadWidget.h
+++ b/include/CPULoadWidget.h
@@ -23,10 +23,10 @@
*
*/
+#ifndef LMMS_GUI_CPU_LOAD_WIDGET_H
+#define LMMS_GUI_CPU_LOAD_WIDGET_H
-#ifndef CPULOAD_WIDGET_H
-#define CPULOAD_WIDGET_H
-
+#include
#include
#include
#include
@@ -41,6 +41,7 @@ namespace lmms::gui
class CPULoadWidget : public QWidget
{
Q_OBJECT
+ Q_PROPERTY(int stepSize MEMBER m_stepSize)
public:
CPULoadWidget( QWidget * _parent );
~CPULoadWidget() override = default;
@@ -55,6 +56,8 @@ protected slots:
private:
+ int stepSize() const { return std::max(1, m_stepSize); }
+
int m_currentLoad;
QPixmap m_temp;
@@ -65,9 +68,11 @@ private:
QTimer m_updateTimer;
+ int m_stepSize = 1;
+
} ;
} // namespace lmms::gui
-#endif
+#endif // LMMS_GUI_CPU_LOAD_WIDGET_H
diff --git a/include/CaptionMenu.h b/include/CaptionMenu.h
index f6a2fff25..4a8889a83 100644
--- a/include/CaptionMenu.h
+++ b/include/CaptionMenu.h
@@ -22,9 +22,8 @@
*
*/
-
-#ifndef CAPTION_MENU_H
-#define CAPTION_MENU_H
+#ifndef LMMS_GUI_CAPTION_MENU_H
+#define LMMS_GUI_CAPTION_MENU_H
#include
@@ -47,4 +46,4 @@ public:
} // namespace lmms::gui
-#endif
+#endif // LMMS_GUI_CAPTION_MENU_H
diff --git a/include/Clip.h b/include/Clip.h
index 204a071a7..a520ad4e4 100644
--- a/include/Clip.h
+++ b/include/Clip.h
@@ -22,8 +22,10 @@
*
*/
-#ifndef TRACK_CONTENT_OBJECT_H
-#define TRACK_CONTENT_OBJECT_H
+#ifndef LMMS_CLIP_H
+#define LMMS_CLIP_H
+
+#include
#include
@@ -48,7 +50,6 @@ class TrackView;
class LMMS_EXPORT Clip : public Model, public JournallingObject
{
Q_OBJECT
- MM_OPERATORS
mapPropertyFromModel(bool,isMuted,setMuted,m_mutedModel);
mapPropertyFromModel(bool,isSolo,setSolo,m_soloModel);
public:
@@ -109,24 +110,8 @@ public:
return m_autoResize;
}
- QColor color() const
- {
- return m_color;
- }
-
- void setColor( const QColor & c )
- {
- m_color = c;
- }
-
- bool hasColor();
-
- void useCustomClipColor( bool b );
-
- bool usesCustomClipColor()
- {
- return m_useCustomClipColor;
- }
+ auto color() const -> const std::optional& { return m_color; }
+ void setColor(const std::optional& color);
virtual void movePosition( const TimePos & pos );
virtual void changeLength( const TimePos & length );
@@ -164,13 +149,6 @@ signals:
private:
- enum Actions
- {
- NoAction,
- Move,
- Resize
- } ;
-
Track * m_track;
QString m_name;
@@ -184,8 +162,7 @@ private:
bool m_selectViewOnCreate;
- QColor m_color;
- bool m_useCustomClipColor;
+ std::optional m_color;
friend class ClipView;
@@ -194,4 +171,4 @@ private:
} // namespace lmms
-#endif
+#endif // LMMS_CLIP_H
diff --git a/include/ClipView.h b/include/ClipView.h
index 8cfb9e7a4..14898db65 100644
--- a/include/ClipView.h
+++ b/include/ClipView.h
@@ -22,9 +22,10 @@
*
*/
-#ifndef TRACK_CONTENT_OBJECT_VIEW_H
-#define TRACK_CONTENT_OBJECT_VIEW_H
+#ifndef LMMS_GUI_CLIP_VIEW_H
+#define LMMS_GUI_CLIP_VIEW_H
+#include
#include
@@ -140,7 +141,7 @@ public slots:
void resetColor();
protected:
- enum ContextMenuAction
+ enum class ContextMenuAction
{
Remove,
Cut,
@@ -184,6 +185,7 @@ protected:
virtual void paintTextLabel(QString const & text, QPainter & painter);
+ auto hasCustomColor() const -> bool;
protected slots:
void updateLength();
@@ -191,9 +193,9 @@ protected slots:
private:
- enum Actions
+ enum class Action
{
- NoAction,
+ None,
Move,
MoveSelection,
Resize,
@@ -206,7 +208,7 @@ private:
static TextFloat * s_textFloat;
Clip * m_clip;
- Actions m_action;
+ Action m_action;
QPoint m_initialMousePos;
QPoint m_initialMouseGlobalPos;
QVector m_initialOffsets;
@@ -241,7 +243,7 @@ private:
bool mouseMovedDistance( QMouseEvent * me, int distance );
TimePos draggedClipPos( QMouseEvent * me );
int knifeMarkerPos( QMouseEvent * me );
- void setColor(const QColor* color);
+ void setColor(const std::optional& color);
//! Return true iff the clip could be split. Currently only implemented for samples
virtual bool splitClip( const TimePos pos ){ return false; };
void updateCursor(QMouseEvent * me);
@@ -252,4 +254,4 @@ private:
} // namespace lmms
-#endif
+#endif // LMMS_GUI_CLIP_VIEW_H
diff --git a/include/Clipboard.h b/include/Clipboard.h
index 1c2dcb647..cee40b33a 100644
--- a/include/Clipboard.h
+++ b/include/Clipboard.h
@@ -22,11 +22,13 @@
*
*/
-#ifndef CLIPBOARD_H
-#define CLIPBOARD_H
+#ifndef LMMS_CLIPBOARD_H
+#define LMMS_CLIPBOARD_H
-#include
#include
+#include
+
+#include "lmms_export.h"
class QMimeData;
@@ -44,7 +46,7 @@ namespace lmms::Clipboard
bool hasFormat( MimeType mT );
// Helper methods for String data
- void copyString( const QString & str, MimeType mT );
+ void LMMS_EXPORT copyString(const QString& str, MimeType mT);
QString getString( MimeType mT );
// Helper methods for String Pair data
@@ -68,4 +70,4 @@ namespace lmms::Clipboard
} // namespace lmms::Clipboard
-#endif
+#endif // LMMS_CLIPBOARD_H
diff --git a/include/ColorChooser.h b/include/ColorChooser.h
index 5482a9a03..0e85ea9bb 100644
--- a/include/ColorChooser.h
+++ b/include/ColorChooser.h
@@ -21,8 +21,8 @@
*
*/
-#ifndef COLOR_CHOOSER_H
-#define COLOR_CHOOSER_H
+#ifndef LMMS_GUI_COLOR_CHOOSER_H
+#define LMMS_GUI_COLOR_CHOOSER_H
#include
#include
@@ -34,7 +34,7 @@ namespace lmms::gui
{
-class ColorChooser: public QColorDialog
+class ColorChooser : public QColorDialog
{
public:
ColorChooser(const QColor &initial, QWidget *parent): QColorDialog(initial, parent) {};
@@ -68,5 +68,4 @@ private:
} // namespace lmms::gui
-#endif
-
+#endif // LMMS_GUI_COLOR_CHOOSER_H
diff --git a/include/ColorHelper.h b/include/ColorHelper.h
new file mode 100644
index 000000000..78f99b9e2
--- /dev/null
+++ b/include/ColorHelper.h
@@ -0,0 +1,54 @@
+/* ColorHelper.h - Helper methods for color related algorithms, etc.
+ *
+ * Copyright (c) 2024- Michael Gregorius
+ *
+ * This file is part of LMMS - https://lmms.io
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program (see COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef LMMS_GUI_COLOR_HELPER_H
+#define LMMS_GUI_COLOR_HELPER_H
+
+#include
+
+namespace lmms::gui
+{
+
+class ColorHelper
+{
+public:
+ static QColor interpolateInRgb(const QColor& a, const QColor& b, float t)
+ {
+ qreal ar, ag, ab, aa;
+ a.getRgbF(&ar, &ag, &ab, &aa);
+
+ qreal br, bg, bb, ba;
+ b.getRgbF(&br, &bg, &bb, &ba);
+
+ const float interH = lerp(ar, br, t);
+ const float interS = lerp(ag, bg, t);
+ const float interV = lerp(ab, bb, t);
+ const float interA = lerp(aa, ba, t);
+
+ return QColor::fromRgbF(interH, interS, interV, interA);
+ }
+};
+
+} // namespace lmms::gui
+
+#endif // LMMS_GUI_COLOR_HELPER_H
diff --git a/include/ComboBox.h b/include/ComboBox.h
index 9a0e5a517..cc4ad68dd 100644
--- a/include/ComboBox.h
+++ b/include/ComboBox.h
@@ -22,9 +22,8 @@
*
*/
-
-#ifndef COMBOBOX_H
-#define COMBOBOX_H
+#ifndef LMMS_GUI_COMBOBOX_H
+#define LMMS_GUI_COMBOBOX_H
#include
#include
@@ -67,9 +66,9 @@ protected:
private:
- static QPixmap* s_background;
- static QPixmap* s_arrow;
- static QPixmap* s_arrowSelected;
+ QPixmap m_background = embed::getIconPixmap("combobox_bg");
+ QPixmap m_arrow = embed::getIconPixmap("combobox_arrow");
+ QPixmap m_arrowSelected = embed::getIconPixmap("combobox_arrow_selected");
QMenu m_menu;
@@ -83,4 +82,4 @@ private slots:
} // namespace lmms::gui
-#endif
+#endif // LMMS_GUI_COMBOBOX_H
diff --git a/include/ComboBoxModel.h b/include/ComboBoxModel.h
index 0c76620d8..e90d804e2 100644
--- a/include/ComboBoxModel.h
+++ b/include/ComboBoxModel.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef COMBOBOX_MODEL_H
-#define COMBOBOX_MODEL_H
+#ifndef LMMS_COMBOBOX_MODEL_H
+#define LMMS_COMBOBOX_MODEL_H
#include
#include
@@ -72,12 +72,12 @@ public:
const QString & itemText( int i ) const
{
- return m_items[qBound( minValue(), i, maxValue() )].first;
+ return m_items[std::clamp(i, minValue(), maxValue())].first;
}
const PixmapLoader* itemPixmap( int i ) const
{
- return m_items[qBound( minValue(), i, maxValue() )].second.get();
+ return m_items[std::clamp(i, minValue(), maxValue())].second.get();
}
int size() const
@@ -95,4 +95,4 @@ private:
} // namespace lmms
-#endif
+#endif // LMMS_COMBOBOX_MODEL_H
diff --git a/include/ConfigManager.h b/include/ConfigManager.h
index fd2967b6a..f6239c297 100644
--- a/include/ConfigManager.h
+++ b/include/ConfigManager.h
@@ -22,18 +22,17 @@
*
*/
-
-#ifndef CONFIG_MGR_H
-#define CONFIG_MGR_H
+#ifndef LMMS_CONFIG_MANAGER_H
+#define LMMS_CONFIG_MANAGER_H
#include "lmmsconfig.h"
#include
#include
#include
-#include
#include
+#include
#include "lmms_export.h"
@@ -240,11 +239,8 @@ public:
void addRecentlyOpenedProject(const QString & _file);
- const QString & value(const QString & cls,
- const QString & attribute) const;
- const QString & value(const QString & cls,
- const QString & attribute,
- const QString & defaultVal) const;
+ QString value(const QString& cls, const QString& attribute, const QString& defaultVal = "") const;
+
void setValue(const QString & cls, const QString & attribute,
const QString & value);
void deleteValue(const QString & cls, const QString & attribute);
@@ -303,7 +299,7 @@ private:
unsigned int m_configVersion;
QStringList m_recentlyOpenedProjects;
- using stringPairVector = QVector>;
+ using stringPairVector = std::vector>;
using settingsMap = QMap;
settingsMap m_settings;
@@ -314,4 +310,4 @@ private:
} // namespace lmms
-#endif
+#endif // LMMS_CONFIG_MANAGER_H
diff --git a/include/ControlLayout.h b/include/ControlLayout.h
index 8c629f8e1..568ce1a85 100644
--- a/include/ControlLayout.h
+++ b/include/ControlLayout.h
@@ -70,8 +70,8 @@
**
****************************************************************************/
-#ifndef CONTROLLAYOUT_H
-#define CONTROLLAYOUT_H
+#ifndef LMMS_GUI_CONTROL_LAYOUT_H
+#define LMMS_GUI_CONTROL_LAYOUT_H
#include
#include
@@ -141,4 +141,4 @@ private:
} // namespace lmms::gui
-#endif // CONTROLLAYOUT_H
+#endif // LMMS_GUI_CONTROL_LAYOUT_H
diff --git a/include/Controller.h b/include/Controller.h
index d949cf90c..fe78c55cc 100644
--- a/include/Controller.h
+++ b/include/Controller.h
@@ -23,9 +23,8 @@
*
*/
-
-#ifndef CONTROLLER_H
-#define CONTROLLER_H
+#ifndef LMMS_CONTROLLER_H
+#define LMMS_CONTROLLER_H
#include "lmms_export.h"
#include "Engine.h"
@@ -46,26 +45,25 @@ class ControllerDialog;
} // namespace gui
-using ControllerVector = QVector;
+using ControllerVector = std::vector;
class LMMS_EXPORT Controller : public Model, public JournallingObject
{
Q_OBJECT
public:
- enum ControllerTypes
+ enum class ControllerType
{
- DummyController,
- LfoController,
- MidiController,
- PeakController,
+ Dummy,
+ Lfo,
+ Midi,
+ Peak,
/*
- XYController,
- EquationController
+ XY,
+ Equation
*/
- NumControllerTypes
} ;
- Controller( ControllerTypes _type, Model * _parent,
+ Controller( ControllerType _type, Model * _parent,
const QString & _display_name );
~Controller() override;
@@ -84,7 +82,7 @@ public:
m_sampleExact = _exact;
}
- inline ControllerTypes type() const
+ inline ControllerType type() const
{
return( m_type );
}
@@ -95,8 +93,8 @@ public:
{
switch( m_type )
{
- case LfoController: return( true );
- case PeakController: return( true );
+ case ControllerType::Lfo: return( true );
+ case ControllerType::Peak: return( true );
default:
break;
}
@@ -113,13 +111,13 @@ public:
void loadSettings( const QDomElement & _this ) override;
QString nodeName() const override;
- static Controller * create( ControllerTypes _tt, Model * _parent );
+ static Controller * create( ControllerType _tt, Model * _parent );
static Controller * create( const QDomElement & _this,
Model * _parent );
inline static float fittedValue( float _val )
{
- return qBound( 0.0f, _val, 1.0f );
+ return std::clamp(_val, 0.0f, 1.0f);
}
static long runningPeriods()
@@ -166,7 +164,7 @@ protected:
int m_connectionCount;
QString m_name;
- ControllerTypes m_type;
+ ControllerType m_type;
static ControllerVector s_controllers;
@@ -184,5 +182,4 @@ signals:
} // namespace lmms
-#endif
-
+#endif // LMMS_CONTROLLER_H
diff --git a/include/ControllerConnection.h b/include/ControllerConnection.h
index 8230971cc..b60687123 100644
--- a/include/ControllerConnection.h
+++ b/include/ControllerConnection.h
@@ -26,17 +26,17 @@
*
*/
-
-#ifndef CONTROLLER_CONNECTION_H
-#define CONTROLLER_CONNECTION_H
+#ifndef LMMS_CONTROLLER_CONNECTION_H
+#define LMMS_CONTROLLER_CONNECTION_H
#include
-#include
#include "Controller.h"
#include "JournallingObject.h"
#include "ValueBuffer.h"
+#include
+
namespace lmms
{
@@ -47,7 +47,7 @@ namespace gui
class ControllerConnectionDialog;
}
-using ControllerConnectionVector = QVector;
+using ControllerConnectionVector = std::vector;
class LMMS_EXPORT ControllerConnection : public QObject, public JournallingObject
{
@@ -128,5 +128,4 @@ signals:
} // namespace lmms
-#endif
-
+#endif // LMMS_CONTROLLER_CONNECTION_H
diff --git a/include/ControllerConnectionDialog.h b/include/ControllerConnectionDialog.h
index 5565c8a67..6fb9d45d0 100644
--- a/include/ControllerConnectionDialog.h
+++ b/include/ControllerConnectionDialog.h
@@ -23,9 +23,8 @@
*
*/
-
-#ifndef CONTROLLER_CONNECTION_DIALOG_H
-#define CONTROLLER_CONNECTION_DIALOG_H
+#ifndef LMMS_GUI_CONTROLLER_CONNECTION_DIALOG_H
+#define LMMS_GUI_CONTROLLER_CONNECTION_DIALOG_H
#include
#include
@@ -111,4 +110,4 @@ private:
} // namespace lmms
-#endif
+#endif // LMMS_GUI_CONTROLLER_CONNECTION_DIALOG_H
diff --git a/include/ControllerDialog.h b/include/ControllerDialog.h
index 4f496ad77..0c53a8c84 100644
--- a/include/ControllerDialog.h
+++ b/include/ControllerDialog.h
@@ -23,8 +23,8 @@
*
*/
-#ifndef CONTROLLER_DIALOG_H
-#define CONTROLLER_DIALOG_H
+#ifndef LMMS_GUI_CONTROLLER_DIALOG_H
+#define LMMS_GUI_CONTROLLER_DIALOG_H
#include
@@ -61,4 +61,4 @@ protected:
} // namespace lmms
-#endif
+#endif // LMMS_GUI_CONTROLLER_DIALOG_H
diff --git a/include/ControllerRackView.h b/include/ControllerRackView.h
index 904e523dd..303cc2b40 100644
--- a/include/ControllerRackView.h
+++ b/include/ControllerRackView.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef CONTROLLER_RACK_VIEW_H
-#define CONTROLLER_RACK_VIEW_H
+#ifndef LMMS_GUI_CONTROLLER_RACK_VIEW_H
+#define LMMS_GUI_CONTROLLER_RACK_VIEW_H
#include
#include
@@ -92,4 +92,4 @@ private:
} // namespace lmms
-#endif
+#endif // LMMS_GUI_CONTROLLER_RACK_VIEW_H
diff --git a/include/ControllerView.h b/include/ControllerView.h
index 8b8db0674..d1ba533a1 100644
--- a/include/ControllerView.h
+++ b/include/ControllerView.h
@@ -22,8 +22,8 @@
*
*/
-#ifndef CONTROLLER_VIEW_H
-#define CONTROLLER_VIEW_H
+#ifndef LMMS_GUI_CONTROLLER_VIEW_H
+#define LMMS_GUI_CONTROLLER_VIEW_H
#include
@@ -88,4 +88,4 @@ private:
} // namespace lmms::gui
-#endif
+#endif // LMMS_GUI_CONTROLLER_VIEW_H
diff --git a/include/Controls.h b/include/Controls.h
index 9ffed465e..5ed19027e 100644
--- a/include/Controls.h
+++ b/include/Controls.h
@@ -22,10 +22,8 @@
*
*/
-#ifndef CONTROLS_H
-#define CONTROLS_H
-
-
+#ifndef LMMS_GUI_CONTROLS_H
+#define LMMS_GUI_CONTROLS_H
// headers only required for covariance
#include "AutomatableModel.h"
@@ -146,4 +144,4 @@ public:
} // namespace lmms
-#endif // CONTROLS_H
+#endif // LMMS_GUI_CONTROLS_H
diff --git a/include/CustomTextKnob.h b/include/CustomTextKnob.h
index cde718810..31a58415e 100644
--- a/include/CustomTextKnob.h
+++ b/include/CustomTextKnob.h
@@ -1,6 +1,29 @@
-/* Text customizable knob */
-#ifndef CUSTOM_TEXT_KNOB_H
-#define CUSTOM_TEXT_KNOB_H
+/*
+ * CustomTextKnob.h
+ *
+ * Copyright (c) 2020 Ibuki Sugiyama
+ *
+ * This file is part of LMMS - https://lmms.io
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program 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
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program (see COPYING); if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ */
+
+#ifndef LMMS_GUI_CUSTOM_TEXT_KNOB_H
+#define LMMS_GUI_CUSTOM_TEXT_KNOB_H
#include "Knob.h"
@@ -13,7 +36,7 @@ class LMMS_EXPORT CustomTextKnob : public Knob
protected:
inline void setHintText( const QString & _txt_before, const QString & _txt_after ) {} // inaccessible
public:
- CustomTextKnob( knobTypes _knob_num, QWidget * _parent = nullptr, const QString & _name = QString(), const QString & _value_text = QString() );
+ CustomTextKnob( KnobType _knob_num, QWidget * _parent = nullptr, const QString & _name = QString(), const QString & _value_text = QString() );
CustomTextKnob( QWidget * _parent = nullptr, const QString & _name = QString(), const QString & _value_text = QString() ); //!< default ctor
@@ -34,4 +57,4 @@ protected:
} // namespace lmms::gui
-#endif
+#endif // LMMS_GUI_CUSTOM_TEXT_KNOB_H
diff --git a/include/DataFile.h b/include/DataFile.h
index fb8b2ae3e..452481a7f 100644
--- a/include/DataFile.h
+++ b/include/DataFile.h
@@ -23,15 +23,14 @@
*
*/
-
-#ifndef DATA_FILE_H
-#define DATA_FILE_H
+#ifndef LMMS_DATA_FILE_H
+#define LMMS_DATA_FILE_H
#include
#include
+#include
#include "lmms_export.h"
-#include "MemoryManager.h"
class QTextStream;
@@ -43,14 +42,13 @@ class ProjectVersion;
class LMMS_EXPORT DataFile : public QDomDocument
{
- MM_OPERATORS
using UpgradeMethod = void(DataFile::*)();
public:
- enum Types
+ enum class Type
{
- UnknownType,
+ Unknown,
SongProject,
SongProjectTemplate,
InstrumentTrackSettings,
@@ -58,10 +56,8 @@ public:
ClipboardData,
JournalData,
EffectSettings,
- MidiClip,
- TypeCount
+ MidiClip
} ;
- using Type = Types;
DataFile( const QString& fileName );
DataFile( const QByteArray& data );
@@ -129,6 +125,11 @@ private:
void upgrade_defaultTripleOscillatorHQ();
void upgrade_mixerRename();
void upgrade_bbTcoRename();
+ void upgrade_sampleAndHold();
+ void upgrade_midiCCIndexing();
+ void upgrade_loopsRename();
+ void upgrade_noteTypes();
+ void upgrade_fixCMTDelays();
// List of all upgrade methods
static const std::vector UPGRADE_METHODS;
@@ -148,10 +149,9 @@ private:
QDomElement m_head;
Type m_type;
unsigned int m_fileVersion;
-
} ;
} // namespace lmms
-#endif
+#endif // LMMS_DATA_FILE_H
diff --git a/include/Delay.h b/include/Delay.h
index 529577d58..71fbe1b00 100644
--- a/include/Delay.h
+++ b/include/Delay.h
@@ -22,15 +22,13 @@
* Boston, MA 02110-1301 USA.
*
*/
-
-
-#ifndef DELAY_H
-#define DELAY_H
+
+#ifndef LMMS_DELAY_H
+#define LMMS_DELAY_H
#include "lmms_basics.h"
#include "lmms_math.h"
#include "interpolation.h"
-#include "MemoryManager.h"
namespace lmms
{
@@ -75,20 +73,20 @@ public:
m_delay( 0 ),
m_fraction( 0.0 )
{
- m_buffer = MM_ALLOC (maxDelay );
+ m_buffer = new frame[maxDelay];
memset( m_buffer, 0, sizeof( frame ) * maxDelay );
}
virtual ~CombFeedback()
{
- MM_FREE( m_buffer );
+ delete[] m_buffer;
}
inline void setMaxDelay( int maxDelay )
{
if( maxDelay > m_size )
{
- MM_FREE( m_buffer );
- m_buffer = MM_ALLOC ( maxDelay );
+ delete[] m_buffer;
+ m_buffer = new frame[maxDelay];
memset( m_buffer, 0, sizeof( frame ) * maxDelay );
}
m_size = maxDelay;
@@ -146,20 +144,20 @@ class CombFeedfwd
m_delay( 0 ),
m_fraction( 0.0 )
{
- m_buffer = MM_ALLOC ( maxDelay );
+ m_buffer = new frame[maxDelay];
memset( m_buffer, 0, sizeof( frame ) * maxDelay );
}
virtual ~CombFeedfwd()
{
- MM_FREE( m_buffer );
+ delete[] m_buffer;
}
inline void setMaxDelay( int maxDelay )
{
if( maxDelay > m_size )
{
- MM_FREE( m_buffer );
- m_buffer = MM_ALLOC ( maxDelay );
+ delete[] m_buffer;
+ m_buffer = new frame[maxDelay];
memset( m_buffer, 0, sizeof( frame ) * maxDelay );
}
m_size = maxDelay;
@@ -217,20 +215,20 @@ class CombFeedbackDualtap
m_delay( 0 ),
m_fraction( 0.0 )
{
- m_buffer = MM_ALLOC ( maxDelay );
+ m_buffer = new frame[maxDelay];
memset( m_buffer, 0, sizeof( frame ) * maxDelay );
}
virtual ~CombFeedbackDualtap()
{
- MM_FREE( m_buffer );
+ delete[] m_buffer;
}
inline void setMaxDelay( int maxDelay )
{
if( maxDelay > m_size )
{
- MM_FREE( m_buffer );
- m_buffer = MM_ALLOC ( maxDelay );
+ delete[] m_buffer;
+ m_buffer = new frame[maxDelay];
memset( m_buffer, 0, sizeof( frame ) * maxDelay );
}
m_size = maxDelay;
@@ -298,20 +296,20 @@ public:
m_delay( 0 ),
m_fraction( 0.0 )
{
- m_buffer = MM_ALLOC ( maxDelay );
+ m_buffer = new frame[maxDelay];
memset( m_buffer, 0, sizeof( frame ) * maxDelay );
}
virtual ~AllpassDelay()
{
- MM_FREE( m_buffer );
+ delete[] m_buffer;
}
inline void setMaxDelay( int maxDelay )
{
if( maxDelay > m_size )
{
- MM_FREE( m_buffer );
- m_buffer = MM_ALLOC ( maxDelay );
+ delete[] m_buffer;
+ m_buffer = new frame[maxDelay];
memset( m_buffer, 0, sizeof( frame ) * maxDelay );
}
m_size = maxDelay;
@@ -365,4 +363,4 @@ using StereoAllpassDelay = AllpassDelay<2>;
} // namespace lmms
-#endif
+#endif // LMMS_DELAY_H
diff --git a/include/DeprecationHelper.h b/include/DeprecationHelper.h
index 7786665a3..b9be6d42f 100644
--- a/include/DeprecationHelper.h
+++ b/include/DeprecationHelper.h
@@ -24,8 +24,8 @@
*
*/
-#ifndef DEPRECATIONHELPER_H
-#define DEPRECATIONHELPER_H
+#ifndef LMMS_DEPRECATIONHELPER_H
+#define LMMS_DEPRECATIONHELPER_H
#include
#include
@@ -66,4 +66,4 @@ inline QPoint position(QWheelEvent *wheelEvent)
} // namespace lmms
-#endif // DEPRECATIONHELPER_H
+#endif // LMMS_DEPRECATIONHELPER_H
diff --git a/include/DetuningHelper.h b/include/DetuningHelper.h
index f90af3697..da8eb5983 100644
--- a/include/DetuningHelper.h
+++ b/include/DetuningHelper.h
@@ -23,11 +23,10 @@
*
*/
-#ifndef DETUNING_HELPER_H
-#define DETUNING_HELPER_H
+#ifndef LMMS_DETUNING_HELPER_H
+#define LMMS_DETUNING_HELPER_H
#include "InlineAutomation.h"
-#include "MemoryManager.h"
namespace lmms
{
@@ -35,7 +34,6 @@ namespace lmms
class DetuningHelper : public InlineAutomation
{
Q_OBJECT
- MM_OPERATORS
public:
DetuningHelper() :
InlineAutomation()
@@ -64,4 +62,4 @@ public:
} // namespace lmms
-#endif
+#endif // LMMS_DETUNING_HELPER_H
diff --git a/include/DrumSynth.h b/include/DrumSynth.h
index 98574f2d2..750055ddb 100644
--- a/include/DrumSynth.h
+++ b/include/DrumSynth.h
@@ -23,9 +23,8 @@
*
*/
-
-#ifndef DRUMSYNTH_H
-#define DRUMSYNTH_H
+#ifndef LMMS_DRUM_SYNTH_H
+#define LMMS_DRUM_SYNTH_H
#include
#include "lmms_basics.h"
@@ -57,4 +56,4 @@ class DrumSynth {
} // namespace lmms
-#endif // DRUMSYNTH_H
+#endif // LMMS_DRUM_SYNTH_H
diff --git a/include/DspEffectLibrary.h b/include/DspEffectLibrary.h
index eb03e1cf0..14dbd7ede 100644
--- a/include/DspEffectLibrary.h
+++ b/include/DspEffectLibrary.h
@@ -22,9 +22,8 @@
*
*/
-
-#ifndef DSP_EFFECT_LIBRARY_H
-#define DSP_EFFECT_LIBRARY_H
+#ifndef LMMS_DSPEFFECTLIBRARY_H
+#define LMMS_DSPEFFECTLIBRARY_H
#include "lmms_math.h"
#include "lmms_constants.h"
@@ -188,7 +187,7 @@ namespace lmms::DspEffectLibrary
template
inline sample_t saturate( sample_t x )
{
- return qMin( qMax( -1.0f, x ), 1.0f );
+ return std::min(std::max(-1.0f, x), 1.0f);
}
@@ -199,7 +198,7 @@ namespace lmms::DspEffectLibrary
const sample_t _gain,
const sample_t _ratio,
const FastBassBoost & _orig = FastBassBoost() ) :
- m_frequency( qMax