Compare commits
85 Commits
v1.2.0-rc5
...
v1.2.0-rc6
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1349d45d72 | ||
|
|
75a6502100 | ||
|
|
24ae559de5 | ||
|
|
235e8eef6f | ||
|
|
55d3fbc908 | ||
|
|
b808631975 | ||
|
|
8e9f74df37 | ||
|
|
fcc883f887 | ||
|
|
ee18011dc7 | ||
|
|
49dcd385f5 | ||
|
|
55da698d7c | ||
|
|
1220374a7f | ||
|
|
a2cb7e96ea | ||
|
|
3e8120d532 | ||
|
|
daa3f53515 | ||
|
|
68a621cc16 | ||
|
|
0caaebaecb | ||
|
|
bb43bfb961 | ||
|
|
5d90aecac9 | ||
|
|
03aa5fb3c7 | ||
|
|
511c7a64fe | ||
|
|
af61a82df8 | ||
|
|
9a52c7b901 | ||
|
|
08573fc96d | ||
|
|
ccd4ff3c2c | ||
|
|
84d3c935de | ||
|
|
832e87725a | ||
|
|
386c471ed7 | ||
|
|
fce9326192 | ||
|
|
e614711d29 | ||
|
|
d65fdd4ee6 | ||
|
|
50eada6b2b | ||
|
|
33368bd9d0 | ||
|
|
aaee2ecb15 | ||
|
|
22ca47abba | ||
|
|
18a4346fd5 | ||
|
|
07a23c4e3b | ||
|
|
e554a4c4b0 | ||
|
|
00f9590b18 | ||
|
|
d30a22487e | ||
|
|
b77027d6fb | ||
|
|
ee910d38fe | ||
|
|
1df461d64d | ||
|
|
3673e84ac1 | ||
|
|
ac543ffc75 | ||
|
|
87e6b48df7 | ||
|
|
fc5fc1cbaa | ||
|
|
0d1c874a60 | ||
|
|
7a8a925b83 | ||
|
|
6cd5317e09 | ||
|
|
b4e78065e7 | ||
|
|
a54c54097f | ||
|
|
e9b83378f9 | ||
|
|
ec0f47e9e3 | ||
|
|
38b69a7e3a | ||
|
|
788c990ae1 | ||
|
|
533f475943 | ||
|
|
1d63bd3b4e | ||
|
|
926b6542ae | ||
|
|
9f1c73bc12 | ||
|
|
063a505026 | ||
|
|
a8e8746011 | ||
|
|
31775752b4 | ||
|
|
33d2b71b01 | ||
|
|
fc9c3eadef | ||
|
|
edc8f43d5b | ||
|
|
3980e54667 | ||
|
|
0f0b08b852 | ||
|
|
a39ea2b163 | ||
|
|
c3b4767836 | ||
|
|
27007c258a | ||
|
|
a193ec25f2 | ||
|
|
e2c71e3369 | ||
|
|
d0b3be7f00 | ||
|
|
709fc7948b | ||
|
|
6e0dda692a | ||
|
|
46512fdf19 | ||
|
|
59eba30d33 | ||
|
|
bd8c27249f | ||
|
|
96c5f05120 | ||
|
|
a3d72def4d | ||
|
|
2c3df226ee | ||
|
|
7de9649b2f | ||
|
|
c3438a1b4e | ||
|
|
eb9b460925 |
11
.circleci/config.yml
Normal file
11
.circleci/config.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
# Dummy CircleCI Config File
|
||||
version: 2
|
||||
jobs:
|
||||
build:
|
||||
machine: true
|
||||
branches:
|
||||
ignore: stable-1.2
|
||||
steps:
|
||||
- run:
|
||||
name: Dummy
|
||||
command: echo "Dummy command to prevent error"
|
||||
2
.github/no-response.yml
vendored
Normal file
2
.github/no-response.yml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Label requiring a response
|
||||
responseRequiredLabel: "response required"
|
||||
@@ -1,14 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
PACKAGES="cmake libsndfile-dev fftw3-dev libvorbis-dev libogg-dev libmp3lame-dev
|
||||
libasound2-dev libjack-dev libsdl-dev libsamplerate0-dev libstk0-dev stk
|
||||
libasound2-dev libjack-jackd2-dev libsdl-dev libsamplerate0-dev libstk0-dev stk
|
||||
libfluidsynth-dev portaudio19-dev g++-multilib libfltk1.3-dev
|
||||
libgig-dev libsoundio-dev"
|
||||
|
||||
VST_PACKAGES="wine-dev libqt5x11extras5-dev qtbase5-private-dev libxcb-util0-dev libxcb-keysyms1-dev"
|
||||
|
||||
# Help with unmet dependencies
|
||||
PACKAGES="$PACKAGES $VST_PACKAGES libjack0"
|
||||
PACKAGES="$PACKAGES $VST_PACKAGES libjack-jackd2-0"
|
||||
|
||||
if [ $QT5 ]; then
|
||||
PACKAGES="$PACKAGES qt59base qt59translations qt59tools"
|
||||
|
||||
@@ -1,19 +1,13 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
PACKAGES="cmake pkgconfig fftw libogg libvorbis lame libsndfile libsamplerate jack sdl libgig libsoundio stk portaudio node fltk"
|
||||
PACKAGES="cmake pkgconfig fftw libogg libvorbis lame libsndfile libsamplerate jack sdl libgig libsoundio stk fluid-synth portaudio node fltk"
|
||||
|
||||
if [ $QT5 ]; then
|
||||
PACKAGES="$PACKAGES homebrew/versions/qt55"
|
||||
PACKAGES="$PACKAGES qt5"
|
||||
else
|
||||
PACKAGES="$PACKAGES cartr/qt4/qt"
|
||||
fi
|
||||
|
||||
brew install $PACKAGES ccache
|
||||
|
||||
# Recompile fluid-synth without CoreAudio per issues #649
|
||||
# Changes to fluid-synth.rb must be pushed to URL prior to use
|
||||
url=$(git remote get-url origin)
|
||||
branch=$(git symbolic-ref --short HEAD)
|
||||
brew install --build-from-source $url/raw/$branch/cmake/apple/fluid-synth.rb
|
||||
|
||||
sudo npm install -g appdmg
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
if [ $QT5 ]; then
|
||||
# Workaround; No FindQt5.cmake module exists
|
||||
export CMAKE_PREFIX_PATH="$(brew --prefix qt55)"
|
||||
export CMAKE_PREFIX_PATH="$(brew --prefix qt5)"
|
||||
fi
|
||||
|
||||
cmake $CMAKE_FLAGS -DUSE_WERROR=OFF ..
|
||||
|
||||
@@ -20,8 +20,7 @@ INCLUDE(FindPkgConfig)
|
||||
|
||||
STRING(TOUPPER "${CMAKE_PROJECT_NAME}" PROJECT_NAME_UCASE)
|
||||
|
||||
# Updated by maintenance tasks
|
||||
SET(PROJECT_YEAR 2017)
|
||||
SET(PROJECT_YEAR 2018)
|
||||
|
||||
SET(PROJECT_AUTHOR "LMMS Developers")
|
||||
SET(PROJECT_URL "https://lmms.io")
|
||||
@@ -31,7 +30,7 @@ SET(PROJECT_COPYRIGHT "2008-${PROJECT_YEAR} ${PROJECT_AUTHOR}")
|
||||
SET(VERSION_MAJOR "1")
|
||||
SET(VERSION_MINOR "2")
|
||||
SET(VERSION_RELEASE "0")
|
||||
SET(VERSION_STAGE "rc5")
|
||||
SET(VERSION_STAGE "rc6")
|
||||
SET(VERSION_BUILD "0")
|
||||
SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE}")
|
||||
IF(VERSION_STAGE)
|
||||
@@ -381,7 +380,7 @@ IF(WANT_JACK)
|
||||
SET(STATUS_JACK "OK (weak linking enabled)")
|
||||
SET(JACK_INCLUDE_DIRS "")
|
||||
# use dlsym instead
|
||||
SET(JACK_LIBRARIES "dl")
|
||||
SET(JACK_LIBRARIES ${CMAKE_DL_LIBS})
|
||||
ELSE()
|
||||
SET(STATUS_JACK "OK")
|
||||
ENDIF()
|
||||
@@ -497,6 +496,22 @@ FILE(REMOVE include/lmmsconfig.h)
|
||||
FILE(GLOB LMMS_INCLUDES "${CMAKE_SOURCE_DIR}/include/*.h")
|
||||
LIST(SORT LMMS_INCLUDES)
|
||||
|
||||
# Get list of all committers from git history, ordered by number of commits.
|
||||
# The CONTRIBUTORS file is used by AboutDialog. This information can be provided
|
||||
# with -DCONTRIBUTORS=/path/to/CONTRIBUTORS instead. For instance, to generate
|
||||
# this file for version 1.1.3, the command is:
|
||||
# git shortlog -sne v1.1.3 | cut -c8-
|
||||
FIND_PACKAGE(Git)
|
||||
IF(GIT_FOUND AND NOT CONTRIBUTORS)
|
||||
SET(CONTRIBUTORS "${CMAKE_BINARY_DIR}/CONTRIBUTORS")
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND "${GIT_EXECUTABLE}" shortlog -sne
|
||||
COMMAND cut -c8-
|
||||
OUTPUT_FILE "${CONTRIBUTORS}"
|
||||
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
|
||||
TIMEOUT 1)
|
||||
ENDIF()
|
||||
|
||||
# embedded resources stuff
|
||||
IF(WIN32 OR WIN64)
|
||||
# compile buildtools native
|
||||
|
||||
71
buildtools/update_locales
Executable file
71
buildtools/update_locales
Executable file
@@ -0,0 +1,71 @@
|
||||
#!/bin/bash
|
||||
aberr(){ printf "[\e[31mERROR\e[0m]: \e[1m%s\e[0m\n" "$*" >&2; }
|
||||
abinfo(){ printf "[\e[96mINFO\e[0m]: \e[1m%s\e[0m\n" "$*" >&2; }
|
||||
|
||||
function upload_to_tx() {
|
||||
if ! which tx > /dev/null; then
|
||||
aberr "You don't have Transifex client installed. \n Run \`pip install transifex-client\` to install it."
|
||||
exit 1
|
||||
fi
|
||||
abinfo "Uploading to transifex..."
|
||||
if ! tx push -s; then
|
||||
aberr "Problems occurred when uploading strings to Transifex."
|
||||
printf "\t Either there are syntax errors in source file or you don't have permission to update the source file."
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
}
|
||||
|
||||
function validate() {
|
||||
ERR_LANG=""
|
||||
ERR_BUF=""
|
||||
for i in data/locale/*.ts; do
|
||||
if ! ERR_BUF=$(lconvert-qt5 -i "${i}" -o "/tmp/test.qm" -of qm 2>&1); then
|
||||
ERR_LANG+="\e[96m$(basename "${i}")\e[0m: \e[93m${ERR_BUF}\e[0m "
|
||||
printf "\e[31mx\e[0m"
|
||||
continue
|
||||
fi
|
||||
printf "\e[32m.\e[0m"
|
||||
done
|
||||
echo ""
|
||||
if [[ "x${ERR_LANG}" != "x" ]]; then
|
||||
aberr "The following files failed the validation: "
|
||||
echo -e "${ERR_LANG}"
|
||||
fi
|
||||
}
|
||||
|
||||
abinfo "Checking for your environment..."
|
||||
if ! which lupdate-qt5 > /dev/null; then
|
||||
aberr "You don't seem to have Qt i18n tools installed."
|
||||
printf "\tUsually this comes with your Qt installation, or you need to\n"
|
||||
printf "\tinstall extra packages like \`qt5-tools\` or similar.\n"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
abinfo "Scanning directories..."
|
||||
|
||||
if test -d src/3rdparty/qt5-x11embed/3rdparty/ECM/; then
|
||||
# prevent from collecting strings in ECM
|
||||
rm -rf src/3rdparty/qt5-x11embed/3rdparty/ECM/
|
||||
fi
|
||||
|
||||
if ! lupdate-qt5 -I include/ src/ plugins/ -ts data/locale/en.ts; then
|
||||
aberr "There are some problems when collecting the strings."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
abinfo "Validating translations..."
|
||||
validate
|
||||
|
||||
abinfo "Translations successfully updated."
|
||||
printf "Do you want to upload translations to Transifex? [y/N]: "
|
||||
read -n 1 -r TX
|
||||
echo ""
|
||||
|
||||
if [[ "$TX" == "y" || "$TX" == "Y" ]]; then
|
||||
upload_to_tx
|
||||
fi
|
||||
|
||||
abinfo "No upload as required."
|
||||
|
||||
exit 0
|
||||
@@ -1,42 +0,0 @@
|
||||
# Copyright (c) 2009-present, Homebrew contributors
|
||||
# License: BSD 2-Clause
|
||||
|
||||
class FluidSynth < Formula
|
||||
desc "Real-time software synthesizer based on the SoundFont 2 specs"
|
||||
homepage "http://www.fluidsynth.org"
|
||||
url "https://downloads.sourceforge.net/project/fluidsynth/fluidsynth-1.1.6/fluidsynth-1.1.6.tar.gz"
|
||||
sha256 "50853391d9ebeda9b4db787efb23f98b1e26b7296dd2bb5d0d96b5bccee2171c"
|
||||
|
||||
bottle do
|
||||
cellar :any
|
||||
rebuild 1
|
||||
sha256 "ee86f0e263db0610a340592d725bd2c05bc5ed1bfa6eb496ae304297de261ae0" => :sierra
|
||||
sha256 "dfe31491d27c3c29ff4686900984e5884f89cd249d82b3dba4ad077f7bbe9057" => :el_capitan
|
||||
sha256 "6938c03a61b696870de92435dc0a6e6118fbb0d68adcd0d17ec8d30c2f7eee20" => :yosemite
|
||||
sha256 "5c5e00f88e45dd661c15f0e13793f9cc96f285b08200145ce8b77982350a5625" => :mavericks
|
||||
sha256 "83b972cf7aec57e78dc1c1a6b3e286d8b9bf2a2622e174bca42efa8576e36e5f" => :mountain_lion
|
||||
end
|
||||
|
||||
depends_on "pkg-config" => :build
|
||||
depends_on "cmake" => :build
|
||||
depends_on "glib"
|
||||
depends_on "libsndfile" => :optional
|
||||
depends_on "portaudio" => :optional
|
||||
|
||||
def install
|
||||
args = std_cmake_args
|
||||
args << "-Denable-framework=OFF" << "-DLIB_SUFFIX="
|
||||
args << "-Denable-portaudio=ON" if build.with? "portaudio"
|
||||
args << "-Denable-libsndfile=OFF" if build.without? "libsndfile"
|
||||
args << "-Denable-coreaudio=OFF" # Per lmms/issues/649
|
||||
|
||||
mkdir "build" do
|
||||
system "cmake", "..", *args
|
||||
system "make", "install"
|
||||
end
|
||||
end
|
||||
|
||||
test do
|
||||
assert_match /#{version}/, shell_output("#{bin}/fluidsynth --version")
|
||||
end
|
||||
end
|
||||
@@ -8,9 +8,7 @@
|
||||
|
||||
set -e
|
||||
|
||||
USERBIN="$HOME/bin"
|
||||
LINUXDEPLOYQT="$USERBIN/linuxdeployqt"
|
||||
APPIMAGETOOL="$USERBIN/appimagetool"
|
||||
LINUXDEPLOYQT="@CMAKE_BINARY_DIR@/linuxdeployqt"
|
||||
VERBOSITY=2 # 3=debug
|
||||
LOGFILE="@CMAKE_BINARY_DIR@/appimage.log"
|
||||
APPDIR="@CMAKE_BINARY_DIR@/@PROJECT_NAME_UCASE@.AppDir/"
|
||||
@@ -54,7 +52,7 @@ fi
|
||||
echo -e "\nWriting verbose output to \"${LOGFILE}\""
|
||||
|
||||
# Ensure linuxdeployqt uses the same qmake version as cmake
|
||||
export PATH="$HOME/bin:$(dirname "@QT_QMAKE_EXECUTABLE@")":$PATH
|
||||
export PATH="$(pwd -P)/squashfs-root/usr/bin:$(dirname "@QT_QMAKE_EXECUTABLE@")":$PATH
|
||||
|
||||
# Fetch portable linuxdeployqt if cache is older than $DAYSOLD
|
||||
echo -e "\nDownloading linuxdeployqt to ${LINUXDEPLOYQT}..."
|
||||
@@ -71,12 +69,8 @@ elif ! find "$LINUXDEPLOYQT" -mtime -$DAYSOLD 2>/dev/null|grep -q "." > /dev/nul
|
||||
touch "$LINUXDEPLOYQT"
|
||||
success "Downloaded $LINUXDEPLOYQT"
|
||||
"$LINUXDEPLOYQT" --appimage-extract > /dev/null 2>&1
|
||||
mv "squashfs-root/usr/bin/appimagetool" "$APPIMAGETOOL"
|
||||
APPIMAGETOOL="squashfs-root/usr/bin/appimagetool"
|
||||
success "Extracted $APPIMAGETOOL"
|
||||
mv "squashfs-root/usr/bin/mksquashfs" "$USERBIN/mksquashfs"
|
||||
success "Extracted $USERBIN/mksquashfs"
|
||||
rm -rf "squashfs-root/"
|
||||
|
||||
else
|
||||
skipped "$LINUXDEPLOYQT is less than $DAYSOLD days old"
|
||||
fi
|
||||
@@ -181,12 +175,10 @@ rm -f "${APPDIR}/usr/lib/libwine.so.1"
|
||||
# Use system-provided carla
|
||||
rm -f "${APPDIR}usr/lib/"libcarla*.so
|
||||
|
||||
# Remove problematic jack library, replace with weakjack
|
||||
# Move jack out of LD_LIBRARY_PATH
|
||||
if [ -e "${APPDIR}/usr/lib/libjack.so.0" ]; then
|
||||
rm -f "${APPDIR}/usr/lib/libjack.so.0"
|
||||
mkdir -p "${APPDIR}usr/lib/lmms/optional/"
|
||||
cp "@CMAKE_BINARY_DIR@/optional/weakjack.so" "${APPDIR}usr/lib/lmms/optional/weakjack.so"
|
||||
ln -sr "${APPDIR}usr/lib/lmms/optional/weakjack.so" "${APPDIR}usr/lib/lmms/optional/libjack.so.0"
|
||||
mv "${APPDIR}/usr/lib/libjack.so.0" "${APPDIR}usr/lib/lmms/optional/"
|
||||
fi
|
||||
|
||||
# Create AppImage
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
LIST(APPEND CMAKE_PREFIX_PATH /opt/wine-stable /opt/wine-devel /opt/wine-staging)
|
||||
|
||||
FIND_PATH(WINE_INCLUDE_DIR windows/windows.h PATH_SUFFIXES wine)
|
||||
FIND_PATH(WINE_INCLUDE_DIR windows/windows.h PATH_SUFFIXES wine wine/wine)
|
||||
FIND_LIBRARY(WINE_LIBRARY NAMES wine PATH_SUFFIXES wine i386-linux-gnu/wine)
|
||||
FIND_PROGRAM(WINE_CXX NAMES wineg++ winegcc winegcc64 winegcc32)
|
||||
|
||||
@@ -18,23 +18,23 @@ set(WINE_LIBRARIES ${WINE_LIBRARY} )
|
||||
|
||||
# Handle wine linking problems
|
||||
EXEC_PROGRAM(${WINE_CXX} ARGS "-v -m32 /dev/zero" OUTPUT_VARIABLE WINEBUILD_OUTPUT)
|
||||
STRING(REPLACE " " ";" WINEBUILD_FLAGS "${WINEBUILD_OUTPUT}")
|
||||
|
||||
# Debian systems
|
||||
IF("${WINEBUILD_OUTPUT}" MATCHES ".*x86_64-linux-gnu/wine/libwinecrt0.a.*")
|
||||
SET(WINE_LIBRARY_FIX "/usr/lib/i386-linux-gnu/" )
|
||||
# Fedora systems
|
||||
ELSEIF("${WINEBUILD_OUTPUT}" MATCHES "/usr/lib/lib64/wine/libwinecrt0.a.*")
|
||||
SET(WINE_LIBRARY_FIX "/usr/lib/i386/")
|
||||
# Wine stable
|
||||
ELSEIF("${WINEBUILD_OUTPUT}" MATCHES "/opt/wine-stable/lib64/wine/libwinecrt0.a.*")
|
||||
SET(WINE_LIBRARY_FIX "/opt/wine-stable/lib/")
|
||||
# Wine development
|
||||
ELSEIF("${WINEBUILD_OUTPUT}" MATCHES "/opt/wine-devel/lib64/wine/libwinecrt0.a.*")
|
||||
SET(WINE_LIBRARY_FIX "/opt/wine-devel/lib/")
|
||||
# Wine staging
|
||||
ELSEIF("${WINEBUILD_OUTPUT}" MATCHES "/opt/wine-staging/lib64/wine/libwinecrt0.a.*")
|
||||
SET(WINE_LIBRARY_FIX "/opt/wine-staging/lib/")
|
||||
ENDIF()
|
||||
FOREACH(FLAG ${WINEBUILD_FLAGS})
|
||||
IF("${FLAG}" MATCHES "libwinecrt0.a.*")
|
||||
# Debian systems
|
||||
STRING(REPLACE "/lib/x86_64-" "/lib/i386-" FLAG "${FLAG}")
|
||||
# Fedora systems
|
||||
STRING(REPLACE "/lib/lib64" "/lib/i386" FLAG "${FLAG}")
|
||||
# Gentoo systems
|
||||
STRING(REPLACE "/lib/wine-" "/lib32/wine-" FLAG "${FLAG}")
|
||||
# WineHQ (/opt/wine-stable, /opt/wine-devel, /opt/wine-staging)
|
||||
STRING(REPLACE "/lib64/wine/" "/lib/wine/" FLAG "${FLAG}")
|
||||
|
||||
STRING(REGEX REPLACE "/wine/libwinecrt0.a.*" "" WINE_LIBRARY_FIX "${FLAG}")
|
||||
SET(WINE_LIBRARY_FIX "${WINE_LIBRARY_FIX}/")
|
||||
ENDIF()
|
||||
ENDFOREACH()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Wine DEFAULT_MSG WINE_LIBRARIES WINE_INCLUDE_DIRS)
|
||||
|
||||
7083
data/locale/en.ts
7083
data/locale/en.ts
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@
|
||||
</eldata>
|
||||
<chordcreator chord="0" chordrange="1" chord-enabled="0"/>
|
||||
<arpeggiator arptime="117" arprange="2" arptime_denominator="4" syncmode="6" arpmode="1" arp-enabled="1" arp="0" arptime_numerator="4" arpdir="2" arpgate="20"/>
|
||||
<midiport inputcontroller="0" inports="" fixedoutputvelocity="-1" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="-1" fixedoutputnote="-1" outputprogram="1" basevelocity="127" readable="1"/>
|
||||
<midiport inputcontroller="0" inports="" fixedoutputvelocity="-1" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="-1" fixedoutputnote="-1" outputprogram="1" basevelocity="127" readable="0"/>
|
||||
<fxchain numofeffects="0" enabled="0"/>
|
||||
</instrumenttrack>
|
||||
</instrumenttracksettings>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</eldata>
|
||||
<chordcreator chord="0" chordrange="1" chord-enabled="0"/>
|
||||
<arpeggiator arptime="100" arprange="1" arptime_denominator="4" syncmode="0" arpmode="0" arp-enabled="0" arp="0" arptime_numerator="4" arpdir="0" arpgate="100"/>
|
||||
<midiport inputcontroller="0" inports="" fixedoutputvelocity="-1" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="-1" fixedoutputnote="-1" outputprogram="1" basevelocity="63" readable="1"/>
|
||||
<midiport inputcontroller="0" inports="" fixedoutputvelocity="-1" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="-1" fixedoutputnote="-1" outputprogram="1" basevelocity="63" readable="0"/>
|
||||
<fxchain numofeffects="6" enabled="1">
|
||||
<effect autoquit_numerator="4" autoquit_denominator="4" syncmode="0" autoquit="1" gate="0" name="ladspaeffect" wet="1" on="1">
|
||||
<ladspacontrols ports="10">
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</eldata>
|
||||
<chordcreator chord="0" chordrange="1" chord-enabled="0"/>
|
||||
<arpeggiator arptime="100" arprange="1" arptime_denominator="4" syncmode="0" arpmode="0" arp-enabled="0" arp="0" arptime_numerator="4" arpdir="0" arpgate="100"/>
|
||||
<midiport inputcontroller="0" inports="" fixedoutputvelocity="-1" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="62" fixedoutputnote="-1" outputprogram="1" basevelocity="63" readable="1"/>
|
||||
<midiport inputcontroller="0" inports="" fixedoutputvelocity="-1" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="62" fixedoutputnote="-1" outputprogram="1" basevelocity="63" readable="0"/>
|
||||
<fxchain numofeffects="3" enabled="1">
|
||||
<effect autoquit_numerator="4" autoquit_denominator="4" syncmode="0" autoquit="8000" gate="0.15" name="ladspaeffect" wet="1" on="1">
|
||||
<ladspacontrols ports="4">
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</eldata>
|
||||
<chordcreator chord="0" chordrange="1" chord-enabled="0"/>
|
||||
<arpeggiator arptime="100" arprange="1" arptime_denominator="4" syncmode="0" arpmode="0" arp-enabled="0" arp="0" arptime_numerator="4" arpdir="0" arpgate="100"/>
|
||||
<midiport inputcontroller="0" inports="" fixedoutputvelocity="0" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="-1" fixedoutputnote="-1" outputprogram="1" basevelocity="127" readable="1"/>
|
||||
<midiport inputcontroller="0" inports="" fixedoutputvelocity="0" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="-1" fixedoutputnote="-1" outputprogram="1" basevelocity="127" readable="0"/>
|
||||
<fxchain numofeffects="7" enabled="1">
|
||||
<effect autoquit_numerator="4" autoquit_denominator="4" syncmode="0" autoquit="8000" gate="0" name="ladspaeffect" wet="1" on="1">
|
||||
<ladspacontrols link="1" ports="2">
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</eldata>
|
||||
<chordcreator chord="0" chordrange="1" chord-enabled="0"/>
|
||||
<arpeggiator arptime="25" arprange="4" arptime_denominator="4" syncmode="0" arpmode="1" arp-enabled="0" arp="0" arptime_numerator="4" arpdir="0" arpgate="1"/>
|
||||
<midiport inputcontroller="0" inports="" fixedoutputvelocity="-1" inputchannel="1" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="127" fixedoutputnote="-1" outputprogram="1" basevelocity="63" readable="1"/>
|
||||
<midiport inputcontroller="0" inports="" fixedoutputvelocity="-1" inputchannel="1" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="127" fixedoutputnote="-1" outputprogram="1" basevelocity="63" readable="0"/>
|
||||
<fxchain numofeffects="3" enabled="1">
|
||||
<effect autoquit_numerator="4" autoquit_denominator="4" syncmode="0" autoquit="8000" gate="0" name="ladspaeffect" wet="1" on="1">
|
||||
<ladspacontrols ports="4">
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</eldata>
|
||||
<chordcreator chord="0" chordrange="1" chord-enabled="0"/>
|
||||
<arpeggiator arptime="100" arprange="1" arptime_denominator="4" syncmode="0" arpmode="0" arp-enabled="0" arp="0" arptime_numerator="4" arpdir="0" arpgate="100"/>
|
||||
<midiport inputcontroller="0" inports="" fixedoutputvelocity="0" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="-1" fixedoutputnote="-1" outputprogram="1" basevelocity="127" readable="1"/>
|
||||
<midiport inputcontroller="0" inports="" fixedoutputvelocity="0" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="-1" fixedoutputnote="-1" outputprogram="1" basevelocity="127" readable="0"/>
|
||||
<fxchain numofeffects="6" enabled="1">
|
||||
<effect autoquit_numerator="4" autoquit_denominator="4" syncmode="0" autoquit="8000" gate="0" name="ladspaeffect" wet="1" on="1">
|
||||
<ladspacontrols link="1" ports="2">
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</eldata>
|
||||
<chordcreator chord="0" chordrange="4" chord-enabled="1"/>
|
||||
<arpeggiator arptime="273" arprange="3" arptime_denominator="4" syncmode="5" arpmode="0" arp-enabled="0" arp="0" arptime_numerator="4" arpdir="1" arpgate="100"/>
|
||||
<midiport inputcontroller="0" inports="" fixedoutputvelocity="-1" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="-1" fixedoutputnote="-1" outputprogram="1" basevelocity="127" readable="1"/>
|
||||
<midiport inputcontroller="0" inports="" fixedoutputvelocity="-1" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="-1" fixedoutputnote="-1" outputprogram="1" basevelocity="127" readable="0"/>
|
||||
<fxchain numofeffects="7" enabled="1">
|
||||
<effect autoquit_numerator="1" autoquit_denominator="1" syncmode="0" autoquit="1" gate="0" name="stereomatrix" wet="0.38" on="1">
|
||||
<stereomatrixcontrols l-l="-0.5" l-r="-0.5" r-l="-0.5" r-r="-0.5"/>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</eldata>
|
||||
<chordcreator chord="0" chordrange="1" chord-enabled="0"/>
|
||||
<arpeggiator arptime="100" arprange="1" arptime_denominator="4" syncmode="0" arpmode="0" arp-enabled="0" arp="0" arptime_numerator="4" arpdir="0" arpgate="100"/>
|
||||
<midiport inputcontroller="0" inports="" fixedoutputvelocity="-1" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="127" fixedoutputnote="-1" outputprogram="1" basevelocity="127" readable="1"/>
|
||||
<midiport inputcontroller="0" inports="" fixedoutputvelocity="-1" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="127" fixedoutputnote="-1" outputprogram="1" basevelocity="127" readable="0"/>
|
||||
<fxchain numofeffects="2" enabled="1">
|
||||
<effect autoquit_numerator="4" autoquit_denominator="4" syncmode="0" autoquit="8000" gate="0" name="ladspaeffect" wet="1" on="1">
|
||||
<ladspacontrols ports="4">
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</eldata>
|
||||
<chordcreator chord="0" chordrange="1" chord-enabled="0"/>
|
||||
<arpeggiator arptime="100" arprange="1" arptime_denominator="4" syncmode="0" arpmode="0" arp-enabled="0" arp="0" arptime_numerator="4" arpdir="0" arpgate="100"/>
|
||||
<midiport inputcontroller="0" inports="" fixedoutputvelocity="-1" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="62" fixedoutputnote="-1" outputprogram="1" basevelocity="63" readable="1"/>
|
||||
<midiport inputcontroller="0" inports="" fixedoutputvelocity="-1" inputchannel="0" outputcontroller="0" writable="0" outputchannel="1" fixedinputvelocity="62" fixedoutputnote="-1" outputprogram="1" basevelocity="63" readable="0"/>
|
||||
<fxchain numofeffects="1" enabled="1">
|
||||
<effect autoquit_numerator="4" autoquit_denominator="4" syncmode="0" autoquit="8000" gate="0" name="ladspaeffect" wet="1" on="1">
|
||||
<ladspacontrols ports="4">
|
||||
|
||||
@@ -676,11 +676,6 @@
|
||||
<fxmixer maximized="0" height="332" visible="1" minimized="0" x="9" y="530" width="530">
|
||||
<fxchannel muted="0" num="0" name="Master" volume="0.31" soloed="0">
|
||||
<fxchain enabled="0" numofeffects="0"/>
|
||||
<connection>
|
||||
<muted>
|
||||
<Midicontroller outputchannel="1" outputcontroller="0" basevelocity="127" name="MIDI ch1 ctrl37" outputprogram="1" fixedinputvelocity="-1" fixedoutputvelocity="-1" fixedoutputnote="-1" inputchannel="1" inputcontroller="37" inports="" readable="1" type="2" writable="0"/>
|
||||
</muted>
|
||||
</connection>
|
||||
</fxchannel>
|
||||
</fxmixer>
|
||||
<ControllerRackView maximized="0" height="300" visible="0" minimized="0" x="955" y="413" width="400"/>
|
||||
|
||||
@@ -190,11 +190,6 @@
|
||||
<fxmixer maximized="0" height="332" visible="1" minimized="0" x="1" y="463" width="530">
|
||||
<fxchannel muted="0" num="0" name="Master" volume="1" soloed="0">
|
||||
<fxchain enabled="0" numofeffects="0"/>
|
||||
<connection>
|
||||
<muted>
|
||||
<Midicontroller outputchannel="1" outputcontroller="0" basevelocity="127" name="MIDI ch1 ctrl37" outputprogram="1" fixedinputvelocity="-1" fixedoutputvelocity="-1" fixedoutputnote="-1" inputchannel="1" inputcontroller="37" inports="" readable="1" type="2" writable="0"/>
|
||||
</muted>
|
||||
</connection>
|
||||
</fxchannel>
|
||||
<fxchannel muted="0" num="1" name="Drum" volume="1" soloed="0">
|
||||
<fxchain enabled="0" numofeffects="0"/>
|
||||
|
||||
@@ -117,11 +117,6 @@
|
||||
<fxmixer visible="1" width="561" height="332" x="10" y="314" maximized="0" minimized="0">
|
||||
<fxchannel num="0" muted="0" volume="1" name="Master" soloed="0">
|
||||
<fxchain numofeffects="0" enabled="0"/>
|
||||
<connection>
|
||||
<muted>
|
||||
<Midicontroller type="2" inputchannel="1" fixedinputvelocity="-1" outputcontroller="0" inports="" name="MIDI ch1 ctrl37" outputchannel="1" fixedoutputvelocity="-1" readable="1" fixedoutputnote="-1" outputprogram="1" writable="0" basevelocity="127" inputcontroller="37"/>
|
||||
</muted>
|
||||
</connection>
|
||||
</fxchannel>
|
||||
</fxmixer>
|
||||
<ControllerRackView visible="1" width="258" height="142" x="608" y="307" maximized="0" minimized="0"/>
|
||||
|
||||
@@ -235,11 +235,6 @@
|
||||
<fxmixer visible="1" width="561" height="332" x="10" y="314" maximized="0" minimized="0">
|
||||
<fxchannel num="0" muted="0" volume="1" name="Master" soloed="0">
|
||||
<fxchain numofeffects="0" enabled="0"/>
|
||||
<connection>
|
||||
<muted>
|
||||
<Midicontroller type="2" inputchannel="1" fixedinputvelocity="-1" outputcontroller="0" inports="" name="MIDI ch1 ctrl37" outputchannel="1" fixedoutputvelocity="-1" readable="1" fixedoutputnote="-1" outputprogram="1" writable="0" basevelocity="127" inputcontroller="37"/>
|
||||
</muted>
|
||||
</connection>
|
||||
</fxchannel>
|
||||
<fxchannel num="1" muted="0" volume="0.4" name="cr8000" soloed="0">
|
||||
<fxchain numofeffects="0" enabled="0"/>
|
||||
|
||||
@@ -134,11 +134,6 @@
|
||||
<fxmixer visible="1" width="561" height="332" x="10" y="314" maximized="0" minimized="0">
|
||||
<fxchannel num="0" muted="0" volume="1" name="Master" soloed="0">
|
||||
<fxchain numofeffects="0" enabled="0"/>
|
||||
<connection>
|
||||
<muted>
|
||||
<Midicontroller type="2" inputchannel="1" fixedinputvelocity="-1" outputcontroller="0" inports="" name="MIDI ch1 ctrl37" outputchannel="1" fixedoutputvelocity="-1" readable="1" fixedoutputnote="-1" outputprogram="1" writable="0" basevelocity="127" inputcontroller="37"/>
|
||||
</muted>
|
||||
</connection>
|
||||
</fxchannel>
|
||||
</fxmixer>
|
||||
<ControllerRackView visible="1" width="258" height="142" x="608" y="307" maximized="0" minimized="0"/>
|
||||
|
||||
@@ -20,11 +20,6 @@
|
||||
<fxmixer visible="1" width="561" height="332" x="5" y="310" maximized="0" minimized="0">
|
||||
<fxchannel num="0" muted="0" volume="1" name="Master" soloed="0">
|
||||
<fxchain numofeffects="0" enabled="0"/>
|
||||
<connection>
|
||||
<muted>
|
||||
<Midicontroller type="2" inputchannel="1" fixedinputvelocity="-1" outputcontroller="0" inports="" name="MIDI ch1 ctrl37" outputchannel="1" fixedoutputvelocity="-1" readable="1" fixedoutputnote="-1" outputprogram="1" writable="0" basevelocity="127" inputcontroller="37"/>
|
||||
</muted>
|
||||
</connection>
|
||||
</fxchannel>
|
||||
</fxmixer>
|
||||
<ControllerRackView visible="1" width="258" height="142" x="836" y="407" maximized="0" minimized="0"/>
|
||||
|
||||
@@ -303,11 +303,6 @@
|
||||
<fxmixer visible="1" width="561" height="332" x="10" y="314" maximized="0" minimized="0">
|
||||
<fxchannel num="0" muted="0" volume="1" name="Master" soloed="0">
|
||||
<fxchain numofeffects="0" enabled="0"/>
|
||||
<connection>
|
||||
<muted>
|
||||
<Midicontroller type="2" inputchannel="1" fixedinputvelocity="-1" outputcontroller="0" inports="" name="MIDI ch1 ctrl37" outputchannel="1" fixedoutputvelocity="-1" readable="1" fixedoutputnote="-1" outputprogram="1" writable="0" basevelocity="127" inputcontroller="37"/>
|
||||
</muted>
|
||||
</connection>
|
||||
</fxchannel>
|
||||
<fxchannel num="1" muted="0" volume="0.41" name="tr808" soloed="0">
|
||||
<fxchain numofeffects="0" enabled="0"/>
|
||||
|
||||
@@ -70,11 +70,6 @@
|
||||
<fxmixer visible="1" width="647" height="332" x="9" y="441" maximized="0" minimized="0">
|
||||
<fxchannel num="0" muted="0" volume="1" name="Master" soloed="0">
|
||||
<fxchain numofeffects="0" enabled="0"/>
|
||||
<connection>
|
||||
<muted>
|
||||
<Midicontroller type="2" inputchannel="1" fixedinputvelocity="-1" outputcontroller="0" inports="" name="MIDI ch1 ctrl37" outputchannel="1" fixedoutputvelocity="-1" readable="1" fixedoutputnote="-1" outputprogram="1" writable="0" basevelocity="127" inputcontroller="37"/>
|
||||
</muted>
|
||||
</connection>
|
||||
</fxchannel>
|
||||
</fxmixer>
|
||||
<ControllerRackView visible="1" width="258" height="173" x="664" y="444" maximized="0" minimized="0"/>
|
||||
|
||||
@@ -127,7 +127,7 @@ PianoRoll {
|
||||
qproperty-noteBorders: true; /* boolean property, set false to have borderless notes */
|
||||
qproperty-selectedNoteColor: rgb( 0, 125, 255 );
|
||||
qproperty-barColor: #4afd85;
|
||||
qproperty-markedSemitoneColor: rgba( 40, 40, 40, 200 );
|
||||
qproperty-markedSemitoneColor: rgba( 0, 255, 200, 60 );
|
||||
/* Grid colors */
|
||||
qproperty-lineColor: rgba( 128, 128, 128, 80 );
|
||||
qproperty-beatLineColor: rgba( 128, 128, 128, 160 );
|
||||
|
||||
BIN
data/themes/default/closed_branch.png
Executable file
BIN
data/themes/default/closed_branch.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 288 B |
BIN
data/themes/default/open_branch.png
Executable file
BIN
data/themes/default/open_branch.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 298 B |
Binary file not shown.
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 111 KiB |
@@ -7,6 +7,28 @@ QLabel, QTreeWidget, QListWidget, QGroupBox, QMenuBar {
|
||||
color: #d1d8e4;
|
||||
}
|
||||
|
||||
QTreeView {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
QTreeWidget::item:hover,
|
||||
QTreeWidget::branch:hover {
|
||||
background-color: #3C444E;
|
||||
}
|
||||
|
||||
QTreeWidget::item:selected,
|
||||
QTreeWidget::branch:selected {
|
||||
background-color: #17793b;
|
||||
}
|
||||
|
||||
QTreeView::branch:has-children:open {
|
||||
border-image: url("resources:open_branch.png") 0;
|
||||
}
|
||||
|
||||
QTreeView::branch:has-children:closed {
|
||||
border-image: url("resources:closed_branch.png") 0;
|
||||
}
|
||||
|
||||
QMdiArea {
|
||||
background-color: #111314;
|
||||
}
|
||||
@@ -122,9 +144,9 @@ PianoRoll {
|
||||
qproperty-noteColor: #0bd556;
|
||||
qproperty-noteOpacity: 165;
|
||||
qproperty-noteBorders: false; /* boolean property, set false to have borderless notes */
|
||||
qproperty-selectedNoteColor: #006b65;
|
||||
qproperty-selectedNoteColor: #064d79;
|
||||
qproperty-barColor: #078f3a;
|
||||
qproperty-markedSemitoneColor: #06170E;
|
||||
qproperty-markedSemitoneColor: rgba(255, 255, 255, 30);
|
||||
/* Grid colors */
|
||||
qproperty-lineColor: #292929;
|
||||
qproperty-beatLineColor: #2d6b45;
|
||||
|
||||
@@ -124,6 +124,8 @@ public:
|
||||
return m_writablePorts;
|
||||
}
|
||||
|
||||
void invalidateCilent();
|
||||
|
||||
MidiPortMenu* m_readablePortsMenu;
|
||||
MidiPortMenu* m_writablePortsMenu;
|
||||
|
||||
|
||||
@@ -175,6 +175,7 @@ public:
|
||||
void setAudioDevice( AudioDevice * _dev,
|
||||
const struct qualitySettings & _qs,
|
||||
bool _needs_fifo );
|
||||
void storeAudioDevice();
|
||||
void restoreAudioDevice();
|
||||
inline AudioDevice * audioDev()
|
||||
{
|
||||
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
|
||||
JobQueue() :
|
||||
m_items(),
|
||||
m_queueSize( 0 ),
|
||||
m_writeIndex( 0 ),
|
||||
m_itemsDone( 0 ),
|
||||
m_opMode( Static )
|
||||
{
|
||||
@@ -62,9 +62,9 @@ public:
|
||||
void wait();
|
||||
|
||||
private:
|
||||
#define JOB_QUEUE_SIZE 1024
|
||||
#define JOB_QUEUE_SIZE 8192
|
||||
QAtomicPointer<ThreadableJob> m_items[JOB_QUEUE_SIZE];
|
||||
AtomicInt m_queueSize;
|
||||
AtomicInt m_writeIndex;
|
||||
AtomicInt m_itemsDone;
|
||||
OperationMode m_opMode;
|
||||
|
||||
|
||||
@@ -88,7 +88,6 @@ private:
|
||||
|
||||
AudioFileDevice * m_fileDev;
|
||||
Mixer::qualitySettings m_qualitySettings;
|
||||
Mixer::qualitySettings m_oldQualitySettings;
|
||||
|
||||
volatile int m_progress;
|
||||
volatile bool m_abort;
|
||||
|
||||
@@ -419,6 +419,7 @@ enum RemoteMessageIDs
|
||||
IdQuit,
|
||||
IdSampleRateInformation,
|
||||
IdBufferSizeInformation,
|
||||
IdInformationUpdated,
|
||||
IdMidiEvent,
|
||||
IdStartProcessing,
|
||||
IdProcessingDone,
|
||||
@@ -807,6 +808,7 @@ public:
|
||||
{
|
||||
lock();
|
||||
sendMessage( message( IdSampleRateInformation ).addInt( _sr ) );
|
||||
waitForMessage( IdInformationUpdated, true );
|
||||
unlock();
|
||||
}
|
||||
|
||||
@@ -1318,9 +1320,14 @@ bool RemotePluginClient::processMessage( const message & _m )
|
||||
case IdSampleRateInformation:
|
||||
m_sampleRate = _m.getInt();
|
||||
updateSampleRate();
|
||||
reply_message.id = IdInformationUpdated;
|
||||
reply = true;
|
||||
break;
|
||||
|
||||
case IdBufferSizeInformation:
|
||||
// Should LMMS gain the ability to change buffer size
|
||||
// without a restart, it must wait for this message to
|
||||
// complete processing or else risk VST crashes
|
||||
m_bufferSize = _m.getInt();
|
||||
updateBufferSize();
|
||||
break;
|
||||
|
||||
@@ -65,6 +65,7 @@ private:
|
||||
void restoreMutedState();
|
||||
|
||||
const Mixer::qualitySettings m_qualitySettings;
|
||||
const Mixer::qualitySettings m_oldQualitySettings;
|
||||
const OutputSettings m_outputSettings;
|
||||
ProjectRenderer::ExportFileFormats m_format;
|
||||
QString m_outputPath;
|
||||
|
||||
@@ -290,8 +290,6 @@ private:
|
||||
|
||||
TextFloat * m_hint;
|
||||
|
||||
MidiTime m_oldTime;// used for undo/redo while mouse-button is pressed
|
||||
|
||||
// qproperty fields
|
||||
QColor m_mutedColor;
|
||||
QColor m_mutedBackgroundColor;
|
||||
|
||||
@@ -43,6 +43,7 @@ FlangerControls::FlangerControls( FlangerEffect *effect ) :
|
||||
|
||||
{
|
||||
connect( Engine::mixer(), SIGNAL( sampleRateChanged() ), this, SLOT( changedSampleRate() ) );
|
||||
connect( Engine::getSong(), SIGNAL( playbackStateChanged() ), this, SLOT( changedPlaybackState() ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -81,3 +82,9 @@ void FlangerControls::changedSampleRate()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void FlangerControls::changedPlaybackState()
|
||||
{
|
||||
m_effect->restartLFO();
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ public:
|
||||
|
||||
private slots:
|
||||
void changedSampleRate();
|
||||
void changedPlaybackState();
|
||||
|
||||
private:
|
||||
FlangerEffect* m_effect;
|
||||
|
||||
@@ -68,7 +68,7 @@ FlangerEffect::~FlangerEffect()
|
||||
{
|
||||
delete m_rDelay;
|
||||
}
|
||||
if(m_lfo )
|
||||
if( m_lfo )
|
||||
{
|
||||
delete m_lfo;
|
||||
}
|
||||
@@ -139,6 +139,15 @@ void FlangerEffect::changeSampleRate()
|
||||
|
||||
|
||||
|
||||
|
||||
void FlangerEffect::restartLFO()
|
||||
{
|
||||
m_lfo->restart();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ public:
|
||||
return &m_flangerControls;
|
||||
}
|
||||
void changeSampleRate();
|
||||
void restartLFO();
|
||||
|
||||
private:
|
||||
FlangerControls m_flangerControls;
|
||||
|
||||
@@ -53,6 +53,14 @@ public:
|
||||
|
||||
|
||||
|
||||
inline void restart()
|
||||
{
|
||||
m_phase = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline void setSampleRate ( int samplerate )
|
||||
{
|
||||
m_samplerate = samplerate;
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "VstEffect.h"
|
||||
|
||||
#include "GuiApplication.h"
|
||||
#include "Song.h"
|
||||
#include "TextFloat.h"
|
||||
#include "VstSubPluginFeatures.h"
|
||||
@@ -122,10 +124,14 @@ bool VstEffect::processAudioBuffer( sampleFrame * _buf, const fpp_t _frames )
|
||||
|
||||
void VstEffect::openPlugin( const QString & _plugin )
|
||||
{
|
||||
TextFloat * tf = TextFloat::displayMessage(
|
||||
VstPlugin::tr( "Loading plugin" ),
|
||||
VstPlugin::tr( "Please wait while loading VST plugin..." ),
|
||||
PLUGIN_NAME::getIconPixmap( "logo", 24, 24 ), 0 );
|
||||
TextFloat * tf = NULL;
|
||||
if( gui )
|
||||
{
|
||||
tf = TextFloat::displayMessage(
|
||||
VstPlugin::tr( "Loading plugin" ),
|
||||
VstPlugin::tr( "Please wait while loading VST plugin..." ),
|
||||
PLUGIN_NAME::getIconPixmap( "logo", 24, 24 ), 0 );
|
||||
}
|
||||
|
||||
QMutexLocker ml( &m_pluginMutex ); Q_UNUSED( ml );
|
||||
m_plugin = QSharedPointer<VstPlugin>(new VstPlugin( _plugin ));
|
||||
|
||||
@@ -41,10 +41,10 @@
|
||||
#include <QToolBar>
|
||||
#include <QLabel>
|
||||
|
||||
|
||||
VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
EffectControlDialog( _ctl ),
|
||||
m_pluginWidget( NULL ),
|
||||
|
||||
m_plugin( NULL ),
|
||||
tbLabel( NULL )
|
||||
{
|
||||
@@ -62,24 +62,18 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
embed_vst = m_plugin->embedMethod() != "none";
|
||||
|
||||
if (embed_vst) {
|
||||
m_plugin->createUI( nullptr, true );
|
||||
m_pluginWidget = m_plugin->pluginWidget( false );
|
||||
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
if( !m_pluginWidget )
|
||||
{
|
||||
m_pluginWidget = m_plugin->pluginWidget( false );
|
||||
if (m_plugin->hasEditor() && ! m_plugin->pluginWidget()) {
|
||||
m_plugin->createUI(this);
|
||||
}
|
||||
#endif
|
||||
|
||||
m_pluginWidget = m_plugin->pluginWidget();
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_plugin && (!embed_vst || m_pluginWidget) )
|
||||
if (m_plugin)
|
||||
{
|
||||
setWindowTitle( m_plugin->name() );
|
||||
|
||||
QPushButton * btn = new QPushButton( tr( "Show/hide" ) );
|
||||
QPushButton * btn = new QPushButton( tr( "Show/hide" ));
|
||||
|
||||
if (embed_vst) {
|
||||
btn->setCheckable( true );
|
||||
@@ -87,14 +81,15 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
connect( btn, SIGNAL( toggled( bool ) ),
|
||||
SLOT( togglePluginUI( bool ) ) );
|
||||
} else {
|
||||
connect( btn, SIGNAL( clicked( bool ) ),
|
||||
SLOT( togglePluginUI( bool ) ) );
|
||||
connect( btn, SIGNAL( clicked() ),
|
||||
m_plugin.data(), SLOT( toggleUI() ) );
|
||||
}
|
||||
|
||||
btn->setMinimumWidth( 78 );
|
||||
btn->setMaximumWidth( 78 );
|
||||
btn->setMinimumHeight( 24 );
|
||||
btn->setMaximumHeight( 24 );
|
||||
m_togglePluginButton = btn;
|
||||
|
||||
m_managePluginButton = new PixmapButton( this, "" );
|
||||
m_managePluginButton->setCheckable( false );
|
||||
@@ -192,7 +187,10 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
_ctl->m_selPresetButton->setWhatsThis(
|
||||
tr( "Click here to select presets that are currently loaded in VST." ) );
|
||||
|
||||
_ctl->m_selPresetButton->setMenu(_ctl->menu);
|
||||
QMenu * menu = new QMenu;
|
||||
connect( menu, SIGNAL( aboutToShow() ), _ctl, SLOT( updateMenu() ) );
|
||||
|
||||
_ctl->m_selPresetButton->setMenu(menu);
|
||||
|
||||
_ctl->m_selPresetButton->setMinimumWidth( 16 );
|
||||
_ctl->m_selPresetButton->setMaximumWidth( 16 );
|
||||
@@ -220,7 +218,7 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
|
||||
int newSize = 0;
|
||||
|
||||
if (embed_vst) {
|
||||
if (m_pluginWidget) {
|
||||
newSize = m_pluginWidget->width() + 20;
|
||||
}
|
||||
newSize = std::max(newSize, 250);
|
||||
@@ -236,7 +234,7 @@ VstEffectControlDialog::VstEffectControlDialog( VstEffectControls * _ctl ) :
|
||||
l->addItem( new QSpacerItem( newSize - 20, 30, QSizePolicy::Fixed,
|
||||
QSizePolicy::Fixed ), 1, 0 );
|
||||
l->addWidget( resize, 2, 0, 1, 1, Qt::AlignCenter );
|
||||
if (embed_vst) {
|
||||
if (m_pluginWidget) {
|
||||
l->addWidget( m_pluginWidget, 3, 0, 1, 1, Qt::AlignCenter );
|
||||
}
|
||||
l->setRowStretch( 5, 1 );
|
||||
@@ -275,12 +273,28 @@ void VstEffectControlDialog::paintEvent( QPaintEvent * )
|
||||
}
|
||||
}
|
||||
|
||||
void VstEffectControlDialog::showEvent(QShowEvent *_se)
|
||||
{
|
||||
EffectControlDialog::showEvent( _se );
|
||||
// Workaround for a (unexplained) bug where on project-load the effect
|
||||
// control window has size 0 and would only restore to the proper size upon
|
||||
// moving the window or interacting with it.
|
||||
if (parentWidget()) {
|
||||
parentWidget()->adjustSize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
VstEffectControlDialog::~VstEffectControlDialog()
|
||||
{
|
||||
//delete m_pluginWidget;
|
||||
#if !(QT_VERSION < 0x050000 && defined(LMMS_BUILD_LINUX))
|
||||
if (m_pluginWidget && layout()) {
|
||||
layout()->removeWidget(m_pluginWidget);
|
||||
m_pluginWidget->setParent(nullptr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -292,6 +306,14 @@ void VstEffectControlDialog::togglePluginUI( bool checked )
|
||||
return;
|
||||
}
|
||||
|
||||
m_plugin->toggleUI();
|
||||
if ( m_togglePluginButton->isChecked() != checked ) {
|
||||
m_togglePluginButton->setChecked( checked );
|
||||
}
|
||||
|
||||
if ( checked ) {
|
||||
m_plugin->showUI();
|
||||
} else {
|
||||
m_plugin->hideUI();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,10 +50,12 @@ public:
|
||||
|
||||
protected:
|
||||
virtual void paintEvent( QPaintEvent * _pe );
|
||||
virtual void showEvent( QShowEvent* _se ) override;
|
||||
|
||||
private:
|
||||
QWidget * m_pluginWidget;
|
||||
|
||||
QPushButton * m_togglePluginButton;
|
||||
PixmapButton * m_openPresetButton;
|
||||
PixmapButton * m_rolLPresetButton;
|
||||
PixmapButton * m_rolRPresetButton;
|
||||
@@ -64,7 +66,7 @@ private:
|
||||
|
||||
QLabel * tbLabel;
|
||||
|
||||
private slots:
|
||||
public slots:
|
||||
void togglePluginUI( bool checked );
|
||||
} ;
|
||||
|
||||
|
||||
@@ -39,13 +39,11 @@ VstEffectControls::VstEffectControls( VstEffect * _eff ) :
|
||||
m_effect( _eff ),
|
||||
m_subWindow( NULL ),
|
||||
knobFModel( NULL ),
|
||||
vstKnobs( NULL ),
|
||||
ctrHandle( NULL ),
|
||||
lastPosInMenu (0)
|
||||
lastPosInMenu (0),
|
||||
m_vstGuiVisible ( true )
|
||||
// m_presetLabel ( NULL )
|
||||
{
|
||||
menu = new QMenu;
|
||||
connect( menu, SIGNAL( aboutToShow() ), this, SLOT( updateMenu() ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -67,24 +65,20 @@ void VstEffectControls::loadSettings( const QDomElement & _this )
|
||||
m_effect->m_pluginMutex.lock();
|
||||
if( m_effect->m_plugin != NULL )
|
||||
{
|
||||
m_vstGuiVisible = _this.attribute( "guivisible" ).toInt();
|
||||
|
||||
m_effect->m_plugin->loadSettings( _this );
|
||||
|
||||
const QMap<QString, QString> & dump = m_effect->m_plugin->parameterDump();
|
||||
paramCount = dump.size();
|
||||
char paramStr[35];
|
||||
vstKnobs = new Knob *[ paramCount ];
|
||||
knobFModel = new FloatModel *[ paramCount ];
|
||||
QStringList s_dumpValues;
|
||||
QWidget * widget = new QWidget();
|
||||
for( int i = 0; i < paramCount; i++ )
|
||||
{
|
||||
sprintf( paramStr, "param%d", i );
|
||||
s_dumpValues = dump[ paramStr ].split( ":" );
|
||||
|
||||
vstKnobs[i] = new Knob( knobBright_26, widget, s_dumpValues.at( 1 ) );
|
||||
vstKnobs[i]->setHintText( s_dumpValues.at( 1 ) + ":", "" );
|
||||
vstKnobs[i]->setLabel( s_dumpValues.at( 1 ).left( 15 ) );
|
||||
|
||||
knobFModel[i] = new FloatModel( 0.0f, 0.0f, 1.0f, 0.01f, this, QString::number(i) );
|
||||
knobFModel[i]->loadSettings( _this, paramStr );
|
||||
|
||||
@@ -96,8 +90,6 @@ void VstEffectControls::loadSettings( const QDomElement & _this )
|
||||
}
|
||||
|
||||
connect( knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) );
|
||||
|
||||
vstKnobs[i]->setModel( knobFModel[i] );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -149,8 +141,16 @@ void VstEffectControls::saveSettings( QDomDocument & _doc, QDomElement & _this )
|
||||
|
||||
int VstEffectControls::controlCount()
|
||||
{
|
||||
return m_effect->m_plugin != NULL &&
|
||||
m_effect->m_plugin->hasEditor() ? 1 : 0;
|
||||
return m_effect->m_plugin != NULL ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EffectControlDialog *VstEffectControls::createView()
|
||||
{
|
||||
auto dialog = new VstEffectControlDialog( this );
|
||||
dialog->togglePluginUI( m_vstGuiVisible );
|
||||
return dialog;
|
||||
}
|
||||
|
||||
|
||||
@@ -317,7 +317,7 @@ manageVSTEffectView::manageVSTEffectView( VstEffect * _eff, VstEffectControls *
|
||||
m_vi->m_subWindow->setWidget(m_vi->m_scrollArea);
|
||||
m_vi->m_subWindow->setWindowTitle( _eff->m_plugin->name() + tr( " - VST parameter control" ) );
|
||||
m_vi->m_subWindow->setWindowIcon( PLUGIN_NAME::getIconPixmap( "logo" ) );
|
||||
//m_vi->m_subWindow->setAttribute(Qt::WA_DeleteOnClose);
|
||||
m_vi->m_subWindow->setAttribute(Qt::WA_DeleteOnClose, false);
|
||||
|
||||
|
||||
l->setContentsMargins( 20, 10, 10, 10 );
|
||||
@@ -358,37 +358,35 @@ manageVSTEffectView::manageVSTEffectView( VstEffect * _eff, VstEffectControls *
|
||||
const QMap<QString, QString> & dump = m_effect->m_plugin->parameterDump();
|
||||
m_vi->paramCount = dump.size();
|
||||
|
||||
bool isVstKnobs = true;
|
||||
vstKnobs = new Knob *[ m_vi->paramCount ];
|
||||
|
||||
|
||||
if (m_vi->vstKnobs == NULL) {
|
||||
m_vi->vstKnobs = new Knob *[ m_vi->paramCount ];
|
||||
isVstKnobs = false;
|
||||
}
|
||||
bool hasKnobModel = true;
|
||||
if (m_vi->knobFModel == NULL) {
|
||||
m_vi->knobFModel = new FloatModel *[ m_vi->paramCount ];
|
||||
hasKnobModel = false;
|
||||
}
|
||||
|
||||
char paramStr[35];
|
||||
QStringList s_dumpValues;
|
||||
|
||||
if (isVstKnobs == false) {
|
||||
for( int i = 0; i < m_vi->paramCount; i++ )
|
||||
for( int i = 0; i < m_vi->paramCount; i++ )
|
||||
{
|
||||
sprintf( paramStr, "param%d", i);
|
||||
s_dumpValues = dump[ paramStr ].split( ":" );
|
||||
|
||||
vstKnobs[ i ] = new Knob( knobBright_26, widget, s_dumpValues.at( 1 ) );
|
||||
vstKnobs[ i ]->setHintText( s_dumpValues.at( 1 ) + ":", "" );
|
||||
vstKnobs[ i ]->setLabel( s_dumpValues.at( 1 ).left( 15 ) );
|
||||
|
||||
if( !hasKnobModel )
|
||||
{
|
||||
sprintf( paramStr, "param%d", i);
|
||||
s_dumpValues = dump[ paramStr ].split( ":" );
|
||||
|
||||
m_vi->vstKnobs[ i ] = new Knob( knobBright_26, widget, s_dumpValues.at( 1 ) );
|
||||
m_vi->vstKnobs[ i ]->setHintText( s_dumpValues.at( 1 ) + ":", "" );
|
||||
m_vi->vstKnobs[ i ]->setLabel( s_dumpValues.at( 1 ).left( 15 ) );
|
||||
|
||||
sprintf( paramStr, "%d", i);
|
||||
m_vi->knobFModel[ i ] = new FloatModel( ( s_dumpValues.at( 2 ) ).toFloat(),
|
||||
0.0f, 1.0f, 0.01f, _eff, tr( paramStr ) );
|
||||
connect( m_vi->knobFModel[ i ], SIGNAL( dataChanged() ), this,
|
||||
SLOT( setParameter() ) );
|
||||
m_vi->vstKnobs[ i ] ->setModel( m_vi->knobFModel[ i ] );
|
||||
}
|
||||
connect( m_vi->knobFModel[ i ], SIGNAL( dataChanged() ), this,
|
||||
SLOT( setParameter() ) );
|
||||
vstKnobs[ i ] ->setModel( m_vi->knobFModel[ i ] );
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
@@ -398,7 +396,7 @@ manageVSTEffectView::manageVSTEffectView( VstEffect * _eff, VstEffectControls *
|
||||
{
|
||||
if( i < m_vi->paramCount )
|
||||
{
|
||||
l->addWidget( m_vi->vstKnobs[i], lrow, lcolumn, Qt::AlignCenter );
|
||||
l->addWidget( vstKnobs[i], lrow, lcolumn, Qt::AlignCenter );
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@@ -466,12 +464,12 @@ void manageVSTEffectView::displayAutomatedOnly( void )
|
||||
if( !( m_vi2->knobFModel[ i ]->isAutomated() ||
|
||||
m_vi2->knobFModel[ i ]->controllerConnection() ) )
|
||||
{
|
||||
if( m_vi2->vstKnobs[ i ]->isVisible() == true && isAuto )
|
||||
if( vstKnobs[ i ]->isVisible() == true && isAuto )
|
||||
{
|
||||
m_vi2->vstKnobs[ i ]->hide();
|
||||
vstKnobs[ i ]->hide();
|
||||
m_displayAutomatedOnly->setText( "All" );
|
||||
} else {
|
||||
m_vi2->vstKnobs[ i ]->show();
|
||||
vstKnobs[ i ]->show();
|
||||
m_displayAutomatedOnly->setText( "Automated" );
|
||||
}
|
||||
}
|
||||
@@ -502,14 +500,14 @@ manageVSTEffectView::~manageVSTEffectView()
|
||||
for( int i = 0; i < m_vi2->paramCount; i++ )
|
||||
{
|
||||
delete m_vi2->knobFModel[ i ];
|
||||
delete m_vi2->vstKnobs[ i ];
|
||||
delete vstKnobs[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
if( m_vi2->vstKnobs != NULL )
|
||||
if( vstKnobs != NULL )
|
||||
{
|
||||
delete [] m_vi2->vstKnobs;
|
||||
m_vi2->vstKnobs = NULL;
|
||||
delete [] vstKnobs;
|
||||
vstKnobs = NULL;
|
||||
}
|
||||
|
||||
if( m_vi2->knobFModel != NULL )
|
||||
|
||||
@@ -59,10 +59,7 @@ public:
|
||||
|
||||
virtual int controlCount();
|
||||
|
||||
virtual EffectControlDialog * createView()
|
||||
{
|
||||
return new VstEffectControlDialog( this );
|
||||
}
|
||||
virtual EffectControlDialog * createView();
|
||||
|
||||
|
||||
protected slots:
|
||||
@@ -82,12 +79,10 @@ private:
|
||||
VstEffect * m_effect;
|
||||
|
||||
QPushButton * m_selPresetButton;
|
||||
QMenu *menu;
|
||||
|
||||
QMdiSubWindow * m_subWindow;
|
||||
QScrollArea * m_scrollArea;
|
||||
FloatModel ** knobFModel;
|
||||
Knob ** vstKnobs;
|
||||
int paramCount;
|
||||
|
||||
QObject * ctrHandle;
|
||||
@@ -98,6 +93,7 @@ private:
|
||||
friend class VstEffectControlDialog;
|
||||
friend class manageVSTEffectView;
|
||||
|
||||
bool m_vstGuiVisible;
|
||||
} ;
|
||||
|
||||
|
||||
@@ -133,6 +129,7 @@ private:
|
||||
QPushButton * m_syncButton;
|
||||
QPushButton * m_displayAutomatedOnly;
|
||||
QPushButton * m_closeButton;
|
||||
Knob ** vstKnobs;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.5 KiB |
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "Controller.h"
|
||||
#include "Song.h"
|
||||
#include "PresetPreviewPlayHandle.h"
|
||||
#include "PeakController.h"
|
||||
#include "peak_controller_effect.h"
|
||||
#include "lmms_math.h"
|
||||
@@ -67,7 +68,7 @@ PeakControllerEffect::PeakControllerEffect(
|
||||
m_autoController( NULL )
|
||||
{
|
||||
m_autoController = new PeakController( Engine::getSong(), this );
|
||||
if( !Engine::getSong()->isLoadingProject() )
|
||||
if( !Engine::getSong()->isLoadingProject() && !PresetPreviewPlayHandle::isPreviewing() )
|
||||
{
|
||||
Engine::getSong()->addController( m_autoController );
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "PeakController.h"
|
||||
#include "peak_controller_effect_controls.h"
|
||||
#include "peak_controller_effect.h"
|
||||
#include "PresetPreviewPlayHandle.h"
|
||||
#include "Song.h"
|
||||
|
||||
|
||||
@@ -80,12 +79,6 @@ void PeakControllerEffectControls::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
m_effect->m_effectId = rand();
|
||||
}
|
||||
|
||||
if( m_effect->m_autoController && PresetPreviewPlayHandle::isPreviewing() == true )
|
||||
{
|
||||
delete m_effect->m_autoController;
|
||||
m_effect->m_autoController = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -113,6 +113,12 @@ sf2Instrument::sf2Instrument( InstrumentTrack * _instrument_track ) :
|
||||
m_notesRunning[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
#if QT_VERSION_CHECK(FLUIDSYNTH_VERSION_MAJOR, FLUIDSYNTH_VERSION_MINOR, FLUIDSYNTH_VERSION_MICRO) >= QT_VERSION_CHECK(1,1,9)
|
||||
// Deactivate all audio drivers in fluidsynth
|
||||
const char *none[] = { NULL };
|
||||
fluid_audio_driver_register( none );
|
||||
#endif
|
||||
m_settings = new_fluid_settings();
|
||||
|
||||
//fluid_settings_setint( m_settings, (char *) "audio.period-size", engine::mixer()->framesPerPeriod() );
|
||||
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
|
||||
inline ~malletsSynth()
|
||||
{
|
||||
m_voice->noteOff( 0.0 );
|
||||
if (m_voice) {m_voice->noteOff(0.0);}
|
||||
delete[] m_delay;
|
||||
delete m_voice;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
#include "vestige.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QDropEvent>
|
||||
#include <QMessageBox>
|
||||
#include <QPainter>
|
||||
@@ -73,6 +75,59 @@ Plugin::Descriptor PLUGIN_EXPORT vestige_plugin_descriptor =
|
||||
}
|
||||
|
||||
|
||||
class vstSubWin : public QMdiSubWindow
|
||||
{
|
||||
public:
|
||||
vstSubWin( QWidget * _parent ) :
|
||||
QMdiSubWindow( _parent )
|
||||
{
|
||||
setAttribute( Qt::WA_DeleteOnClose, false );
|
||||
setWindowFlags( Qt::WindowCloseButtonHint );
|
||||
}
|
||||
|
||||
virtual ~vstSubWin()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void closeEvent( QCloseEvent * e )
|
||||
{
|
||||
// ignore close-events - for some reason otherwise the VST GUI
|
||||
// remains hidden when re-opening
|
||||
hide();
|
||||
e->ignore();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class VstInstrumentPlugin : public VstPlugin
|
||||
{
|
||||
public:
|
||||
using VstPlugin::VstPlugin;
|
||||
|
||||
void createUI( QWidget *parent ) override
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
if ( embedMethod() != "none" ) {
|
||||
m_pluginSubWindow.reset(new vstSubWin( gui->mainWindow()->workspace() ));
|
||||
VstPlugin::createUI( m_pluginSubWindow.get() );
|
||||
m_pluginSubWindow->setWidget(pluginWidget());
|
||||
} else {
|
||||
VstPlugin::createUI( nullptr );
|
||||
}
|
||||
}
|
||||
|
||||
/// Overwrite editor() to return the sub window instead of the embed widget
|
||||
/// itself. This makes toggleUI() and related functions toggle the
|
||||
/// sub window's visibility.
|
||||
QWidget* editor() override
|
||||
{
|
||||
return m_pluginSubWindow.get();
|
||||
}
|
||||
private:
|
||||
unique_ptr<QMdiSubWindow> m_pluginSubWindow;
|
||||
};
|
||||
|
||||
|
||||
QPixmap * VestigeInstrumentView::s_artwork = NULL;
|
||||
QPixmap * manageVestigeInstrumentView::s_artwork = NULL;
|
||||
|
||||
@@ -83,7 +138,6 @@ vestigeInstrument::vestigeInstrument( InstrumentTrack * _instrument_track ) :
|
||||
m_pluginMutex(),
|
||||
m_subWindow( NULL ),
|
||||
m_scrollArea( NULL ),
|
||||
vstKnobs( NULL ),
|
||||
knobFModel( NULL ),
|
||||
p_subWindow( NULL )
|
||||
{
|
||||
@@ -128,22 +182,22 @@ void vestigeInstrument::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
m_plugin->loadSettings( _this );
|
||||
|
||||
if ( _this.attribute( "guivisible" ).toInt() ) {
|
||||
m_plugin->showUI();
|
||||
} else {
|
||||
m_plugin->hideUI();
|
||||
}
|
||||
|
||||
const QMap<QString, QString> & dump = m_plugin->parameterDump();
|
||||
paramCount = dump.size();
|
||||
char paramStr[35];
|
||||
vstKnobs = new Knob *[ paramCount ];
|
||||
knobFModel = new FloatModel *[ paramCount ];
|
||||
QStringList s_dumpValues;
|
||||
QWidget * widget = new QWidget();
|
||||
for( int i = 0; i < paramCount; i++ )
|
||||
{
|
||||
sprintf( paramStr, "param%d", i );
|
||||
s_dumpValues = dump[ paramStr ].split( ":" );
|
||||
|
||||
vstKnobs[i] = new Knob( knobBright_26, widget, s_dumpValues.at( 1 ) );
|
||||
vstKnobs[i]->setHintText( s_dumpValues.at( 1 ) + ":", "" );
|
||||
vstKnobs[i]->setLabel( s_dumpValues.at( 1 ).left( 15 ) );
|
||||
|
||||
knobFModel[i] = new FloatModel( 0.0f, 0.0f, 1.0f, 0.01f, this, QString::number(i) );
|
||||
knobFModel[i]->loadSettings( _this, paramStr );
|
||||
|
||||
@@ -154,8 +208,6 @@ void vestigeInstrument::loadSettings( const QDomElement & _this )
|
||||
}
|
||||
|
||||
connect( knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) );
|
||||
|
||||
vstKnobs[i]->setModel( knobFModel[i] );
|
||||
}
|
||||
}
|
||||
m_pluginMutex.unlock();
|
||||
@@ -266,13 +318,17 @@ void vestigeInstrument::loadFile( const QString & _file )
|
||||
closePlugin();
|
||||
}
|
||||
m_pluginDLL = SampleBuffer::tryToMakeRelative( _file );
|
||||
TextFloat * tf = TextFloat::displayMessage(
|
||||
tr( "Loading plugin" ),
|
||||
tr( "Please wait while loading VST-plugin..." ),
|
||||
PLUGIN_NAME::getIconPixmap( "logo", 24, 24 ), 0 );
|
||||
TextFloat * tf = NULL;
|
||||
if( gui )
|
||||
{
|
||||
tf = TextFloat::displayMessage(
|
||||
tr( "Loading plugin" ),
|
||||
tr( "Please wait while loading VST-plugin..." ),
|
||||
PLUGIN_NAME::getIconPixmap( "logo", 24, 24 ), 0 );
|
||||
}
|
||||
|
||||
m_pluginMutex.lock();
|
||||
m_plugin = new VstPlugin( m_pluginDLL );
|
||||
m_plugin = new VstInstrumentPlugin( m_pluginDLL );
|
||||
if( m_plugin->failed() )
|
||||
{
|
||||
m_pluginMutex.unlock();
|
||||
@@ -283,6 +339,7 @@ void vestigeInstrument::loadFile( const QString & _file )
|
||||
return;
|
||||
}
|
||||
|
||||
m_plugin->createUI(nullptr);
|
||||
m_plugin->showUI();
|
||||
|
||||
if( set_ch_name )
|
||||
@@ -347,16 +404,9 @@ void vestigeInstrument::closePlugin( void )
|
||||
for( int i = 0; i < paramCount; i++ )
|
||||
{
|
||||
delete knobFModel[ i ];
|
||||
delete vstKnobs[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
if( vstKnobs != NULL )
|
||||
{
|
||||
delete [] vstKnobs;
|
||||
vstKnobs = NULL;
|
||||
}
|
||||
|
||||
if( knobFModel != NULL )
|
||||
{
|
||||
delete [] knobFModel;
|
||||
@@ -920,35 +970,34 @@ manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrume
|
||||
const QMap<QString, QString> & dump = m_vi->m_plugin->parameterDump();
|
||||
m_vi->paramCount = dump.size();
|
||||
|
||||
bool isVstKnobs = true;
|
||||
vstKnobs = new Knob *[ m_vi->paramCount ];
|
||||
|
||||
if (m_vi->vstKnobs == NULL) {
|
||||
m_vi->vstKnobs = new Knob *[ m_vi->paramCount ];
|
||||
isVstKnobs = false;
|
||||
}
|
||||
bool hasKnobModel = true;
|
||||
if (m_vi->knobFModel == NULL) {
|
||||
m_vi->knobFModel = new FloatModel *[ m_vi->paramCount ];
|
||||
hasKnobModel = false;
|
||||
}
|
||||
|
||||
char paramStr[35];
|
||||
QStringList s_dumpValues;
|
||||
|
||||
if (isVstKnobs == false) {
|
||||
for( int i = 0; i < m_vi->paramCount; i++ )
|
||||
for( int i = 0; i < m_vi->paramCount; i++ )
|
||||
{
|
||||
sprintf( paramStr, "param%d", i);
|
||||
s_dumpValues = dump[ paramStr ].split( ":" );
|
||||
|
||||
vstKnobs[ i ] = new Knob( knobBright_26, this, s_dumpValues.at( 1 ) );
|
||||
vstKnobs[ i ]->setHintText( s_dumpValues.at( 1 ) + ":", "" );
|
||||
vstKnobs[ i ]->setLabel( s_dumpValues.at( 1 ).left( 15 ) );
|
||||
|
||||
if( !hasKnobModel )
|
||||
{
|
||||
sprintf( paramStr, "param%d", i);
|
||||
s_dumpValues = dump[ paramStr ].split( ":" );
|
||||
|
||||
m_vi->vstKnobs[ i ] = new Knob( knobBright_26, this, s_dumpValues.at( 1 ) );
|
||||
m_vi->vstKnobs[ i ]->setHintText( s_dumpValues.at( 1 ) + ":", "" );
|
||||
m_vi->vstKnobs[ i ]->setLabel( s_dumpValues.at( 1 ).left( 15 ) );
|
||||
|
||||
sprintf( paramStr, "%d", i);
|
||||
m_vi->knobFModel[ i ] = new FloatModel( (s_dumpValues.at( 2 )).toFloat(),
|
||||
0.0f, 1.0f, 0.01f, castModel<vestigeInstrument>(), tr( paramStr ) );
|
||||
connect( m_vi->knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) );
|
||||
m_vi->vstKnobs[i] ->setModel( m_vi->knobFModel[i] );
|
||||
}
|
||||
connect( m_vi->knobFModel[i], SIGNAL( dataChanged() ), this, SLOT( setParameter() ) );
|
||||
vstKnobs[i] ->setModel( m_vi->knobFModel[i] );
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
@@ -958,7 +1007,7 @@ manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrume
|
||||
{
|
||||
if( i < m_vi->paramCount )
|
||||
{
|
||||
l->addWidget( m_vi->vstKnobs[i], lrow, lcolumn, Qt::AlignCenter );
|
||||
l->addWidget( vstKnobs[i], lrow, lcolumn, Qt::AlignCenter );
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@@ -1024,12 +1073,12 @@ void manageVestigeInstrumentView::displayAutomatedOnly( void )
|
||||
|
||||
if( !( m_vi->knobFModel[ i ]->isAutomated() || m_vi->knobFModel[ i ]->controllerConnection() ) )
|
||||
{
|
||||
if( m_vi->vstKnobs[ i ]->isVisible() == true && isAuto )
|
||||
if( vstKnobs[ i ]->isVisible() == true && isAuto )
|
||||
{
|
||||
m_vi->vstKnobs[ i ]->hide();
|
||||
vstKnobs[ i ]->hide();
|
||||
m_displayAutomatedOnly->setText( "All" );
|
||||
} else {
|
||||
m_vi->vstKnobs[ i ]->show();
|
||||
vstKnobs[ i ]->show();
|
||||
m_displayAutomatedOnly->setText( "Automated" );
|
||||
}
|
||||
}
|
||||
@@ -1044,13 +1093,13 @@ manageVestigeInstrumentView::~manageVestigeInstrumentView()
|
||||
for( int i = 0; i < m_vi->paramCount; i++ )
|
||||
{
|
||||
delete m_vi->knobFModel[ i ];
|
||||
delete m_vi->vstKnobs[ i ];
|
||||
delete vstKnobs[ i ];
|
||||
}
|
||||
}
|
||||
|
||||
if (m_vi->vstKnobs != NULL) {
|
||||
delete []m_vi->vstKnobs;
|
||||
m_vi->vstKnobs = NULL;
|
||||
if (vstKnobs != NULL) {
|
||||
delete []vstKnobs;
|
||||
vstKnobs = NULL;
|
||||
}
|
||||
|
||||
if( m_vi->knobFModel != NULL )
|
||||
|
||||
@@ -87,7 +87,6 @@ private:
|
||||
QString m_pluginDLL;
|
||||
QMdiSubWindow * m_subWindow;
|
||||
QScrollArea * m_scrollArea;
|
||||
Knob ** vstKnobs;
|
||||
FloatModel ** knobFModel;
|
||||
QObject * p_subWindow;
|
||||
int paramCount;
|
||||
@@ -130,6 +129,7 @@ private:
|
||||
QPushButton * m_syncButton;
|
||||
QPushButton * m_displayAutomatedOnly;
|
||||
QPushButton * m_closeButton;
|
||||
Knob ** vstKnobs;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ SET(WINE_CXX_ARGS
|
||||
-I${CMAKE_BINARY_DIR}
|
||||
-I${CMAKE_SOURCE_DIR}/include
|
||||
-I${WINE_INCLUDE_BASE_DIR}
|
||||
-I${WINE_INCLUDE_DIR}/windows
|
||||
-L${WINE_LIBRARY_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/RemoteVstPlugin.cpp
|
||||
-std=c++0x
|
||||
|
||||
@@ -110,6 +110,7 @@ static VstHostLanguages hlang = LanguageEnglish;
|
||||
static bool EMBED = false;
|
||||
static bool EMBED_X11 = false;
|
||||
static bool EMBED_WIN32 = false;
|
||||
static bool HEADLESS = false;
|
||||
|
||||
class RemoteVstPlugin;
|
||||
|
||||
@@ -133,6 +134,8 @@ public:
|
||||
|
||||
void init( const std::string & _plugin_file );
|
||||
void initEditor();
|
||||
void showEditor();
|
||||
void hideEditor();
|
||||
void destroyEditor();
|
||||
|
||||
virtual void process( const sampleFrame * _in, sampleFrame * _out );
|
||||
@@ -237,21 +240,16 @@ public:
|
||||
// has to be called as soon as input- or output-count changes
|
||||
void updateInOutCount();
|
||||
|
||||
inline void lock()
|
||||
{
|
||||
pthread_mutex_lock( &m_pluginLock );
|
||||
}
|
||||
|
||||
inline void unlock()
|
||||
{
|
||||
pthread_mutex_unlock( &m_pluginLock );
|
||||
}
|
||||
|
||||
inline void lockShm()
|
||||
{
|
||||
pthread_mutex_lock( &m_shmLock );
|
||||
}
|
||||
|
||||
inline bool tryLockShm()
|
||||
{
|
||||
return pthread_mutex_trylock( &m_shmLock ) == 0;
|
||||
}
|
||||
|
||||
inline void unlockShm()
|
||||
{
|
||||
pthread_mutex_unlock( &m_shmLock );
|
||||
@@ -297,8 +295,8 @@ public:
|
||||
static DWORD WINAPI processingThread( LPVOID _param );
|
||||
static bool setupMessageWindow();
|
||||
static DWORD WINAPI guiEventLoop();
|
||||
static LRESULT CALLBACK messageWndProc( HWND hwnd, UINT uMsg,
|
||||
WPARAM wParam, LPARAM lParam );
|
||||
static LRESULT CALLBACK wndProc( HWND hwnd, UINT uMsg,
|
||||
WPARAM wParam, LPARAM lParam );
|
||||
|
||||
|
||||
private:
|
||||
@@ -318,22 +316,8 @@ private:
|
||||
|
||||
bool load( const std::string & _plugin_file );
|
||||
|
||||
// thread-safe dispatching of plugin
|
||||
int pluginDispatch( int cmd, int param1 = 0, int param2 = 0,
|
||||
void * p = NULL, float f = 0 )
|
||||
{
|
||||
int ret = 0;
|
||||
lock();
|
||||
if( m_plugin )
|
||||
{
|
||||
ret = m_plugin->dispatcher( m_plugin, cmd, param1, param2, p, f );
|
||||
}
|
||||
unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
// thread-safe dispatching of plugin
|
||||
int pluginDispatchNoLocking( int cmd, int param1 = 0, int param2 = 0, void * p = NULL, float f = 0 )
|
||||
{
|
||||
if( m_plugin )
|
||||
{
|
||||
@@ -354,9 +338,7 @@ private:
|
||||
int m_windowHeight;
|
||||
|
||||
bool m_initialized;
|
||||
bool m_registeredWindowClass;
|
||||
|
||||
pthread_mutex_t m_pluginLock;
|
||||
bool m_processing;
|
||||
|
||||
std::queue<message> m_messageList;
|
||||
@@ -407,8 +389,6 @@ RemoteVstPlugin::RemoteVstPlugin( const char * socketPath ) :
|
||||
m_windowWidth( 0 ),
|
||||
m_windowHeight( 0 ),
|
||||
m_initialized( false ),
|
||||
m_registeredWindowClass( false ),
|
||||
m_pluginLock(),
|
||||
m_processing( false ),
|
||||
m_messageList(),
|
||||
m_shouldGiveIdle( false ),
|
||||
@@ -424,7 +404,6 @@ RemoteVstPlugin::RemoteVstPlugin( const char * socketPath ) :
|
||||
m_shmID( -1 ),
|
||||
m_vstSyncData( NULL )
|
||||
{
|
||||
pthread_mutex_init( &m_pluginLock, NULL );
|
||||
pthread_mutex_init( &m_shmLock, NULL );
|
||||
|
||||
__plugin = this;
|
||||
@@ -518,7 +497,6 @@ RemoteVstPlugin::~RemoteVstPlugin()
|
||||
delete[] m_outputs;
|
||||
|
||||
pthread_mutex_destroy( &m_shmLock );
|
||||
pthread_mutex_destroy( &m_pluginLock );
|
||||
}
|
||||
|
||||
|
||||
@@ -531,27 +509,28 @@ bool RemoteVstPlugin::processMessage( const message & _m )
|
||||
switch( _m.id )
|
||||
{
|
||||
case IdShowUI:
|
||||
initEditor();
|
||||
showEditor();
|
||||
return true;
|
||||
|
||||
case IdHideUI:
|
||||
destroyEditor();
|
||||
hideEditor();
|
||||
return true;
|
||||
|
||||
case IdToggleUI:
|
||||
if( m_window )
|
||||
if( m_window && IsWindowVisible( m_window ) )
|
||||
{
|
||||
destroyEditor();
|
||||
hideEditor();
|
||||
}
|
||||
else
|
||||
{
|
||||
initEditor();
|
||||
showEditor();
|
||||
}
|
||||
return true;
|
||||
|
||||
case IdIsUIVisible:
|
||||
bool visible = m_window && IsWindowVisible( m_window );
|
||||
sendMessage( message( IdIsUIVisible )
|
||||
.addInt( m_window ? 1 : 0 ) );
|
||||
.addInt( visible ? 1 : 0 ) );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -623,9 +602,7 @@ bool RemoteVstPlugin::processMessage( const message & _m )
|
||||
break;
|
||||
|
||||
case IdVstSetParameter:
|
||||
lock();
|
||||
m_plugin->setParameter( m_plugin, _m.getInt( 0 ), _m.getFloat( 1 ) );
|
||||
unlock();
|
||||
//sendMessage( IdVstSetParameter );
|
||||
break;
|
||||
|
||||
@@ -660,12 +637,8 @@ void RemoteVstPlugin::init( const std::string & _plugin_file )
|
||||
}
|
||||
|
||||
updateInOutCount();
|
||||
|
||||
// some plugins have to set samplerate during init
|
||||
if( m_vstSyncData->hasSHM )
|
||||
{
|
||||
updateSampleRate();
|
||||
}
|
||||
updateBufferSize();
|
||||
updateSampleRate();
|
||||
|
||||
/* set program to zero */
|
||||
/* i comment this out because it breaks dfx Geometer
|
||||
@@ -718,7 +691,7 @@ static void close_check( int fd )
|
||||
|
||||
void RemoteVstPlugin::initEditor()
|
||||
{
|
||||
if( m_window || !( m_plugin->flags & effFlagsHasEditor ) )
|
||||
if( HEADLESS || m_window || !( m_plugin->flags & effFlagsHasEditor ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -732,27 +705,6 @@ void RemoteVstPlugin::initEditor()
|
||||
}
|
||||
|
||||
|
||||
if( !m_registeredWindowClass )
|
||||
{
|
||||
WNDCLASS wc;
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = DefWindowProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = hInst;
|
||||
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
|
||||
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
|
||||
wc.hbrBackground = NULL;
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = "LVSL";
|
||||
|
||||
if( !RegisterClass( &wc ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_registeredWindowClass = true;
|
||||
}
|
||||
|
||||
DWORD dwStyle;
|
||||
if (EMBED) {
|
||||
dwStyle = WS_POPUP | WS_SYSMENU | WS_BORDER;
|
||||
@@ -760,7 +712,7 @@ void RemoteVstPlugin::initEditor()
|
||||
dwStyle = WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX;
|
||||
}
|
||||
|
||||
m_window = CreateWindowEx( 0, "LVSL", pluginName(),
|
||||
m_window = CreateWindowEx( WS_EX_APPWINDOW, "LVSL", pluginName(),
|
||||
dwStyle,
|
||||
0, 0, 10, 10, NULL, NULL, hInst, NULL );
|
||||
if( m_window == NULL )
|
||||
@@ -778,13 +730,15 @@ void RemoteVstPlugin::initEditor()
|
||||
m_windowWidth = er->right - er->left;
|
||||
m_windowHeight = er->bottom - er->top;
|
||||
|
||||
SetWindowPos( m_window, 0, 0, 0, m_windowWidth + 8,
|
||||
m_windowHeight + 26, SWP_NOACTIVATE |
|
||||
RECT windowSize = { 0, 0, m_windowWidth, m_windowHeight };
|
||||
AdjustWindowRect( &windowSize, dwStyle, false );
|
||||
SetWindowPos( m_window, 0, 0, 0, windowSize.right - windowSize.left,
|
||||
windowSize.bottom - windowSize.top, SWP_NOACTIVATE |
|
||||
SWP_NOMOVE | SWP_NOZORDER );
|
||||
pluginDispatch( effEditTop );
|
||||
|
||||
if (! EMBED) {
|
||||
ShowWindow( m_window, SW_SHOWNORMAL );
|
||||
showEditor();
|
||||
}
|
||||
|
||||
#ifdef LMMS_BUILD_LINUX
|
||||
@@ -798,6 +752,26 @@ void RemoteVstPlugin::initEditor()
|
||||
|
||||
|
||||
|
||||
void RemoteVstPlugin::showEditor() {
|
||||
if( !EMBED && !HEADLESS && m_window )
|
||||
{
|
||||
ShowWindow( m_window, SW_SHOWNORMAL );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void RemoteVstPlugin::hideEditor() {
|
||||
if( !EMBED && !HEADLESS && m_window )
|
||||
{
|
||||
ShowWindow( m_window, SW_HIDE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void RemoteVstPlugin::destroyEditor()
|
||||
{
|
||||
if( m_window == NULL )
|
||||
@@ -906,13 +880,14 @@ void RemoteVstPlugin::process( const sampleFrame * _in, sampleFrame * _out )
|
||||
|
||||
// now we're ready to fetch sound from VST-plugin
|
||||
|
||||
lock();
|
||||
lockShm();
|
||||
if( !tryLockShm() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( !isShmValid() )
|
||||
{
|
||||
unlockShm();
|
||||
unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -943,7 +918,6 @@ void RemoteVstPlugin::process( const sampleFrame * _in, sampleFrame * _out )
|
||||
#endif
|
||||
|
||||
unlockShm();
|
||||
unlock();
|
||||
|
||||
m_currentSamplePos += bufferSize();
|
||||
}
|
||||
@@ -1050,8 +1024,6 @@ void RemoteVstPlugin::sendCurrentProgramName()
|
||||
|
||||
void RemoteVstPlugin::getParameterDump()
|
||||
{
|
||||
lock();
|
||||
|
||||
message m( IdVstParameterDump );
|
||||
m.addInt( m_plugin->numParams );
|
||||
|
||||
@@ -1059,7 +1031,7 @@ void RemoteVstPlugin::getParameterDump()
|
||||
{
|
||||
char paramName[32];
|
||||
memset( paramName, 0, sizeof( paramName ) );
|
||||
pluginDispatchNoLocking( effGetParamName, i, 0, paramName );
|
||||
pluginDispatch( effGetParamName, i, 0, paramName );
|
||||
paramName[sizeof(paramName)-1] = 0;
|
||||
|
||||
m.addInt( i );
|
||||
@@ -1067,8 +1039,6 @@ void RemoteVstPlugin::getParameterDump()
|
||||
m.addFloat( m_plugin->getParameter( m_plugin, i ) );
|
||||
}
|
||||
|
||||
unlock();
|
||||
|
||||
sendMessage( m );
|
||||
}
|
||||
|
||||
@@ -1077,7 +1047,6 @@ void RemoteVstPlugin::getParameterDump()
|
||||
|
||||
void RemoteVstPlugin::setParameterDump( const message & _m )
|
||||
{
|
||||
lock();
|
||||
const int n = _m.getInt( 0 );
|
||||
const int params = ( n > m_plugin->numParams ) ?
|
||||
m_plugin->numParams : n;
|
||||
@@ -1090,7 +1059,6 @@ void RemoteVstPlugin::setParameterDump( const message & _m )
|
||||
item.value = _m.getFloat( ++p );
|
||||
m_plugin->setParameter( m_plugin, item.index, item.value );
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -1243,14 +1211,12 @@ void RemoteVstPlugin::savePreset( const std::string & _file )
|
||||
chunk_size = m_plugin->numParams * sizeof( float );
|
||||
data = new char[ chunk_size ];
|
||||
unsigned int* toUIntArray = reinterpret_cast<unsigned int*>( data );
|
||||
lock();
|
||||
for ( int i = 0; i < m_plugin->numParams; i++ )
|
||||
{
|
||||
float value = m_plugin->getParameter( m_plugin, i );
|
||||
unsigned int * pValue = ( unsigned int * ) &value;
|
||||
toUIntArray[ i ] = endian_swap( *pValue );
|
||||
}
|
||||
unlock();
|
||||
} else chunk_size = (((m_plugin->numParams * sizeof( float )) + 56)*m_plugin->numPrograms);
|
||||
}
|
||||
|
||||
@@ -1296,14 +1262,12 @@ void RemoteVstPlugin::savePreset( const std::string & _file )
|
||||
pluginDispatch( effSetProgram, 0, j );
|
||||
pluginDispatch( effGetProgramName, 0, 0, pBank->prgName );
|
||||
fwrite ( pBank, 1, 56, stream );
|
||||
lock();
|
||||
for ( int i = 0; i < m_plugin->numParams; i++ )
|
||||
{
|
||||
value = m_plugin->getParameter( m_plugin, i );
|
||||
pValue = ( unsigned int * ) &value;
|
||||
toUIntArray[ i ] = endian_swap( *pValue );
|
||||
}
|
||||
unlock();
|
||||
fwrite ( data, 1, chunk_size, stream );
|
||||
}
|
||||
pluginDispatch( effSetProgram, 0, currProgram );
|
||||
@@ -1370,7 +1334,6 @@ void RemoteVstPlugin::loadPresetFile( const std::string & _file )
|
||||
pluginDispatch( 24, 1, len, chunk );
|
||||
else
|
||||
{
|
||||
lock();
|
||||
unsigned int* toUIntArray = reinterpret_cast<unsigned int*>( chunk );
|
||||
for (int i = 0; i < pBank->numPrograms; i++ )
|
||||
{
|
||||
@@ -1378,7 +1341,6 @@ void RemoteVstPlugin::loadPresetFile( const std::string & _file )
|
||||
pFloat = ( float* ) &toUInt;
|
||||
m_plugin->setParameter( m_plugin, i, *pFloat );
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
} else {
|
||||
if(pBank->fxMagic != 0x6B427846) {
|
||||
@@ -1389,7 +1351,6 @@ void RemoteVstPlugin::loadPresetFile( const std::string & _file )
|
||||
int currProgram = pluginDispatch( effGetProgram );
|
||||
chunk = new char[ len = sizeof(float)*m_plugin->numParams ];
|
||||
toUIntArray = reinterpret_cast<unsigned int *>( chunk );
|
||||
lock();
|
||||
for (int i =0; i < numPrograms; i++) {
|
||||
if ( fread (pBank, 1, 56, stream) != 56 )
|
||||
{
|
||||
@@ -1410,7 +1371,6 @@ void RemoteVstPlugin::loadPresetFile( const std::string & _file )
|
||||
m_plugin->setParameter( m_plugin, j, *pFloat );
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
pluginDispatch( effSetProgram, 0, currProgram );
|
||||
fclose( stream );
|
||||
}
|
||||
@@ -1515,7 +1475,6 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode,
|
||||
case audioMasterAutomate:
|
||||
SHOW_CALLBACK( "amc: audioMasterAutomate\n" );
|
||||
// index, value, returns 0
|
||||
_effect->setParameter( _effect, _index, _opt );
|
||||
return 0;
|
||||
|
||||
case audioMasterVersion:
|
||||
@@ -1542,7 +1501,7 @@ intptr_t RemoteVstPlugin::hostCallback( AEffect * _effect, int32_t _opcode,
|
||||
// value is 0 for input and != 0 otherwise. note: the
|
||||
// return value is 0 for <true> such that older versions
|
||||
// will always return true.
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
case audioMasterGetTime:
|
||||
SHOW_CALLBACK( "amc: audioMasterGetTime\n" );
|
||||
@@ -1950,8 +1909,6 @@ bool RemoteVstPlugin::setupMessageWindow()
|
||||
__MessageHwnd = CreateWindowEx( 0, "LVSL", "dummy",
|
||||
0, 0, 0, 0, 0, NULL, NULL,
|
||||
hInst, NULL );
|
||||
SetWindowLongPtr( __MessageHwnd, GWLP_WNDPROC,
|
||||
reinterpret_cast<LONG_PTR>( RemoteVstPlugin::messageWndProc ) );
|
||||
// install GUI update timer
|
||||
SetTimer( __MessageHwnd, 1000, 50, NULL );
|
||||
|
||||
@@ -1976,7 +1933,7 @@ DWORD WINAPI RemoteVstPlugin::guiEventLoop()
|
||||
|
||||
|
||||
|
||||
LRESULT CALLBACK RemoteVstPlugin::messageWndProc( HWND hwnd, UINT uMsg,
|
||||
LRESULT CALLBACK RemoteVstPlugin::wndProc( HWND hwnd, UINT uMsg,
|
||||
WPARAM wParam, LPARAM lParam )
|
||||
{
|
||||
if( uMsg == WM_TIMER && __plugin->isInitialized() )
|
||||
@@ -2013,9 +1970,9 @@ LRESULT CALLBACK RemoteVstPlugin::messageWndProc( HWND hwnd, UINT uMsg,
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( uMsg == WM_SYSCOMMAND && wParam == SC_CLOSE )
|
||||
else if( uMsg == WM_SYSCOMMAND && (wParam & 0xfff0) == SC_CLOSE )
|
||||
{
|
||||
__plugin->destroyEditor();
|
||||
__plugin->hideEditor();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2062,6 +2019,29 @@ int main( int _argc, char * * _argv )
|
||||
}
|
||||
#endif
|
||||
|
||||
HMODULE hInst = GetModuleHandle( NULL );
|
||||
if( hInst == NULL )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
WNDCLASS wc;
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = RemoteVstPlugin::wndProc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = hInst;
|
||||
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION );
|
||||
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
|
||||
wc.hbrBackground = NULL;
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = "LVSL";
|
||||
|
||||
if( !RegisterClass( &wc ) )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
{
|
||||
#ifdef SYNC_WITH_SHM_FIFO
|
||||
int embedMethodIndex = 3;
|
||||
@@ -2073,27 +2053,32 @@ int main( int _argc, char * * _argv )
|
||||
if ( embedMethod == "none" )
|
||||
{
|
||||
cerr << "Starting detached." << endl;
|
||||
EMBED = EMBED_X11 = EMBED_WIN32 = false;
|
||||
EMBED = EMBED_X11 = EMBED_WIN32 = HEADLESS = false;
|
||||
}
|
||||
else if ( embedMethod == "win32" )
|
||||
{
|
||||
cerr << "Starting using Win32-native embedding." << endl;
|
||||
EMBED = EMBED_WIN32 = true; EMBED_X11= false;
|
||||
EMBED = EMBED_WIN32 = true; EMBED_X11 = HEADLESS = false;
|
||||
}
|
||||
else if ( embedMethod == "qt" )
|
||||
{
|
||||
cerr << "Starting using Qt-native embedding." << endl;
|
||||
EMBED = true; EMBED_X11 = EMBED_WIN32 = false;
|
||||
EMBED = true; EMBED_X11 = EMBED_WIN32 = HEADLESS = false;
|
||||
}
|
||||
else if ( embedMethod == "xembed" )
|
||||
{
|
||||
cerr << "Starting using X11Embed protocol." << endl;
|
||||
EMBED = EMBED_X11 = true; EMBED_WIN32 = false;
|
||||
EMBED = EMBED_X11 = true; EMBED_WIN32 = HEADLESS = false;
|
||||
}
|
||||
else if ( embedMethod == "headless" )
|
||||
{
|
||||
cerr << "Starting without UI." << endl;
|
||||
HEADLESS = true; EMBED = EMBED_X11 = EMBED_WIN32 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Unknown embed method " << embedMethod << ". Starting detached instead." << endl;
|
||||
EMBED = EMBED_X11 = EMBED_WIN32 = false;
|
||||
EMBED = EMBED_X11 = EMBED_WIN32 = HEADLESS = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
#include <QMdiSubWindow>
|
||||
|
||||
#ifdef LMMS_BUILD_LINUX
|
||||
# include <QX11Info>
|
||||
# if QT_VERSION < 0x050000
|
||||
# include <QX11EmbedContainer>
|
||||
# include <QX11Info>
|
||||
# else
|
||||
# include "X11EmbedContainer.h"
|
||||
# include <QWindow>
|
||||
@@ -62,33 +62,17 @@
|
||||
#include "templates.h"
|
||||
#include "FileDialog.h"
|
||||
|
||||
class vstSubWin : public QMdiSubWindow
|
||||
{
|
||||
public:
|
||||
vstSubWin( QWidget * _parent ) :
|
||||
QMdiSubWindow( _parent )
|
||||
{
|
||||
setAttribute( Qt::WA_DeleteOnClose, false );
|
||||
}
|
||||
|
||||
virtual ~vstSubWin()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void closeEvent( QCloseEvent * e )
|
||||
{
|
||||
// ignore close-events - for some reason otherwise the VST GUI
|
||||
// remains hidden when re-opening
|
||||
hide();
|
||||
e->ignore();
|
||||
}
|
||||
} ;
|
||||
#ifdef LMMS_BUILD_LINUX
|
||||
# include <X11/Xlib.h>
|
||||
#endif
|
||||
|
||||
|
||||
VstPlugin::VstPlugin( const QString & _plugin ) :
|
||||
m_plugin( _plugin ),
|
||||
m_pluginWindowID( 0 ),
|
||||
m_embedMethod( ConfigManager::inst()->vstEmbedMethod() ),
|
||||
m_embedMethod( gui
|
||||
? ConfigManager::inst()->vstEmbedMethod()
|
||||
: "headless" ),
|
||||
m_badDllFormat( false ),
|
||||
m_version( 0 ),
|
||||
m_currentProgram()
|
||||
@@ -122,7 +106,6 @@ VstPlugin::VstPlugin( const QString & _plugin ) :
|
||||
|
||||
VstPlugin::~VstPlugin()
|
||||
{
|
||||
delete m_pluginSubWindow;
|
||||
delete m_pluginWidget;
|
||||
}
|
||||
|
||||
@@ -172,41 +155,8 @@ void VstPlugin::tryLoad( const QString &remoteVstPluginExecutable )
|
||||
|
||||
|
||||
|
||||
void VstPlugin::hideEditor()
|
||||
{
|
||||
QWidget * w = pluginWidget();
|
||||
if( w )
|
||||
{
|
||||
w->hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VstPlugin::toggleEditor()
|
||||
{
|
||||
QWidget * w = pluginWidget();
|
||||
if( w )
|
||||
{
|
||||
w->setVisible( !w->isVisible() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VstPlugin::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
if( _this.attribute( "guivisible" ).toInt() )
|
||||
{
|
||||
showUI();
|
||||
}
|
||||
else
|
||||
{
|
||||
hideUI();
|
||||
}
|
||||
|
||||
const int num_params = _this.attribute( "numparams" ).toInt();
|
||||
// if it exists try to load settings chunk
|
||||
if( _this.hasAttribute( "chunk" ) )
|
||||
@@ -284,7 +234,7 @@ void VstPlugin::toggleUI()
|
||||
}
|
||||
else if (pluginWidget())
|
||||
{
|
||||
toggleEditor();
|
||||
toggleEditorVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,6 +256,7 @@ void VstPlugin::updateSampleRate()
|
||||
lock();
|
||||
sendMessage( message( IdSampleRateInformation ).
|
||||
addInt( Engine::mixer()->processingSampleRate() ) );
|
||||
waitForMessage( IdInformationUpdated, true );
|
||||
unlock();
|
||||
}
|
||||
|
||||
@@ -359,21 +310,9 @@ void VstPlugin::setParameterDump( const QMap<QString, QString> & _pdump )
|
||||
unlock();
|
||||
}
|
||||
|
||||
QWidget *VstPlugin::pluginWidget(bool _top_widget)
|
||||
QWidget *VstPlugin::pluginWidget()
|
||||
{
|
||||
if ( m_embedMethod == "none" || !m_pluginWidget )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if ( _top_widget && m_pluginWidget->parentWidget() == m_pluginSubWindow )
|
||||
{
|
||||
return m_pluginSubWindow;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_pluginWidget;
|
||||
}
|
||||
return m_pluginWidget;
|
||||
}
|
||||
|
||||
|
||||
@@ -389,6 +328,22 @@ bool VstPlugin::processMessage( const message & _m )
|
||||
|
||||
case IdVstPluginWindowID:
|
||||
m_pluginWindowID = _m.getInt();
|
||||
if( m_embedMethod == "none" )
|
||||
{
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
// We're changing the owner, not the parent,
|
||||
// so this is legal despite MSDN's warning
|
||||
SetWindowLongPtr( (HWND)(intptr_t) m_pluginWindowID,
|
||||
GWLP_HWNDPARENT,
|
||||
(LONG_PTR) gui->mainWindow()->winId() );
|
||||
#endif
|
||||
|
||||
#ifdef LMMS_BUILD_LINUX
|
||||
XSetTransientForHint( QX11Info::display(),
|
||||
m_pluginWindowID,
|
||||
gui->mainWindow()->winId() );
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
case IdVstPluginEditorGeometry:
|
||||
@@ -455,6 +410,10 @@ bool VstPlugin::processMessage( const message & _m )
|
||||
}
|
||||
|
||||
|
||||
QWidget *VstPlugin::editor()
|
||||
{
|
||||
return m_pluginWidget;
|
||||
}
|
||||
|
||||
|
||||
void VstPlugin::openPreset( )
|
||||
@@ -574,17 +533,12 @@ void VstPlugin::showUI()
|
||||
{
|
||||
RemotePlugin::showUI();
|
||||
}
|
||||
else
|
||||
else if ( m_embedMethod != "headless" )
|
||||
{
|
||||
if (! pluginWidget()) {
|
||||
createUI( NULL, false );
|
||||
}
|
||||
|
||||
QWidget * w = pluginWidget();
|
||||
if( w )
|
||||
{
|
||||
w->show();
|
||||
if (! editor()) {
|
||||
qWarning() << "VstPlugin::showUI called before VstPlugin::createUI";
|
||||
}
|
||||
toggleEditorVisibility( true );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -596,7 +550,7 @@ void VstPlugin::hideUI()
|
||||
}
|
||||
else if ( pluginWidget() != nullptr )
|
||||
{
|
||||
hideEditor();
|
||||
toggleEditorVisibility( false );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -651,22 +605,39 @@ QByteArray VstPlugin::saveChunk()
|
||||
return a;
|
||||
}
|
||||
|
||||
void VstPlugin::createUI( QWidget * parent, bool isEffect )
|
||||
void VstPlugin::toggleEditorVisibility( int visible )
|
||||
{
|
||||
QWidget* w = editor();
|
||||
if ( ! w ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( visible < 0 ) {
|
||||
visible = ! w->isVisible();
|
||||
}
|
||||
w->setVisible( visible );
|
||||
}
|
||||
|
||||
void VstPlugin::createUI( QWidget * parent )
|
||||
{
|
||||
if ( m_pluginWidget ) {
|
||||
qWarning() << "VstPlugin::createUI called twice";
|
||||
m_pluginWidget->setParent( parent );
|
||||
return;
|
||||
}
|
||||
|
||||
if( m_pluginWindowID == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QWidget* container = nullptr;
|
||||
m_pluginSubWindow = new vstSubWin( gui->mainWindow()->workspace() );
|
||||
auto sw = m_pluginSubWindow.data();
|
||||
|
||||
#if QT_VERSION >= 0x050100
|
||||
if (m_embedMethod == "qt" )
|
||||
{
|
||||
QWindow* vw = QWindow::fromWinId(m_pluginWindowID);
|
||||
container = QWidget::createWindowContainer(vw, sw );
|
||||
container = QWidget::createWindowContainer(vw, parent );
|
||||
container->installEventFilter(this);
|
||||
} else
|
||||
#endif
|
||||
@@ -705,7 +676,11 @@ void VstPlugin::createUI( QWidget * parent, bool isEffect )
|
||||
#ifdef LMMS_BUILD_LINUX
|
||||
if (m_embedMethod == "xembed" )
|
||||
{
|
||||
QX11EmbedContainer * embedContainer = new QX11EmbedContainer( sw );
|
||||
if (parent)
|
||||
{
|
||||
parent->setAttribute(Qt::WA_NativeWindow);
|
||||
}
|
||||
QX11EmbedContainer * embedContainer = new QX11EmbedContainer( parent );
|
||||
connect(embedContainer, SIGNAL(clientIsEmbedded()), this, SLOT(handleClientEmbed()));
|
||||
embedContainer->embedClient( m_pluginWindowID );
|
||||
container = embedContainer;
|
||||
@@ -713,31 +688,13 @@ void VstPlugin::createUI( QWidget * parent, bool isEffect )
|
||||
#endif
|
||||
{
|
||||
qCritical() << "Unknown embed method" << m_embedMethod;
|
||||
delete m_pluginSubWindow;
|
||||
return;
|
||||
}
|
||||
|
||||
container->setFixedSize( m_pluginGeometry );
|
||||
container->setWindowTitle( name() );
|
||||
|
||||
if( parent == NULL )
|
||||
{
|
||||
m_pluginWidget = container;
|
||||
|
||||
sw->setWidget(container);
|
||||
|
||||
if( isEffect )
|
||||
{
|
||||
sw->setAttribute( Qt::WA_TranslucentBackground );
|
||||
sw->setWindowFlags( Qt::FramelessWindowHint );
|
||||
}
|
||||
else
|
||||
{
|
||||
sw->setWindowFlags( Qt::WindowCloseButtonHint );
|
||||
}
|
||||
};
|
||||
|
||||
container->setFixedSize( m_pluginGeometry );
|
||||
m_pluginWidget = container;
|
||||
}
|
||||
|
||||
bool VstPlugin::eventFilter(QObject *obj, QEvent *event)
|
||||
|
||||
@@ -54,8 +54,10 @@ public:
|
||||
return m_pluginWindowID != 0;
|
||||
}
|
||||
|
||||
void hideEditor();
|
||||
void toggleEditor();
|
||||
/// Same as pluginWidget(), but can be overwritten in sub-classes to modify
|
||||
/// behavior the UI. This is used in VstInstrumentPlugin to wrap the VST UI
|
||||
/// in a QMdiSubWindow
|
||||
virtual QWidget* editor();
|
||||
|
||||
inline const QString & name() const
|
||||
{
|
||||
@@ -93,7 +95,7 @@ public:
|
||||
void setParameterDump( const QMap<QString, QString> & _pdump );
|
||||
|
||||
|
||||
QWidget * pluginWidget( bool _top_widget = true );
|
||||
QWidget * pluginWidget();
|
||||
|
||||
virtual void loadSettings( const QDomElement & _this );
|
||||
virtual void saveSettings( QDomDocument & _doc, QDomElement & _this );
|
||||
@@ -103,9 +105,8 @@ public:
|
||||
return "vstplugin";
|
||||
}
|
||||
|
||||
void toggleUI() override;
|
||||
|
||||
void createUI( QWidget *parent, bool isEffect );
|
||||
virtual void createUI(QWidget *parent);
|
||||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
|
||||
QString embedMethod() const;
|
||||
@@ -123,6 +124,7 @@ public slots:
|
||||
|
||||
void showUI() override;
|
||||
void hideUI() override;
|
||||
void toggleUI() override;
|
||||
|
||||
void handleClientEmbed();
|
||||
|
||||
@@ -130,9 +132,10 @@ private:
|
||||
void loadChunk( const QByteArray & _chunk );
|
||||
QByteArray saveChunk();
|
||||
|
||||
void toggleEditorVisibility(int visible = -1);
|
||||
|
||||
QString m_plugin;
|
||||
QPointer<QWidget> m_pluginWidget;
|
||||
QPointer<vstSubWin> m_pluginSubWindow;
|
||||
int m_pluginWindowID;
|
||||
QSize m_pluginGeometry;
|
||||
const QString m_embedMethod;
|
||||
|
||||
@@ -62,18 +62,11 @@ public:
|
||||
waitForMessage( IdInitDone );
|
||||
|
||||
pthread_mutex_init( &m_guiMutex, NULL );
|
||||
pthread_create( &m_guiThreadHandle, NULL, guiThread, this );
|
||||
pthread_create( &m_messageThreadHandle, NULL, messageLoop, this );
|
||||
}
|
||||
|
||||
virtual ~RemoteZynAddSubFx()
|
||||
{
|
||||
m_guiExit = true;
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
Sleep( m_guiSleepTime * 2 );
|
||||
#else
|
||||
usleep( m_guiSleepTime * 2 * 1000 );
|
||||
#endif
|
||||
|
||||
Nio::stop();
|
||||
}
|
||||
|
||||
@@ -87,7 +80,7 @@ public:
|
||||
LocalZynAddSubFx::setBufferSize( bufferSize() );
|
||||
}
|
||||
|
||||
void run()
|
||||
void messageLoop()
|
||||
{
|
||||
message m;
|
||||
while( ( m = receiveMessage() ).id != IdQuit )
|
||||
@@ -96,6 +89,7 @@ public:
|
||||
processMessage( m );
|
||||
pthread_mutex_unlock( &m_master->mutex );
|
||||
}
|
||||
m_guiExit = true;
|
||||
}
|
||||
|
||||
virtual bool processMessage( const message & _m )
|
||||
@@ -151,23 +145,22 @@ public:
|
||||
LocalZynAddSubFx::processAudio( _out );
|
||||
}
|
||||
|
||||
static void * guiThread( void * _arg )
|
||||
static void * messageLoop( void * _arg )
|
||||
{
|
||||
RemoteZynAddSubFx * _this =
|
||||
static_cast<RemoteZynAddSubFx *>( _arg );
|
||||
|
||||
_this->guiThread();
|
||||
_this->messageLoop();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void guiLoop();
|
||||
|
||||
private:
|
||||
void guiThread();
|
||||
|
||||
const int m_guiSleepTime;
|
||||
|
||||
pthread_t m_guiThreadHandle;
|
||||
pthread_t m_messageThreadHandle;
|
||||
pthread_mutex_t m_guiMutex;
|
||||
std::queue<RemotePluginClient::message> m_guiMessages;
|
||||
bool m_guiExit;
|
||||
@@ -177,7 +170,7 @@ private:
|
||||
|
||||
|
||||
|
||||
void RemoteZynAddSubFx::guiThread()
|
||||
void RemoteZynAddSubFx::guiLoop()
|
||||
{
|
||||
int exitProgram = 0;
|
||||
MasterUI * ui = NULL;
|
||||
@@ -292,7 +285,7 @@ int main( int _argc, char * * _argv )
|
||||
RemoteZynAddSubFx * remoteZASF = new RemoteZynAddSubFx( _argv[1] );
|
||||
#endif
|
||||
|
||||
remoteZASF->run();
|
||||
remoteZASF->guiLoop();
|
||||
|
||||
delete remoteZASF;
|
||||
|
||||
|
||||
@@ -49,5 +49,24 @@ class FFTwrapper
|
||||
fftwf_plan planfftw, planfftw_inv;
|
||||
};
|
||||
|
||||
/*
|
||||
* The "std::polar" template has no clear definition for the range of
|
||||
* the input parameters, and some C++ standard library implementations
|
||||
* don't accept negative amplitude among others. Define our own
|
||||
* FFTpolar template, which works like we expect it to.
|
||||
*/
|
||||
template<class _Tp>
|
||||
std::complex<_Tp>
|
||||
FFTpolar(const _Tp& __rho, const _Tp& __theta = _Tp(0))
|
||||
{
|
||||
_Tp __x = __rho * cos(__theta);
|
||||
if (std::isnan(__x))
|
||||
__x = 0;
|
||||
_Tp __y = __rho * sin(__theta);
|
||||
if (std::isnan(__y))
|
||||
__y = 0;
|
||||
return std::complex<_Tp>(__x, __y);
|
||||
}
|
||||
|
||||
void FFT_cleanup();
|
||||
#endif
|
||||
|
||||
@@ -505,7 +505,7 @@ float QtXmlWrapper::getparreal(const char *name, float defaultpar) const
|
||||
return defaultpar;
|
||||
}
|
||||
|
||||
return tmp.attribute( "value" ).toFloat();
|
||||
return QLocale().toFloat( tmp.attribute( "value" ) );
|
||||
}
|
||||
|
||||
float QtXmlWrapper::getparreal(const char *name,
|
||||
|
||||
@@ -615,7 +615,7 @@ void PADnoteParameters::applyparameters(bool lockmutex)
|
||||
|
||||
newsample.smp[0] = 0.0f;
|
||||
for(int i = 1; i < spectrumsize; ++i) //randomize the phases
|
||||
fftfreqs[i] = std::polar(spectrum[i], (float)RND * 6.29f);
|
||||
fftfreqs[i] = FFTpolar(spectrum[i], (float)RND * 6.29f);
|
||||
fft->freqs2smps(fftfreqs, newsample.smp); //that's all; here is the only ifft for the whole sample; no windows are used ;-)
|
||||
|
||||
|
||||
|
||||
@@ -533,7 +533,7 @@ void OscilGen::spectrumadjust()
|
||||
mag = 1.0f;
|
||||
break;
|
||||
}
|
||||
oscilFFTfreqs[i] = std::polar<fftw_real>(mag, phase);
|
||||
oscilFFTfreqs[i] = FFTpolar<fftw_real>(mag, phase);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -629,7 +629,7 @@ void OscilGen::prepare()
|
||||
int k = i * (j + 1);
|
||||
if(k >= synth->oscilsize / 2)
|
||||
break;
|
||||
oscilFFTfreqs[k] += basefuncFFTfreqs[i] * std::polar<fftw_real>(
|
||||
oscilFFTfreqs[k] += basefuncFFTfreqs[i] * FFTpolar<fftw_real>(
|
||||
hmag[j],
|
||||
hphase[j] * k);
|
||||
}
|
||||
@@ -857,7 +857,7 @@ short int OscilGen::get(float *smps, float freqHz, int resonance)
|
||||
const float rnd = PI * powf((Prand - 64.0f) / 64.0f, 2.0f);
|
||||
for(int i = 1; i < nyquist - 1; ++i) //to Nyquist only for AntiAliasing
|
||||
outoscilFFTfreqs[i] *=
|
||||
std::polar<fftw_real>(1.0f, (float)(rnd * i * RND));
|
||||
FFTpolar<fftw_real>(1.0f, (float)(rnd * i * RND));
|
||||
}
|
||||
|
||||
//Harmonic Amplitude Randomness
|
||||
|
||||
2
src/3rdparty/rpmalloc/rpmalloc
vendored
2
src/3rdparty/rpmalloc/rpmalloc
vendored
Submodule src/3rdparty/rpmalloc/rpmalloc updated: 2e0479192b...36b1942fbc
@@ -43,10 +43,7 @@ IF(WIN32)
|
||||
DEPENDS "${CMAKE_BINARY_DIR}/lmms.rc")
|
||||
ENDIF()
|
||||
|
||||
SET(lmms_EMBEDDED_RESOURCES
|
||||
"${CMAKE_SOURCE_DIR}/doc/AUTHORS"
|
||||
"${CMAKE_SOURCE_DIR}/LICENSE.txt"
|
||||
"${CMAKE_SOURCE_DIR}/doc/CONTRIBUTORS")
|
||||
SET(lmms_EMBEDDED_RESOURCES "${CMAKE_SOURCE_DIR}/doc/AUTHORS" "${CMAKE_SOURCE_DIR}/LICENSE.txt" "${CONTRIBUTORS}")
|
||||
SET(LMMS_ER_H "${CMAKE_CURRENT_BINARY_DIR}/embedded_resources.h")
|
||||
ADD_CUSTOM_COMMAND(OUTPUT "${LMMS_ER_H}" COMMAND "${BIN2RES}" ARGS ${lmms_EMBEDDED_RESOURCES} > "${LMMS_ER_H}" DEPENDS bin2res)
|
||||
|
||||
@@ -123,7 +120,7 @@ IF(LMMS_BUILD_WIN32)
|
||||
ENDIF()
|
||||
|
||||
IF(LMMS_BUILD_APPLE)
|
||||
SET(EXTRA_LIBRARIES "-framework CoreMIDI")
|
||||
SET(EXTRA_LIBRARIES "-framework CoreMIDI -framework CoreFoundation")
|
||||
ENDIF()
|
||||
|
||||
if(LMMS_HAVE_OSS AND LMMS_BUILD_OPENBSD)
|
||||
|
||||
@@ -189,7 +189,7 @@ MidiTime AutomationPattern::timeMapLength() const
|
||||
{
|
||||
if( m_timeMap.isEmpty() ) return 0;
|
||||
timeMap::const_iterator it = m_timeMap.end();
|
||||
return MidiTime( qMax( MidiTime( (it-1).key() ).getTact() + 1, 1 ), 0 );
|
||||
return MidiTime( MidiTime( (it-1).key() ).nextFullTact(), 0 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
IF(LMMS_HAVE_WEAKJACK)
|
||||
set(WEAKJACK core/audio/AudioWeakJack.c)
|
||||
|
||||
# Build libjack.so.0 stub as weakjack.so for AppImages
|
||||
IF(LMMS_BUILD_LINUX)
|
||||
ADD_LIBRARY(weakjack MODULE ../../src/core/audio/AudioWeakJack.c)
|
||||
INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include")
|
||||
# We can't predict an AppImage build, so stash the build artifact for later
|
||||
INSTALL(TARGETS weakjack LIBRARY DESTINATION "${CMAKE_BINARY_DIR}/optional")
|
||||
SET_TARGET_PROPERTIES(weakjack PROPERTIES PREFIX "" SUFFIX ".so")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
set(LMMS_SRCS
|
||||
|
||||
@@ -26,6 +26,11 @@
|
||||
#include <QDir>
|
||||
#include <QMessageBox>
|
||||
#include <QApplication>
|
||||
#if QT_VERSION >= 0x050000
|
||||
#include <QStandardPaths>
|
||||
#else
|
||||
#include <QDesktopServices>
|
||||
#endif
|
||||
#include <QtCore/QTextStream>
|
||||
|
||||
#include "ConfigManager.h"
|
||||
@@ -50,7 +55,11 @@ ConfigManager * ConfigManager::s_instanceOfMe = NULL;
|
||||
|
||||
ConfigManager::ConfigManager() :
|
||||
m_lmmsRcFile( QDir::home().absolutePath() +"/.lmmsrc.xml" ),
|
||||
m_workingDir( QDir::home().absolutePath() + "/lmms/"),
|
||||
#if QT_VERSION >= 0x050000
|
||||
m_workingDir( QStandardPaths::writableLocation( QStandardPaths::DocumentsLocation ) + "/lmms/"),
|
||||
#else
|
||||
m_workingDir( QDesktopServices::storageLocation( QDesktopServices::DocumentsLocation ) + "/lmms/"),
|
||||
#endif
|
||||
m_dataDir( "data:/" ),
|
||||
m_artworkDir( defaultArtworkDir() ),
|
||||
m_vstDir( m_workingDir + "vst/" ),
|
||||
@@ -58,6 +67,10 @@ ConfigManager::ConfigManager() :
|
||||
m_sf2Dir( m_workingDir + SF2_PATH ),
|
||||
m_version( defaultVersion() )
|
||||
{
|
||||
// Detect < 1.2.0 working directory as a courtesy
|
||||
if ( QFileInfo( QDir::home().absolutePath() + "/lmms/projects/" ).exists() )
|
||||
m_workingDir = QDir::home().absolutePath() + "/lmms/";
|
||||
|
||||
if (! qgetenv("LMMS_DATA_DIR").isEmpty())
|
||||
QDir::addSearchPath("data", QString::fromLocal8Bit(qgetenv("LMMS_DATA_DIR")));
|
||||
|
||||
@@ -225,9 +238,9 @@ bool ConfigManager::hasWorkingDir() const
|
||||
}
|
||||
|
||||
|
||||
void ConfigManager::setWorkingDir( const QString & _wd )
|
||||
void ConfigManager::setWorkingDir( const QString & wd )
|
||||
{
|
||||
m_workingDir = ensureTrailingSlash( _wd );
|
||||
m_workingDir = ensureTrailingSlash( QDir::cleanPath( wd ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -279,9 +292,7 @@ void ConfigManager::setDefaultSoundfont( const QString & _sf )
|
||||
|
||||
void ConfigManager::setBackgroundArtwork( const QString & _ba )
|
||||
{
|
||||
#ifdef LMMS_HAVE_FLUIDSYNTH
|
||||
m_backgroundArtwork = _ba;
|
||||
#endif
|
||||
}
|
||||
|
||||
void ConfigManager::setGIGDir(const QString &gd)
|
||||
@@ -553,6 +564,8 @@ void ConfigManager::loadConfigFile( const QString & configFile )
|
||||
}
|
||||
#endif
|
||||
|
||||
upgrade();
|
||||
|
||||
QStringList searchPaths;
|
||||
if(! qgetenv("LMMS_THEME_PATH").isNull())
|
||||
searchPaths << qgetenv("LMMS_THEME_PATH");
|
||||
@@ -564,8 +577,6 @@ void ConfigManager::loadConfigFile( const QString & configFile )
|
||||
{
|
||||
createWorkingDir();
|
||||
}
|
||||
|
||||
upgrade();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -202,11 +202,8 @@ bool EffectChain::processAudioBuffer( sampleFrame * _buf, const fpp_t _frames, b
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const bool exporting = Engine::getSong()->isExporting();
|
||||
if( exporting ) // strip infs/nans if exporting
|
||||
{
|
||||
MixHelpers::sanitize( _buf, _frames );
|
||||
}
|
||||
|
||||
MixHelpers::sanitize( _buf, _frames );
|
||||
|
||||
bool moreEffects = false;
|
||||
for( EffectList::Iterator it = m_effects.begin(); it != m_effects.end(); ++it )
|
||||
@@ -214,10 +211,7 @@ bool EffectChain::processAudioBuffer( sampleFrame * _buf, const fpp_t _frames, b
|
||||
if( hasInputNoise || ( *it )->isRunning() )
|
||||
{
|
||||
moreEffects |= ( *it )->processAudioBuffer( _buf, _frames );
|
||||
if( exporting ) // strip infs/nans if exporting
|
||||
{
|
||||
MixHelpers::sanitize( _buf, _frames );
|
||||
}
|
||||
MixHelpers::sanitize( _buf, _frames );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,7 +117,6 @@ void FxChannel::unmuteForSolo()
|
||||
void FxChannel::doProcessing()
|
||||
{
|
||||
const fpp_t fpp = Engine::mixer()->framesPerPeriod();
|
||||
const bool exporting = Engine::getSong()->isExporting();
|
||||
|
||||
if( m_muted == false )
|
||||
{
|
||||
@@ -140,25 +139,21 @@ void FxChannel::doProcessing()
|
||||
if( ! volBuf && ! sendBuf ) // neither volume nor send has sample-exact data...
|
||||
{
|
||||
const float v = sender->m_volumeModel.value() * sendModel->value();
|
||||
if( exporting ) { MixHelpers::addSanitizedMultiplied( m_buffer, ch_buf, v, fpp ); }
|
||||
else { MixHelpers::addMultiplied( m_buffer, ch_buf, v, fpp ); }
|
||||
MixHelpers::addSanitizedMultiplied( m_buffer, ch_buf, v, fpp );
|
||||
}
|
||||
else if( volBuf && sendBuf ) // both volume and send have sample-exact data
|
||||
{
|
||||
if( exporting ) { MixHelpers::addSanitizedMultipliedByBuffers( m_buffer, ch_buf, volBuf, sendBuf, fpp ); }
|
||||
else { MixHelpers::addMultipliedByBuffers( m_buffer, ch_buf, volBuf, sendBuf, fpp ); }
|
||||
MixHelpers::addSanitizedMultipliedByBuffers( m_buffer, ch_buf, volBuf, sendBuf, fpp );
|
||||
}
|
||||
else if( volBuf ) // volume has sample-exact data but send does not
|
||||
{
|
||||
const float v = sendModel->value();
|
||||
if( exporting ) { MixHelpers::addSanitizedMultipliedByBuffer( m_buffer, ch_buf, v, volBuf, fpp ); }
|
||||
else { MixHelpers::addMultipliedByBuffer( m_buffer, ch_buf, v, volBuf, fpp ); }
|
||||
MixHelpers::addSanitizedMultipliedByBuffer( m_buffer, ch_buf, v, volBuf, fpp );
|
||||
}
|
||||
else // vice versa
|
||||
{
|
||||
const float v = sender->m_volumeModel.value();
|
||||
if( exporting ) { MixHelpers::addSanitizedMultipliedByBuffer( m_buffer, ch_buf, v, sendBuf, fpp ); }
|
||||
else { MixHelpers::addMultipliedByBuffer( m_buffer, ch_buf, v, sendBuf, fpp ); }
|
||||
MixHelpers::addSanitizedMultipliedByBuffer( m_buffer, ch_buf, v, sendBuf, fpp );
|
||||
}
|
||||
m_hasInput = true;
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ InstrumentFunctionNoteStacking::ChordTable::Init InstrumentFunctionNoteStacking:
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "aug" ), { 0, 4, 8, -1 } },
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "augsus4" ), { 0, 5, 8, -1 } },
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "tri" ), { 0, 3, 6, 9, -1 } },
|
||||
|
||||
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "6" ), { 0, 4, 7, 9, -1 } },
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "6sus4" ), { 0, 5, 7, 9, -1 } },
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "6add9" ), { 0, 4, 7, 9, 14, -1 } },
|
||||
@@ -125,7 +125,7 @@ InstrumentFunctionNoteStacking::ChordTable::Init InstrumentFunctionNoteStacking:
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Neopolitan minor" ), { 0, 1, 3, 5, 7, 8, 11, -1 } },
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Hungarian minor" ), { 0, 2, 3, 6, 7, 8, 11, -1 } },
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Dorian" ), { 0, 2, 3, 5, 7, 9, 10, -1 } },
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Phrygolydian" ), { 0, 1, 3, 5, 7, 8, 10, -1 } },
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Phrygian" ), { 0, 1, 3, 5, 7, 8, 10, -1 } },
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Lydian" ), { 0, 2, 4, 6, 7, 9, 11, -1 } },
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Mixolydian" ), { 0, 2, 4, 5, 7, 9, 10, -1 } },
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Aeolian" ), { 0, 2, 3, 5, 7, 8, 10, -1 } },
|
||||
@@ -133,7 +133,7 @@ InstrumentFunctionNoteStacking::ChordTable::Init InstrumentFunctionNoteStacking:
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Minor" ), { 0, 2, 3, 5, 7, 8, 10, -1 } },
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Chromatic" ), { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -1 } },
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Half-Whole Diminished" ), { 0, 1, 3, 4, 6, 7, 9, 10, -1 } },
|
||||
|
||||
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "5" ), { 0, 7, -1 } },
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Phrygian dominant" ), { 0, 1, 4, 5, 7, 8, 10, -1 } },
|
||||
{ QT_TRANSLATE_NOOP( "InstrumentFunctionNoteStacking", "Persian" ), { 0, 1, 4, 5, 6, 8, 11, -1 } }
|
||||
@@ -262,7 +262,7 @@ void InstrumentFunctionNoteStacking::processNote( NotePlayHandle * _n )
|
||||
|
||||
// create sub-note-play-handle, only note is
|
||||
// different
|
||||
Engine::mixer()->addPlayHandle(
|
||||
Engine::mixer()->addPlayHandle(
|
||||
NotePlayHandleManager::acquire( _n->instrumentTrack(), _n->offset(), _n->frames(), note_copy,
|
||||
_n, -1, NotePlayHandle::OriginNoteStacking )
|
||||
);
|
||||
@@ -344,7 +344,7 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n )
|
||||
if( _n->origin() == NotePlayHandle::OriginArpeggio ||
|
||||
_n->origin() == NotePlayHandle::OriginNoteStacking ||
|
||||
!m_arpEnabledModel.value() ||
|
||||
( _n->isReleased() && _n->releaseFramesDone() >= _n->actualReleaseFramesToDo() ) )
|
||||
_n->isReleased() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -412,7 +412,6 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n )
|
||||
// Skip notes randomly
|
||||
if( m_arpSkipModel.value() )
|
||||
{
|
||||
|
||||
if( 100 * ( (float) rand() / (float)( RAND_MAX + 1.0f ) ) < m_arpSkipModel.value() )
|
||||
{
|
||||
// Set master note to prevent the note to extend over skipped notes
|
||||
@@ -501,12 +500,6 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n )
|
||||
continue;
|
||||
}
|
||||
|
||||
float vol_level = 1.0f;
|
||||
if( _n->isReleased() )
|
||||
{
|
||||
vol_level = _n->volumeLevel( cur_frame + gated_frames );
|
||||
}
|
||||
|
||||
// create new arp-note
|
||||
|
||||
// create sub-note-play-handle, only ptr to note is different
|
||||
@@ -515,7 +508,7 @@ void InstrumentFunctionArpeggio::processNote( NotePlayHandle * _n )
|
||||
NotePlayHandleManager::acquire( _n->instrumentTrack(),
|
||||
frames_processed,
|
||||
gated_frames,
|
||||
Note( MidiTime( 0 ), MidiTime( 0 ), sub_note_key, (volume_t) qRound( _n->getVolume() * vol_level ),
|
||||
Note( MidiTime( 0 ), MidiTime( 0 ), sub_note_key, _n->getVolume(),
|
||||
_n->getPanning(), _n->detuning() ),
|
||||
_n, -1, NotePlayHandle::OriginArpeggio )
|
||||
);
|
||||
@@ -569,13 +562,10 @@ void InstrumentFunctionArpeggio::loadSettings( const QDomElement & _this )
|
||||
// Keep compatibility with version 0.2.1 file format
|
||||
if( _this.hasAttribute( "arpsyncmode" ) )
|
||||
{
|
||||
m_arpTimeKnob->setSyncMode(
|
||||
m_arpTimeKnob->setSyncMode(
|
||||
( tempoSyncKnob::tempoSyncMode ) _this.attribute(
|
||||
"arpsyncmode" ).toInt() );
|
||||
}*/
|
||||
|
||||
m_arpModeModel.loadSettings( _this, "arpmode" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -82,6 +82,10 @@ bool sanitize( sampleFrame * src, int frames )
|
||||
src[f][c] = 0.0f;
|
||||
found = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
src[f][c] = qBound( -4.0f, src[f][c], 4.0f );
|
||||
}
|
||||
}
|
||||
}
|
||||
return found;
|
||||
|
||||
@@ -579,8 +579,6 @@ void Mixer::setAudioDevice( AudioDevice * _dev )
|
||||
{
|
||||
stopProcessing();
|
||||
|
||||
m_oldAudioDev = m_audioDev;
|
||||
|
||||
if( _dev == NULL )
|
||||
{
|
||||
printf( "param _dev == NULL in Mixer::setAudioDevice(...). "
|
||||
@@ -608,7 +606,6 @@ void Mixer::setAudioDevice( AudioDevice * _dev,
|
||||
stopProcessing();
|
||||
|
||||
m_qualitySettings = _qs;
|
||||
m_oldAudioDev = m_audioDev;
|
||||
|
||||
if( _dev == NULL )
|
||||
{
|
||||
@@ -630,6 +627,17 @@ void Mixer::setAudioDevice( AudioDevice * _dev,
|
||||
|
||||
|
||||
|
||||
void Mixer::storeAudioDevice()
|
||||
{
|
||||
if( !m_oldAudioDev )
|
||||
{
|
||||
m_oldAudioDev = m_audioDev;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Mixer::restoreAudioDevice()
|
||||
{
|
||||
if( m_oldAudioDev != NULL )
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "MixerWorkerThread.h"
|
||||
|
||||
#include "denormals.h"
|
||||
#include <QDebug>
|
||||
#include <QMutex>
|
||||
#include <QWaitCondition>
|
||||
#include "ThreadableJob.h"
|
||||
@@ -39,7 +40,7 @@ QList<MixerWorkerThread *> MixerWorkerThread::workerThreads;
|
||||
// implementation of internal JobQueue
|
||||
void MixerWorkerThread::JobQueue::reset( OperationMode _opMode )
|
||||
{
|
||||
m_queueSize = 0;
|
||||
m_writeIndex = 0;
|
||||
m_itemsDone = 0;
|
||||
m_opMode = _opMode;
|
||||
}
|
||||
@@ -54,7 +55,13 @@ void MixerWorkerThread::JobQueue::addJob( ThreadableJob * _job )
|
||||
// update job state
|
||||
_job->queue();
|
||||
// actually queue the job via atomic operations
|
||||
m_items[m_queueSize.fetchAndAddOrdered(1)] = _job;
|
||||
auto index = m_writeIndex.fetchAndAddOrdered(1);
|
||||
if (index < JOB_QUEUE_SIZE) {
|
||||
m_items[index] = _job;
|
||||
} else {
|
||||
qWarning() << "Job queue is full!";
|
||||
m_itemsDone.fetchAndAddOrdered(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,10 +70,10 @@ void MixerWorkerThread::JobQueue::addJob( ThreadableJob * _job )
|
||||
void MixerWorkerThread::JobQueue::run()
|
||||
{
|
||||
bool processedJob = true;
|
||||
while( processedJob && (int) m_itemsDone < (int) m_queueSize )
|
||||
while( processedJob && (int) m_itemsDone < (int) m_writeIndex )
|
||||
{
|
||||
processedJob = false;
|
||||
for( int i = 0; i < m_queueSize; ++i )
|
||||
for( int i = 0; i < m_writeIndex && i < JOB_QUEUE_SIZE; ++i )
|
||||
{
|
||||
ThreadableJob * job = m_items[i].fetchAndStoreOrdered( NULL );
|
||||
if( job )
|
||||
@@ -86,7 +93,7 @@ void MixerWorkerThread::JobQueue::run()
|
||||
|
||||
void MixerWorkerThread::JobQueue::wait()
|
||||
{
|
||||
while( (int) m_itemsDone < (int) m_queueSize )
|
||||
while( (int) m_itemsDone < (int) m_writeIndex )
|
||||
{
|
||||
#if defined(LMMS_HOST_X86) || defined(LMMS_HOST_X86_64)
|
||||
asm( "pause" );
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "Mixer.h"
|
||||
#include "EffectChain.h"
|
||||
#include "plugins/peak_controller_effect/peak_controller_effect.h"
|
||||
#include "PresetPreviewPlayHandle.h"
|
||||
|
||||
PeakControllerEffectVector PeakController::s_effects;
|
||||
int PeakController::m_getCount;
|
||||
@@ -64,11 +63,7 @@ PeakController::PeakController( Model * _parent,
|
||||
|
||||
PeakController::~PeakController()
|
||||
{
|
||||
//EffectChain::loadSettings() appends effect to EffectChain::m_effects
|
||||
//When it's previewing, EffectChain::loadSettings(<Controller Fx XML>) is not called
|
||||
//Therefore, we shouldn't call removeEffect() as it is not even appended.
|
||||
//NB: Most XML setting are loaded on preview, except controller fx.
|
||||
if( m_peakEffect != NULL && m_peakEffect->effectChain() != NULL && PresetPreviewPlayHandle::isPreviewing() == false )
|
||||
if( m_peakEffect != NULL && m_peakEffect->effectChain() != NULL )
|
||||
{
|
||||
m_peakEffect->effectChain()->removeEffect( m_peakEffect );
|
||||
}
|
||||
|
||||
@@ -77,7 +77,6 @@ ProjectRenderer::ProjectRenderer( const Mixer::qualitySettings & qualitySettings
|
||||
QThread( Engine::mixer() ),
|
||||
m_fileDev( NULL ),
|
||||
m_qualitySettings( qualitySettings ),
|
||||
m_oldQualitySettings( Engine::mixer()->currentQualitySettings() ),
|
||||
m_progress( 0 ),
|
||||
m_abort( false )
|
||||
{
|
||||
@@ -103,8 +102,6 @@ ProjectRenderer::ProjectRenderer( const Mixer::qualitySettings & qualitySettings
|
||||
|
||||
ProjectRenderer::~ProjectRenderer()
|
||||
{
|
||||
Engine::mixer()->restoreAudioDevice(); // also deletes audio-dev
|
||||
Engine::mixer()->changeQuality( m_oldQualitySettings );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -37,21 +37,29 @@ RenderManager::RenderManager(
|
||||
ProjectRenderer::ExportFileFormats fmt,
|
||||
QString outputPath) :
|
||||
m_qualitySettings(qualitySettings),
|
||||
m_oldQualitySettings( Engine::mixer()->currentQualitySettings() ),
|
||||
m_outputSettings(outputSettings),
|
||||
m_format(fmt),
|
||||
m_outputPath(outputPath),
|
||||
m_activeRenderer(NULL)
|
||||
{
|
||||
Engine::mixer()->storeAudioDevice();
|
||||
}
|
||||
|
||||
RenderManager::~RenderManager()
|
||||
{
|
||||
delete m_activeRenderer;
|
||||
m_activeRenderer = NULL;
|
||||
|
||||
Engine::mixer()->restoreAudioDevice(); // Also deletes audio dev.
|
||||
Engine::mixer()->changeQuality( m_oldQualitySettings );
|
||||
}
|
||||
|
||||
void RenderManager::abortProcessing()
|
||||
{
|
||||
if ( m_activeRenderer ) {
|
||||
disconnect( m_activeRenderer, SIGNAL( finished() ),
|
||||
this, SLOT( renderNextTrack() ) );
|
||||
m_activeRenderer->abortProcessing();
|
||||
}
|
||||
restoreMutedState();
|
||||
|
||||
@@ -1415,7 +1415,8 @@ QString SampleBuffer::tryToMakeRelative( const QString & file )
|
||||
{
|
||||
if( QFileInfo( file ).isRelative() == false )
|
||||
{
|
||||
QString f = QString( file ).replace( QDir::separator(), '/' );
|
||||
// Normalize the path
|
||||
QString f( QDir::cleanPath( file ) );
|
||||
|
||||
// First, look in factory samples
|
||||
// Isolate "samples/" from "data:/samples/"
|
||||
@@ -1424,7 +1425,7 @@ QString SampleBuffer::tryToMakeRelative( const QString & file )
|
||||
// Iterate over all valid "data:/" searchPaths
|
||||
for ( const QString & path : QDir::searchPaths( "data" ) )
|
||||
{
|
||||
QString samplesPath = QString( path + samplesSuffix ).replace( QDir::separator(), '/' );
|
||||
QString samplesPath = QDir::cleanPath( path + samplesSuffix ) + "/";
|
||||
if ( f.startsWith( samplesPath ) )
|
||||
{
|
||||
return QString( f ).mid( samplesPath.length() );
|
||||
|
||||
@@ -143,7 +143,9 @@ void TrackContentObject::movePosition( const MidiTime & pos )
|
||||
{
|
||||
if( m_startPosition != pos )
|
||||
{
|
||||
Engine::mixer()->requestChangeInModel();
|
||||
m_startPosition = pos;
|
||||
Engine::mixer()->doneChangeInModel();
|
||||
Engine::getSong()->updateLength();
|
||||
emit positionChanged();
|
||||
}
|
||||
@@ -701,10 +703,8 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me )
|
||||
if( me->x() < width() - RESIZE_GRIP_WIDTH )
|
||||
{
|
||||
m_action = Move;
|
||||
m_oldTime = m_tco->startPosition();
|
||||
QCursor c( Qt::SizeAllCursor );
|
||||
QApplication::setOverrideCursor( c );
|
||||
s_textFloat->setTitle( tr( "Current position" ) );
|
||||
delete m_hint;
|
||||
m_hint = TextFloat::displayMessage( tr( "Hint" ),
|
||||
tr( "Press <%1> and drag to make "
|
||||
@@ -715,14 +715,18 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me )
|
||||
"Ctrl"),
|
||||
#endif
|
||||
embed::getIconPixmap( "hint" ), 0 );
|
||||
s_textFloat->setTitle( tr( "Current position" ) );
|
||||
s_textFloat->setText( QString( "%1:%2" ).
|
||||
arg( m_tco->startPosition().getTact() + 1 ).
|
||||
arg( m_tco->startPosition().getTicks() %
|
||||
MidiTime::ticksPerTact() ) );
|
||||
s_textFloat->moveGlobal( this, QPoint( width() + 2, height() + 2 ) );
|
||||
}
|
||||
else if( !m_tco->getAutoResize() )
|
||||
{
|
||||
m_action = Resize;
|
||||
m_oldTime = m_tco->length();
|
||||
QCursor c( Qt::SizeHorCursor );
|
||||
QApplication::setOverrideCursor( c );
|
||||
s_textFloat->setTitle( tr( "Current length" ) );
|
||||
delete m_hint;
|
||||
m_hint = TextFloat::displayMessage( tr( "Hint" ),
|
||||
tr( "Press <%1> for free "
|
||||
@@ -733,10 +737,20 @@ void TrackContentObjectView::mousePressEvent( QMouseEvent * me )
|
||||
"Ctrl"),
|
||||
#endif
|
||||
embed::getIconPixmap( "hint" ), 0 );
|
||||
s_textFloat->setTitle( tr( "Current length" ) );
|
||||
s_textFloat->setText( tr( "%1:%2 (%3:%4 to %5:%6)" ).
|
||||
arg( m_tco->length().getTact() ).
|
||||
arg( m_tco->length().getTicks() %
|
||||
MidiTime::ticksPerTact() ).
|
||||
arg( m_tco->startPosition().getTact() + 1 ).
|
||||
arg( m_tco->startPosition().getTicks() %
|
||||
MidiTime::ticksPerTact() ).
|
||||
arg( m_tco->endPosition().getTact() + 1 ).
|
||||
arg( m_tco->endPosition().getTicks() %
|
||||
MidiTime::ticksPerTact() ) );
|
||||
s_textFloat->moveGlobal( this, QPoint( width() + 2, height() + 2) );
|
||||
}
|
||||
// s_textFloat->reparent( this );
|
||||
// setup text-float as if TCO was already moved/resized
|
||||
mouseMoveEvent( me );
|
||||
s_textFloat->show();
|
||||
}
|
||||
else if( me->button() == Qt::RightButton )
|
||||
@@ -846,8 +860,7 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me )
|
||||
arg( m_tco->startPosition().getTact() + 1 ).
|
||||
arg( m_tco->startPosition().getTicks() %
|
||||
MidiTime::ticksPerTact() ) );
|
||||
s_textFloat->moveGlobal( this, QPoint( width() + 2,
|
||||
height() + 2 ) );
|
||||
s_textFloat->moveGlobal( this, QPoint( width() + 2, height() + 2 ) );
|
||||
}
|
||||
else if( m_action == MoveSelection )
|
||||
{
|
||||
@@ -906,8 +919,7 @@ void TrackContentObjectView::mouseMoveEvent( QMouseEvent * me )
|
||||
arg( m_tco->endPosition().getTact() + 1 ).
|
||||
arg( m_tco->endPosition().getTicks() %
|
||||
MidiTime::ticksPerTact() ) );
|
||||
s_textFloat->moveGlobal( this, QPoint( width() + 2,
|
||||
height() + 2) );
|
||||
s_textFloat->moveGlobal( this, QPoint( width() + 2, height() + 2) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1801,6 +1813,7 @@ void TrackOperationsWidget::cloneTrack()
|
||||
void TrackOperationsWidget::clearTrack()
|
||||
{
|
||||
Track * t = m_trackView->getTrack();
|
||||
t->addJournalCheckPoint();
|
||||
t->lock();
|
||||
t->deleteTCOs();
|
||||
t->unlock();
|
||||
|
||||
@@ -38,6 +38,10 @@ MidiClient::MidiClient()
|
||||
MidiClient::~MidiClient()
|
||||
{
|
||||
//TODO: noteOffAll(); / clear all ports
|
||||
for (MidiPort* port : m_midiPorts)
|
||||
{
|
||||
port->invalidateCilent();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,9 +27,12 @@
|
||||
|
||||
#include "MidiPort.h"
|
||||
#include "MidiClient.h"
|
||||
#include "MidiDummy.h"
|
||||
#include "Note.h"
|
||||
#include "Song.h"
|
||||
|
||||
static MidiDummy s_dummyClient;
|
||||
|
||||
|
||||
|
||||
MidiPort::MidiPort( const QString& name,
|
||||
@@ -410,4 +413,7 @@ void MidiPort::updateOutputProgram()
|
||||
|
||||
|
||||
|
||||
|
||||
void MidiPort::invalidateCilent()
|
||||
{
|
||||
m_midiClient = &s_dummyClient;
|
||||
}
|
||||
|
||||
@@ -115,6 +115,8 @@ void ExportProjectDialog::accept()
|
||||
m_renderManager = NULL;
|
||||
|
||||
QDialog::accept();
|
||||
|
||||
gui->mainWindow()->resetWindowTitle();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -424,7 +424,7 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me )
|
||||
m_previewPlayHandle = s;
|
||||
delete tf;
|
||||
}
|
||||
else if( ( f->extension ()== "xiz" || f->extension() == "sf2" || f->extension() == "gig" ) &&
|
||||
else if( ( f->extension ()== "xiz" || f->extension() == "sf2" || f->extension() == "gig" || f->extension() == "pat" ) &&
|
||||
! pluginFactory->pluginSupportingExtension(f->extension()).isNull() )
|
||||
{
|
||||
m_previewPlayHandle = new PresetPreviewPlayHandle( f->fullName(), f->handling() == FileItem::LoadByPlugin );
|
||||
@@ -489,6 +489,10 @@ void FileBrowserTreeWidget::mouseMoveEvent( QMouseEvent * me )
|
||||
new StringPairDrag( "soundfontfile", f->fullName(),
|
||||
embed::getIconPixmap( "soundfont_file" ), this );
|
||||
break;
|
||||
case FileItem::PatchFile:
|
||||
new StringPairDrag( "patchfile", f->fullName(),
|
||||
embed::getIconPixmap( "sample_file" ), this );
|
||||
break;
|
||||
case FileItem::VstPluginFile:
|
||||
new StringPairDrag( "vstpluginfile", f->fullName(),
|
||||
embed::getIconPixmap( "vst_plugin_file" ), this );
|
||||
|
||||
@@ -102,6 +102,7 @@
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>RowTableView</class>
|
||||
<extends>QTableView</extends>
|
||||
<header>RowTableView.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
|
||||
@@ -59,7 +59,7 @@ GuiApplication::GuiApplication()
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
|
||||
#endif
|
||||
|
||||
// prompt the user to create the LMMS working directory (e.g. ~/lmms) if it doesn't exist
|
||||
// prompt the user to create the LMMS working directory (e.g. ~/Documents/lmms) if it doesn't exist
|
||||
if ( !ConfigManager::inst()->hasWorkingDir() &&
|
||||
QMessageBox::question( NULL,
|
||||
tr( "Working directory" ),
|
||||
|
||||
@@ -177,6 +177,13 @@ void LmmsStyle::drawComplexControl( ComplexControl control,
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (control == CC_MdiControls)
|
||||
{
|
||||
QStyleOptionComplex so(*option);
|
||||
so.palette.setColor(QPalette::Button, QColor(223, 228, 236));
|
||||
QProxyStyle::drawComplexControl(control, &so, painter, widget);
|
||||
return;
|
||||
}
|
||||
/* else if( control == CC_ScrollBar )
|
||||
{
|
||||
painter->fillRect( option->rect, QApplication::palette().color( QPalette::Active,
|
||||
@@ -365,4 +372,3 @@ void LmmsStyle::hoverColors( bool sunken, bool hover, bool active, QColor& color
|
||||
blend = QColor( 33, 33, 33 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -327,7 +327,9 @@ void PianoView::modelChanged()
|
||||
*/
|
||||
int PianoView::getKeyFromMouse( const QPoint & _p ) const
|
||||
{
|
||||
int key_num = (int)( (float) _p.x() / (float) PW_WHITE_KEY_WIDTH );
|
||||
int offset = _p.x() % PW_WHITE_KEY_WIDTH;
|
||||
if( offset < 0 ) offset += PW_WHITE_KEY_WIDTH;
|
||||
int key_num = ( _p.x() - offset) / PW_WHITE_KEY_WIDTH;
|
||||
|
||||
for( int i = 0; i <= key_num; ++i )
|
||||
{
|
||||
@@ -336,6 +338,13 @@ int PianoView::getKeyFromMouse( const QPoint & _p ) const
|
||||
++key_num;
|
||||
}
|
||||
}
|
||||
for( int i = 0; i >= key_num; --i )
|
||||
{
|
||||
if ( Piano::isBlackKey( m_startKey+i ) )
|
||||
{
|
||||
--key_num;
|
||||
}
|
||||
}
|
||||
|
||||
key_num += m_startKey;
|
||||
|
||||
@@ -345,16 +354,14 @@ int PianoView::getKeyFromMouse( const QPoint & _p ) const
|
||||
// then do extra checking whether the mouse-cursor is over
|
||||
// a black key
|
||||
if( key_num > 0 && Piano::isBlackKey( key_num-1 ) &&
|
||||
_p.x() % PW_WHITE_KEY_WIDTH <=
|
||||
( PW_WHITE_KEY_WIDTH / 2 ) -
|
||||
( PW_BLACK_KEY_WIDTH / 2 ) )
|
||||
offset <= ( PW_WHITE_KEY_WIDTH / 2 ) -
|
||||
( PW_BLACK_KEY_WIDTH / 2 ) )
|
||||
{
|
||||
--key_num;
|
||||
}
|
||||
if( key_num < NumKeys - 1 && Piano::isBlackKey( key_num+1 ) &&
|
||||
_p.x() % PW_WHITE_KEY_WIDTH >=
|
||||
( PW_WHITE_KEY_WIDTH -
|
||||
PW_BLACK_KEY_WIDTH / 2 ) )
|
||||
offset >= ( PW_WHITE_KEY_WIDTH -
|
||||
PW_BLACK_KEY_WIDTH / 2 ) )
|
||||
{
|
||||
++key_num;
|
||||
}
|
||||
|
||||
@@ -1525,9 +1525,7 @@ void SetupDialog::setDefaultSoundfont( const QString & _sf )
|
||||
|
||||
void SetupDialog::setBackgroundArtwork( const QString & _ba )
|
||||
{
|
||||
#ifdef LMMS_HAVE_FLUIDSYNTH
|
||||
m_backgroundArtwork = _ba;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -113,8 +113,11 @@ void SubWindow::paintEvent( QPaintEvent * )
|
||||
p.drawLine( width() - 1, m_titleBarHeight, width() - 1, height() - 1 );
|
||||
|
||||
// window icon
|
||||
QPixmap winicon( widget()->windowIcon().pixmap( m_buttonSize ) );
|
||||
p.drawPixmap( 3, 3, m_buttonSize.width(), m_buttonSize.height(), winicon );
|
||||
if( widget() )
|
||||
{
|
||||
QPixmap winicon( widget()->windowIcon().pixmap( m_buttonSize ) );
|
||||
p.drawPixmap( 3, 3, m_buttonSize.width(), m_buttonSize.height(), winicon );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -267,25 +270,31 @@ void SubWindow::adjustTitleBar()
|
||||
// we're keeping the restore button around if we open projects
|
||||
// from older versions that have saved minimized windows
|
||||
m_restoreBtn->setVisible( isMaximized() || isMinimized() );
|
||||
|
||||
// title QLabel adjustments
|
||||
m_windowTitle->setAlignment( Qt::AlignHCenter );
|
||||
m_windowTitle->setFixedWidth( widget()->width() - ( menuButtonSpace + buttonBarWidth ) );
|
||||
m_windowTitle->move( menuButtonSpace,
|
||||
( m_titleBarHeight / 2 ) - ( m_windowTitle->sizeHint().height() / 2 ) - 1 );
|
||||
|
||||
// if minimized we can't use widget()->width(). We have to hard code the width,
|
||||
// as the width of all minimized windows is the same.
|
||||
if( isMinimized() )
|
||||
{
|
||||
m_restoreBtn->move( m_maximizeBtn->isHidden() ? middleButtonPos : leftButtonPos );
|
||||
m_windowTitle->setFixedWidth( 120 );
|
||||
}
|
||||
|
||||
// truncate the label string if the window is to small. Adds "..."
|
||||
elideText( m_windowTitle, widget()->windowTitle() );
|
||||
m_windowTitle->setTextInteractionFlags( Qt::NoTextInteraction );
|
||||
m_windowTitle->adjustSize();
|
||||
if( widget() )
|
||||
{
|
||||
// title QLabel adjustments
|
||||
m_windowTitle->setAlignment( Qt::AlignHCenter );
|
||||
m_windowTitle->setFixedWidth( widget()->width() - ( menuButtonSpace + buttonBarWidth ) );
|
||||
m_windowTitle->move( menuButtonSpace,
|
||||
( m_titleBarHeight / 2 ) - ( m_windowTitle->sizeHint().height() / 2 ) - 1 );
|
||||
|
||||
// if minimized we can't use widget()->width(). We have to hard code the width,
|
||||
// as the width of all minimized windows is the same.
|
||||
if( isMinimized() )
|
||||
{
|
||||
m_windowTitle->setFixedWidth( 120 );
|
||||
}
|
||||
|
||||
// truncate the label string if the window is to small. Adds "..."
|
||||
elideText( m_windowTitle, widget()->windowTitle() );
|
||||
m_windowTitle->setTextInteractionFlags( Qt::NoTextInteraction );
|
||||
m_windowTitle->adjustSize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -340,7 +340,7 @@ void TrackContainerView::dragEnterEvent( QDragEnterEvent * _dee )
|
||||
{
|
||||
StringPairDrag::processDragEnterEvent( _dee,
|
||||
QString( "presetfile,pluginpresetfile,samplefile,instrument,"
|
||||
"importedproject,soundfontfile,vstpluginfile,projectfile,"
|
||||
"importedproject,soundfontfile,patchfile,vstpluginfile,projectfile,"
|
||||
"track_%1,track_%2" ).
|
||||
arg( Track::InstrumentTrack ).
|
||||
arg( Track::SampleTrack ) );
|
||||
@@ -378,7 +378,8 @@ void TrackContainerView::dropEvent( QDropEvent * _de )
|
||||
_de->accept();
|
||||
}
|
||||
else if( type == "samplefile" || type == "pluginpresetfile"
|
||||
|| type == "soundfontfile" || type == "vstpluginfile")
|
||||
|| type == "soundfontfile" || type == "vstpluginfile"
|
||||
|| type == "patchfile" )
|
||||
{
|
||||
InstrumentTrack * it = dynamic_cast<InstrumentTrack *>(
|
||||
Track::create( Track::InstrumentTrack,
|
||||
|
||||
@@ -1076,8 +1076,8 @@ void AutomationEditor::mouseMoveEvent(QMouseEvent * mouseEvent )
|
||||
inline void AutomationEditor::drawCross( QPainter & p )
|
||||
{
|
||||
QPoint mouse_pos = mapFromGlobal( QCursor::pos() );
|
||||
float level = getLevel( mouse_pos.y() );
|
||||
int grid_bottom = height() - SCROLLBAR_SIZE - 1;
|
||||
float level = getLevel( mouse_pos.y() );
|
||||
float cross_y = m_y_auto ?
|
||||
grid_bottom - ( ( grid_bottom - TOP_MARGIN )
|
||||
* ( level - m_minLevel )
|
||||
@@ -1086,13 +1086,23 @@ inline void AutomationEditor::drawCross( QPainter & p )
|
||||
|
||||
p.setPen( crossColor() );
|
||||
p.drawLine( VALUES_WIDTH, (int) cross_y, width(), (int) cross_y );
|
||||
p.drawLine( mouse_pos.x(), TOP_MARGIN, mouse_pos.x(),
|
||||
height() - SCROLLBAR_SIZE );
|
||||
p.drawLine( mouse_pos.x(), TOP_MARGIN, mouse_pos.x(), height() - SCROLLBAR_SIZE );
|
||||
|
||||
|
||||
QPoint tt_pos = QCursor::pos();
|
||||
tt_pos.ry() -= 64;
|
||||
tt_pos.rx() += 32;
|
||||
tt_pos.ry() -= 51;
|
||||
tt_pos.rx() += 26;
|
||||
|
||||
float scaledLevel = m_pattern->firstObject()->scaledValue( level );
|
||||
QToolTip::showText( tt_pos, QString::number( scaledLevel ), this );
|
||||
|
||||
// Limit the scaled-level tooltip to the grid
|
||||
if( mouse_pos.x() >= 0 &&
|
||||
mouse_pos.x() <= width() - SCROLLBAR_SIZE &&
|
||||
mouse_pos.y() >= 0 &&
|
||||
mouse_pos.y() <= height() - SCROLLBAR_SIZE )
|
||||
{
|
||||
QToolTip::showText( tt_pos, QString::number( scaledLevel ), this );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include <QLayout>
|
||||
#include <QMdiArea>
|
||||
#include <QPainter>
|
||||
#include <QPointer>
|
||||
#include <QScrollBar>
|
||||
#include <QStyleOption>
|
||||
#include <QSignalMapper>
|
||||
@@ -889,10 +890,6 @@ void PianoRoll::drawDetuningInfo( QPainter & _p, const Note * _n, int _x,
|
||||
for( timeMap::ConstIterator it = map.begin(); it != map.end(); ++it )
|
||||
{
|
||||
int pos_ticks = it.key();
|
||||
if( pos_ticks > _n->length() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
int pos_x = _x + pos_ticks * m_ppt / MidiTime::ticksPerTact();
|
||||
|
||||
const float level = it.value();
|
||||
@@ -1338,8 +1335,8 @@ void PianoRoll::mousePressEvent(QMouseEvent * me )
|
||||
|
||||
if( m_editMode == ModeEditDetuning && noteUnderMouse() )
|
||||
{
|
||||
static AutomationPattern* detuningPattern = nullptr;
|
||||
if (detuningPattern != nullptr)
|
||||
static QPointer<AutomationPattern> detuningPattern = nullptr;
|
||||
if (detuningPattern.data() != nullptr)
|
||||
{
|
||||
detuningPattern->disconnect(this);
|
||||
}
|
||||
@@ -1349,7 +1346,7 @@ void PianoRoll::mousePressEvent(QMouseEvent * me )
|
||||
n->createDetuning();
|
||||
}
|
||||
detuningPattern = n->detuning()->automationPattern();
|
||||
connect(detuningPattern, SIGNAL(dataChanged()), this, SLOT(update()));
|
||||
connect(detuningPattern.data(), SIGNAL(dataChanged()), this, SLOT(update()));
|
||||
gui->automationEditor()->open(detuningPattern);
|
||||
return;
|
||||
}
|
||||
@@ -2059,7 +2056,8 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
|
||||
pauseTestNotes( false );
|
||||
}
|
||||
}
|
||||
else if( ( edit_note || m_action == ActionChangeNoteProperty ) &&
|
||||
else if( m_editMode != ModeErase &&
|
||||
( edit_note || m_action == ActionChangeNoteProperty ) &&
|
||||
( me->buttons() & Qt::LeftButton || me->buttons() & Qt::MiddleButton
|
||||
|| ( me->buttons() & Qt::RightButton && me->modifiers() & Qt::ShiftModifier ) ) )
|
||||
{
|
||||
@@ -2121,9 +2119,14 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
|
||||
bool isUnderPosition = n->withinRange( ticks_start, ticks_end );
|
||||
// Play note under the cursor
|
||||
if ( isUnderPosition ) { testPlayNote( n ); }
|
||||
// If note is the one under the cursor or is selected when alt is
|
||||
// not pressed
|
||||
if ( ( isUnderPosition && !isSelection() ) || ( n->selected() && !altPressed ) )
|
||||
// If note is:
|
||||
// Under the cursor, when there is no selection
|
||||
// Selected, and alt is not pressed
|
||||
// Under the cursor, selected, and alt is pressed
|
||||
if ( ( isUnderPosition && !isSelection() ) ||
|
||||
( n->selected() && !altPressed ) ||
|
||||
( isUnderPosition && n->selected() && altPressed )
|
||||
)
|
||||
{
|
||||
if( m_noteEditMode == NoteEditVolume )
|
||||
{
|
||||
@@ -2249,9 +2252,11 @@ void PianoRoll::mouseMoveEvent( QMouseEvent * me )
|
||||
--m_selectedKeys;
|
||||
}
|
||||
}
|
||||
else if( m_editMode == ModeDraw && me->buttons() & Qt::RightButton )
|
||||
else if( ( m_editMode == ModeDraw && me->buttons() & Qt::RightButton )
|
||||
|| ( m_editMode == ModeErase && me->buttons() ) )
|
||||
{
|
||||
// holding down right-click to delete notes
|
||||
// holding down right-click to delete notes or holding down
|
||||
// any key if in erase mode
|
||||
|
||||
// get tick in which the user clicked
|
||||
int pos_ticks = x * MidiTime::ticksPerTact() / m_ppt +
|
||||
@@ -2629,23 +2634,6 @@ void PianoRoll::paintEvent(QPaintEvent * pe )
|
||||
|
||||
int key = m_startKey;
|
||||
|
||||
// display note marks before drawing other lines
|
||||
for( int i = 0; i < m_markedSemiTones.size(); i++ )
|
||||
{
|
||||
const int key_num = m_markedSemiTones.at( i );
|
||||
const int y = keyAreaBottom() + 5
|
||||
- KEY_LINE_HEIGHT * ( key_num - m_startKey + 1 );
|
||||
|
||||
if( y > keyAreaBottom() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
p.fillRect( WHITE_KEY_WIDTH + 1, y - KEY_LINE_HEIGHT / 2, width() - 10, KEY_LINE_HEIGHT,
|
||||
markedSemitoneColor() );
|
||||
}
|
||||
|
||||
|
||||
// draw all white keys...
|
||||
for( int y = key_line_y + 1 + y_offset; y > PR_TOP_MARGIN;
|
||||
key_line_y -= KEY_LINE_HEIGHT, ++keys_processed )
|
||||
@@ -2909,7 +2897,6 @@ void PianoRoll::paintEvent(QPaintEvent * pe )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Draw the vertical beat lines
|
||||
int ticksPerBeat = DefaultTicksPerTact /
|
||||
Engine::getSong()->getTimeSigModel().getDenominator();
|
||||
@@ -2930,8 +2917,23 @@ void PianoRoll::paintEvent(QPaintEvent * pe )
|
||||
p.setPen( barLineColor() );
|
||||
p.drawLine( x, PR_TOP_MARGIN, x, height() - PR_BOTTOM_MARGIN );
|
||||
}
|
||||
}
|
||||
|
||||
// draw marked semitones after the grid
|
||||
for( int i = 0; i < m_markedSemiTones.size(); i++ )
|
||||
{
|
||||
const int key_num = m_markedSemiTones.at( i );
|
||||
const int y = keyAreaBottom() + 5
|
||||
- KEY_LINE_HEIGHT * ( key_num - m_startKey + 1 );
|
||||
|
||||
if( y > keyAreaBottom() )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
p.fillRect( WHITE_KEY_WIDTH + 1, y - KEY_LINE_HEIGHT / 2, width() - 10, KEY_LINE_HEIGHT + 1,
|
||||
markedSemitoneColor() );
|
||||
}
|
||||
}
|
||||
|
||||
// following code draws all notes in visible area
|
||||
// and the note editing stuff (volume, panning, etc)
|
||||
@@ -3404,6 +3406,7 @@ void PianoRoll::record()
|
||||
return;
|
||||
}
|
||||
|
||||
m_pattern->addJournalCheckPoint();
|
||||
m_recording = true;
|
||||
|
||||
Engine::getSong()->playPattern( m_pattern, false );
|
||||
@@ -3423,6 +3426,7 @@ void PianoRoll::recordAccompany()
|
||||
return;
|
||||
}
|
||||
|
||||
m_pattern->addJournalCheckPoint();
|
||||
m_recording = true;
|
||||
|
||||
if( m_pattern->getTrack()->trackContainer() == Engine::getSong() )
|
||||
@@ -3757,7 +3761,7 @@ void PianoRoll::pasteNotes()
|
||||
// create the note
|
||||
Note cur_note;
|
||||
cur_note.restoreState( list.item( i ).toElement() );
|
||||
cur_note.setPos( cur_note.pos() + m_timeLine->pos() );
|
||||
cur_note.setPos( cur_note.pos() + Note::quantized( m_timeLine->pos(), quantization() ) );
|
||||
|
||||
// select it
|
||||
cur_note.setSelected( true );
|
||||
@@ -4070,14 +4074,14 @@ PianoRollWindow::PianoRollWindow() :
|
||||
QAction* drawAction = editModeGroup->addAction( embed::getIconPixmap( "edit_draw" ), tr( "Draw mode (Shift+D)" ) );
|
||||
QAction* eraseAction = editModeGroup->addAction( embed::getIconPixmap( "edit_erase" ), tr("Erase mode (Shift+E)" ) );
|
||||
QAction* selectAction = editModeGroup->addAction( embed::getIconPixmap( "edit_select" ), tr( "Select mode (Shift+S)" ) );
|
||||
QAction* detuneAction = editModeGroup->addAction( embed::getIconPixmap( "automation" ), tr("Detune mode (Shift+T)" ) );
|
||||
QAction* pitchBendAction = editModeGroup->addAction( embed::getIconPixmap( "automation" ), tr("Pitch Bend mode (Shift+T)" ) );
|
||||
|
||||
drawAction->setChecked( true );
|
||||
|
||||
drawAction->setShortcut( Qt::SHIFT | Qt::Key_D );
|
||||
eraseAction->setShortcut( Qt::SHIFT | Qt::Key_E );
|
||||
selectAction->setShortcut( Qt::SHIFT | Qt::Key_S );
|
||||
detuneAction->setShortcut( Qt::SHIFT | Qt::Key_T );
|
||||
pitchBendAction->setShortcut( Qt::SHIFT | Qt::Key_T );
|
||||
|
||||
drawAction->setWhatsThis(
|
||||
tr( "Click here and draw mode will be activated. In this "
|
||||
@@ -4105,8 +4109,8 @@ PianoRollWindow::PianoRollWindow() :
|
||||
#else
|
||||
"Ctrl" ) );
|
||||
#endif
|
||||
detuneAction->setWhatsThis(
|
||||
tr( "Click here and detune mode will be activated. "
|
||||
pitchBendAction->setWhatsThis(
|
||||
tr( "Click here and Pitch Bend mode will be activated. "
|
||||
"In this mode you can click a note to open its "
|
||||
"automation detuning. You can utilize this to slide "
|
||||
"notes from one to another. You can also press "
|
||||
@@ -4120,7 +4124,7 @@ PianoRollWindow::PianoRollWindow() :
|
||||
notesActionsToolBar->addAction( drawAction );
|
||||
notesActionsToolBar->addAction( eraseAction );
|
||||
notesActionsToolBar->addAction( selectAction );
|
||||
notesActionsToolBar->addAction( detuneAction );
|
||||
notesActionsToolBar->addAction( pitchBendAction );
|
||||
notesActionsToolBar->addSeparator();
|
||||
notesActionsToolBar->addAction( quantizeAction );
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <QMdiSubWindow>
|
||||
#include <QPainter>
|
||||
#include <QWhatsThis>
|
||||
#include <QLayout>
|
||||
|
||||
#include "EffectView.h"
|
||||
#include "DummyEffect.h"
|
||||
@@ -109,7 +110,9 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) :
|
||||
{
|
||||
m_subWindow = gui->mainWindow()->addWindowedWidget( m_controlView );
|
||||
m_subWindow->setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
|
||||
m_subWindow->setFixedSize( m_subWindow->size() );
|
||||
if (m_subWindow->layout()) {
|
||||
m_subWindow->layout()->setSizeConstraint(QLayout::SetFixedSize);
|
||||
}
|
||||
|
||||
Qt::WindowFlags flags = m_subWindow->windowFlags();
|
||||
flags &= ~Qt::WindowMaximizeButtonHint;
|
||||
@@ -161,18 +164,7 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) :
|
||||
|
||||
EffectView::~EffectView()
|
||||
{
|
||||
|
||||
#ifdef LMMS_BUILD_LINUX
|
||||
|
||||
delete m_subWindow;
|
||||
#else
|
||||
if( m_subWindow )
|
||||
{
|
||||
// otherwise on win32 build VST GUI can get lost
|
||||
m_subWindow->hide();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -393,14 +393,20 @@ void EnvelopeAndLfoView::dropEvent( QDropEvent * _de )
|
||||
m_params->m_userWave.setAudioFile(
|
||||
StringPairDrag::decodeValue( _de ) );
|
||||
m_userLfoBtn->model()->setValue( true );
|
||||
m_params->m_lfoWaveModel.setValue(EnvelopeAndLfoParameters::UserDefinedWave);
|
||||
_de->accept();
|
||||
update();
|
||||
}
|
||||
else if( type == QString( "tco_%1" ).arg( Track::SampleTrack ) )
|
||||
{
|
||||
DataFile dataFile( value.toUtf8() );
|
||||
m_params->m_userWave.setAudioFile( dataFile.content().firstChild().toElement(). attribute( "src" ) );
|
||||
m_params->m_userWave.setAudioFile( dataFile.content().
|
||||
firstChildElement().firstChildElement().
|
||||
firstChildElement().attribute( "src" ) );
|
||||
m_userLfoBtn->model()->setValue( true );
|
||||
m_params->m_lfoWaveModel.setValue(EnvelopeAndLfoParameters::UserDefinedWave);
|
||||
_de->accept();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -188,6 +188,13 @@ void Fader::mousePressEvent( QMouseEvent* mouseEvent )
|
||||
if( mouseEvent->button() == Qt::LeftButton &&
|
||||
! ( mouseEvent->modifiers() & Qt::ControlModifier ) )
|
||||
{
|
||||
AutomatableModel *thisModel = model();
|
||||
if( thisModel )
|
||||
{
|
||||
thisModel->addJournalCheckPoint();
|
||||
thisModel->saveJournallingState( false );
|
||||
}
|
||||
|
||||
if( mouseEvent->y() >= knobPosY() - ( *m_knob ).height() && mouseEvent->y() < knobPosY() )
|
||||
{
|
||||
updateTextFloat();
|
||||
@@ -245,8 +252,17 @@ void Fader::mouseDoubleClickEvent( QMouseEvent* mouseEvent )
|
||||
|
||||
|
||||
|
||||
void Fader::mouseReleaseEvent( QMouseEvent * _me )
|
||||
void Fader::mouseReleaseEvent( QMouseEvent * mouseEvent )
|
||||
{
|
||||
if( mouseEvent && mouseEvent->button() == Qt::LeftButton )
|
||||
{
|
||||
AutomatableModel *thisModel = model();
|
||||
if( thisModel )
|
||||
{
|
||||
thisModel->restoreJournallingState();
|
||||
}
|
||||
}
|
||||
|
||||
s_textFloat->hide();
|
||||
}
|
||||
|
||||
|
||||
@@ -178,7 +178,8 @@ void LcdSpinBox::enterValue()
|
||||
arg( model()->maxValue() ),
|
||||
model()->value(),
|
||||
model()->minValue(),
|
||||
model()->maxValue(), 4, &ok );
|
||||
model()->maxValue(),
|
||||
model()->step<int>(), &ok );
|
||||
|
||||
if( ok )
|
||||
{
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user