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..b80d5df75 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -8,21 +8,18 @@ jobs:
linux:
name: linux
runs-on: ubuntu-latest
- container: lmmsci/linux.gcc:18.04
+ container: ghcr.io/lmms/linux.gcc:20.04
env:
CMAKE_OPTS: >-
-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
- run: |
- add-apt-repository ppa:git-core/ppa
- apt-get update
- apt-get --yes install git
- git config --global --add safe.directory "$GITHUB_WORKSPACE"
+ - name: Configure git
+ run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Check out
uses: actions/checkout@v3
with:
@@ -38,47 +35,72 @@ 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
cmake --build build --target appimage
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
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 --show-config
echo "[ccache stats]"
- ccache -s
+ ccache --show-stats
+ env:
+ CCACHE_MAXSIZE: 500M
macos:
- name: macos
- runs-on: macos-11
+ strategy:
+ fail-fast: false
+ matrix:
+ arch: [ x86_64, arm64 ]
+ include:
+ - arch: x86_64
+ os: macos-12
+ xcode: "13.1"
+ - arch: arm64
+ os: macos-14
+ xcode: "14.3.1"
+ name: macos-${{ matrix.arch }}
+ runs-on: ${{ matrix.os }}
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_${{ matrix.xcode }}.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,40 +111,53 @@ 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 \
-DCMAKE_INSTALL_PREFIX="../target" \
- -DCMAKE_PREFIX_PATH="$(brew --prefix qt5)" \
+ -DCMAKE_PREFIX_PATH="$(brew --prefix qt@5)" \
+ -DCMAKE_OSX_ARCHITECTURES=${{ matrix.arch }} \
$CMAKE_OPTS \
-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
cmake --build build --target dmg
- name: Upload artifacts
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
with:
- name: macos
+ name: macos-${{ matrix.arch }}
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
@@ -130,21 +165,18 @@ jobs:
arch: ['32', '64']
name: mingw${{ matrix.arch }}
runs-on: ubuntu-latest
- container: lmmsci/linux.mingw${{ matrix.arch }}:18.04
+ container: ghcr.io/lmms/linux.mingw:20.04
env:
CMAKE_OPTS: >-
-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
- run: |
- add-apt-repository ppa:git-core/ppa
- apt-get update
- apt-get --yes install git
- git config --global --add safe.directory "$GITHUB_WORKSPACE"
+ - name: Configure git
+ run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Check out
uses: actions/checkout@v3
with:
@@ -161,25 +193,27 @@ 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
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
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 --show-config
echo "[ccache stats]"
- ccache -s
+ ccache --show-stats
+ env:
+ CCACHE_MAXSIZE: 500M
msvc:
strategy:
fail-fast: false
@@ -188,7 +222,8 @@ jobs:
name: msvc-${{ matrix.arch }}
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,57 +231,78 @@ 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
- - name: Install 64-bit Qt
- if: matrix.arch == 'x64'
- uses: jurplel/install-qt-action@64bdb64f2c14311d23733a8463e5fcbc65e8775e
+ path: build\vcpkg_installed
+ - name: Cache ccache data
+ uses: actions/cache@v3
with:
- version: ${{ env.qt-version }}
- arch: win64_msvc2019_64
+ 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 Qt
+ uses: jurplel/install-qt-action@b3ea5275e37b734d027040e2c7fe7a10ea2ef946
+ with:
+ version: '5.15.2'
+ arch: |-
+ ${{
+ fromJSON('
+ {
+ "x86": "win32_msvc2019",
+ "x64": "win64_msvc2019_64"
+ }
+ ')[matrix.arch]
+ }}
archives: qtbase qtsvg qttools
cache: true
- - name: Install 32-bit Qt
- uses: jurplel/install-qt-action@64bdb64f2c14311d23733a8463e5fcbc65e8775e
- 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
- uses: actions/upload-artifact@v3
+ uses: actions/upload-artifact@v4
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/.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 fa6980ac5..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
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 0b6d3b4ff..1da10775b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,20 +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})
-# CMAKE_POLICY Section
-IF(COMMAND CMAKE_POLICY)
- # TODO: Keep CMP0074 but remove this condition when cmake 3.12+ is guaranteed
- IF(${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.12)
- # Needed for the SWH Ladspa plugins. See below.
- CMAKE_POLICY(SET CMP0074 NEW) # find_package() uses _ROOT variables
- ENDIF()
-ENDIF(COMMAND CMAKE_POLICY)
-
# Import of windows.h breaks min()/max()
ADD_DEFINITIONS(-DNOMINMAX)
@@ -35,7 +46,7 @@ INCLUDE(GenerateExportHeader)
STRING(TOUPPER "${CMAKE_PROJECT_NAME}" PROJECT_NAME_UCASE)
-SET(PROJECT_YEAR 2023)
+SET(PROJECT_YEAR 2024)
SET(PROJECT_AUTHOR "LMMS Developers")
SET(PROJECT_URL "https://lmms.io")
@@ -60,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)
@@ -82,8 +94,8 @@ 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)
@@ -98,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)
@@ -110,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 "")
@@ -126,16 +145,6 @@ ELSE(LMMS_BUILD_WIN32)
SET(STATUS_WINMM "")
ENDIF(LMMS_BUILD_WIN32)
-
-# TODO: Fix linking issues with msys debug builds
-IF(LMMS_BUILD_MSYS AND CMAKE_BUILD_TYPE STREQUAL "Debug")
- SET(WANT_GIG OFF)
- SET(WANT_STK OFF)
- SET(WANT_SWH OFF)
- SET(STATUS_GIG "not built as requested")
- SET(STATUS_STK "not built as requested")
-ENDIF()
-
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
CHECK_INCLUDE_FILES(pthread.h LMMS_HAVE_PTHREAD_H)
@@ -160,7 +169,7 @@ check_library_exists(rt shm_open "" LMMS_HAVE_LIBRT)
LIST(APPEND CMAKE_PREFIX_PATH "${CMAKE_INSTALL_PREFIX}")
-FIND_PACKAGE(Qt5 5.6.0 COMPONENTS Core Gui Widgets Xml REQUIRED)
+FIND_PACKAGE(Qt5 5.9.0 COMPONENTS Core Gui Widgets Xml REQUIRED)
FIND_PACKAGE(Qt5 COMPONENTS LinguistTools QUIET)
INCLUDE_DIRECTORIES(
@@ -201,7 +210,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
@@ -428,8 +444,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")
@@ -448,13 +462,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
@@ -524,7 +538,7 @@ 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)
if(FluidSynth_VERSION_STRING VERSION_GREATER_EQUAL 2)
@@ -566,26 +580,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)
@@ -615,6 +645,7 @@ IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
ENDIF()
ELSEIF(MSVC)
# Remove any existing /W flags
+ string(REGEX REPLACE "/W[0-4]" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS})
STRING(REGEX REPLACE "/W[0-4]" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
SET(WERROR_FLAGS "/W2")
IF(${USE_WERROR})
@@ -831,8 +862,9 @@ MESSAGE(
"* 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"
diff --git a/cmake/apple/CMakeLists.txt b/cmake/apple/CMakeLists.txt
index 0b66689e7..3fd0a4da4 100644
--- a/cmake/apple/CMakeLists.txt
+++ b/cmake/apple/CMakeLists.txt
@@ -19,8 +19,19 @@ CONFIGURE_FILE("lmms.plist.in" "${CMAKE_BINARY_DIR}/Info.plist")
CONFIGURE_FILE("install_apple.sh.in" "${CMAKE_BINARY_DIR}/install_apple.sh" @ONLY)
CONFIGURE_FILE("package_apple.json.in" "${CMAKE_BINARY_DIR}/package_apple.json" @ONLY)
+IF(CMAKE_OSX_ARCHITECTURES)
+ SET(DMG_ARCH "${CMAKE_OSX_ARCHITECTURES}")
+ELSEIF(IS_ARM64)
+ # Target arch is host arch
+ SET(DMG_ARCH "arm64")
+ELSE()
+ # Fallback to Intel
+ SET(DMG_ARCH "x86_64")
+ENDIF()
+
# DMG creation target
-SET(DMG_FILE "${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}-${VERSION}-mac${APPLE_OS_VER}.dmg")
+SET(DMG_FILE "${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}-${VERSION}-mac${APPLE_OS_VER}-${DMG_ARCH}.dmg")
+
FILE(REMOVE "${DMG_FILE}")
ADD_CUSTOM_TARGET(removedmg
COMMAND touch "\"${DMG_FILE}\"" && rm "\"${DMG_FILE}\""
diff --git a/cmake/build_win32.sh b/cmake/build_win32.sh
index 33cd8ecce..bccda3a48 100755
--- a/cmake/build_win32.sh
+++ b/cmake/build_win32.sh
@@ -31,7 +31,7 @@ fi
export PATH=$MINGW/bin:$PATH
export CXXFLAGS="$CFLAGS"
if [ "$ARCH" == "32" ]; then
- export CFLAGS="-march=pentium3 -mtune=generic -mpreferred-stack-boundary=5 -mfpmath=sse"
+ export CFLAGS="-march=pentium4 -mtune=generic -mpreferred-stack-boundary=5 -mfpmath=sse"
fi
CMAKE_OPTS="-DCMAKE_PREFIX_PATH=$MINGW $CMAKE_OPTS"
diff --git a/cmake/install/excludelist-win b/cmake/install/excludelist-win
index 17793a113..ac3c47901 100644
--- a/cmake/install/excludelist-win
+++ b/cmake/install/excludelist-win
@@ -3,17 +3,21 @@
ADVAPI32.dll
COMCTL32.dll
comdlg32.dll
+d3d11.dll
dwmapi.dll
+dxgi.dll
GDI32.dll
IMM32.dll
KERNEL32.dll
MPR.DLL
msvcrt.dll
+netapi32.dll
ole32.dll
OLEAUT32.dll
OPENGL32.DLL
SHELL32.dll
USER32.dll
+userenv.dll
UxTheme.dll
VERSION.dll
WINMM.DLL
diff --git a/cmake/modules/BuildPlugin.cmake b/cmake/modules/BuildPlugin.cmake
index f8b3d3153..aaccd3c4b 100644
--- a/cmake/modules/BuildPlugin.cmake
+++ b/cmake/modules/BuildPlugin.cmake
@@ -1,12 +1,12 @@
# BuildPlugin.cmake - Copyright (c) 2008 Tobias Doerffel
#
# description: build LMMS-plugin
-# usage: BUILD_PLUGIN( MOCFILES EMBEDDED_RESOURCES UICFILES LINK )
+# usage: BUILD_PLUGIN( MOCFILES EMBEDDED_RESOURCES LINK )
INCLUDE(GenQrc)
MACRO(BUILD_PLUGIN PLUGIN_NAME)
- CMAKE_PARSE_ARGUMENTS(PLUGIN "" "LINK;EXPORT_BASE_NAME" "MOCFILES;EMBEDDED_RESOURCES;UICFILES" ${ARGN})
+ CMAKE_PARSE_ARGUMENTS(PLUGIN "" "LINK;EXPORT_BASE_NAME" "MOCFILES;EMBEDDED_RESOURCES" ${ARGN})
SET(PLUGIN_SOURCES ${PLUGIN_UNPARSED_ARGUMENTS})
INCLUDE_DIRECTORIES("${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}/include")
@@ -31,10 +31,9 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME)
ENDIF(ER_LEN)
QT5_WRAP_CPP(plugin_MOC_out ${PLUGIN_MOCFILES})
- QT5_WRAP_UI(plugin_UIC_out ${PLUGIN_UICFILES})
FOREACH(f ${PLUGIN_SOURCES})
- ADD_FILE_DEPENDENCIES(${f} ${RCC_OUT} ${plugin_UIC_out})
+ ADD_FILE_DEPENDENCIES(${f} ${RCC_OUT})
ENDFOREACH(f)
IF(LMMS_BUILD_APPLE)
@@ -45,10 +44,6 @@ MACRO(BUILD_PLUGIN PLUGIN_NAME)
LINK_DIRECTORIES("${CMAKE_BINARY_DIR}" "${CMAKE_SOURCE_DIR}")
LINK_LIBRARIES(${QT_LIBRARIES})
ENDIF(LMMS_BUILD_WIN32)
- IF(LMMS_BUILD_MSYS AND CMAKE_BUILD_TYPE STREQUAL "Debug")
- # Override Qt debug libraries with release versions
- SET(QT_LIBRARIES "${QT_OVERRIDE_LIBRARIES}")
- ENDIF()
IF (NOT PLUGIN_LINK)
SET(PLUGIN_LINK "MODULE")
@@ -56,11 +51,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 +61,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/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/DetectMachine.cmake b/cmake/modules/DetectMachine.cmake
index 388efeb82..b9aa4c8c6 100644
--- a/cmake/modules/DetectMachine.cmake
+++ b/cmake/modules/DetectMachine.cmake
@@ -12,11 +12,6 @@ ELSE()
SET(LMMS_BUILD_LINUX 1)
ENDIF(WIN32)
-# LMMS_BUILD_MSYS also set in build_winXX.sh
-IF(LMMS_BUILD_WIN32 AND CMAKE_COMPILER_IS_GNUCXX AND DEFINED ENV{MSYSCON})
- SET(LMMS_BUILD_MSYS TRUE)
-ENDIF()
-
MESSAGE("PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
SET(LMMS_HOST_X86 FALSE)
SET(LMMS_HOST_X86_64 FALSE)
@@ -92,7 +87,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/FindSDL2.cmake b/cmake/modules/FindSDL2.cmake
index 3bad1002e..6e07f7aff 100644
--- a/cmake/modules/FindSDL2.cmake
+++ b/cmake/modules/FindSDL2.cmake
@@ -33,6 +33,18 @@
find_package(SDL2 CONFIG QUIET)
if(TARGET SDL2::SDL2)
+ # SDL2::SDL2 under MinGW is an interface target for reasons, so we can't get
+ # the library location from it. Print minimal information and return early.
+ get_target_property(sdl2_target_type SDL2::SDL2 TYPE)
+ if(sdl2_target_type STREQUAL "INTERFACE_LIBRARY")
+ unset(sdl2_target_type)
+ if(NOT SDL2_FIND_QUIETLY)
+ message(STATUS "Found SDL2 (found version \"${SDL2_VERSION}\")")
+ endif()
+ return()
+ endif()
+ unset(sdl2_target_type)
+
# Extract details for find_package_handle_standard_args
get_target_property(SDL2_LIBRARY SDL2::SDL2 LOCATION)
get_target_property(SDL2_INCLUDE_DIR SDL2::SDL2 INTERFACE_INCLUDE_DIRECTORIES)
diff --git a/cmake/modules/FindSTK.cmake b/cmake/modules/FindSTK.cmake
index 0718f5039..5564d24f8 100644
--- a/cmake/modules/FindSTK.cmake
+++ b/cmake/modules/FindSTK.cmake
@@ -1,39 +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()
-# find STK rawwave path
-find_path(STK_RAWWAVE_ROOT
- NAMES silence.raw sinewave.raw
- HINTS "${STK_INCLUDE_DIR}/.."
- PATH_SUFFIXES share/stk/rawwaves share/libstk/rawwaves
-)
-
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..19a0cffbb 100644
--- a/cmake/modules/FindWine.cmake
+++ b/cmake/modules/FindWine.cmake
@@ -2,8 +2,15 @@
# Once done this will define
#
# WINE_FOUND - System has wine
-# WINE_INCLUDE_DIRS - The wine include directories
-# WINE_DEFINITIONS - Compiler switches required for using wine
+#
+# WINE_INCLUDE_DIR - Wine include directory
+# WINE_BUILD - Path to winebuild
+# WINE_CXX - Path to wineg++
+# WINE_GCC - Path to winegcc
+# WINE_32_LIBRARY_DIRS - Path(s) to 32-bit wine libs
+# WINE_32_FLAGS - 32-bit linker flags
+# WINE_64_LIBRARY_DIRS - Path(s) to 64-bit wine libs
+# WINE_64_FLAGS - 64-bit linker flags
#
MACRO(_findwine_find_flags output expression result)
@@ -23,17 +30,49 @@ MACRO(_regex_replace_foreach EXPRESSION REPLACEMENT RESULT INPUT)
ENDFOREACH()
ENDMACRO()
-LIST(APPEND CMAKE_PREFIX_PATH /opt/wine-stable /opt/wine-devel /opt/wine-staging /usr/lib/wine/)
+# Prefer newest wine first
+list(APPEND WINE_LOCATIONS
+ /opt/wine-staging
+ /opt/wine-devel
+ /opt/wine-stable
+ /usr/lib/wine)
-FIND_PROGRAM(WINE_CXX
- NAMES wineg++ winegcc winegcc64 winegcc32 winegcc-stable
- PATHS /usr/lib/wine
+# Prepare bin search
+foreach(_loc ${WINE_LOCATIONS})
+ if(_loc STREQUAL /usr/lib/wine)
+ # /usr/lib/wine doesn't have a "bin"
+ list(APPEND WINE_CXX_LOCATIONS "${_loc}")
+ else()
+ # expect "bin"
+ list(APPEND WINE_CXX_LOCATIONS "${_loc}/bin")
+ endif()
+endforeach()
+# Fallback
+list(APPEND WINE_CXX_LOCATIONS "/usr/bin")
+
+# Prefer most-common to least common
+FIND_PROGRAM(WINE_CXX NAMES
+ wineg++
+ wineg++-stable
+ PATHS
+ ${WINE_CXX_LOCATIONS}
+ NO_DEFAULT_PATH
)
-FIND_PROGRAM(WINE_BUILD NAMES winebuild)
+
+FIND_PROGRAM(WINE_GCC NAMES
+ winegcc
+ winegcc-stable
+ PATHS
+ ${WINE_CXX_LOCATIONS}
+ NO_DEFAULT_PATH
+)
+
+FIND_PROGRAM(WINE_BUILD NAMES winebuild PATHS ${WINE_CXX_LOCATIONS} NO_DEFAULT_PATH)
# 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)
+ # call wineg++ to obtain implied includes and libs
+ execute_process(COMMAND ${WINE_CXX} -m32 -v /dev/zero OUTPUT_VARIABLE WINEBUILD_OUTPUT_32 ERROR_QUIET)
+ execute_process(COMMAND ${WINE_CXX} -m64 -v /dev/zero OUTPUT_VARIABLE WINEBUILD_OUTPUT_64 ERROR_QUIET)
_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)
@@ -42,6 +81,9 @@ IF(WINE_CXX)
_regex_replace_foreach("/wine/windows$" "" WINE_INCLUDE_HINT "${WINE_INCLUDE_HINT}")
STRING(REGEX REPLACE "wine/libwinecrt0\\.a.*" "" WINE_32_LIBRARY_DIR "${WINECRT_32}")
STRING(REGEX REPLACE "wine/libwinecrt0\\.a.*" "" WINE_64_LIBRARY_DIR "${WINECRT_64}")
+ # Handle winehq
+ STRING(REGEX REPLACE "/libwinecrt0\\.a.*" "/" WINE_32_LIBRARY_DIR "${WINE_32_LIBRARY_DIR}")
+ STRING(REGEX REPLACE "/libwinecrt0\\.a.*" "/" WINE_64_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}")
IF(BUGGED_WINEGCC)
MESSAGE(WARNING "Your winegcc is unusable due to https://bugs.winehq.org/show_bug.cgi?id=46293,\n
@@ -98,7 +140,11 @@ find_package_handle_standard_args(Wine DEFAULT_MSG WINE_CXX WINE_INCLUDE_DIRS)
mark_as_advanced(WINE_INCLUDE_DIR WINE_LIBRARY WINE_CXX WINE_BUILD)
IF(WINE_32_LIBRARY_DIR)
- IF(WINE_32_LIBRARY_DIR MATCHES "wine*/lib")
+ IF(WINE_32_LIBRARY_DIR MATCHES "^/opt/wine-.*")
+ # winehq uses a singular lib directory
+ SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR}")
+ SET(WINE_32_LIBRARY_DIRS "${WINE_32_LIBRARY_DIR}")
+ ELSEIF(WINE_32_LIBRARY_DIR MATCHES "wine*/lib")
SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR} -L${WINE_32_LIBRARY_DIR}../")
SET(WINE_32_LIBRARY_DIRS "${WINE_32_LIBRARY_DIR}:${WINE_32_LIBRARY_DIR}/..")
ELSE()
@@ -108,7 +154,11 @@ IF(WINE_32_LIBRARY_DIR)
ENDIF()
IF(WINE_64_LIBRARY_DIR)
- IF(WINE_64_LIBRARY_DIR MATCHES "wine*/lib")
+ IF(WINE_32_LIBRARY_DIR MATCHES "^/opt/wine-.*")
+ # winehq uses a singular lib directory
+ SET(WINE_64_FLAGS "-L${WINE_64_LIBRARY_DIR}")
+ SET(WINE_64_LIBRARY_DIRS "${WINE_64_LIBRARY_DIR}")
+ ELSEIF(WINE_64_LIBRARY_DIR MATCHES "wine*/lib")
SET(WINE_64_FLAGS "-L${WINE_64_LIBRARY_DIR} -L${WINE_64_LIBRARY_DIR}../")
SET(WINE_64_LIBRARY_DIRS "${WINE_64_LIBRARY_DIR}:${WINE_64_LIBRARY_DIR}/..")
ELSE()
@@ -117,6 +167,12 @@ IF(WINE_64_LIBRARY_DIR)
ENDIF()
ENDIF()
-# Create winegcc wrapper
+message(STATUS " WINE_INCLUDE_DIR: ${WINE_INCLUDE_DIR}")
+message(STATUS " WINE_CXX: ${WINE_CXX}")
+message(STATUS " WINE_GCC: ${WINE_GCC}")
+message(STATUS " WINE_32_FLAGS: ${WINE_32_FLAGS}")
+message(STATUS " WINE_64_FLAGS: ${WINE_64_FLAGS}")
+
+# Create winegcc (technically, wineg++) wrapper
configure_file(${CMAKE_CURRENT_LIST_DIR}/winegcc_wrapper.in winegcc_wrapper @ONLY)
SET(WINEGCC "${CMAKE_CURRENT_BINARY_DIR}/winegcc_wrapper")
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 167a93f35..29e5b207c 100644
--- a/cmake/modules/InstallDependencies.cmake
+++ b/cmake/modules/InstallDependencies.cmake
@@ -1,7 +1,8 @@
include(GetPrerequisites)
include(CMakeParseArguments)
-# Project's cmake_minimum_required doesn't always propagate
+# 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)
@@ -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 0a4686fb2..8b26d4ed5 100644
--- a/cmake/modules/PluginList.cmake
+++ b/cmake/modules/PluginList.cmake
@@ -41,6 +41,7 @@ SET(LMMS_PLUGIN_LIST
HydrogenImport
LadspaBrowser
LadspaEffect
+ LOMM
Lv2Effect
Lv2Instrument
Lb302
@@ -59,6 +60,7 @@ SET(LMMS_PLUGIN_LIST
Sf2Player
Sfxr
Sid
+ SlicerT
SpectrumAnalyzer
StereoEnhancer
StereoMatrix
@@ -98,12 +100,3 @@ IF(LIST_PLUGINS)
UNSET(LIST_PLUGINS CACHE)
LIST_ALL_PLUGINS()
ENDIF()
-
-IF(MSVC)
- SET(MSVC_INCOMPATIBLE_PLUGINS
- LadspaEffect
- )
- message(WARNING "Compiling with MSVC. The following plugins are not available: ${MSVC_INCOMPATIBLE_PLUGINS}")
- LIST(REMOVE_ITEM PLUGIN_LIST ${MSVC_INCOMPATIBLE_PLUGINS})
-ENDIF()
-
diff --git a/cmake/msys/extract_debs.sh b/cmake/msys/extract_debs.sh
deleted file mode 100644
index 939912bb2..000000000
--- a/cmake/msys/extract_debs.sh
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-set -e
-
-ppa_dir=./ppa/
-
-pushd $ppa_dir
-
-for f in *.deb; do
- echo "Extracting $f..."
- ar xv "$f"
- rm debian-binary
- rm control.tar.*
- tar xf data.tar.* --exclude=*mingw*/bin/fluid
- rm data.tar.*
-done
-
-popd
-
-echo "Your extracted files should be located in $ppa_dir"
diff --git a/cmake/msys/fetch_ppa.sh b/cmake/msys/fetch_ppa.sh
deleted file mode 100644
index ba8697c81..000000000
--- a/cmake/msys/fetch_ppa.sh
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/bin/bash
-
-# Trusty=14.04, Precise=12.04
-PPA_DISTRO=trusty
-
-# Architecture=i386, amd64
-PPA_ARCH=amd64
-
-# These shouldn't change
-PPA_HOST=http://ppa.launchpad.net
-PPA_USER=tobydox
-PPA_PROJECT=mingw-x-trusty
-PPA_ROOT=$PPA_HOST/$PPA_USER/$PPA_PROJECT/ubuntu
-
-PPA_URL=$PPA_ROOT/dists/$PPA_DISTRO/main/binary-$PPA_ARCH/Packages.gz
-
-ppa_dir=./ppa/
-
-temp_file=/tmp/ppa_listing_$$
-temp_temp_file=/tmp/ppa_listing_temp_$$
-
-skip_files="binutils openssl flac libgig libogg libvorbis x-bootstrap zlib"
-skip_files="$skip_files x-runtime gcc qt_4 qt5 x-stk pkgconfig"
-skip_files="$skip_files glib2 libpng"
-
-echo "Connecting to $PPA_URL to get list of packages..."
-wget -qO- $PPA_URL | gzip -d -c | grep "Filename:" > $temp_file
-
-for j in $skip_files ; do
- grep -v "$j" $temp_file > $temp_temp_file
- mv $temp_temp_file $temp_file
-done
-
-line_count=$(wc -l $temp_file |awk '{print $1}')
-
-echo "Found $line_count packages for download..."
-
-echo "Downloading packages. They will be saved to $ppa_dir"
-
-mkdir $ppa_dir
-
-while read -r j
-do
- echo "Downloading $j..."
- echo "$PPA_ROOT/$j"
- wget -qO "$ppa_dir$(basename "$j")" "$(echo "$PPA_ROOT/$j" | sed 's/\/Filename: /\//gi')"
-done < $temp_file
-
-
-echo "Cleaning up temporary files..."
-rm -rf $temp_file
-
-echo "Packages have been saved to $ppa_dir. Please run extract_debs.sh"
diff --git a/cmake/msys/msys_helper.sh b/cmake/msys/msys_helper.sh
deleted file mode 100644
index a6a7e6aae..000000000
--- a/cmake/msys/msys_helper.sh
+++ /dev/null
@@ -1,226 +0,0 @@
-#!/bin/bash
-
-set -eu
-
-# Git repo information
-fork="lmms" # i.e. "lmms" or "tobydox"
-branch="master" # i.e. "master" or "stable-1.2"
-
-# Console colors
-red="\\x1B[1;31m"
-green="\\x1B[1;32m"
-yellow="\\x1B[1;33m"
-plain="\\x1B[0m"
-
-function info() { echo -e "\n${green}$1${plain}"; }
-function warn() { echo -e "\n${yellow}$1${plain}"; }
-function err() { echo -e "\n${red}$1${plain}"; exit 1;}
-
-info "Checking for mingw environment"
-if ! env | grep MINGW; then
- err " - Failed. Please relaunch using MinGW shell"
-fi
-
-info "Preparing the git directory..."
-mkdir "$HOME/.git" || true
-touch "$HOME/.git/config" > /dev/null 2>&1
-git config --global http.sslverify false
-
-info "Cloning the repository..."
-if [ -d ./lmms ]; then
- warn " - Skipping, ./lmms already exists"
-else
- git clone -b $branch https://github.com/$fork/lmms.git
-fi
-
-info "Fetching ppa using cmake/msys/fetch_ppas.sh..."
-if [ -d "$HOME/ppa" ]; then
- warn " - Skipping, $HOME/ppa already exists"
-else
- lmms/cmake/msys/fetch_ppa.sh
-fi
-
-info "Extracting debs to $HOME/ppa/opt/, etc..."
-if [ -d "$HOME/ppa/opt" ]; then
- warn " - Skipping, $HOME/ppa/opt already exists"
-else
- lmms/cmake/msys/extract_debs.sh
-fi
-
-info "Preparing library merge, making all qt headers writable..."
-chmod u+w /mingw64/include/qt4 -R
-chmod u+w /mingw32/include/qt4 -R
-
-info "Merging mingw headers and libraries from ppa over existing system libraries..."
-if ! find /mingw64 | grep sndfile.h; then
- command cp -r "$HOME/ppa/opt/mingw"* /
-else
- warn " - Skipping, sndfile.h has already been merged"
-fi
-
-fltkver="1.3.3"
-oggver="1.3.2"
-vorbisver="1.3.5"
-flacver="1.3.2"
-gigver="4.0.0"
-stkver="4.5.1"
-
-mingw_root="/$(echo "$MSYSTEM"|tr '[:upper:]' '[:lower:]')"
-
-info "Downloading and building fltk $fltkver"
-if ! command -v fluid; then
- wget http://fltk.org/pub/fltk/$fltkver/fltk-$fltkver-source.tar.gz -O "$HOME/fltk-source.tar.gz"
- tar zxf "$HOME/fltk-source.tar.gz" -C "$HOME/"
- pushd "$HOME/fltk-$fltkver"
-
- info " - Compiling fltk $fltkver..."
- ./configure --prefix="$mingw_root" --enable-shared
- make
-
- info " - Installing fltk..."
- make install
-
-# ln -s $mingw_root/usr/local/bin/fluid.exe $mingw_root/bin/fluid.exe
- popd
-else
- warn " - Skipping, fluid binary already exists"
-fi
-
-info "Downloading and building libogg $oggver"
-if [ ! -e "$mingw_root/lib/libogg.dll.a" ]; then
- wget http://downloads.xiph.org/releases/ogg/libogg-$oggver.tar.xz -O "$HOME/libogg-source.tar.xz"
- tar xf "$HOME/libogg-source.tar.xz" -C "$HOME/"
- pushd "$HOME/libogg-$oggver"
-
- info " - Compiling libogg $oggver..."
- ./configure --prefix="$mingw_root"
- make
-
- info " - Installing libogg..."
- make install
- # for some reason libgig needs this
- ./configure --prefix="/opt$mingw_root"
- make
-
- info " - Installing libogg..."
- make install
-
- popd
-else
- warn " - Skipping, libogg binary already exists"
-fi
-
-info "Downloading and building libvorbis $vorbisver"
-if [ ! -e "$mingw_root/lib/libvorbis.dll.a" ]; then
- wget http://downloads.xiph.org/releases/vorbis/libvorbis-$vorbisver.tar.xz -O "$HOME/libvorbis-source.tar.xz"
- tar xf "$HOME/libvorbis-source.tar.xz" -C "$HOME/"
- pushd "$HOME/libvorbis-$vorbisver"
-
- info " - Compiling libvorbis $vorbisver..."
- ./configure --prefix="$mingw_root"
- make
-
- info " - Installing libvorbis..."
- make install
-
- # for some reason libgig needs this
- ./configure --prefix="/opt$mingw_root"
- make
- info " - Installing libvorbis..."
- make install
-
- popd
-else
- warn " - Skipping, libvorbis binary already exists"
-fi
-
-info "Downloading and building flac $flacver"
-
-if [ ! -e "$mingw_root/lib/libFLAC.dll.a" ]; then
-
- wget http://downloads.xiph.org/releases/flac/flac-$flacver.tar.xz -O "$HOME/flac-source.tar.xz"
- tar xf "$HOME/flac-source.tar.xz" -C "$HOME/"
- pushd "$HOME/flac-$flacver"
-
- info " - Compiling flac $flacver..."
- ./configure --prefix="$mingw_root"
- make
-
- info " - Installing flac..."
- make install
-
- # for some reason libgig needs this
- ./configure --prefix="/opt$mingw_root"
- make
-
- info " - Installing flac..."
- make install
-
- popd
-else
- warn " - Skipping, libvorbis flac already exists"
-fi
-
-info "Downloading and building libgig $gigver"
-
-if [ ! -e "$mingw_root/lib/libgig/libgig.dll.a" ]; then
- wget http://download.linuxsampler.org/packages/libgig-$gigver.tar.bz2 -O "$HOME/gig-source.tar.xz"
- tar xf "$HOME/gig-source.tar.xz" -C "$HOME/"
- pushd "$HOME/libgig-$gigver"
-
- info " - Compiling libgig $gigver..."
- ./configure --prefix="$mingw_root"
- make
-
- info " - Installing libgig..."
- make install
-
- mv "$mingw_root/lib/bin/libakai-0.dll" "$mingw_root/bin"
- mv "$mingw_root/lib/bin/libgig-7.dll" "$mingw_root/bin"
-
- popd
-else
- warn " - Skipping, libgig binary already exists"
-fi
-
-info "Downloading and building stk $stkver"
-
-if [ ! -e "$mingw_root/lib/libstk.dll" ]; then
- wget http://ccrma.stanford.edu/software/stk/release/stk-$stkver.tar.gz -O "$HOME/stk-source.tar.xz"
- tar xf "$HOME/stk-source.tar.xz" -C "$HOME/"
- pushd "$HOME/stk-$stkver"
-
- info " - Compiling stk $stkver..."
- ./configure --prefix="$mingw_root"
- make
-
- info " - Installing stk..."
- make install
-
- mv "$mingw_root/lib/libstk.so" "$mingw_root/lib/libstk.dll"
- mv "$mingw_root/lib/libstk-$stkver.so" "$mingw_root/lib/libstk-$stkver.dll"
-
- popd
-else
- warn " - Skipping, stk binary already exists"
-fi
-
-# make a symlink to make cmake happy
-if [ "$mingw_root" = "/mingw64" ]; then
- if [ ! -e /opt/mingw64/bin/x86_64-w64-mingw32-pkg-config ]; then
- ln -s /usr/bin/pkg-config /opt/mingw64/bin/x86_64-w64-mingw32-pkg-config
- fi
-elif [ "$mingw_root" = "/mingw32" ]; then
- if [ ! -e /opt/mingw32/bin/i686-w64-mingw32-pkg-config ]; then
- ln -s /usr/bin/pkg-config /opt/mingw32/bin/i686-w64-mingw32-pkg-config
- fi
-fi
-
-info "Cleaning up..."
-rm -rf "$HOME/fltk-$fltkver"
-rm -rf "$HOME/libogg-$oggver"
-rm -rf "$HOME/libvorbis-$vorbisver"
-rm -rf "$HOME/flac-$flacver"
-rm -rf "$HOME/libgig-$gigver"
-rm -rf "$HOME/stk-$stkver"
-info "Done."
diff --git a/cmake/nsis/CMakeLists.txt b/cmake/nsis/CMakeLists.txt
index ee1bd45c3..e926e074d 100644
--- a/cmake/nsis/CMakeLists.txt
+++ b/cmake/nsis/CMakeLists.txt
@@ -3,10 +3,9 @@ if(LMMS_MSVC_YEAR)
SET(WIN_PLATFORM "msvc${LMMS_MSVC_YEAR}")
endif()
-SET(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis/nsis_branding.bmp")
-IF(MSVC)
- STRING(REPLACE "/" "\\\\" CPACK_PACKAGE_ICON ${CPACK_PACKAGE_ICON})
-ENDIF(MSVC)
+# the final slash needs to be flipped for CPACK_PACKAGE_ICON to work:
+# https://cmake.org/pipermail/cmake/2008-June/022085.html
+SET(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis\\\\nsis_branding.bmp")
SET(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/cmake/nsis/icon.ico")
SET(CPACK_NSIS_INSTALLED_ICON_NAME "${CMAKE_PROJECT_NAME}.exe" PARENT_SCOPE)
SET(CPACK_NSIS_DISPLAY_NAME "${PROJECT_NAME_UCASE} ${VERSION}" PARENT_SCOPE)
@@ -44,25 +43,6 @@ IF(WIN64)
")
ENDIF()
-# Fix windows paths for msys
-IF(LMMS_BUILD_MSYS)
- STRING(REPLACE "/" "\\\\" CPACK_PACKAGE_ICON "${CPACK_PACKAGE_ICON}")
- STRING(REPLACE "/" "\\\\" CPACK_NSIS_MUI_ICON "${CPACK_NSIS_MUI_ICON}")
- STRING(REPLACE "/" "\\\\" CPACK_NSIS_DEFINES "${CPACK_NSIS_DEFINES}")
- STRING(REPLACE "/" "\\\\" CMAKE_BINARY_DIR_FIX "${CMAKE_BINARY_DIR}")
-
- # FIXME: there's no easy way to fix $INST_DIR, so we'll redefine it manually
- IF(WIN64)
- SET(NSIS_ARCH "win64")
- ELSE()
- SET(NSIS_ARCH "win32")
- ENDIF()
- SET(CPACK_NSIS_DEFINES "
- ${CPACK_NSIS_DEFINES}
- !define /redef INST_DIR ${CMAKE_BINARY_DIR_FIX}\\\\_CPack_Packages\\\\${NSIS_ARCH}\\\\NSIS\\\\${CPACK_PACKAGE_FILE_NAME}
- ")
-ENDIF()
-
# Setup missing parent scopes
SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}" PARENT_SCOPE)
SET(CPACK_NSIS_DEFINES "${CPACK_NSIS_DEFINES}" PARENT_SCOPE)
diff --git a/cmake/toolchains/MSYS-32.cmake b/cmake/toolchains/MSYS-32.cmake
deleted file mode 100644
index 698dd5437..000000000
--- a/cmake/toolchains/MSYS-32.cmake
+++ /dev/null
@@ -1,4 +0,0 @@
-INCLUDE(${CMAKE_CURRENT_LIST_DIR}/common/MSYS.cmake)
-INCLUDE(${CMAKE_CURRENT_LIST_DIR}/common/Win32.cmake)
-
-SET(MINGW_PREFIX /mingw32)
\ No newline at end of file
diff --git a/cmake/toolchains/MSYS-64.cmake b/cmake/toolchains/MSYS-64.cmake
deleted file mode 100644
index 8becd51b3..000000000
--- a/cmake/toolchains/MSYS-64.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-INCLUDE(${CMAKE_CURRENT_LIST_DIR}/common/MSYS.cmake)
-INCLUDE(${CMAKE_CURRENT_LIST_DIR}/common/Win64.cmake)
-
-SET(MINGW_PREFIX /mingw64)
-SET(MINGW_PREFIX32 /mingw32)
diff --git a/cmake/toolchains/common/MSYS.cmake b/cmake/toolchains/common/MSYS.cmake
deleted file mode 100644
index 0b27e8d32..000000000
--- a/cmake/toolchains/common/MSYS.cmake
+++ /dev/null
@@ -1,22 +0,0 @@
-# The target environment
-SET(CMAKE_FIND_ROOT_PATH ${MINGW_PREFIX})
-SET(CMAKE_INSTALL_PREFIX ${MINGW_PREFIX})
-
-# Windows msys mingw ships with a mostly-suitable preconfigured environment
-SET(STRIP ${MINGW_PREFIX}/bin/strip)
-SET(CMAKE_RC_COMPILER ${MINGW_PREFIX}/bin/windres)
-SET(CMAKE_C_COMPILER ${MINGW_PREFIX}/bin/gcc)
-SET(CMAKE_CXX_COMPILER ${MINGW_PREFIX}/bin/g++)
-
-# For 32-bit vst support
-IF(WIN64)
- # Specify the 32-bit cross compiler
- SET(CMAKE_C_COMPILER32 ${MINGW_PREFIX32}/bin/gcc)
- SET(CMAKE_CXX_COMPILER32 ${MINGW_PREFIX32}/bin/g++)
-ENDIF()
-
-# Msys compiler does not support @CMakeFiles/Include syntax
-SET(CMAKE_C_USE_RESPONSE_FILE_FOR_INCLUDES OFF)
-SET(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES OFF)
-
-SET(LMMS_BUILD_MSYS 1)
diff --git a/data/locale/ar.ts b/data/locale/ar.ts
index 0d44c22bf..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
diff --git a/data/locale/bs.ts b/data/locale/bs.ts
index 7abf0baf1..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
@@ -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 0e27c39db..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
diff --git a/data/locale/cs.ts b/data/locale/cs.ts
index 022f55459..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
diff --git a/data/locale/de.ts b/data/locale/de.ts
index 7817857fd..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
diff --git a/data/locale/el.ts b/data/locale/el.ts
index 07e61778f..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
diff --git a/data/locale/en.ts b/data/locale/en.ts
index 15c3ab1f0..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
diff --git a/data/locale/eo.ts b/data/locale/eo.ts
index 0dd9c405f..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
diff --git a/data/locale/es.ts b/data/locale/es.ts
index 3953ddc11..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
diff --git a/data/locale/eu.ts b/data/locale/eu.ts
index fe6495c0a..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
diff --git a/data/locale/fa.ts b/data/locale/fa.ts
index b376a8424..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
diff --git a/data/locale/fr.ts b/data/locale/fr.ts
index 4862f4263..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
diff --git a/data/locale/gl.ts b/data/locale/gl.ts
index a1a9e6bf1..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
diff --git a/data/locale/he.ts b/data/locale/he.ts
index fef0caa91..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
diff --git a/data/locale/hi_IN.ts b/data/locale/hi_IN.ts
index 82cf364e3..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
diff --git a/data/locale/hu_HU.ts b/data/locale/hu_HU.ts
index a0f1e4d45..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
diff --git a/data/locale/id.ts b/data/locale/id.ts
index c504740e9..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
diff --git a/data/locale/it.ts b/data/locale/it.ts
index d5a68e6e7..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
diff --git a/data/locale/ja.ts b/data/locale/ja.ts
index 14b38c698..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
diff --git a/data/locale/ka.ts b/data/locale/ka.ts
index 51eededf2..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
diff --git a/data/locale/ko.ts b/data/locale/ko.ts
index 43b99e7f4..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 채널
diff --git a/data/locale/ms_MY.ts b/data/locale/ms_MY.ts
index ff3478421..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
diff --git a/data/locale/nb.ts b/data/locale/nb.ts
index 659344d64..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
diff --git a/data/locale/nl.ts b/data/locale/nl.ts
index 7ff3e8735..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
diff --git a/data/locale/oc.ts b/data/locale/oc.ts
index 045eaf3ad..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
diff --git a/data/locale/pl.ts b/data/locale/pl.ts
index ff36a8dac..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
diff --git a/data/locale/pt.ts b/data/locale/pt.ts
index f8cfe7618..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
diff --git a/data/locale/ro.ts b/data/locale/ro.ts
index 58abbba99..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
diff --git a/data/locale/ru.ts b/data/locale/ru.ts
index 73b7e06ad..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
Новый канал ЭФ
diff --git a/data/locale/sl.ts b/data/locale/sl.ts
index e7bfbc308..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
diff --git a/data/locale/sr.ts b/data/locale/sr.ts
index 183936bc7..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
@@ -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 f5d4e0fb4..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
diff --git a/data/locale/tr.ts b/data/locale/tr.ts
index b899337a5..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ı
diff --git a/data/locale/uk.ts b/data/locale/uk.ts
index 9fb6389c9..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
Новий ефект каналу
diff --git a/data/locale/zh_CN.ts b/data/locale/zh_CN.ts
index 9b783b963..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
新的效果通道
diff --git a/data/locale/zh_TW.ts b/data/locale/zh_TW.ts
index a3a727edb..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
新的效果通道
diff --git a/data/projects/demos/unfa-Spoken.mmpz b/data/projects/demos/unfa-Spoken.mmpz
index 66b7589d1..58d00d50d 100644
Binary files a/data/projects/demos/unfa-Spoken.mmpz and b/data/projects/demos/unfa-Spoken.mmpz differ
diff --git a/data/projects/shorties/Greshz-CoolSnip.mmpz b/data/projects/shorties/Greshz-CoolSnip.mmpz
deleted file mode 100644
index dadeef1ba..000000000
Binary files a/data/projects/shorties/Greshz-CoolSnip.mmpz and /dev/null differ
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/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/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/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/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 522d694ff..5489a7d21 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 {
@@ -33,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 */
@@ -143,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 */
@@ -184,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;
}
@@ -197,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);
}
@@ -205,7 +213,7 @@ lmms--gui--Oscilloscope {
lmms--gui--CPULoadWidget {
border: none;
- background: url(resources:cpuload_bg.png);
+ background: url("resources:cpuload_bg.png");
qproperty-stepSize: 4;
}
@@ -322,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 */
@@ -344,14 +352,24 @@ lmms--gui--TrackView > QWidget {
/* autoscroll, loop, stop behaviour toggle buttons */
-/* track background colors */
+/* track background config */
lmms--gui--TrackContentWidget {
- qproperty-darkerColor: qlineargradient(x1:0, y1:0, x2:0, y2:1,
- stop:0 rgb( 50, 50, 50 ), stop:0.33 rgb( 20, 20, 20 ), stop:1 rgb( 15, 15, 15 ) );
- qproperty-lighterColor: qlineargradient(x1:0, y1:0, x2:0, y2:1,
- stop:0 rgb( 50, 50, 50 ), stop:0.33 rgb( 40, 40, 40 ), stop:1 rgb( 30, 30, 30 ) );
- qproperty-gridColor: rgba( 0, 0, 0, 160 );
- qproperty-embossColor: rgba( 140, 140, 140, 64 );
+ /* colors */
+ qproperty-darkerColor: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgb(50, 50, 50), stop:0.33 rgb(20, 20, 20), stop:1 rgb(15, 15, 15));
+ qproperty-lighterColor: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 rgb(50, 50, 50), stop:0.33 rgb(40, 40, 40), stop:1 rgb(30, 30, 30));
+ qproperty-coarseGridColor: rgba(0, 0, 0, 160);
+ qproperty-fineGridColor: rgba(0, 0, 0, 80);
+ qproperty-horizontalColor: rgba(0, 0, 0, 160);
+ qproperty-embossColor: rgba(140, 140, 140, 64);
+
+ /* line widths */
+ qproperty-coarseGridWidth: 2;
+ qproperty-fineGridWidth: 1;
+ qproperty-horizontalWidth: 1;
+ qproperty-embossWidth: 0;
+
+ /* positive offset shifts emboss to the right */
+ qproperty-embossOffset: 0;
}
@@ -367,7 +385,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;
@@ -375,12 +393,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;
}
@@ -409,7 +427,7 @@ 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;
@@ -428,7 +446,7 @@ lmms--gui--AutomatableSlider::groove:horizontal {
lmms--gui--AutomatableSlider::handle:horizontal {
background: none;
- border-image: url(resources:horizontal_slider.png);
+ border-image: url("resources:horizontal_slider.png");
width: 10px;
height: 26px;
border-radius: 2px;
@@ -627,7 +645,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,
@@ -638,11 +656,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 {
@@ -658,15 +681,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 {
@@ -899,6 +932,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;
@@ -967,6 +1008,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 {
@@ -975,6 +1017,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/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/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 26b2dd14b..a4f94de09 100644
--- a/data/themes/default/style.css
+++ b/data/themes/default/style.css
@@ -9,6 +9,7 @@ QLabel, QTreeWidget, QListWidget, QGroupBox, QMenuBar, QCheckBox {
QTreeView {
outline: none;
+ alternate-background-color: #111314;
}
QTreeWidget::item {
@@ -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 */
@@ -174,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 */
@@ -214,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;
}
@@ -228,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);
}
@@ -236,7 +244,7 @@ lmms--gui--Oscilloscope {
lmms--gui--CPULoadWidget {
border: none;
- background: url(resources:cpuload_bg.png);
+ background: url("resources:cpuload_bg.png");
qproperty-stepSize: 1;
}
@@ -270,33 +278,33 @@ QScrollBar::add-page:vertical:pressed, QScrollBar::sub-page:vertical:pressed {
/* scrollbar: handles (sliders) */
QScrollBar::handle:horizontal {
- background: #3f4750;
+ background: #5d6b77;
border: none;
border-radius: 4px;
min-width: 24px;
}
QScrollBar::handle:horizontal:hover {
- background: #525e69;
+ background: #b8c4d1;
}
QScrollBar::handle:horizontal:pressed {
- background: rgba(11,213,86,100);
+ background: #ffffff;
}
QScrollBar::handle:vertical {
- background: #3f4750;
+ background: #5d6b77;
border: none;
border-radius: 4px;
min-height: 24px;
}
QScrollBar::handle:vertical:hover {
- background: #525e69;
+ background: #b8c4d1;
}
QScrollBar::handle:vertical:pressed {
- background: rgba(11,213,86,100);
+ background: #ffffff;
}
QScrollBar::handle:horizontal:disabled, QScrollBar::handle:vertical:disabled {
@@ -355,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 */
@@ -380,12 +388,24 @@ lmms--gui--TrackView > QWidget {
/* autoscroll, loop, stop behaviour toggle buttons */
-/* track background colors */
+/* track background config */
lmms--gui--TrackContentWidget {
+ /* colors */
qproperty-darkerColor: #0C0E0F;
qproperty-lighterColor: #14151A;
- qproperty-gridColor: #262B30;
- qproperty-embossColor: rgba( 0, 0, 0, 0 );
+ qproperty-coarseGridColor: #3C444C;
+ qproperty-fineGridColor: #262B30;
+ qproperty-horizontalColor: #3C444C;
+ qproperty-embossColor: rgba(0, 0, 0, 0);
+
+ /* line widths */
+ qproperty-coarseGridWidth: 2;
+ qproperty-fineGridWidth: 1;
+ qproperty-horizontalWidth: 1;
+ qproperty-embossWidth: 0;
+
+ /* positive offset shifts emboss to the right */
+ qproperty-embossOffset: 0;
}
@@ -401,7 +421,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;
@@ -410,7 +430,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;
}
@@ -433,7 +453,7 @@ 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;
@@ -452,7 +472,7 @@ lmms--gui--AutomatableSlider::groove:horizontal {
lmms--gui--AutomatableSlider::handle:horizontal {
background: none;
- border-image: url(resources:horizontal_slider.png);
+ border-image: url("resources:horizontal_slider.png");
width: 10px;
height: 26px;
border-radius: 2px;
@@ -531,6 +551,12 @@ QToolButton:hover {
background: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1, stop:0 #7c8799, stop:1 #343840)
}
+QToolButton:hover:checked {
+ border: 2px solid #343840;
+ border-radius: 2px;
+ background: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1, stop:0 #292d33, stop:1 #22262c)
+}
+
QToolButton:pressed {
border-top: 1px solid #778394;
border-bottom: 1px solid #1e2226;
@@ -542,7 +568,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 */
@@ -591,7 +617,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;
@@ -601,7 +627,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;
@@ -669,7 +695,7 @@ lmms--gui--ControllerRackView QPushButton {
font-size: 10px;
}
-lmms--gui--MixerLine {
+lmms--gui--MixerChannelView {
background: #14161A;
color: #d1d8e4;
qproperty-backgroundActive: #3B424A;
@@ -679,11 +705,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 {
@@ -699,27 +730,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
@@ -946,6 +982,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;
@@ -1014,6 +1058,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 {
@@ -1022,6 +1067,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/include/AudioAlsa.h b/include/AudioAlsa.h
index 975532071..92c47a6ac 100644
--- a/include/AudioAlsa.h
+++ b/include/AudioAlsa.h
@@ -84,7 +84,6 @@ public:
private:
void startProcessing() override;
void stopProcessing() override;
- void applyQualitySettings() override;
void run() override;
int setHWParams( const ch_cnt_t _channels, snd_pcm_access_t _access );
diff --git a/include/AudioDevice.h b/include/AudioDevice.h
index d1a9617cd..577bb7d0e 100644
--- a/include/AudioDevice.h
+++ b/include/AudioDevice.h
@@ -89,18 +89,10 @@ public:
virtual void stopProcessing();
- virtual void applyQualitySettings();
-
-
-
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 +101,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 );
@@ -117,13 +108,6 @@ protected:
void clearS16Buffer( int_sample_t * _outbuf,
const fpp_t _frames );
- // resample given buffer from samplerate _src_sr to samplerate _dst_sr
- fpp_t resample( const surroundSampleFrame * _src,
- const fpp_t _frames,
- surroundSampleFrame * _dst,
- const sample_rate_t _src_sr,
- const sample_rate_t _dst_sr );
-
inline void setSampleRate( const sample_rate_t _new_sr )
{
m_sampleRate = _new_sr;
@@ -134,8 +118,6 @@ protected:
return m_audioEngine;
}
- bool hqAudio() const;
-
static void stopProcessingThread( QThread * thread );
@@ -151,9 +133,6 @@ private:
QMutex m_devMutex;
- SRC_DATA m_srcData;
- SRC_STATE * m_srcState;
-
surroundSampleFrame * m_buffer;
};
diff --git a/include/AudioDummy.h b/include/AudioDummy.h
index e34260171..6907ad167 100644
--- a/include/AudioDummy.h
+++ b/include/AudioDummy.h
@@ -104,7 +104,7 @@ private:
delete[] b;
}
- const int microseconds = static_cast( audioEngine()->framesPerPeriod() * 1000000.0f / audioEngine()->processingSampleRate() - timer.elapsed() );
+ const int microseconds = static_cast( audioEngine()->framesPerPeriod() * 1000000.0f / audioEngine()->outputSampleRate() - timer.elapsed() );
if( microseconds > 0 )
{
usleep( microseconds );
diff --git a/include/AudioEngine.h b/include/AudioEngine.h
index d3d0d025f..e434b7f15 100644
--- a/include/AudioEngine.h
+++ b/include/AudioEngine.h
@@ -25,14 +25,13 @@
#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
@@ -109,13 +108,6 @@ public:
struct qualitySettings
{
- enum class Mode
- {
- Draft,
- HighQuality,
- FinalMix
- } ;
-
enum class Interpolation
{
Linear,
@@ -124,53 +116,11 @@ public:
SincBest
} ;
- enum class Oversampling
- {
- None,
- X2,
- X4,
- X8
- } ;
-
Interpolation interpolation;
- Oversampling oversampling;
- qualitySettings(Mode m)
+ qualitySettings(Interpolation i) :
+ interpolation(i)
{
- switch (m)
- {
- case Mode::Draft:
- interpolation = Interpolation::Linear;
- oversampling = Oversampling::None;
- break;
- case Mode::HighQuality:
- interpolation =
- Interpolation::SincFastest;
- oversampling = Oversampling::X2;
- break;
- case Mode::FinalMix:
- interpolation = Interpolation::SincBest;
- oversampling = Oversampling::X8;
- break;
- }
- }
-
- qualitySettings(Interpolation i, Oversampling o) :
- interpolation(i),
- oversampling(o)
- {
- }
-
- int sampleRateMultiplier() const
- {
- switch( oversampling )
- {
- case Oversampling::None: return 1;
- case Oversampling::X2: return 2;
- case Oversampling::X4: return 4;
- case Oversampling::X8: return 8;
- }
- return 1;
}
int libsrcInterpolation() const
@@ -290,8 +240,6 @@ public:
sample_rate_t baseSampleRate() const;
sample_rate_t outputSampleRate() const;
sample_rate_t inputSampleRate() const;
- sample_rate_t processingSampleRate() const;
-
inline float masterGain() const
{
@@ -420,10 +368,6 @@ 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;
std::vector m_audioPorts;
@@ -453,8 +397,6 @@ private:
struct qualitySettings m_qualitySettings;
float m_masterGain;
- bool m_isProcessing;
-
// audio device stuff
void doSetAudioDevice( AudioDevice *_dev );
AudioDevice * m_audioDev;
@@ -476,19 +418,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;
diff --git a/include/AudioFileFlac.h b/include/AudioFileFlac.h
index 944e30478..9432f4231 100644
--- a/include/AudioFileFlac.h
+++ b/include/AudioFileFlac.h
@@ -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();
diff --git a/include/AudioFileMP3.h b/include/AudioFileMP3.h
index 4289ad211..013c93a3e 100644
--- a/include/AudioFileMP3.h
+++ b/include/AudioFileMP3.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();
diff --git a/include/AudioFileOgg.h b/include/AudioFileOgg.h
index 77be8ca1c..fc3ce25b4 100644
--- a/include/AudioFileOgg.h
+++ b/include/AudioFileOgg.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();
diff --git a/include/AudioFileWave.h b/include/AudioFileWave.h
index c186aaaa7..22b124f93 100644
--- a/include/AudioFileWave.h
+++ b/include/AudioFileWave.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();
diff --git a/include/AudioJack.h b/include/AudioJack.h
index 164258e5f..01f41f092 100644
--- a/include/AudioJack.h
+++ b/include/AudioJack.h
@@ -57,88 +57,78 @@ 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();
void startProcessing() override;
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;
- std::vector 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
diff --git a/include/AudioOss.h b/include/AudioOss.h
index 55f64de85..91d456073 100644
--- a/include/AudioOss.h
+++ b/include/AudioOss.h
@@ -79,7 +79,6 @@ class setupWidget : public gui::AudioDeviceSetupWidget
private:
void startProcessing() override;
void stopProcessing() override;
- void applyQualitySettings() override;
void run() override;
int m_audioFD;
diff --git a/include/AudioPort.h b/include/AudioPort.h
index d9803d205..9e3ce2bd6 100644
--- a/include/AudioPort.h
+++ b/include/AudioPort.h
@@ -29,7 +29,6 @@
#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,
diff --git a/include/AudioPortAudio.h b/include/AudioPortAudio.h
index 01b8f3fd7..4465b18c1 100644
--- a/include/AudioPortAudio.h
+++ b/include/AudioPortAudio.h
@@ -109,7 +109,6 @@ public:
private:
void startProcessing() override;
void stopProcessing() override;
- void applyQualitySettings() override;
#ifdef PORTAUDIO_V19
static int _process_callback( const void *_inputBuffer, void * _outputBuffer,
diff --git a/include/AudioPulseAudio.h b/include/AudioPulseAudio.h
index b6a998274..db3c566bf 100644
--- a/include/AudioPulseAudio.h
+++ b/include/AudioPulseAudio.h
@@ -88,7 +88,6 @@ public:
private:
void startProcessing() override;
void stopProcessing() override;
- void applyQualitySettings() override;
void run() override;
volatile bool m_quit;
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 8937ceb5e..a3e776881 100644
--- a/include/AudioSampleRecorder.h
+++ b/include/AudioSampleRecorder.h
@@ -28,6 +28,7 @@
#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;
diff --git a/include/AudioSdl.h b/include/AudioSdl.h
index 62db8b68a..5062f79ea 100644
--- a/include/AudioSdl.h
+++ b/include/AudioSdl.h
@@ -74,7 +74,6 @@ public:
private:
void startProcessing() override;
void stopProcessing() override;
- void applyQualitySettings() override;
static void sdlAudioCallback( void * _udata, Uint8 * _buf, int _len );
void sdlAudioCallback( Uint8 * _buf, int _len );
diff --git a/include/AudioSndio.h b/include/AudioSndio.h
index 594ca94e7..beb4913eb 100644
--- a/include/AudioSndio.h
+++ b/include/AudioSndio.h
@@ -75,7 +75,6 @@ public:
private:
void startProcessing() override;
void stopProcessing() override;
- void applyQualitySettings() override;
void run() override;
struct sio_hdl *m_hdl;
diff --git a/include/AutomatableModel.h b/include/AutomatableModel.h
index 2264a592e..15285e17a 100644
--- a/include/AutomatableModel.h
+++ b/include/AutomatableModel.h
@@ -25,15 +25,15 @@
#ifndef LMMS_AUTOMATABLE_MODEL_H
#define LMMS_AUTOMATABLE_MODEL_H
+#include
#include
#include
-#include
+#include
#include "JournallingObject.h"
#include "Model.h"
#include "TimePos.h"
#include "ValueBuffer.h"
-#include "MemoryManager.h"
#include "ModelVisitor.h"
@@ -77,7 +77,6 @@ class ControllerConnection;
class LMMS_EXPORT AutomatableModel : public Model, public JournallingObject
{
Q_OBJECT
- MM_OPERATORS
public:
using AutoModelVector = std::vector;
diff --git a/include/AutomationClipView.h b/include/AutomationClipView.h
index a20e2ce28..bdd2f0568 100644
--- a/include/AutomationClipView.h
+++ b/include/AutomationClipView.h
@@ -74,9 +74,6 @@ private:
QPixmap m_paintPixmap;
QStaticText m_staticTextName;
-
- static QPixmap * s_clip_rec;
-
void scaleTimemapToFit( float oldMin, float oldMax );
} ;
diff --git a/include/AutomationEditor.h b/include/AutomationEditor.h
index dad0e4916..1110e8e4c 100644
--- a/include/AutomationEditor.h
+++ b/include/AutomationEditor.h
@@ -26,16 +26,18 @@
#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;
@@ -68,8 +70,13 @@ class AutomationEditor : public QWidget, public JournallingObject
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
{
@@ -159,6 +166,13 @@ 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 class Action
@@ -183,17 +197,23 @@ 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_toolEditTangents;
- 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;
@@ -211,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();
@@ -261,6 +285,9 @@ private:
QBrush m_scaleColor;
QColor m_crossColor;
QColor m_backgroundShade;
+ QColor m_ghostNoteColor;
+ QColor m_detuningNoteColor;
+ QColor m_ghostSampleColor;
friend class AutomationEditorWindow;
@@ -284,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;
@@ -337,6 +367,8 @@ private:
ComboBox * m_zoomingXComboBox;
ComboBox * m_zoomingYComboBox;
ComboBox * m_quantizeComboBox;
+
+ QPushButton* m_resetGhostNotes;
};
} // namespace gui
diff --git a/include/BandLimitedWave.h b/include/BandLimitedWave.h
index 1f402aa6e..1c1a052ca 100644
--- a/include/BandLimitedWave.h
+++ b/include/BandLimitedWave.h
@@ -107,7 +107,7 @@ public:
*/
static inline float freqToLen( float f )
{
- return freqToLen( f, Engine::audioEngine()->processingSampleRate() );
+ return freqToLen( f, Engine::audioEngine()->outputSampleRate() );
}
/*! \brief This method converts frequency to wavelength, but you can use any custom sample rate with it.
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 9351cbafb..25dcf834c 100644
--- a/include/BasicFilters.h
+++ b/include/BasicFilters.h
@@ -40,7 +40,6 @@
#include "lmms_basics.h"
#include "lmms_constants.h"
#include "interpolation.h"
-#include "MemoryManager.h"
namespace lmms
{
@@ -50,7 +49,6 @@ template class BasicFilters;
template
class LinkwitzRiley
{
- MM_OPERATORS
public:
LinkwitzRiley( float sampleRate )
{
@@ -145,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();
}
@@ -188,7 +190,6 @@ using StereoBiQuad = BiQuad<2>;
template
class OnePole
{
- MM_OPERATORS
public:
OnePole()
{
@@ -222,7 +223,6 @@ using StereoOnePole = OnePole<2>;
template
class BasicFilters
{
- MM_OPERATORS
public:
enum class FilterType
{
@@ -328,9 +328,19 @@ 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 FilterType::Moog:
@@ -365,7 +375,6 @@ public:
// input signal is linear-interpolated after oversampling, output signal is averaged from oversampled outputs
case FilterType::Tripole:
{
- out = 0.0f;
float ip = 0.0f;
for( int i = 0; i < 4; ++i )
{
@@ -421,7 +430,6 @@ public:
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];
@@ -434,8 +442,7 @@ public:
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 */
@@ -443,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];
}
@@ -459,19 +466,19 @@ public:
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;
+ 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 = std::clamp(lp, -1.0f, 1.0f);
- hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] );
+ 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;
+ sample_t bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
bp = std::clamp(bp, -1.0f, 1.0f);
m_rclast0[_chnl] = in;
@@ -484,10 +491,10 @@ public:
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;
+ 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] );
@@ -505,20 +512,20 @@ public:
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;
+ 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 = std::clamp(lp, -1.0f, 1.0f);
- hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] );
+ 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;
+ sample_t bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
bp = std::clamp(bp, -1.0f, 1.0f);
m_rclast0[_chnl] = in;
@@ -549,11 +556,11 @@ public:
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;
+ 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] );
@@ -590,20 +597,18 @@ public:
case FilterType::FastFormant:
{
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
- sample_t hp, bp, in;
- out = 0;
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;
+ 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] );
+ 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];
+ 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;
diff --git a/include/CPULoadWidget.h b/include/CPULoadWidget.h
index dfa5bac73..bed10b05e 100644
--- a/include/CPULoadWidget.h
+++ b/include/CPULoadWidget.h
@@ -68,7 +68,7 @@ private:
QTimer m_updateTimer;
- int m_stepSize;
+ int m_stepSize = 1;
} ;
diff --git a/include/Clip.h b/include/Clip.h
index 96394602f..a520ad4e4 100644
--- a/include/Clip.h
+++ b/include/Clip.h
@@ -25,6 +25,8 @@
#ifndef LMMS_CLIP_H
#define LMMS_CLIP_H
+#include
+
#include
#include "AutomatableModel.h"
@@ -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 );
@@ -177,8 +162,7 @@ private:
bool m_selectViewOnCreate;
- QColor m_color;
- bool m_useCustomClipColor;
+ std::optional m_color;
friend class ClipView;
diff --git a/include/ClipView.h b/include/ClipView.h
index 942258367..14898db65 100644
--- a/include/ClipView.h
+++ b/include/ClipView.h
@@ -25,6 +25,7 @@
#ifndef LMMS_GUI_CLIP_VIEW_H
#define LMMS_GUI_CLIP_VIEW_H
+#include
#include
@@ -184,6 +185,7 @@ protected:
virtual void paintTextLabel(QString const & text, QPainter & painter);
+ auto hasCustomColor() const -> bool;
protected slots:
void updateLength();
@@ -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);
diff --git a/include/Clipboard.h b/include/Clipboard.h
index c6ae66ee8..cee40b33a 100644
--- a/include/Clipboard.h
+++ b/include/Clipboard.h
@@ -25,8 +25,10 @@
#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
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 8153451e8..cc4ad68dd 100644
--- a/include/ComboBox.h
+++ b/include/ComboBox.h
@@ -66,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;
diff --git a/include/ComboBoxModel.h b/include/ComboBoxModel.h
index e90d804e2..7037495ea 100644
--- a/include/ComboBoxModel.h
+++ b/include/ComboBoxModel.h
@@ -47,11 +47,6 @@ public:
{
}
- ~ComboBoxModel() override
- {
- clear();
- }
-
void addItem( QString item, std::unique_ptr loader = nullptr );
void replaceItem(std::size_t index, QString item, std::unique_ptr loader = nullptr);
diff --git a/include/ControllerRackView.h b/include/ControllerRackView.h
index 303cc2b40..93d1e8438 100644
--- a/include/ControllerRackView.h
+++ b/include/ControllerRackView.h
@@ -65,9 +65,11 @@ public:
public slots:
- void deleteController( lmms::gui::ControllerView * _view );
- void onControllerAdded( lmms::Controller * );
- void onControllerRemoved( lmms::Controller * );
+ void deleteController(ControllerView* view);
+ void moveUp(ControllerView* view);
+ void moveDown(ControllerView* view);
+ void addController(Controller* controller);
+ void removeController(Controller* controller);
protected:
void closeEvent( QCloseEvent * _ce ) override;
diff --git a/include/ControllerView.h b/include/ControllerView.h
index d1ba533a1..9b442672d 100644
--- a/include/ControllerView.h
+++ b/include/ControllerView.h
@@ -63,12 +63,16 @@ public:
public slots:
void editControls();
- void deleteController();
+ void removeController();
void closeControls();
void renameController();
+ void moveUp();
+ void moveDown();
signals:
- void deleteController( lmms::gui::ControllerView * _view );
+ void movedUp(ControllerView* view);
+ void movedDown(ControllerView* view);
+ void removedController(ControllerView* view);
protected:
diff --git a/include/DataFile.h b/include/DataFile.h
index dc82315ad..452481a7f 100644
--- a/include/DataFile.h
+++ b/include/DataFile.h
@@ -28,9 +28,9 @@
#include
#include
+#include
#include "lmms_export.h"
-#include "MemoryManager.h"
class QTextStream;
@@ -42,7 +42,6 @@ class ProjectVersion;
class LMMS_EXPORT DataFile : public QDomDocument
{
- MM_OPERATORS
using UpgradeMethod = void(DataFile::*)();
@@ -128,6 +127,9 @@ private:
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;
@@ -147,7 +149,6 @@ private:
QDomElement m_head;
Type m_type;
unsigned int m_fileVersion;
-
} ;
diff --git a/include/Delay.h b/include/Delay.h
index daa871baf..71fbe1b00 100644
--- a/include/Delay.h
+++ b/include/Delay.h
@@ -29,7 +29,6 @@
#include "lmms_basics.h"
#include "lmms_math.h"
#include "interpolation.h"
-#include "MemoryManager.h"
namespace lmms
{
@@ -74,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;
@@ -145,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;
@@ -216,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;
@@ -297,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;
diff --git a/include/DetuningHelper.h b/include/DetuningHelper.h
index e5d5f5712..da8eb5983 100644
--- a/include/DetuningHelper.h
+++ b/include/DetuningHelper.h
@@ -27,7 +27,6 @@
#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()
diff --git a/include/Effect.h b/include/Effect.h
index 1f566e0e9..c3745a352 100644
--- a/include/Effect.h
+++ b/include/Effect.h
@@ -31,7 +31,6 @@
#include "AudioEngine.h"
#include "AutomatableModel.h"
#include "TempoSyncKnobModel.h"
-#include "MemoryManager.h"
namespace lmms
{
@@ -49,7 +48,6 @@ class EffectView;
class LMMS_EXPORT Effect : public Plugin
{
- MM_OPERATORS
Q_OBJECT
public:
Effect( const Plugin::Descriptor * _desc,
@@ -113,7 +111,7 @@ public:
inline f_cnt_t timeout() const
{
- const float samples = Engine::audioEngine()->processingSampleRate() * m_autoQuitModel.value() / 1000.0f;
+ const float samples = Engine::audioEngine()->outputSampleRate() * m_autoQuitModel.value() / 1000.0f;
return 1 + ( static_cast( samples ) / Engine::audioEngine()->framesPerPeriod() );
}
@@ -157,6 +155,11 @@ public:
{
m_noRun = _state;
}
+
+ inline TempoSyncKnobModel* autoQuitModel()
+ {
+ return &m_autoQuitModel;
+ }
EffectChain * effectChain() const
{
@@ -189,7 +192,7 @@ protected:
sample_rate_t _dst_sr )
{
resample( 0, _src_buf,
- Engine::audioEngine()->processingSampleRate(),
+ Engine::audioEngine()->outputSampleRate(),
_dst_buf, _dst_sr,
Engine::audioEngine()->framesPerPeriod() );
}
@@ -199,12 +202,14 @@ protected:
sample_rate_t _src_sr )
{
resample( 1, _src_buf, _src_sr, _dst_buf,
- Engine::audioEngine()->processingSampleRate(),
+ Engine::audioEngine()->outputSampleRate(),
Engine::audioEngine()->framesPerPeriod() * _src_sr /
- Engine::audioEngine()->processingSampleRate() );
+ Engine::audioEngine()->outputSampleRate() );
}
void reinitSRC();
+ virtual void onEnabledChanged() {}
+
private:
EffectChain * m_parent;
diff --git a/include/EffectRackView.h b/include/EffectRackView.h
index a1e21be09..4a90c6b7a 100644
--- a/include/EffectRackView.h
+++ b/include/EffectRackView.h
@@ -53,10 +53,9 @@ public:
public slots:
void clearViews();
- void moveUp( lmms::gui::EffectView* view );
- void moveDown( lmms::gui::EffectView* view );
- void deletePlugin( lmms::gui::EffectView* view );
-
+ void moveUp(EffectView* view);
+ void moveDown(EffectView* view);
+ void deletePlugin(EffectView* view);
private slots:
virtual void update();
diff --git a/include/EffectSelectDialog.h b/include/EffectSelectDialog.h
index 493b07774..53e8dbe7e 100644
--- a/include/EffectSelectDialog.h
+++ b/include/EffectSelectDialog.h
@@ -2,6 +2,7 @@
* EffectSelectDialog.h - dialog to choose effect plugin
*
* Copyright (c) 2006-2009 Tobias Doerffel
+ * Copyright (c) 2023 Lost Robot
*
* This file is part of LMMS - https://lmms.io
*
@@ -25,49 +26,95 @@
#ifndef LMMS_GUI_EFFECT_SELECT_DIALOG_H
#define LMMS_GUI_EFFECT_SELECT_DIALOG_H
-#include
-#include
-#include
-
#include "Effect.h"
-
-namespace Ui { class EffectSelectDialog; }
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
namespace lmms::gui
{
+class DualColumnFilterProxyModel : public QSortFilterProxyModel
+{
+ Q_OBJECT
+public:
+ DualColumnFilterProxyModel(QObject* parent = nullptr) : QSortFilterProxyModel(parent)
+ {
+ }
+
+ void setEffectTypeFilter(const QString& filter)
+ {
+ m_effectTypeFilter = filter;
+ invalidateFilter();
+ }
+
+protected:
+ bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override
+ {
+ QModelIndex nameIndex = sourceModel()->index(source_row, 0, source_parent);
+ QModelIndex typeIndex = sourceModel()->index(source_row, 1, source_parent);
+
+ QString name = sourceModel()->data(nameIndex, Qt::DisplayRole).toString();
+ QString type = sourceModel()->data(typeIndex, Qt::DisplayRole).toString();
+
+ // TODO: cleanup once we drop Qt5 support
+#if (QT_VERSION >= QT_VERSION_CHECK(5,12,0))
+ QRegularExpression nameRegularExpression(filterRegularExpression());
+ nameRegularExpression.setPatternOptions(QRegularExpression::CaseInsensitiveOption);
+
+ bool nameFilterPassed = nameRegularExpression.match(name).capturedStart() != -1;
+#else
+ QRegExp nameRegularExpression(filterRegExp());
+ nameRegularExpression.setCaseSensitivity(Qt::CaseInsensitive);
+
+ bool nameFilterPassed = nameRegularExpression.indexIn(name) != -1;
+#endif
+
+ bool typeFilterPassed = type.contains(m_effectTypeFilter, Qt::CaseInsensitive);
+
+ return nameFilterPassed && typeFilterPassed;
+ }
+
+private:
+ QString m_effectTypeFilter;
+};
+
class EffectSelectDialog : public QDialog
{
Q_OBJECT
public:
- EffectSelectDialog( QWidget * _parent );
- ~EffectSelectDialog() override;
-
- Effect * instantiateSelectedPlugin( EffectChain * _parent );
+ EffectSelectDialog(QWidget* parent);
+ Effect* instantiateSelectedPlugin(EffectChain* parent);
protected slots:
void acceptSelection();
- void rowChanged( const QModelIndex &, const QModelIndex & );
- void sortAgain();
+ void rowChanged(const QModelIndex&, const QModelIndex&);
void updateSelection();
-
+
+ bool eventFilter(QObject* obj, QEvent* event) override;
private:
- Ui::EffectSelectDialog * ui;
-
EffectKeyList m_effectKeys;
EffectKey m_currentSelection;
QStandardItemModel m_sourceModel;
- QSortFilterProxyModel m_model;
- QWidget * m_descriptionWidget;
-
-} ;
-
+ DualColumnFilterProxyModel m_model;
+ QWidget* m_descriptionWidget;
+ QTableView* m_pluginList;
+ QScrollArea* m_scrollArea;
+ QLineEdit* m_filterEdit;
+};
} // namespace lmms::gui
-#endif // LMMS_GUI_EFFECT_SELECT_DIALOG_H
+#endif
diff --git a/include/EffectView.h b/include/EffectView.h
index e90700952..805e4a427 100644
--- a/include/EffectView.h
+++ b/include/EffectView.h
@@ -77,10 +77,9 @@ public slots:
signals:
- void moveUp( lmms::gui::EffectView * _plugin );
- void moveDown( lmms::gui::EffectView * _plugin );
- void deletePlugin( lmms::gui::EffectView * _plugin );
-
+ void movedUp(EffectView* view);
+ void movedDown(EffectView* view);
+ void deletedPlugin(EffectView* view);
protected:
void contextMenuEvent( QContextMenuEvent * _me ) override;
diff --git a/include/EnvelopeAndLfoParameters.h b/include/EnvelopeAndLfoParameters.h
index 7abc3910e..50bfdf787 100644
--- a/include/EnvelopeAndLfoParameters.h
+++ b/include/EnvelopeAndLfoParameters.h
@@ -25,6 +25,7 @@
#ifndef LMMS_ENVELOPE_AND_LFO_PARAMETERS_H
#define LMMS_ENVELOPE_AND_LFO_PARAMETERS_H
+#include
#include
#include "JournallingObject.h"
@@ -70,7 +71,18 @@ public:
using LfoList = QList;
LfoList m_lfos;
- } ;
+ };
+
+ enum class LfoShape
+ {
+ SineWave,
+ TriangleWave,
+ SawWave,
+ SquareWave,
+ UserDefinedWave,
+ RandomWave,
+ Count
+ };
EnvelopeAndLfoParameters( float _value_for_zero_amount,
Model * _parent );
@@ -113,6 +125,28 @@ public:
return m_rFrames;
}
+ // Envelope
+ const FloatModel& getPredelayModel() const { return m_predelayModel; }
+ const FloatModel& getAttackModel() const { return m_attackModel; }
+ const FloatModel& getHoldModel() const { return m_holdModel; }
+ const FloatModel& getDecayModel() const { return m_decayModel; }
+ const FloatModel& getSustainModel() const { return m_sustainModel; }
+ const FloatModel& getReleaseModel() const { return m_releaseModel; }
+ const FloatModel& getAmountModel() const { return m_amountModel; }
+ FloatModel& getAmountModel() { return m_amountModel; }
+
+
+ // LFO
+ inline f_cnt_t getLfoPredelayFrames() const { return m_lfoPredelayFrames; }
+ inline f_cnt_t getLfoAttackFrames() const { return m_lfoAttackFrames; }
+ inline f_cnt_t getLfoOscillationFrames() const { return m_lfoOscillationFrames; }
+
+ const FloatModel& getLfoAmountModel() const { return m_lfoAmountModel; }
+ FloatModel& getLfoAmountModel() { return m_lfoAmountModel; }
+ const TempoSyncKnobModel& getLfoSpeedModel() const { return m_lfoSpeedModel; }
+ const BoolModel& getX100Model() const { return m_x100Model; }
+ const IntModel& getLfoWaveModel() const { return m_lfoWaveModel; }
+ std::shared_ptr getLfoUserWave() const { return m_userWave; }
public slots:
void updateSampleVars();
@@ -167,18 +201,8 @@ private:
sample_t * m_lfoShapeData;
sample_t m_random;
bool m_bad_lfoShapeData;
- SampleBuffer m_userWave;
+ std::shared_ptr m_userWave = SampleBuffer::emptyBuffer();
- enum class LfoShape
- {
- SineWave,
- TriangleWave,
- SawWave,
- SquareWave,
- UserDefinedWave,
- RandomWave,
- Count
- } ;
constexpr static auto NumLfoShapes = static_cast(LfoShape::Count);
sample_t lfoShapeSample( fpp_t _frame_offset );
diff --git a/include/EnvelopeAndLfoView.h b/include/EnvelopeAndLfoView.h
index b5c7a67d4..0063dc788 100644
--- a/include/EnvelopeAndLfoView.h
+++ b/include/EnvelopeAndLfoView.h
@@ -30,9 +30,6 @@
#include "ModelView.h"
-class QPaintEvent;
-class QPixmap;
-
namespace lmms
{
@@ -46,6 +43,8 @@ class Knob;
class LedCheckBox;
class PixmapButton;
class TempoSyncKnob;
+class EnvelopeGraph;
+class LfoGraph;
@@ -62,8 +61,6 @@ protected:
void dragEnterEvent( QDragEnterEvent * _dee ) override;
void dropEvent( QDropEvent * _de ) override;
- void mousePressEvent( QMouseEvent * _me ) override;
- void paintEvent( QPaintEvent * _pe ) override;
protected slots:
@@ -71,13 +68,10 @@ protected slots:
private:
- static QPixmap * s_envGraph;
- static QPixmap * s_lfoGraph;
-
EnvelopeAndLfoParameters * m_params;
-
// envelope stuff
+ EnvelopeGraph* m_envelopeGraph;
Knob * m_predelayKnob;
Knob * m_attackKnob;
Knob * m_holdKnob;
@@ -87,6 +81,7 @@ private:
Knob * m_amountKnob;
// LFO stuff
+ LfoGraph* m_lfoGraph;
Knob * m_lfoPredelayKnob;
Knob * m_lfoAttackKnob;
TempoSyncKnob * m_lfoSpeedKnob;
@@ -96,8 +91,6 @@ private:
LedCheckBox * m_x100Cb;
LedCheckBox * m_controlEnvAmountCb;
-
- float m_randomGraph;
} ;
} // namespace gui
diff --git a/include/EnvelopeGraph.h b/include/EnvelopeGraph.h
new file mode 100644
index 000000000..4f8a5c386
--- /dev/null
+++ b/include/EnvelopeGraph.h
@@ -0,0 +1,77 @@
+/*
+ * EnvelopeGraph.h - Displays envelope graphs
+ *
+ * Copyright (c) 2004-2009 Tobias Doerffel
+ * 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_ENVELOPE_GRAPH_H
+#define LMMS_GUI_ENVELOPE_GRAPH_H
+
+#include
+
+#include "ModelView.h"
+#include "embed.h"
+
+namespace lmms
+{
+
+class EnvelopeAndLfoParameters;
+
+namespace gui
+{
+
+class EnvelopeGraph : public QWidget, public ModelView
+{
+public:
+ enum class ScalingMode
+ {
+ Dynamic,
+ Absolute,
+ Relative
+ };
+
+public:
+ EnvelopeGraph(QWidget* parent);
+
+protected:
+ void modelChanged() override;
+
+ void mousePressEvent(QMouseEvent*) override;
+ void contextMenuEvent(QContextMenuEvent*) override;
+ void paintEvent(QPaintEvent*) override;
+
+private:
+ void toggleAmountModel();
+
+private:
+ QPixmap m_envGraph = embed::getIconPixmap("envelope_graph");
+
+ EnvelopeAndLfoParameters* m_params = nullptr;
+
+ ScalingMode m_scaling = ScalingMode::Dynamic;
+};
+
+} // namespace gui
+
+} // namespace lmms
+
+#endif // LMMS_GUI_ENVELOPE_GRAPH_H
diff --git a/include/Fader.h b/include/Fader.h
index b46bed11b..a3158a8b4 100644
--- a/include/Fader.h
+++ b/include/Fader.h
@@ -53,6 +53,8 @@
#include "AutomatableModelView.h"
+#include "embed.h"
+#include "lmms_math.h"
namespace lmms::gui
@@ -65,21 +67,21 @@ class LMMS_EXPORT Fader : public QWidget, public FloatModelView
{
Q_OBJECT
public:
- Q_PROPERTY( QColor peakGreen READ peakGreen WRITE setPeakGreen )
- Q_PROPERTY( QColor peakRed READ peakRed WRITE setPeakRed )
- Q_PROPERTY( QColor peakYellow READ peakYellow WRITE setPeakYellow )
- Q_PROPERTY( bool levelsDisplayedInDBFS READ getLevelsDisplayedInDBFS WRITE setLevelsDisplayedInDBFS )
+ Q_PROPERTY(QColor peakOk MEMBER m_peakOk)
+ Q_PROPERTY(QColor peakClip MEMBER m_peakClip)
+ Q_PROPERTY(QColor peakWarn MEMBER m_peakWarn)
+ Q_PROPERTY(bool levelsDisplayedInDBFS MEMBER m_levelsDisplayedInDBFS)
+ Q_PROPERTY(bool renderUnityLine READ getRenderUnityLine WRITE setRenderUnityLine)
+ Q_PROPERTY(QColor unityMarker MEMBER m_unityMarker)
- Fader( FloatModel * _model, const QString & _name, QWidget * _parent );
- Fader( FloatModel * _model, const QString & _name, QWidget * _parent, QPixmap * back, QPixmap * leds, QPixmap * knob );
+ Fader(FloatModel* model, const QString& name, QWidget* parent);
+ Fader(FloatModel* model, const QString& name, QWidget* parent, const QPixmap& knob);
~Fader() override = default;
- void init(FloatModel * model, QString const & name);
-
- void setPeak_L( float fPeak );
+ void setPeak_L(float fPeak);
float getPeak_L() { return m_fPeakValue_L; }
- void setPeak_R( float fPeak );
+ void setPeak_R(float fPeak);
float getPeak_R() { return m_fPeakValue_R; }
inline float getMinPeak() const { return m_fMinPeak; }
@@ -88,87 +90,71 @@ public:
inline float getMaxPeak() const { return m_fMaxPeak; }
inline void setMaxPeak(float maxPeak) { m_fMaxPeak = maxPeak; }
- QColor const & peakGreen() const;
- void setPeakGreen( const QColor & c );
+ inline bool getRenderUnityLine() const { return m_renderUnityLine; }
+ inline void setRenderUnityLine(bool value = true) { m_renderUnityLine = value; }
- QColor const & peakRed() const;
- void setPeakRed( const QColor & c );
-
- QColor const & peakYellow() const;
- void setPeakYellow( const QColor & c );
-
- inline bool getLevelsDisplayedInDBFS() const { return m_levelsDisplayedInDBFS; }
- inline void setLevelsDisplayedInDBFS(bool value = true) { m_levelsDisplayedInDBFS = value; }
-
- void setDisplayConversion( bool b )
+ void setDisplayConversion(bool b)
{
m_conversionFactor = b ? 100.0 : 1.0;
}
- inline void setHintText( const QString & _txt_before,
- const QString & _txt_after )
+ inline void setHintText(const QString& txt_before,
+ const QString& txt_after)
{
- setDescription( _txt_before );
- setUnit( _txt_after );
+ setDescription(txt_before);
+ setUnit(txt_after);
}
private:
- void contextMenuEvent( QContextMenuEvent * _me ) override;
- void mousePressEvent( QMouseEvent *ev ) override;
- void mouseDoubleClickEvent( QMouseEvent* mouseEvent ) override;
- void mouseMoveEvent( QMouseEvent *ev ) override;
- void mouseReleaseEvent( QMouseEvent * _me ) override;
- void wheelEvent( QWheelEvent *ev ) override;
- void paintEvent( QPaintEvent *ev ) override;
+ void contextMenuEvent(QContextMenuEvent* me) override;
+ void mousePressEvent(QMouseEvent* ev) override;
+ void mouseDoubleClickEvent(QMouseEvent* mouseEvent) override;
+ void mouseMoveEvent(QMouseEvent* ev) override;
+ void mouseReleaseEvent(QMouseEvent* me) override;
+ void wheelEvent(QWheelEvent* ev) override;
+ void paintEvent(QPaintEvent* ev) override;
- inline bool clips(float const & value) const { return value >= 1.0f; }
-
- void paintDBFSLevels(QPaintEvent *ev, QPainter & painter);
- void paintLinearLevels(QPaintEvent *ev, QPainter & painter);
+ void paintLevels(QPaintEvent* ev, QPainter& painter, bool linear = false);
int knobPosY() const
{
float fRange = model()->maxValue() - model()->minValue();
float realVal = model()->value() - model()->minValue();
- return height() - ( ( height() - m_knob->height() ) * ( realVal / fRange ) );
+ return height() - ((height() - m_knob.height()) * (realVal / fRange));
}
- void setPeak( float fPeak, float &targetPeak, float &persistentPeak, QElapsedTimer &lastPeakTimer );
- int calculateDisplayPeak( float fPeak );
+ void setPeak(float fPeak, float& targetPeak, float& persistentPeak, QElapsedTimer& lastPeakTimer);
void updateTextFloat();
// Private members
private:
- float m_fPeakValue_L;
- float m_fPeakValue_R;
- float m_persistentPeak_L;
- float m_persistentPeak_R;
- float m_fMinPeak;
- float m_fMaxPeak;
+ float m_fPeakValue_L {0.};
+ float m_fPeakValue_R {0.};
+ float m_persistentPeak_L {0.};
+ float m_persistentPeak_R {0.};
+ float m_fMinPeak {dbfsToAmp(-42)};
+ float m_fMaxPeak {dbfsToAmp(9)};
QElapsedTimer m_lastPeakTimer_L;
QElapsedTimer m_lastPeakTimer_R;
- static QPixmap * s_back;
- static QPixmap * s_leds;
- static QPixmap * s_knob;
-
- QPixmap * m_back;
- QPixmap * m_leds;
- QPixmap * m_knob;
+ QPixmap m_knob {embed::getIconPixmap("fader_knob")};
- bool m_levelsDisplayedInDBFS;
+ bool m_levelsDisplayedInDBFS {true};
- int m_moveStartPoint;
- float m_startValue;
+ int m_moveStartPoint {-1};
+ float m_startValue {0.};
- static SimpleTextFloat * s_textFloat;
+ static SimpleTextFloat* s_textFloat;
- QColor m_peakGreen;
- QColor m_peakRed;
- QColor m_peakYellow;
+ QColor m_peakOk {10, 212, 92};
+ QColor m_peakClip {193, 32, 56};
+ QColor m_peakWarn {214, 236, 82};
+ QColor m_unityMarker {63, 63, 63, 255};
+
+ bool m_renderUnityLine {true};
} ;
diff --git a/include/FileBrowser.h b/include/FileBrowser.h
index eafb827da..9185f5147 100644
--- a/include/FileBrowser.h
+++ b/include/FileBrowser.h
@@ -28,14 +28,19 @@
#include
#include
#include
+#include
+#include
+
+#include "FileSearch.h"
+#include "embed.h"
+
#if (QT_VERSION >= QT_VERSION_CHECK(5,14,0))
#include
#endif
#include
-
#include "SideBarWidget.h"
-
+#include "lmmsconfig.h"
class QLineEdit;
@@ -66,16 +71,31 @@ public:
*/
FileBrowser( const QString & directories, const QString & filter,
const QString & title, const QPixmap & pm,
- QWidget * parent, bool dirs_as_items = false, bool recurse = false,
+ QWidget * parent, bool dirs_as_items = false,
const QString& userDir = "",
const QString& factoryDir = "");
~FileBrowser() override = default;
+ static QStringList excludedPaths()
+ {
+ static auto s_excludedPaths = QStringList{
+#ifdef LMMS_BUILD_LINUX
+ "/bin", "/boot", "/dev", "/etc", "/proc", "/run", "/sbin",
+ "/sys"
+#endif
+#ifdef LMMS_BUILD_WIN32
+ "C:\\Windows"
+#endif
+ };
+ return s_excludedPaths;
+ }
+ static QDir::Filters dirFilters() { return QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot; }
+ static QDir::SortFlags sortFlags() { return QDir::LocaleAware | QDir::DirsFirst | QDir::Name | QDir::IgnoreCase; }
+
private slots:
void reloadTree();
- void expandItems( QTreeWidgetItem * item=nullptr, QList expandedDirs = QList() );
- bool filterAndExpandItems(const QString & filter, QTreeWidgetItem * item = nullptr);
+ void expandItems(const QList& expandedDirs, QTreeWidgetItem* item = nullptr);
void giveFocusToFilter();
private:
@@ -86,15 +106,23 @@ private:
void saveDirectoriesStates();
void restoreDirectoriesStates();
+ void foundSearchMatch(FileSearch* search, const QString& match);
+ void searchCompleted(FileSearch* search);
+ void onSearch(const QString& filter);
+ void displaySearch(bool on);
+
FileBrowserTreeWidget * m_fileBrowserTreeWidget;
+ FileBrowserTreeWidget * m_searchTreeWidget;
QLineEdit * m_filterEdit;
+ std::shared_ptr m_currentSearch;
+ QProgressBar* m_searchIndicator = nullptr;
+
QString m_directories; //!< Directories to search, split with '*'
QString m_filter; //!< Filter as used in QDir::match()
bool m_dirsAsItems;
- bool m_recurse;
void addContentCheckBox();
QCheckBox* m_showUserContent = nullptr;
@@ -167,12 +195,10 @@ private slots:
-
class Directory : public QTreeWidgetItem
{
public:
- Directory( const QString & filename, const QString & path,
- const QString & filter );
+ Directory(const QString& filename, const QString& path, const QString& filter, bool disableEntryPopulation = false);
void update();
@@ -197,14 +223,12 @@ public:
private:
- void initPixmaps();
-
bool addItems( const QString & path );
- static QPixmap * s_folderPixmap;
- static QPixmap * s_folderOpenedPixmap;
- static QPixmap * s_folderLockedPixmap;
+ QPixmap m_folderPixmap = embed::getIconPixmap("folder");
+ QPixmap m_folderOpenedPixmap = embed::getIconPixmap("folder_opened");
+ QPixmap m_folderLockedPixmap = embed::getIconPixmap("folder_locked");
//! Directories that lead here
//! Initially, this is just set to the current path of a directory
@@ -217,7 +241,7 @@ private:
QString m_filter;
int m_dirCount;
-
+ bool m_disableEntryPopulation = false;
} ;
@@ -274,20 +298,13 @@ public:
QString extension();
static QString extension( const QString & file );
+ static QString defaultFilters();
private:
void initPixmaps();
void determineFileType();
- static QPixmap * s_projectFilePixmap;
- static QPixmap * s_presetFilePixmap;
- static QPixmap * s_sampleFilePixmap;
- static QPixmap * s_soundfontFilePixmap;
- static QPixmap * s_vstPluginFilePixmap;
- static QPixmap * s_midiFilePixmap;
- static QPixmap * s_unknownFilePixmap;
-
QString m_path;
FileType m_type;
FileHandling m_handling;
diff --git a/include/FileSearch.h b/include/FileSearch.h
new file mode 100644
index 000000000..fd311c903
--- /dev/null
+++ b/include/FileSearch.h
@@ -0,0 +1,73 @@
+/*
+ * FileSearch.h - File system search task
+ *
+ * Copyright (c) 2024 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_FILE_SEARCH_H
+#define LMMS_FILE_SEARCH_H
+
+#include
+#include
+#include
+
+namespace lmms {
+//! A Qt object that encapsulates the operation of searching the file system.
+class FileSearch : public QObject
+{
+ Q_OBJECT
+public:
+ //! Number of milliseconds the search waits before signaling a matching result.
+ static constexpr int MillisecondsBetweenResults = 1;
+
+ //! Create a `FileSearch` object that uses the specified string filter `filter` and extension filters in
+ //! `extensions` to search within the given `paths`.
+ //! `excludedPaths`, `dirFilters`, and `sortFlags` can optionally be specified to exclude certain directories, filter
+ //! out certain types of entries, and sort the matches.
+ FileSearch(const QString& filter, const QStringList& paths, const QStringList& extensions,
+ const QStringList& excludedPaths = {}, QDir::Filters dirFilters = QDir::Filters{},
+ QDir::SortFlags sortFlags = QDir::SortFlags{});
+
+ //! Execute the search, emitting the `foundResult` signal when matches are found.
+ void operator()();
+
+ //! Cancel the search.
+ void cancel();
+
+signals:
+ //! Emitted when a result is found when searching the file system.
+ void foundMatch(FileSearch* search, const QString& match);
+
+ //! Emitted when the search completes.
+ void searchCompleted(FileSearch* search);
+
+private:
+ static auto isPathExcluded(const QString& path) -> bool;
+ QString m_filter;
+ QStringList m_paths;
+ QStringList m_extensions;
+ QStringList m_excludedPaths;
+ QDir::Filters m_dirFilters;
+ QDir::SortFlags m_sortFlags;
+ std::atomic m_cancel = false;
+};
+} // namespace lmms
+#endif // LMMS_FILE_SEARCH_H
diff --git a/include/FloatModelEditorBase.h b/include/FloatModelEditorBase.h
new file mode 100644
index 000000000..72f1450de
--- /dev/null
+++ b/include/FloatModelEditorBase.h
@@ -0,0 +1,121 @@
+/*
+ * FloatModelEditorBase.h - Base editor for float models
+ *
+ * Copyright (c) 2004-2008 Tobias Doerffel
+ * Copyright (c) 2023 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_FLOAT_MODEL_EDITOR_BASE_H
+#define LMMS_GUI_FLOAT_MODEL_EDITOR_BASE_H
+
+#include
+#include
+
+#include "AutomatableModelView.h"
+
+
+namespace lmms::gui
+{
+
+class SimpleTextFloat;
+
+class LMMS_EXPORT FloatModelEditorBase : public QWidget, public FloatModelView
+{
+ Q_OBJECT
+
+ mapPropertyFromModel(bool, isVolumeKnob, setVolumeKnob, m_volumeKnob);
+ mapPropertyFromModel(float, volumeRatio, setVolumeRatio, m_volumeRatio);
+
+ void initUi(const QString & name); //!< to be called by ctors
+
+public:
+ enum class DirectionOfManipulation
+ {
+ Vertical,
+ Horizontal
+ };
+
+ FloatModelEditorBase(DirectionOfManipulation directionOfManipulation = DirectionOfManipulation::Vertical, QWidget * _parent = nullptr, const QString & _name = QString()); //!< default ctor
+ FloatModelEditorBase(const FloatModelEditorBase& other) = delete;
+
+ // TODO: remove
+ inline void setHintText(const QString & txt_before, const QString & txt_after)
+ {
+ setDescription(txt_before);
+ setUnit(txt_after);
+ }
+
+signals:
+ void sliderPressed();
+ void sliderReleased();
+ void sliderMoved(float value);
+
+
+protected:
+ void contextMenuEvent(QContextMenuEvent * me) override;
+ void dragEnterEvent(QDragEnterEvent * dee) override;
+ void dropEvent(QDropEvent * de) override;
+ void focusOutEvent(QFocusEvent * fe) override;
+ void mousePressEvent(QMouseEvent * me) override;
+ void mouseReleaseEvent(QMouseEvent * me) override;
+ void mouseMoveEvent(QMouseEvent * me) override;
+ void mouseDoubleClickEvent(QMouseEvent * me) override;
+ void paintEvent(QPaintEvent * me) override;
+ void wheelEvent(QWheelEvent * me) override;
+
+ void enterEvent(QEvent *event) override;
+ void leaveEvent(QEvent *event) override;
+
+ virtual float getValue(const QPoint & p);
+
+private slots:
+ virtual void enterValue();
+ void friendlyUpdate();
+ void toggleScale();
+
+private:
+ virtual QString displayValue() const;
+
+ void doConnections() override;
+
+ void showTextFloat(int msecBeforeDisplay, int msecDisplayTime);
+ void setPosition(const QPoint & p);
+
+ inline float pageSize() const
+ {
+ return (model()->maxValue() - model()->minValue()) / 100.0f;
+ }
+
+ static SimpleTextFloat * s_textFloat;
+
+ BoolModel m_volumeKnob;
+ FloatModel m_volumeRatio;
+
+ QPoint m_lastMousePos; //!< mouse position in last mouseMoveEvent
+ float m_leftOver;
+ bool m_buttonPressed;
+
+ DirectionOfManipulation m_directionOfManipulation;
+};
+
+} // namespace lmms::gui
+
+#endif // LMMS_GUI_FLOAT_MODEL_EDITOR_BASE_H
diff --git a/include/GroupBox.h b/include/GroupBox.h
index 6a8f424f9..fdeb31c4d 100644
--- a/include/GroupBox.h
+++ b/include/GroupBox.h
@@ -50,6 +50,21 @@ public:
return m_led;
}
+ /**
+ * @brief Returns whether the LED button is shown or not
+ *
+ * @return true LED button is shown
+ * @return false LED button is hidden
+ */
+ bool ledButtonShown() const;
+
+ /**
+ * @brief Sets if the LED check box is shown or not
+ *
+ * @param value Set to true to show the LED check box or to false to hide it.
+ */
+ void setLedButtonShown(bool value);
+
int titleBarHeight() const
{
return m_titleBarHeight;
diff --git a/include/Instrument.h b/include/Instrument.h
index f23e0b401..e2e980372 100644
--- a/include/Instrument.h
+++ b/include/Instrument.h
@@ -31,10 +31,12 @@
#include "Flags.h"
#include "lmms_export.h"
#include "lmms_basics.h"
-#include "MemoryManager.h"
#include "Plugin.h"
#include "TimePos.h"
+#include
+
+
namespace lmms
{
@@ -47,7 +49,6 @@ class Track;
class LMMS_EXPORT Instrument : public Plugin
{
- MM_OPERATORS
public:
enum class Flag
{
@@ -61,7 +62,8 @@ public:
Instrument(InstrumentTrack * _instrument_track,
const Descriptor * _descriptor,
- const Descriptor::SubPluginFeatures::Key * key = nullptr);
+ const Descriptor::SubPluginFeatures::Key * key = nullptr,
+ Flags flags = Flag::NoFlags);
~Instrument() override = default;
// --------------------------------------------------------------------
@@ -93,18 +95,39 @@ public:
virtual f_cnt_t beatLen( NotePlayHandle * _n ) const;
- // some instruments need a certain number of release-frames even
- // if no envelope is active - such instruments can re-implement this
- // method for returning how many frames they at least like to have for
- // release
- virtual f_cnt_t desiredReleaseFrames() const
+ // This method can be overridden by instruments that need a certain
+ // release time even if no envelope is active. It returns the time
+ // in milliseconds that these instruments would like to have for
+ // their release stage.
+ virtual float desiredReleaseTimeMs() const
{
- return 0;
+ return 0.f;
}
- virtual Flags flags() const
+ // Converts the desired release time in milliseconds to the corresponding
+ // number of frames depending on the sample rate.
+ f_cnt_t desiredReleaseFrames() const
{
- return Flag::NoFlags;
+ const sample_rate_t sampleRate = getSampleRate();
+
+ return static_cast(std::ceil(desiredReleaseTimeMs() * sampleRate / 1000.f));
+ }
+
+ sample_rate_t getSampleRate() const;
+
+ bool isSingleStreamed() const
+ {
+ return m_flags.testFlag(Instrument::Flag::IsSingleStreamed);
+ }
+
+ bool isMidiBased() const
+ {
+ return m_flags.testFlag(Instrument::Flag::IsMidiBased);
+ }
+
+ bool isBendable() const
+ {
+ return !m_flags.testFlag(Instrument::Flag::IsNotBendable);
}
// sub-classes can re-implement this for receiving all incoming
@@ -144,11 +167,13 @@ protected:
// desiredReleaseFrames() frames are left
void applyRelease( sampleFrame * buf, const NotePlayHandle * _n );
+ float computeReleaseTimeMsByFrameCount(f_cnt_t frames) const;
+
private:
InstrumentTrack * m_instrumentTrack;
-
-} ;
+ Flags m_flags;
+};
LMMS_DECLARE_OPERATORS_FOR_FLAGS(Instrument::Flag)
diff --git a/include/InstrumentSoundShapingView.h b/include/InstrumentSoundShapingView.h
index 8f671514a..c9caea28c 100644
--- a/include/InstrumentSoundShapingView.h
+++ b/include/InstrumentSoundShapingView.h
@@ -56,7 +56,7 @@ private:
void modelChanged() override;
- InstrumentSoundShaping * m_ss;
+ InstrumentSoundShaping * m_ss = nullptr;
TabWidget * m_targetsTabWidget;
EnvelopeAndLfoView * m_envLfoViews[InstrumentSoundShaping::NumTargets];
diff --git a/include/InstrumentTrack.h b/include/InstrumentTrack.h
index 5efafe0c7..3d84df597 100644
--- a/include/InstrumentTrack.h
+++ b/include/InstrumentTrack.h
@@ -60,7 +60,6 @@ class MidiCCRackView;
class LMMS_EXPORT InstrumentTrack : public Track, public MidiEventProcessor
{
Q_OBJECT
- MM_OPERATORS
mapPropertyFromModel(int,getVolume,setVolume,m_volumeModel);
public:
InstrumentTrack( TrackContainer* tc );
diff --git a/include/InstrumentTrackView.h b/include/InstrumentTrackView.h
index d7d5fb83a..c7d524b36 100644
--- a/include/InstrumentTrackView.h
+++ b/include/InstrumentTrackView.h
@@ -25,7 +25,7 @@
#ifndef LMMS_GUI_INSTRUMENT_TRACK_VIEW_H
#define LMMS_GUI_INSTRUMENT_TRACK_VIEW_H
-#include "MixerLineLcdSpinBox.h"
+#include "MixerChannelLcdSpinBox.h"
#include "TrackView.h"
#include "InstrumentTrack.h"
@@ -93,13 +93,15 @@ private slots:
void handleConfigChange(QString cls, QString attr, QString value);
+private:
+ static QPixmap determinePixmap(InstrumentTrack* instrumentTrack);
private:
InstrumentTrackWindow * m_window;
// widgets in track-settings-widget
TrackLabelButton * m_tlb;
- MixerLineLcdSpinBox* m_mixerChannelNumber;
+ MixerChannelLcdSpinBox* m_mixerChannelNumber;
Knob * m_volumeKnob;
Knob * m_panningKnob;
FadeButton * m_activityIndicator;
diff --git a/include/InstrumentTrackWindow.h b/include/InstrumentTrackWindow.h
index 971c63899..48a352cbd 100644
--- a/include/InstrumentTrackWindow.h
+++ b/include/InstrumentTrackWindow.h
@@ -43,7 +43,7 @@ namespace gui
{
class EffectRackView;
-class MixerLineLcdSpinBox;
+class MixerChannelLcdSpinBox;
class InstrumentFunctionArpeggioView;
class InstrumentFunctionNoteStackingView;
class InstrumentMidiIOView;
@@ -142,7 +142,7 @@ private:
QLabel * m_pitchLabel;
LcdSpinBox* m_pitchRangeSpinBox;
QLabel * m_pitchRangeLabel;
- MixerLineLcdSpinBox * m_mixerChannelNumber;
+ MixerChannelLcdSpinBox * m_mixerChannelNumber;
diff --git a/include/IoHelper.h b/include/IoHelper.h
index 40c576b83..3c453fa58 100644
--- a/include/IoHelper.h
+++ b/include/IoHelper.h
@@ -75,13 +75,12 @@ inline FILE* F_OPEN_UTF8(std::string const& fname, const char* mode){
inline int fileToDescriptor(FILE* f, bool closeFile = true)
{
- int fh;
if (f == nullptr) {return -1;}
#ifdef LMMS_BUILD_WIN32
- fh = _dup(_fileno(f));
+ int fh = _dup(_fileno(f));
#else
- fh = dup(fileno(f));
+ int fh = dup(fileno(f));
#endif
if (closeFile) {fclose(f);}
diff --git a/include/Knob.h b/include/Knob.h
index d5739bb1c..3c3339a6f 100644
--- a/include/Knob.h
+++ b/include/Knob.h
@@ -26,12 +26,9 @@
#define LMMS_GUI_KNOB_H
#include
-#include
-#include
-#include
#include
-#include "AutomatableModelView.h"
+#include "FloatModelEditorBase.h"
class QPixmap;
@@ -50,7 +47,7 @@ enum class KnobType
void convertPixmapToGrayScale(QPixmap &pixMap);
-class LMMS_EXPORT Knob : public QWidget, public FloatModelView
+class LMMS_EXPORT Knob : public FloatModelEditorBase
{
Q_OBJECT
Q_ENUMS( KnobType )
@@ -72,9 +69,6 @@ class LMMS_EXPORT Knob : public QWidget, public FloatModelView
Q_PROPERTY(QColor arcActiveColor MEMBER m_arcActiveColor)
Q_PROPERTY(QColor arcInactiveColor MEMBER m_arcInactiveColor)
- mapPropertyFromModel(bool,isVolumeKnob,setVolumeKnob,m_volumeKnob);
- mapPropertyFromModel(float,volumeRatio,setVolumeRatio,m_volumeRatio);
-
Q_PROPERTY(KnobType knobNum READ knobNum WRITE setknobNum)
Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor)
@@ -87,13 +81,6 @@ public:
Knob( QWidget * _parent = nullptr, const QString & _name = QString() ); //!< default ctor
Knob( const Knob& other ) = delete;
- // TODO: remove
- inline void setHintText( const QString & _txt_before,
- const QString & _txt_after )
- {
- setDescription( _txt_before );
- setUnit( _txt_after );
- }
void setLabel( const QString & txt );
void setHtmlLabel( const QString &htmltxt );
@@ -125,46 +112,16 @@ public:
void setTextColor( const QColor & c );
-signals:
- void sliderPressed();
- void sliderReleased();
- void sliderMoved( float value );
-
-
protected:
- void contextMenuEvent( QContextMenuEvent * _me ) override;
- void dragEnterEvent( QDragEnterEvent * _dee ) override;
- void dropEvent( QDropEvent * _de ) override;
- void focusOutEvent( QFocusEvent * _fe ) override;
- void mousePressEvent( QMouseEvent * _me ) override;
- void mouseReleaseEvent( QMouseEvent * _me ) override;
- void mouseMoveEvent( QMouseEvent * _me ) override;
- void mouseDoubleClickEvent( QMouseEvent * _me ) override;
void paintEvent( QPaintEvent * _me ) override;
- void wheelEvent( QWheelEvent * _me ) override;
+
void changeEvent(QEvent * ev) override;
- void enterEvent(QEvent *event) override;
- void leaveEvent(QEvent *event) override;
-
- virtual float getValue( const QPoint & _p );
-
-private slots:
- virtual void enterValue();
- void friendlyUpdate();
- void toggleScale();
-
private:
- virtual QString displayValue() const;
-
- void doConnections() override;
-
QLineF calculateLine( const QPointF & _mid, float _radius,
float _innerRadius = 1) const;
void drawKnob( QPainter * _p );
- void showTextFloat(int msecBeforeDisplay, int msecDisplayTime);
- void setPosition( const QPoint & _p );
bool updateAngle();
int angleFromValue( float value, float minValue, float maxValue, float totalAngle ) const
@@ -172,25 +129,11 @@ private:
return static_cast( ( value - 0.5 * ( minValue + maxValue ) ) / ( maxValue - minValue ) * m_totalAngle ) % 360;
}
- inline float pageSize() const
- {
- return ( model()->maxValue() - model()->minValue() ) / 100.0f;
- }
-
-
- static SimpleTextFloat * s_textFloat;
-
QString m_label;
bool m_isHtmlLabel;
QTextDocument* m_tdRenderer;
std::unique_ptr m_knobPixmap;
- BoolModel m_volumeKnob;
- FloatModel m_volumeRatio;
-
- QPoint m_lastMousePos; //!< mouse position in last mouseMoveEvent
- float m_leftOver;
- bool m_buttonPressed;
float m_totalAngle;
int m_angle;
@@ -211,9 +154,7 @@ private:
QColor m_textColor;
KnobType m_knobNum;
-
-} ;
-
+};
} // namespace lmms::gui
diff --git a/include/LadspaBase.h b/include/LadspaBase.h
index 6569c5a30..0a2b067d4 100644
--- a/include/LadspaBase.h
+++ b/include/LadspaBase.h
@@ -26,6 +26,8 @@
#ifndef LMMS_LADSPA_BASE_H
#define LMMS_LADSPA_BASE_H
+#include
+
#include "LadspaManager.h"
#include "Plugin.h"
@@ -75,7 +77,7 @@ inline Plugin::Descriptor::SubPluginFeatures::Key ladspaKeyToSubPluginKey(
{
Plugin::Descriptor::SubPluginFeatures::Key::AttributeMap m;
QString file = _key.first;
- m["file"] = file.remove( QRegExp( "\\.so$" ) ).remove( QRegExp( "\\.dll$" ) );
+ m["file"] = file.remove(QRegularExpression("\\.so$")).remove(QRegularExpression("\\.dll$"));
m["plugin"] = _key.second;
return Plugin::Descriptor::SubPluginFeatures::Key( _desc, _name, m );
}
diff --git a/include/LadspaControl.h b/include/LadspaControl.h
index e4f0cd745..8af8f9923 100644
--- a/include/LadspaControl.h
+++ b/include/LadspaControl.h
@@ -41,6 +41,7 @@ namespace gui
{
class LadspaControlView;
+class LadspaMatrixControlDialog;
} // namespace gui
@@ -125,6 +126,7 @@ private:
friend class gui::LadspaControlView;
+ friend class gui::LadspaMatrixControlDialog;
} ;
diff --git a/include/LcdWidget.h b/include/LcdWidget.h
index cef121b3f..f900fea15 100644
--- a/include/LcdWidget.h
+++ b/include/LcdWidget.h
@@ -47,8 +47,6 @@ public:
LcdWidget(int numDigits, const QString& style, QWidget* parent, const QString& name = QString(),
bool leadingZero = false);
- ~LcdWidget() override;
-
void setValue(int value);
void setValue(float value);
void setLabel(const QString& label);
@@ -98,7 +96,7 @@ private:
QString m_display;
QString m_label;
- QPixmap* m_lcdPixmap;
+ QPixmap m_lcdPixmap;
QColor m_textColor;
QColor m_textShadowColor;
diff --git a/include/LedCheckBox.h b/include/LedCheckBox.h
index e3629e143..4f23cd74b 100644
--- a/include/LedCheckBox.h
+++ b/include/LedCheckBox.h
@@ -47,13 +47,12 @@ public:
LedCheckBox( const QString & _txt, QWidget * _parent,
const QString & _name = QString(),
- LedColor _color = LedColor::Yellow );
+ LedColor _color = LedColor::Yellow,
+ bool legacyMode = true);
LedCheckBox( QWidget * _parent,
const QString & _name = QString(),
- LedColor _color = LedColor::Yellow );
-
- ~LedCheckBox() override;
-
+ LedColor _color = LedColor::Yellow,
+ bool legacyMode = true);
inline const QString & text()
{
@@ -69,13 +68,18 @@ protected:
private:
- QPixmap * m_ledOnPixmap;
- QPixmap * m_ledOffPixmap;
+ QPixmap m_ledOnPixmap;
+ QPixmap m_ledOffPixmap;
QString m_text;
+ bool m_legacyMode;
+
void initUi( LedColor _color ); //!< to be called by ctors
+
void onTextUpdated(); //!< to be called when you updated @a m_text
+ void paintLegacy(QPaintEvent * p);
+ void paintNonLegacy(QPaintEvent * p);
} ;
diff --git a/include/LfoController.h b/include/LfoController.h
index 109edbd3f..01b4b1862 100644
--- a/include/LfoController.h
+++ b/include/LfoController.h
@@ -87,7 +87,7 @@ protected:
private:
float m_heldSample;
- SampleBuffer * m_userDefSampleBuffer;
+ std::shared_ptr m_userDefSampleBuffer = SampleBuffer::emptyBuffer();
protected slots:
void updatePhase();
diff --git a/include/LfoGraph.h b/include/LfoGraph.h
new file mode 100644
index 000000000..9d566770f
--- /dev/null
+++ b/include/LfoGraph.h
@@ -0,0 +1,65 @@
+/*
+ * LfoGraph.h - Displays LFO graphs
+ *
+ * Copyright (c) 2004-2009 Tobias Doerffel
+ * 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_LFO_GRAPH_H
+#define LMMS_GUI_LFO_GRAPH_H
+
+#include
+
+#include "ModelView.h"
+#include "embed.h"
+
+namespace lmms
+{
+
+class EnvelopeAndLfoParameters;
+
+namespace gui
+{
+
+class LfoGraph : public QWidget, public ModelView
+{
+public:
+ LfoGraph(QWidget* parent);
+
+protected:
+ void mousePressEvent(QMouseEvent* me) override;
+ void paintEvent(QPaintEvent* pe) override;
+
+private:
+ void drawInfoText(const EnvelopeAndLfoParameters&);
+ void toggleAmountModel();
+
+private:
+ QPixmap m_lfoGraph = embed::getIconPixmap("lfo_graph");
+
+ float m_randomGraph {0.};
+};
+
+} // namespace gui
+
+} // namespace lmms
+
+#endif // LMMS_GUI_LFO_GRAPH_H
diff --git a/include/LocaleHelper.h b/include/LocaleHelper.h
index 9c829fcaa..c1e1b4735 100644
--- a/include/LocaleHelper.h
+++ b/include/LocaleHelper.h
@@ -39,10 +39,9 @@ namespace lmms::LocaleHelper
inline double toDouble(QString str, bool* ok = nullptr)
{
bool isOkay;
- double value;
QLocale c(QLocale::C);
c.setNumberOptions(QLocale::RejectGroupSeparator);
- value = c.toDouble(str, &isOkay);
+ double value = c.toDouble(str, &isOkay);
if (!isOkay)
{
QLocale german(QLocale::German);
diff --git a/include/Lv2ControlBase.h b/include/Lv2ControlBase.h
index 2d44f0ecf..9bfb40f87 100644
--- a/include/Lv2ControlBase.h
+++ b/include/Lv2ControlBase.h
@@ -102,9 +102,6 @@ protected:
Lv2ControlBase& operator=(const Lv2ControlBase&) = delete;
- //! Must be checked after ctor or reload
- bool isValid() const { return m_valid; }
-
/*
overrides
*/
@@ -149,7 +146,6 @@ private:
//! fulfill LMMS' requirement of having stereo input and output
std::vector> m_procs;
- bool m_valid = true;
bool m_hasGUI = false;
unsigned m_channelsPerProc;
diff --git a/include/Lv2Options.h b/include/Lv2Options.h
index ca4fe2b7f..69d294cbe 100644
--- a/include/Lv2Options.h
+++ b/include/Lv2Options.h
@@ -30,8 +30,8 @@
#ifdef LMMS_HAVE_LV2
#include
-#include
-#include
+#include
+#include
#include
#include
#include
@@ -84,6 +84,8 @@ public:
return m_options.data();
}
+ void clear();
+
private:
//! Initialize an option internally
void initOption(LV2_URID key,
diff --git a/include/Lv2Proc.h b/include/Lv2Proc.h
index 76fa5eec2..65bd90698 100644
--- a/include/Lv2Proc.h
+++ b/include/Lv2Proc.h
@@ -66,6 +66,7 @@ namespace Lv2Ports
//! For Mono effects, 1 Lv2ControlBase references 2 Lv2Proc.
class Lv2Proc : public LinkedModelGroup
{
+ friend class Lv2ProcSuspender;
public:
static Plugin::Type check(const LilvPlugin* plugin,
std::vector &issues);
@@ -77,8 +78,6 @@ public:
~Lv2Proc() override;
void reload();
void onSampleRateChanged();
- //! Must be checked after ctor or reload
- bool isValid() const { return m_valid; }
/*
port access
@@ -172,10 +171,8 @@ protected:
void shutdownPlugin();
private:
- bool m_valid = true;
-
const LilvPlugin* m_plugin;
- LilvInstance* m_instance;
+ LilvInstance* m_instance = nullptr;
Lv2Features m_features;
// options
diff --git a/include/Lv2UridMap.h b/include/Lv2UridMap.h
index 6c22aca3e..23f8f758a 100644
--- a/include/Lv2UridMap.h
+++ b/include/Lv2UridMap.h
@@ -29,7 +29,7 @@
#ifdef LMMS_HAVE_LV2
-#include
+#include
#include // TODO: use semaphore, even though this is not realtime critical
#include
#include
diff --git a/include/Lv2ViewBase.h b/include/Lv2ViewBase.h
index 3c8f1bc3f..43086849c 100644
--- a/include/Lv2ViewBase.h
+++ b/include/Lv2ViewBase.h
@@ -37,7 +37,7 @@
class QPushButton;
class QMdiSubWindow;
-
+class QLabel;
namespace lmms
{
@@ -64,9 +64,25 @@ private:
};
+
+
+class HelpWindowEventFilter : public QObject
+{
+ Q_OBJECT
+ class Lv2ViewBase* const m_viewBase;
+protected:
+ bool eventFilter(QObject* obj, QEvent* event) override;
+public:
+ HelpWindowEventFilter(class Lv2ViewBase* viewBase);
+};
+
+
+
+
//! Base class for view for one Lv2 plugin
class LMMS_EXPORT Lv2ViewBase : public LinkedModelGroupsView
{
+ friend class HelpWindowEventFilter;
protected:
//! @param pluginWidget A child class which inherits QWidget
Lv2ViewBase(class QWidget *pluginWidget, Lv2ControlBase *ctrlBase);
@@ -79,6 +95,7 @@ protected:
void toggleUI();
void toggleHelp(bool visible);
+ void closeHelpWindow();
// to be called by child virtuals
//! Reconnect models if model changed
@@ -94,12 +111,14 @@ private:
static AutoLilvNode uri(const char *uriStr);
LinkedModelGroupView* getGroupView() override { return m_procView; }
+ void onHelpWindowClosed();
Lv2ViewProc* m_procView;
//! Numbers of controls per row; must be multiple of 2 for mono effects
const int m_colNum = 6;
QMdiSubWindow* m_helpWindow = nullptr;
+ HelpWindowEventFilter m_helpWindowEventFilter;
};
diff --git a/include/Lv2Worker.h b/include/Lv2Worker.h
index 7931f8e7c..b15bd9026 100644
--- a/include/Lv2Worker.h
+++ b/include/Lv2Worker.h
@@ -30,7 +30,7 @@
#ifdef LMMS_HAVE_LV2
#include
-#include
+#include
#include
#include
@@ -47,16 +47,17 @@ class Lv2Worker
{
public:
// CTOR/DTOR/feature access
- Lv2Worker(const LV2_Worker_Interface* iface, Semaphore* common_work_lock, bool threaded);
+ Lv2Worker(Semaphore* commonWorkLock, bool threaded);
~Lv2Worker();
- void setHandle(LV2_Handle handle) { m_handle = handle; }
+ void setHandle(LV2_Handle handle);
+ void setInterface(const LV2_Worker_Interface* newInterface);
LV2_Worker_Schedule* feature() { return &m_scheduleFeature; }
// public API
void emitResponses();
void notifyPluginThatRunFinished()
{
- if(m_iface->end_run) { m_iface->end_run(m_scheduleFeature.handle); }
+ if(m_interface->end_run) { m_interface->end_run(m_scheduleFeature.handle); }
}
// to be called only by static functions
@@ -69,9 +70,9 @@ private:
std::size_t bufferSize() const; //!< size of internal buffers
// parameters
- const LV2_Worker_Interface* m_iface;
- bool m_threaded;
- LV2_Handle m_handle;
+ const bool m_threaded;
+ const LV2_Worker_Interface* m_interface = nullptr;
+ LV2_Handle m_handle = nullptr;
LV2_Worker_Schedule m_scheduleFeature;
// threading/synchronization
diff --git a/include/MainWindow.h b/include/MainWindow.h
index 30d52ec3a..4442a7ac2 100644
--- a/include/MainWindow.h
+++ b/include/MainWindow.h
@@ -248,7 +248,6 @@ private slots:
void onExportProject();
void onExportProjectTracks();
void onImportProject();
- void onSongStopped();
void onSongModified();
void onProjectFileNameChanged();
diff --git a/include/MemoryManager.h b/include/MemoryManager.h
deleted file mode 100644
index fa2fe8110..000000000
--- a/include/MemoryManager.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * MemoryManager.h
- *
- * Copyright (c) 2017 Lukas W
- * Copyright (c) 2014 Vesa Kivimäki
- * Copyright (c) 2007-2014 Tobias Doerffel
- *
- * 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_MEMORY_MANAGER_H
-#define LMMS_MEMORY_MANAGER_H
-
-#include
-#include
-
-#include "lmms_export.h"
-
-namespace lmms
-{
-
-
-class LMMS_EXPORT MemoryManager
-{
-public:
- struct ThreadGuard
- {
- ThreadGuard();
- ~ThreadGuard();
- };
-
- static void * alloc( size_t size );
- static void free( void * ptr );
-};
-
-template
-struct MmAllocator
-{
- using value_type = T;
- template struct rebind {
- using other = MmAllocator;
- };
-
- T* allocate( std::size_t n )
- {
- return reinterpret_cast( MemoryManager::alloc( sizeof(T) * n ) );
- }
-
- void deallocate( T* p, std::size_t )
- {
- MemoryManager::free( p );
- }
-
- using vector = std::vector>;
-};
-
-
-#define MM_OPERATORS \
-public: \
-static void * operator new ( size_t size ) \
-{ \
- return MemoryManager::alloc( size ); \
-} \
-static void * operator new[] ( size_t size ) \
-{ \
- return MemoryManager::alloc( size ); \
-} \
-static void operator delete ( void * ptr ) \
-{ \
- MemoryManager::free( ptr ); \
-} \
-static void operator delete[] ( void * ptr ) \
-{ \
- MemoryManager::free( ptr ); \
-}
-
-// for use in cases where overriding new/delete isn't a possibility
-template
-T* MM_ALLOC(size_t count)
-{
- return reinterpret_cast(
- MemoryManager::alloc(sizeof(T) * count));
-}
-
-// and just for symmetry...
-template
-void MM_FREE(T* ptr)
-{
- MemoryManager::free(ptr);
-}
-
-
-} // namespace lmms
-
-#endif // LMMS_MEMORY_MANAGER_H
diff --git a/include/MidiClip.h b/include/MidiClip.h
index c2287bd00..b3ed0d84a 100644
--- a/include/MidiClip.h
+++ b/include/MidiClip.h
@@ -63,7 +63,8 @@ public:
// note management
Note * addNote( const Note & _new_note, const bool _quant_pos = true );
- void removeNote( Note * _note_to_del );
+ NoteVector::const_iterator removeNote(NoteVector::const_iterator it);
+ NoteVector::const_iterator removeNote(Note* note);
Note * noteAtStep( int _step );
diff --git a/include/MidiClipView.h b/include/MidiClipView.h
index 6558688b4..4285bf9da 100644
--- a/include/MidiClipView.h
+++ b/include/MidiClipView.h
@@ -27,6 +27,7 @@
#include
#include "ClipView.h"
+#include "embed.h"
namespace lmms
{
@@ -70,6 +71,7 @@ public slots:
protected slots:
void openInPianoRoll();
void setGhostInPianoRoll();
+ void setGhostInAutomationEditor();
void resetName();
void changeName();
@@ -85,10 +87,10 @@ protected:
private:
- static QPixmap * s_stepBtnOn0;
- static QPixmap * s_stepBtnOn200;
- static QPixmap * s_stepBtnOff;
- static QPixmap * s_stepBtnOffLight;
+ QPixmap m_stepBtnOn0 = embed::getIconPixmap("step_btn_on_0");
+ QPixmap m_stepBtnOn200 = embed::getIconPixmap("step_btn_on_200");
+ QPixmap m_stepBtnOff = embed::getIconPixmap("step_btn_off");
+ QPixmap m_stepBtnOffLight = embed::getIconPixmap("step_btn_off_light");
MidiClip* m_clip;
QPixmap m_paintPixmap;
@@ -99,7 +101,7 @@ private:
QColor m_mutedNoteBorderColor;
QStaticText m_staticTextName;
-
+
bool m_legacySEPattern;
} ;
diff --git a/include/MidiEventProcessor.h b/include/MidiEventProcessor.h
index 1c45b3e3f..0fcb9610e 100644
--- a/include/MidiEventProcessor.h
+++ b/include/MidiEventProcessor.h
@@ -26,7 +26,6 @@
#define LMMS_MIDI_EVENT_PROCESSOR_H
#include "MidiEvent.h"
-#include "MemoryManager.h"
#include "TimePos.h"
namespace lmms
@@ -35,7 +34,6 @@ namespace lmms
// all classes being able to process MIDI-events should inherit from this
class MidiEventProcessor
{
- MM_OPERATORS
public:
MidiEventProcessor() = default;
diff --git a/include/MixHelpers.h b/include/MixHelpers.h
index 6458c65fc..dde17dd02 100644
--- a/include/MixHelpers.h
+++ b/include/MixHelpers.h
@@ -45,6 +45,8 @@ bool sanitize( sampleFrame * src, int frames );
/*! \brief Add samples from src to dst */
void add( sampleFrame* dst, const sampleFrame* src, int frames );
+/*! \brief Multiply samples from `dst` by `coeff` */
+void multiply(sampleFrame* dst, float coeff, int frames);
/*! \brief Add samples from src multiplied by coeffSrc to dst */
void addMultiplied( sampleFrame* dst, const sampleFrame* src, float coeffSrc, int frames );
diff --git a/include/Mixer.h b/include/Mixer.h
index 35787a414..302492cab 100644
--- a/include/Mixer.h
+++ b/include/Mixer.h
@@ -31,7 +31,7 @@
#include "ThreadableJob.h"
#include
-
+#include
#include
namespace lmms
@@ -76,26 +76,18 @@ class MixerChannel : public ThreadableJob
bool requiresProcessing() const override { return true; }
void unmuteForSolo();
+ auto color() const -> const std::optional& { return m_color; }
+ void setColor(const std::optional& color) { m_color = color; }
- void setColor (QColor newColor)
- {
- m_color = newColor;
- m_hasColor = true;
- }
-
- // TODO C++17 and above: use std::optional instead
- QColor m_color;
- bool m_hasColor;
-
-
std::atomic_int m_dependenciesMet;
void incrementDeps();
void processed();
private:
void doProcessing() override;
-};
+ std::optional m_color;
+};
class MixerRoute : public QObject
{
diff --git a/include/MixerLineLcdSpinBox.h b/include/MixerChannelLcdSpinBox.h
similarity index 74%
rename from include/MixerLineLcdSpinBox.h
rename to include/MixerChannelLcdSpinBox.h
index 1ae2813f2..0abd9f100 100644
--- a/include/MixerLineLcdSpinBox.h
+++ b/include/MixerChannelLcdSpinBox.h
@@ -1,5 +1,5 @@
/*
- * MixerLineLcdSpinBox.h - a specialization of LcdSpnBox for setting mixer channels
+ * MixerChannelLcdSpinBox.h - a specialization of LcdSpnBox for setting mixer channels
*
* Copyright (c) 2004-2014 Tobias Doerffel
*
@@ -22,8 +22,8 @@
*
*/
-#ifndef LMMS_GUI_MIXER_LINE_LCD_SPIN_BOX_H
-#define LMMS_GUI_MIXER_LINE_LCD_SPIN_BOX_H
+#ifndef LMMS_GUI_MIXER_CHANNEL_LCD_SPIN_BOX_H
+#define LMMS_GUI_MIXER_CHANNEL_LCD_SPIN_BOX_H
#include "LcdSpinBox.h"
@@ -34,14 +34,14 @@ namespace lmms::gui
class TrackView;
-class MixerLineLcdSpinBox : public LcdSpinBox
+class MixerChannelLcdSpinBox : public LcdSpinBox
{
Q_OBJECT
public:
- MixerLineLcdSpinBox(int numDigits, QWidget * parent, const QString& name, TrackView * tv = nullptr) :
+ MixerChannelLcdSpinBox(int numDigits, QWidget * parent, const QString& name, TrackView * tv = nullptr) :
LcdSpinBox(numDigits, parent, name), m_tv(tv)
{}
- ~MixerLineLcdSpinBox() override = default;
+ ~MixerChannelLcdSpinBox() override = default;
void setTrackView(TrackView * tv);
@@ -56,4 +56,4 @@ private:
} // namespace lmms::gui
-#endif // LMMS_GUI_MIXER_LINE_LCD_SPIN_BOX_H
+#endif // LMMS_GUI_MIXER_CHANNEL_LCD_SPIN_BOX_H
diff --git a/include/MixerChannelView.h b/include/MixerChannelView.h
new file mode 100644
index 000000000..cbaf0ccc6
--- /dev/null
+++ b/include/MixerChannelView.h
@@ -0,0 +1,139 @@
+/*
+ * MixerChannelView.h - the mixer channel view
+ *
+ * Copyright (c) 2022 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 MIXER_CHANNEL_VIEW_H
+#define MIXER_CHANNEL_VIEW_H
+
+#include "EffectRackView.h"
+#include "Fader.h"
+#include "Knob.h"
+#include "LcdWidget.h"
+#include "PixmapButton.h"
+#include "SendButtonIndicator.h"
+
+#include
+#include
+#include
+#include
+#include
+
+namespace lmms
+{
+ class MixerChannel;
+}
+
+namespace lmms::gui
+{
+ constexpr int MIXER_CHANNEL_INNER_BORDER_SIZE = 3;
+ constexpr int MIXER_CHANNEL_OUTER_BORDER_SIZE = 1;
+
+ class MixerChannelView : public QWidget
+ {
+ Q_OBJECT
+ Q_PROPERTY(QBrush backgroundActive READ backgroundActive WRITE setBackgroundActive)
+ Q_PROPERTY(QColor strokeOuterActive READ strokeOuterActive WRITE setStrokeOuterActive)
+ Q_PROPERTY(QColor strokeOuterInactive READ strokeOuterInactive WRITE setStrokeOuterInactive)
+ Q_PROPERTY(QColor strokeInnerActive READ strokeInnerActive WRITE setStrokeInnerActive)
+ Q_PROPERTY(QColor strokeInnerInactive READ strokeInnerInactive WRITE setStrokeInnerInactive)
+ public:
+ enum class SendReceiveState
+ {
+ None, SendToThis, ReceiveFromThis
+ };
+
+ MixerChannelView(QWidget* parent, MixerView* mixerView, int channelIndex);
+ void paintEvent(QPaintEvent* event) override;
+ void contextMenuEvent(QContextMenuEvent*) override;
+ void mousePressEvent(QMouseEvent*) override;
+ void mouseDoubleClickEvent(QMouseEvent*) override;
+ bool eventFilter(QObject* dist, QEvent* event) override;
+
+ int channelIndex() const;
+ void setChannelIndex(int index);
+
+ SendReceiveState sendReceiveState() const;
+ void setSendReceiveState(const SendReceiveState& state);
+
+ QBrush backgroundActive() const;
+ void setBackgroundActive(const QBrush& c);
+
+ QColor strokeOuterActive() const;
+ void setStrokeOuterActive(const QColor& c);
+
+ QColor strokeOuterInactive() const;
+ void setStrokeOuterInactive(const QColor& c);
+
+ QColor strokeInnerActive() const;
+ void setStrokeInnerActive(const QColor& c);
+
+ QColor strokeInnerInactive() const;
+ void setStrokeInnerInactive(const QColor& c);
+
+ public slots:
+ void renameChannel();
+ void resetColor();
+ void selectColor();
+ void randomizeColor();
+
+ private slots:
+ void renameFinished();
+ void removeChannel();
+ void removeUnusedChannels();
+ void moveChannelLeft();
+ void moveChannelRight();
+
+ private:
+ bool confirmRemoval(int index);
+ QString elideName(const QString& name);
+ MixerChannel* mixerChannel() const;
+ auto isMasterChannel() const -> bool { return m_channelIndex == 0; }
+
+ private:
+ SendButtonIndicator* m_sendButton;
+ Knob* m_sendKnob;
+ LcdWidget* m_channelNumberLcd;
+ QLineEdit* m_renameLineEdit;
+ QGraphicsView* m_renameLineEditView;
+ QLabel* m_sendArrow;
+ QLabel* m_receiveArrow;
+ PixmapButton* m_muteButton;
+ PixmapButton* m_soloButton;
+ Fader* m_fader;
+ EffectRackView* m_effectRackView;
+ MixerView* m_mixerView;
+ SendReceiveState m_sendReceiveState = SendReceiveState::None;
+ int m_channelIndex = 0;
+ bool m_inRename = false;
+
+ QBrush m_backgroundActive;
+ QColor m_strokeOuterActive;
+ QColor m_strokeOuterInactive;
+ QColor m_strokeInnerActive;
+ QColor m_strokeInnerInactive;
+
+ friend class MixerView;
+ };
+} // namespace lmms::gui
+
+#endif
\ No newline at end of file
diff --git a/include/MixerLine.h b/include/MixerLine.h
deleted file mode 100644
index 68a61728c..000000000
--- a/include/MixerLine.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * MixerLine.h - Mixer line widget
- *
- * Copyright (c) 2009 Andrew Kelley
- * Copyright (c) 2014 Tobias Doerffel
- *
- * 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_MIXER_LINE_H
-#define LMMS_GUI_MIXER_LINE_H
-
-#include
-
-class QGraphicsView;
-class QLineEdit;
-
-namespace lmms::gui
-{
-
-
-class Knob;
-class LcdWidget;
-class MixerView;
-class SendButtonIndicator;
-
-class MixerLine : public QWidget
-{
- Q_OBJECT
-public:
- Q_PROPERTY( QBrush backgroundActive READ backgroundActive WRITE setBackgroundActive )
- Q_PROPERTY( QColor strokeOuterActive READ strokeOuterActive WRITE setStrokeOuterActive )
- Q_PROPERTY( QColor strokeOuterInactive READ strokeOuterInactive WRITE setStrokeOuterInactive )
- Q_PROPERTY( QColor strokeInnerActive READ strokeInnerActive WRITE setStrokeInnerActive )
- Q_PROPERTY( QColor strokeInnerInactive READ strokeInnerInactive WRITE setStrokeInnerInactive )
- MixerLine( QWidget * _parent, MixerView * _mv, int _channelIndex);
- ~MixerLine() override;
-
- void paintEvent( QPaintEvent * ) override;
- void mousePressEvent( QMouseEvent * ) override;
- void mouseDoubleClickEvent( QMouseEvent * ) override;
- void contextMenuEvent( QContextMenuEvent * ) override;
-
- inline int channelIndex() { return m_channelIndex; }
- void setChannelIndex(int index);
-
- Knob * m_sendKnob;
- SendButtonIndicator * m_sendBtn;
-
- QBrush backgroundActive() const;
- void setBackgroundActive( const QBrush & c );
-
- QColor strokeOuterActive() const;
- void setStrokeOuterActive( const QColor & c );
-
- QColor strokeOuterInactive() const;
- void setStrokeOuterInactive( const QColor & c );
-
- QColor strokeInnerActive() const;
- void setStrokeInnerActive( const QColor & c );
-
- QColor strokeInnerInactive() const;
- void setStrokeInnerInactive( const QColor & c );
-
- static const int MixerLineHeight;
-
- bool eventFilter (QObject *dist, QEvent *event) override;
-
-private:
- void drawMixerLine( QPainter* p, const MixerLine *mixerLine, bool isActive, bool sendToThis, bool receiveFromThis );
- QString elideName( const QString & name );
-
- MixerView * m_mv;
- LcdWidget* m_lcd;
- int m_channelIndex;
- QBrush m_backgroundActive;
- QColor m_strokeOuterActive;
- QColor m_strokeOuterInactive;
- QColor m_strokeInnerActive;
- QColor m_strokeInnerInactive;
- static QPixmap * s_sendBgArrow;
- static QPixmap * s_receiveBgArrow;
- bool m_inRename;
- QLineEdit * m_renameLineEdit;
- QGraphicsView * m_view;
-
-public slots:
- void renameChannel();
- void resetColor();
- void selectColor();
- void randomizeColor();
-
-private slots:
- void renameFinished();
- void removeChannel();
- void removeUnusedChannels();
- void moveChannelLeft();
- void moveChannelRight();
-};
-
-
-} // namespace lmms::gui
-
-#endif // LMMS_GUI_MIXER_LINE_H
diff --git a/include/MixerView.h b/include/MixerView.h
index 2bb5ed417..89315f93a 100644
--- a/include/MixerView.h
+++ b/include/MixerView.h
@@ -2,7 +2,7 @@
* MixerView.h - effect-mixer-view for LMMS
*
* Copyright (c) 2008-2014 Tobias Doerffel
- *
+ *
* This file is part of LMMS - https://lmms.io
*
* This program is free software; you can redistribute it and/or
@@ -30,6 +30,7 @@
#include
#include
+#include "MixerChannelView.h"
#include "ModelView.h"
#include "Engine.h"
#include "Fader.h"
@@ -37,65 +38,46 @@
#include "embed.h"
#include "EffectRackView.h"
-class QButtonGroup;
-
+namespace lmms
+{
+ class Mixer;
+}
namespace lmms::gui
{
-
-class MixerLine;
-
class LMMS_EXPORT MixerView : public QWidget, public ModelView,
public SerializingObjectHook
{
Q_OBJECT
public:
- class MixerChannelView
+ MixerView(Mixer* mixer);
+ void keyPressEvent(QKeyEvent* e) override;
+
+ void saveSettings(QDomDocument& doc, QDomElement& domElement) override;
+ void loadSettings(const QDomElement& domElement) override;
+
+ inline MixerChannelView* currentMixerChannel()
{
- public:
- MixerChannelView(QWidget * _parent, MixerView * _mv, int _chIndex );
-
- void setChannelIndex( int index );
-
- MixerLine * m_mixerLine;
- PixmapButton * m_muteBtn;
- PixmapButton * m_soloBtn;
- Fader * m_fader;
- EffectRackView * m_rackView;
- };
-
-
- MixerView();
- ~MixerView() override;
-
- void keyPressEvent(QKeyEvent * e) override;
-
- void saveSettings( QDomDocument & _doc, QDomElement & _this ) override;
- void loadSettings( const QDomElement & _this ) override;
-
- inline MixerLine * currentMixerLine()
- {
- return m_currentMixerLine;
+ return m_currentMixerChannel;
}
- inline MixerChannelView * channelView(int index)
+ inline MixerChannelView* channelView(int index)
{
return m_mixerChannelViews[index];
}
- void setCurrentMixerLine( MixerLine * _line );
- void setCurrentMixerLine( int _line );
+ void setCurrentMixerChannel(MixerChannelView* channel);
+ void setCurrentMixerChannel(int channel);
void clear();
// display the send button and knob correctly
- void updateMixerLine(int index);
+ void updateMixerChannel(int index);
// notify the view that a mixer channel was deleted
void deleteChannel(int index);
- bool confirmRemoval(int index);
// delete all unused channels
void deleteUnusedChannels();
@@ -115,22 +97,33 @@ public slots:
int addNewChannel();
protected:
- void closeEvent( QCloseEvent * _ce ) override;
-
+ void closeEvent(QCloseEvent* ce) override;
+
private slots:
void updateFaders();
+ // TODO This should be improved. Currently the solo and mute models are connected via
+ // the MixerChannelView's constructor with the MixerView. It would already be an improvement
+ // if the MixerView connected itself to each new MixerChannel that it creates/handles.
void toggledSolo();
+ void toggledMute();
private:
- QVector m_mixerChannelViews;
+ Mixer* getMixer() const;
+ void updateAllMixerChannels();
+ void connectToSoloAndMute(int channelIndex);
+ void disconnectFromSoloAndMute(int channelIndex);
- MixerLine * m_currentMixerLine;
+private:
+ QVector m_mixerChannelViews;
- QScrollArea * channelArea;
- QHBoxLayout * chLayout;
- QWidget * m_channelAreaWidget;
- QStackedLayout * m_racksLayout;
- QWidget * m_racksWidget;
+ MixerChannelView* m_currentMixerChannel;
+
+ QScrollArea* channelArea;
+ QHBoxLayout* chLayout;
+ QWidget* m_channelAreaWidget;
+ QStackedLayout* m_racksLayout;
+ QWidget* m_racksWidget;
+ Mixer* m_mixer;
void updateMaxChannelSelector();
diff --git a/include/NStateButton.h b/include/NStateButton.h
index a6b4c4d9a..c948fa843 100644
--- a/include/NStateButton.h
+++ b/include/NStateButton.h
@@ -55,25 +55,20 @@ public:
public slots:
- void changeState( int _n );
-
+ void changeState(int state);
signals:
- void changedState( int _n );
-
+ void changedState(int state);
protected:
- void mousePressEvent( QMouseEvent * _me ) override;
-
+ void mousePressEvent(QMouseEvent* me) override;
private:
- QVector > m_states;
+ QVector> m_states;
QString m_generalToolTip;
int m_curState;
-
-} ;
-
+};
} // namespace lmms::gui
diff --git a/include/NoCopyNoMove.h b/include/NoCopyNoMove.h
new file mode 100644
index 000000000..d59ddee83
--- /dev/null
+++ b/include/NoCopyNoMove.h
@@ -0,0 +1,47 @@
+/*
+ * NoCopyNoMove.h - NoCopyNoMove class
+ *
+ * Copyright (c) 2023-2023 Johannes Lorenz
+ *
+ * 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_NOCOPYNOMOVE_H
+#define LMMS_NOCOPYNOMOVE_H
+
+namespace lmms
+{
+
+/**
+ * Inherit this class to make your class non-copyable and non-movable
+ */
+class NoCopyNoMove
+{
+protected:
+ NoCopyNoMove() = default;
+ NoCopyNoMove(const NoCopyNoMove& other) = delete;
+ NoCopyNoMove& operator=(const NoCopyNoMove& other) = delete;
+ NoCopyNoMove(NoCopyNoMove&& other) = delete;
+ NoCopyNoMove& operator=(NoCopyNoMove&& other) = delete;
+};
+
+} // namespace lmms
+
+#endif // LMMS_NOCOPYNOMOVE_H
+
diff --git a/include/Note.h b/include/Note.h
index 2df196af2..08cbce3db 100644
--- a/include/Note.h
+++ b/include/Note.h
@@ -107,6 +107,16 @@ public:
Note( const Note & note );
~Note() override;
+ // Note types
+ enum class Type
+ {
+ Regular = 0,
+ Step
+ };
+
+ Type type() const { return m_type; }
+ inline void setType(Type t) { m_type = t; }
+
// used by GUI
inline void setSelected( const bool selected ) { m_selected = selected; }
inline void setOldKey( const int oldKey ) { m_oldKey = oldKey; }
@@ -253,6 +263,8 @@ private:
TimePos m_length;
TimePos m_pos;
DetuningHelper * m_detuning;
+
+ Type m_type = Type::Regular;
};
using NoteVector = std::vector;
diff --git a/include/NotePlayHandle.h b/include/NotePlayHandle.h
index 7105d6672..f70268132 100644
--- a/include/NotePlayHandle.h
+++ b/include/NotePlayHandle.h
@@ -32,7 +32,6 @@
#include "Note.h"
#include "PlayHandle.h"
#include "Track.h"
-#include "MemoryManager.h"
class QReadWriteLock;
@@ -47,7 +46,6 @@ using ConstNotePlayHandleList = QList;
class LMMS_EXPORT NotePlayHandle : public PlayHandle, public Note
{
- MM_OPERATORS
public:
void * m_pluginData;
std::unique_ptr> m_filter;
@@ -273,7 +271,6 @@ public:
private:
class BaseDetuning
{
- MM_OPERATORS
public:
BaseDetuning( DetuningHelper* detuning );
@@ -341,7 +338,6 @@ const int NPH_CACHE_INCREMENT = 16;
class NotePlayHandleManager
{
- MM_OPERATORS
public:
static void init();
static NotePlayHandle * acquire( InstrumentTrack* instrumentTrack,
diff --git a/include/Oscillator.h b/include/Oscillator.h
index dab0b948d..ea0227bd0 100644
--- a/include/Oscillator.h
+++ b/include/Oscillator.h
@@ -28,7 +28,9 @@
#include
#include
+#include
#include
+#include "interpolation.h"
#include "Engine.h"
#include "lmms_constants.h"
@@ -46,7 +48,6 @@ class IntModel;
class LMMS_EXPORT Oscillator
{
- MM_OPERATORS
public:
enum class WaveShape
{
@@ -91,18 +92,23 @@ public:
static void waveTableInit();
static void destroyFFTPlans();
- static void generateAntiAliasUserWaveTable(SampleBuffer* sampleBuffer);
+ static std::unique_ptr generateAntiAliasUserWaveTable(const SampleBuffer* sampleBuffer);
inline void setUseWaveTable(bool n)
{
m_useWaveTable = n;
}
- inline void setUserWave( const SampleBuffer * _wave )
+ void setUserWave(std::shared_ptr _wave)
{
m_userWave = _wave;
}
+ void setUserAntiAliasWaveTable(std::shared_ptr waveform)
+ {
+ m_userAntiAliasWaveTable = waveform;
+ }
+
void update(sampleFrame* ab, const fpp_t frames, const ch_cnt_t chnl, bool modulator = false);
// now follow the wave-shape-routines...
@@ -164,9 +170,18 @@ public:
return 1.0f - fast_rand() * 2.0f / FAST_RAND_MAX;
}
- inline sample_t userWaveSample( const float _sample ) const
+ static sample_t userWaveSample(const SampleBuffer* buffer, const float sample)
{
- return m_userWave->userWaveSample( _sample );
+ if (buffer == nullptr || buffer->size() == 0) { return 0; }
+ const auto frames = buffer->size();
+ const auto frame = sample * frames;
+ auto f1 = static_cast(frame) % frames;
+ if (f1 < 0)
+ {
+ f1 += frames;
+ }
+
+ return linearInterpolate(buffer->data()[f1][0], buffer->data()[(f1 + 1) % frames][0], fraction(frame));
}
struct wtSampleControl {
@@ -189,7 +204,7 @@ public:
control.f1 + 1 :
0;
control.band = waveTableBandFromFreq(
- m_freq * m_detuning_div_samplerate * Engine::audioEngine()->processingSampleRate());
+ m_freq * m_detuning_div_samplerate * Engine::audioEngine()->outputSampleRate());
return control;
}
@@ -203,7 +218,7 @@ public:
table[control.band][control.f2], fraction(control.frame));
}
- inline sample_t wtSample(const std::unique_ptr& table, const float sample) const
+ sample_t wtSample(const OscillatorConstants::waveform_t* table, const float sample) const
{
assert(table != nullptr);
wtSampleControl control = getWtSampleControl(sample);
@@ -247,7 +262,8 @@ private:
Oscillator * m_subOsc;
float m_phaseOffset;
float m_phase;
- const SampleBuffer * m_userWave;
+ std::shared_ptr m_userWave = SampleBuffer::emptyBuffer();
+ std::shared_ptr m_userAntiAliasWaveTable;
bool m_useWaveTable;
// There are many update*() variants; the modulator flag is stored as a member variable to avoid
// adding more explicit parameters to all of them. Can be converted to a parameter if needed.
diff --git a/include/Oscilloscope.h b/include/Oscilloscope.h
index 209370ce0..13c946aa5 100644
--- a/include/Oscilloscope.h
+++ b/include/Oscilloscope.h
@@ -38,7 +38,9 @@ class Oscilloscope : public QWidget
{
Q_OBJECT
public:
- Q_PROPERTY( QColor normalColor READ normalColor WRITE setNormalColor )
+ Q_PROPERTY( QColor leftChannelColor READ leftChannelColor WRITE setLeftChannelColor )
+ Q_PROPERTY( QColor rightChannelColor READ rightChannelColor WRITE setRightChannelColor )
+ Q_PROPERTY( QColor otherChannelsColor READ otherChannelsColor WRITE setOtherChannelsColor )
Q_PROPERTY( QColor clippingColor READ clippingColor WRITE setClippingColor )
Oscilloscope( QWidget * _parent );
@@ -46,8 +48,14 @@ public:
void setActive( bool _active );
- QColor const & normalColor() const;
- void setNormalColor(QColor const & normalColor);
+ QColor const & leftChannelColor() const;
+ void setLeftChannelColor(QColor const & leftChannelColor);
+
+ QColor const & rightChannelColor() const;
+ void setRightChannelColor(QColor const & rightChannelColor);
+
+ QColor const & otherChannelsColor() const;
+ void setOtherChannelsColor(QColor const & otherChannelsColor);
QColor const & clippingColor() const;
void setClippingColor(QColor const & clippingColor);
@@ -62,7 +70,7 @@ protected slots:
void updateAudioBuffer( const lmms::surroundSampleFrame * buffer );
private:
- QColor const & determineLineColor(float level) const;
+ bool clips(float level) const;
private:
QPixmap m_background;
@@ -71,7 +79,9 @@ private:
sampleFrame * m_buffer;
bool m_active;
- QColor m_normalColor;
+ QColor m_leftChannelColor;
+ QColor m_rightChannelColor;
+ QColor m_otherChannelsColor;
QColor m_clippingColor;
} ;
diff --git a/include/PianoRoll.h b/include/PianoRoll.h
index 38788180f..35550a5b3 100644
--- a/include/PianoRoll.h
+++ b/include/PianoRoll.h
@@ -73,6 +73,7 @@ class PianoRoll : public QWidget
Q_PROPERTY(QColor lineColor MEMBER m_lineColor)
Q_PROPERTY(QColor noteModeColor MEMBER m_noteModeColor)
Q_PROPERTY(QColor noteColor MEMBER m_noteColor)
+ Q_PROPERTY(QColor stepNoteColor MEMBER m_stepNoteColor)
Q_PROPERTY(QColor ghostNoteColor MEMBER m_ghostNoteColor)
Q_PROPERTY(QColor noteTextColor MEMBER m_noteTextColor)
Q_PROPERTY(QColor ghostNoteTextColor MEMBER m_ghostNoteTextColor)
@@ -339,12 +340,12 @@ private:
static const int cm_scrollAmtHoriz = 10;
static const int cm_scrollAmtVert = 1;
- static QPixmap * s_toolDraw;
- static QPixmap * s_toolErase;
- static QPixmap * s_toolSelect;
- static QPixmap * s_toolMove;
- static QPixmap * s_toolOpen;
- static QPixmap* s_toolKnife;
+ QPixmap m_toolDraw = embed::getIconPixmap("edit_draw");
+ QPixmap m_toolErase = embed::getIconPixmap("edit_erase");
+ QPixmap m_toolSelect = embed::getIconPixmap("edit_select");
+ QPixmap m_toolMove = embed::getIconPixmap("edit_move");
+ QPixmap m_toolOpen = embed::getIconPixmap("automation");
+ QPixmap m_toolKnife = embed::getIconPixmap("edit_knife");
static std::array prKeyOrder;
@@ -375,6 +376,7 @@ private:
TimePos m_currentPosition;
bool m_recording;
+ bool m_doAutoQuantization{false};
QList m_recordingNotes;
Note * m_currentNote;
@@ -466,6 +468,7 @@ private:
QColor m_lineColor;
QColor m_noteModeColor;
QColor m_noteColor;
+ QColor m_stepNoteColor;
QColor m_noteTextColor;
QColor m_ghostNoteColor;
QColor m_ghostNoteTextColor;
diff --git a/include/PianoView.h b/include/PianoView.h
index 6421ff438..3f8d8026f 100644
--- a/include/PianoView.h
+++ b/include/PianoView.h
@@ -30,6 +30,7 @@
#include "AutomatableModel.h"
#include "ModelView.h"
+#include "embed.h"
namespace lmms
{
@@ -73,12 +74,12 @@ private:
int getKeyHeight(int key_num) const;
IntModel *getNearestMarker(int key, QString* title = nullptr);
- static QPixmap * s_whiteKeyPm;
- static QPixmap * s_blackKeyPm;
- static QPixmap * s_whiteKeyPressedPm;
- static QPixmap * s_blackKeyPressedPm;
- static QPixmap * s_whiteKeyDisabledPm;
- static QPixmap * s_blackKeyDisabledPm;
+ QPixmap m_whiteKeyPm = embed::getIconPixmap("white_key");
+ QPixmap m_blackKeyPm = embed::getIconPixmap("black_key");
+ QPixmap m_whiteKeyPressedPm = embed::getIconPixmap("white_key_pressed");
+ QPixmap m_blackKeyPressedPm = embed::getIconPixmap("black_key_pressed");
+ QPixmap m_whiteKeyDisabledPm = embed::getIconPixmap("white_key_disabled");
+ QPixmap m_blackKeyDisabledPm = embed::getIconPixmap("black_key_disabled");
Piano * m_piano;
diff --git a/include/PixmapButton.h b/include/PixmapButton.h
index e8f546dc0..734bd11ae 100644
--- a/include/PixmapButton.h
+++ b/include/PixmapButton.h
@@ -56,6 +56,8 @@ protected:
void mouseReleaseEvent( QMouseEvent * _me ) override;
void mouseDoubleClickEvent( QMouseEvent * _me ) override;
+private:
+ bool isActive() const;
private:
QPixmap m_activePixmap;
diff --git a/include/Plugin.h b/include/Plugin.h
index 439dd95ad..100e9f658 100644
--- a/include/Plugin.h
+++ b/include/Plugin.h
@@ -30,7 +30,6 @@
#include "JournallingObject.h"
#include "Model.h"
-#include "MemoryManager.h"
class QWidget;
@@ -71,7 +70,6 @@ class PluginView;
*/
class LMMS_EXPORT Plugin : public Model, public JournallingObject
{
- MM_OPERATORS
Q_OBJECT
public:
enum class Type
diff --git a/include/RemotePluginBase.h b/include/RemotePluginBase.h
index 357be1bea..5214b6f92 100644
--- a/include/RemotePluginBase.h
+++ b/include/RemotePluginBase.h
@@ -41,10 +41,6 @@
#ifdef LMMS_HAVE_PROCESS_H
#include
#endif
-
-#include
-#include
-#include
#else // !(LMMS_HAVE_SYS_IPC_H && LMMS_HAVE_SEMAPHORE_H)
#ifdef LMMS_HAVE_UNISTD_H
#include
@@ -75,6 +71,7 @@
#include
#include
#include
+#include
#ifndef SYNC_WITH_SHM_FIFO
#include
@@ -85,6 +82,7 @@
#ifdef SYNC_WITH_SHM_FIFO
#include "SharedMemory.h"
+#include "SystemSemaphore.h"
#endif
namespace lmms
@@ -120,12 +118,11 @@ class shmFifo
} ;
public:
+#ifndef BUILD_REMOTE_PLUGIN_CLIENT
// constructor for master-side
shmFifo() :
m_invalid( false ),
m_master( true ),
- m_dataSem( QString() ),
- m_messageSem( QString() ),
m_lockDepth( 0 )
{
m_data.create(QUuid::createUuid().toString().toStdString());
@@ -133,26 +130,21 @@ public:
static int k = 0;
m_data->dataSem.semKey = ( getpid()<<10 ) + ++k;
m_data->messageSem.semKey = ( getpid()<<10 ) + ++k;
- m_dataSem.setKey( QString::number( m_data->dataSem.semKey ),
- 1, QSystemSemaphore::Create );
- m_messageSem.setKey( QString::number(
- m_data->messageSem.semKey ),
- 0, QSystemSemaphore::Create );
+ m_dataSem = SystemSemaphore{std::to_string(m_data->dataSem.semKey), 1u};
+ m_messageSem = SystemSemaphore{std::to_string(m_data->messageSem.semKey), 0u};
}
+#endif
// constructor for remote-/client-side - use _shm_key for making up
// the connection to master
shmFifo(const std::string& shmKey) :
m_invalid( false ),
m_master( false ),
- m_dataSem( QString() ),
- m_messageSem( QString() ),
m_lockDepth( 0 )
{
m_data.attach(shmKey);
- m_dataSem.setKey( QString::number( m_data->dataSem.semKey ) );
- m_messageSem.setKey( QString::number(
- m_data->messageSem.semKey ) );
+ m_dataSem = SystemSemaphore{std::to_string(m_data->dataSem.semKey)};
+ m_messageSem = SystemSemaphore{std::to_string(m_data->messageSem.semKey)};
}
inline bool isInvalid() const
@@ -336,11 +328,10 @@ private:
volatile bool m_invalid;
bool m_master;
SharedMemory m_data;
- QSystemSemaphore m_dataSem;
- QSystemSemaphore m_messageSem;
+ SystemSemaphore m_dataSem;
+ SystemSemaphore m_messageSem;
std::atomic_int m_lockDepth;
-
-} ;
+};
#endif // SYNC_WITH_SHM_FIFO
diff --git a/include/RingBuffer.h b/include/RingBuffer.h
index 90a607a13..98f726475 100644
--- a/include/RingBuffer.h
+++ b/include/RingBuffer.h
@@ -29,7 +29,7 @@
#include
#include
#include "lmms_basics.h"
-#include "MemoryManager.h"
+#include "lmms_export.h"
namespace lmms
@@ -41,7 +41,6 @@ namespace lmms
class LMMS_EXPORT RingBuffer : public QObject
{
Q_OBJECT
- MM_OPERATORS
public:
/** \brief Constructs a ringbuffer of specified size, will not care about samplerate changes
* \param size The size of the buffer in frames. The actual size will be size + period size
diff --git a/include/Sample.h b/include/Sample.h
new file mode 100644
index 000000000..92ac1a58a
--- /dev/null
+++ b/include/Sample.h
@@ -0,0 +1,134 @@
+/*
+ * Sample.h - State for container-class SampleBuffer
+ *
+ * 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_SAMPLE_H
+#define LMMS_SAMPLE_H
+
+#include
+#include