Compare commits

...

85 Commits

Author SHA1 Message Date
Hyunin Song
1349d45d72 Bump version to 1.2.0-rc6 2018-06-01 09:04:01 +09:00
Hyunin Song
75a6502100 Fix Mallets crash when STK rawwave files can't be loaded 2018-05-30 19:14:06 +09:00
Hyunin Song
24ae559de5 Fix crash when re-opening VST effect manage dialog
Unset Qt::WA_DeleteOnClose for the dialog to avoid deletion when closed
2018-05-30 09:02:05 +09:00
Hyunin Song
235e8eef6f Allow controlling VST effects without own GUI 2018-05-30 09:02:05 +09:00
Hyunin Song
55d3fbc908 Fix RemoteVstPlugin not exiting when effect removed 2018-05-30 09:02:05 +09:00
Lukas W
b808631975 VST: Add workaround for small effect window on project load 2018-05-30 09:02:05 +09:00
DomClark
8e9f74df37 Minor fixes
From MSDN: "In WM_SYSCOMMAND messages, the four low-order bits of the
wParam parameter are used internally by the system. To obtain the
correct result when testing the value of wParam, an application must
combine the value 0xFFF0 with the wParam value by using the bitwise AND
operator."
Also calculate the required window size using AdjustWindowRect, rather
than hard-coding some constants.
2018-05-30 09:02:05 +09:00
DomClark
fcc883f887 Preserve VST GUI positions and keep them on top 2018-05-30 09:02:05 +09:00
DomClark
ee18011dc7 Fix toggling UI for non-embedded VST effects 2018-05-30 09:02:05 +09:00
DomClark
49dcd385f5 Fix VST effect load crash on non-primary monitor 2018-05-30 09:02:05 +09:00
DomClark
55da698d7c Fix X11 embedding on Qt4 2018-05-30 09:02:05 +09:00
Lukas W
1220374a7f Fix effect dialog layout glitches
QMdiSubWindow::setSizePolicy doesn't have any effect because QMdiSubWindow
uses a layout. This patch uses QMdiSubWindow::layout()->setSizeConstraint
instead. This may cause effects that don't have a layout and don't
implement sizeHint() to now be resizable. For effects that do though, it
fixes the size constraint.
2018-05-30 09:02:05 +09:00
Lukas W
a2cb7e96ea Fix VST sub-window creation glitches in project loading
Fixes bugs where during project loading (observed with VST effects), empty
widgets and sub-windows would be left floating around. These were caused by
inconsistencies between the way VST UIs were created when loading a project
and when adding an effect in an existing project. In some situations, this
caused createUI to be called twice, leaving over multiple empty widgets.

This commit refactors some code in order to avoid creating unnecessary sub-
windows, which aren't needed with VST effects, but were still created,
usually being invisible. All sub-window related code was moved out of
VstPlugin into vestige.cpp, which is the only place where sub-window VSTs
are actually used. A new sub-class of VstPlugin, VstInstrumentPlugin, now
handles VST sub-windows and is used by vestigeInstrument.

"guivisible" attribute loading was moved out of VstPlugin as well and is
now done in VstEffectControls' and vestigeInstrument's loadSettings method
respectively. This causes some minor code duplication unfortunately.

Closes #4110
2018-05-30 09:02:05 +09:00
Hyunin Song
3e8120d532 Make "Clear this track" undoable
Fixes #4375
2018-05-28 13:49:38 +09:00
Hyunjin Song
daa3f53515 Fix compilation with Qt 5.11 (#4374)
Add extends attribute for custom widget RowTableView per upstream uic change http://code.qt.io/cgit/qt/qtbase.git/commit/?id=058474884c2505a8a00d4c59b4922bfcd3597c2f
2018-05-23 14:59:45 +09:00
Joshua Wade
68a621cc16 Restart flanger LFO on Song::playbackStateChanged signal (#4363)
Closes https://github.com/LMMS/lmms/issues/3689
2018-05-18 13:34:46 -04:00
Hussam Eddin Alhomsi
0caaebaecb Remove FluidSynth requirement for background pic (#4364) 2018-05-17 19:35:52 +02:00
Oskar Wallgren
bb43bfb961 Remove release time from arpeggiated note (#4355)
An arpeggio master note shouldn't trigger new notes while it's decaying.

#fixes #4342
2018-05-17 18:39:31 +02:00
Colin Wallace
5d90aecac9 Merge pull request #4339 from PhysSong/tcomove
Fix occasional crash when moving TCOs
2018-05-08 21:29:41 -07:00
Hyunjin Song
03aa5fb3c7 Fix crash on exit from MIDI connections (#4340) 2018-05-07 17:08:43 -07:00
Hyunin Song
511c7a64fe Fix occasional crash when moving TCOs 2018-05-03 11:23:35 +09:00
Lukas W
af61a82df8 Merge pull request #4335 from LMMS/fix/job-queue
Fix job queue crash
2018-05-02 12:55:09 +02:00
Lukas W
9a52c7b901 JobQueue: Rename m_queueSize to m_writeIndex
Hopefully makes it less confusing that m_writeIndex grows beyond
JOB_QUEUE_SIZE when the queue is full.
2018-05-02 12:54:45 +02:00
Hyunjin Song
08573fc96d Fix detuning crash after deleting the note being edited (#4324) 2018-04-30 14:54:34 +09:00
Lukas W
ccd4ff3c2c Fix job queue crash
* Don't add jobs when job queue is full
* Icrease job queue size from 1024 to 8192
2018-04-29 17:01:51 +02:00
Lukas W
84d3c935de Merge pull request #4333 from PhysSong/circledummy
Add dummy CircleCI config file for stable-1.2
2018-04-29 16:04:44 +02:00
Hyunin Song
832e87725a Add dummy CircleCI config file 2018-04-29 21:59:09 +09:00
Hussam Eddin Alhomsi
386c471ed7 Limit the automation-editor scaled-level tooltip to the grid (#4308) 2018-04-26 18:37:43 +03:00
Lukas W
fce9326192 Update rpmalloc to 1.3.0
Fixes #4055
2018-04-25 11:00:13 +02:00
Lukas W
e614711d29 Merge pull request #4307 from LMMS/fix/contributors
Revert contributor file removal
2018-04-25 07:52:03 +02:00
Lukas W
d65fdd4ee6 Create no-response.yml 2018-04-22 08:34:46 +02:00
Lukas W
50eada6b2b Update project year 2018-04-21 13:33:35 +02:00
Lukas W
33368bd9d0 Revert CONTRIBUTOR file removal
This reverts commit 30f1e52be3.

# Conflicts:
#	CMakeLists.txt
2018-04-21 13:31:14 +02:00
tresf
aaee2ecb15 Better fluidsynth version detection
Per #4300 comment
2018-04-20 21:53:13 -04:00
Tres Finocchiaro
22ca47abba Disable fluidsynth audio backends if possible (#4300)
Closes #649
Partially reverts #3446
2018-04-20 15:46:13 -04:00
Tres Finocchiaro
18a4346fd5 Better default working directory (#4288)
* Better default working directory
Closes #1135
2018-04-20 15:41:08 -04:00
Oskar Wallgren
07a23c4e3b Allways remove infs/nans (#3706)
When exporting a project lmms performs extra tests for bad data.
The tests are for infs and nans. Switching these tests on for all
occasions as the extra performance hit would be in the order of
only ~2% and the problems, when it hits the end user, are hard to
debug and/or work around.

After testing for inf/nan we clamp the sound to +/-4.0f as sometimes
you will get large transients passing through (an issue that is currently
only present when exporting).

Fixes: #1048
2018-04-15 15:44:38 +02:00
Hussam Eddin Alhomsi
e554a4c4b0 Better behavior when left-clicking a TCO (#4290)
Instead of calling MouseMoveEvent(), the TCO's "text float" text and position are updated.
This prevents left-clicking the right edge of a resizable TCO from decreasing its size.

Also, removed an unused variable: m_oldTime
2018-04-11 13:39:43 +03:00
Hyunjin Song
00f9590b18 Fix preset preview issues with peak controllers (#3904) 2018-04-04 09:06:58 +09:00
Dominic Clark
d30a22487e Don't call setParameter from audioMasterAutomate (#4279) 2018-04-03 19:08:53 +01:00
Umcaruje
b77027d6fb Fix MDI subwindow buttons contrast in the MenuBar (#4242)
* Fix MDI subwindow buttons contrast in the MenuBar

* Hard code the button color in LmmsStyle.cpp (thanks @PhysSong)

* Fix code formatting
2018-04-02 19:36:07 +02:00
Umcaruje
ee910d38fe Fix marked semitones in the piano roll (#4239)
* Fix marked semitones in the piano roll

* Don't draw in invalid patterns

* update classic theme

* Fix contrast

* update classic theme
2018-04-02 19:33:01 +02:00
Tres Finocchiaro
1df461d64d Fix VSTs on Fedora 27 (#4276) 2018-03-30 14:13:31 -04:00
Tres Finocchiaro
3673e84ac1 Allow relative paths on non-existent directories (#4271)
* Use cleanPath for calculating relative directories
Closes #4267
2018-03-26 21:51:55 -04:00
Hyunjin Song
ac543ffc75 Play correct note when dragging left side of virtual keyboard (#4265) 2018-03-21 23:39:17 -04:00
Noah Brecht
87e6b48df7 Fix ui glitch where track ticks did not line up (#4171) 2018-03-21 04:13:42 +01:00
Orbital Ink
fc5fc1cbaa Change Detune To Pitch Bend in Piano Roll (#4194) 2018-03-19 20:23:00 +03:00
Umcaruje
0d1c874a60 Change selected notes color (#4243) 2018-03-19 17:35:15 +01:00
Tres Finocchiaro
7a8a925b83 Fix toFloat Qt5 regression (#4244)
Closes #4241
2018-03-19 12:18:47 -04:00
Tres Finocchiaro
6cd5317e09 Fix C++ standards library portability issue. (#4261)
Fix C++ standards library portability issue.
Cherry-pick of upstream 2.5 patches: zynaddsubfx/zynaddsubfx@417d49b, zynaddsubfx/zynaddsubfx@edca8ab
Closes #4152
2018-03-18 13:36:05 -04:00
Hyunjin Song
b4e78065e7 Fix some bugs with LFO waveform drag&drop (#4227)
* Change to user-wave mode and update display after dropping a sample
* Fix broken drag&drop from sample tracks
2018-03-14 14:48:18 +09:00
Oskar Wallgren
a54c54097f Draw the entire length of a notes pitch bend info (#4233) 2018-03-12 14:49:45 +01:00
Orbital Ink
e9b83378f9 Typo - Phrygolydian to phrygian (#4223) 2018-03-07 16:44:16 +01:00
Hyunjin Song
ec0f47e9e3 Fix AppImage tool path 2018-03-07 23:27:28 +09:00
tresf
38b69a7e3a Fix incrementation of LcdSpinBox QInputDialog
Closes #4218
2018-03-06 14:35:24 -05:00
Hyunjin Song
788c990ae1 Remove MIDI connection from factory files (#4207) 2018-03-06 09:57:40 +09:00
Hyunjin Song
533f475943 Ensure correct length of automation patterns in BB editor (#4212)
When the length of an automation pattern is an integer multiple of one bar, it was displayed with wrong length. This commit fixes the bug.
2018-03-06 09:57:16 +09:00
Tres Finocchiaro
1d63bd3b4e Use Canonical Paths for Relative Paths Calculations (#4211)
Fix redundant path elements
Closes #4173
2018-03-03 22:46:07 -05:00
Hyunjin Song
926b6542ae Don't restore audio device during exporting (#4083)
Fixes deadlock on multi-track export with SDL
2018-03-02 13:28:56 +09:00
Tres Finocchiaro
9f1c73bc12 Fix theme after upgrade
Closes #4199
2018-03-01 20:37:04 -05:00
Oskar Wallgren
063a505026 Turn journalling off when moving fader (#4147) 2018-03-01 19:03:02 +01:00
tresf
a8e8746011 Add support for .pat previews, drag+drop
Closes #4202
2018-02-28 21:34:45 -05:00
Dominic Clark
31775752b4 Fix rendering cancellation with VSTs (#4189) 2018-02-27 16:08:42 +01:00
Oskar Wallgren
33d2b71b01 Piano Roll - Erase on mouse button drag in erase mode (#4150) 2018-02-27 15:59:15 +01:00
tresf
fc9c3eadef Fix the AppImages 2018-02-27 01:54:26 -05:00
tresf
edc8f43d5b Use bundled jack if missing
Closes #4094
2018-02-27 01:54:26 -05:00
Tres Finocchiaro
3980e54667 Better wine prefix detection (#4176)
Closes #4108
2018-02-23 13:20:35 -05:00
Hyunin Song
0f0b08b852 Travis: replace homebrew/versions/qt55 with qt5 2018-02-17 13:01:19 +09:00
noahb01
a39ea2b163 Reset window title after render
Closes #4160
2018-02-08 23:40:15 -05:00
Oskar Wallgren
c3b4767836 Add journaling checkpoint to recording notes (#4144) 2018-02-01 19:45:05 +01:00
Dominic Clark
27007c258a Fix command line rendering with VSTs (#4093)
Fix command line rendering with VSTs
2018-01-26 10:48:46 -05:00
Filip Hron
a193ec25f2 Fix patman logo
Closes #3660
Supercedes #4121
2018-01-17 17:05:38 -05:00
DomClark
e2c71e3369 Fix lack of sound in iZotope plugins (#4095) 2018-01-17 15:56:01 +09:00
DomClark
d0b3be7f00 Wait for reply when updating sample rate 2018-01-17 15:56:01 +09:00
DomClark
709fc7948b Set buffer size during plugin init
Fixes AmpliTube crash
2018-01-17 15:56:01 +09:00
DomClark
6e0dda692a Remove plugin lock from RemoteVstPlugin 2018-01-17 15:56:01 +09:00
tresf
46512fdf19 Fix macOS compilation without SDL
Closes #4105
2018-01-09 21:34:24 -05:00
Mark-Agent003
59eba30d33 Add File Browser Styling (#4085)
Use CSS to style the selected and hovered items in the File Browser
2018-01-05 11:43:24 -05:00
David Carlier
bd8c27249f Using the cmake variable will insure the proper value
regardless of the platform (already available in 2.0.7 version)
2018-01-02 13:09:03 +01:00
liushuyu
96c5f05120 update i18n and add i18n maint script 2017-12-30 01:21:00 -07:00
Tres Finocchiaro
a3d72def4d Move Zyn GUI to main thread (#4065) 2017-12-22 15:29:32 -05:00
gandalf3
2c3df226ee Allow individual velocity/pan changes with alt (#3923)
Fix regression caused by 6e3d4f4, allow ALT to change the velocity of multiple selected notes.
2017-12-22 15:29:08 -05:00
tresf
7de9649b2f Fix quantization of pasted notes
Fixes a regression caused by #4058
2017-12-22 14:58:20 -05:00
Tres Finocchiaro
c3438a1b4e Remove alpha channel from splash
Closes #4062
2017-12-20 20:46:47 -05:00
Hyunjin Song
eb9b460925 Travis: install jack2 in Linux build
Per #4026: Installing Carla will remove jack1 if it's installed, since Carla requires jack2.
2017-12-20 12:54:31 +09:00
102 changed files with 5751 additions and 2876 deletions

11
.circleci/config.yml Normal file
View 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
View File

@@ -0,0 +1,2 @@
# Label requiring a response
responseRequiredLabel: "response required"

View File

@@ -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"

View File

@@ -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

View File

@@ -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 ..

View File

@@ -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
View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

File diff suppressed because it is too large Load Diff

View File

@@ -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>

View File

@@ -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">

View File

@@ -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">

View File

@@ -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">

View File

@@ -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">

View File

@@ -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">

View File

@@ -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"/>

View File

@@ -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">

View File

@@ -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">

View File

@@ -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"/>

View File

@@ -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"/>

View File

@@ -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"/>

View File

@@ -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"/>

View File

@@ -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"/>

View File

@@ -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"/>

View File

@@ -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"/>

View File

@@ -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"/>

View File

@@ -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 );

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 B

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

View File

@@ -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;

View File

View File

@@ -124,6 +124,8 @@ public:
return m_writablePorts;
}
void invalidateCilent();
MidiPortMenu* m_readablePortsMenu;
MidiPortMenu* m_writablePortsMenu;

View File

@@ -175,6 +175,7 @@ public:
void setAudioDevice( AudioDevice * _dev,
const struct qualitySettings & _qs,
bool _needs_fifo );
void storeAudioDevice();
void restoreAudioDevice();
inline AudioDevice * audioDev()
{

View File

@@ -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;

View File

@@ -88,7 +88,6 @@ private:
AudioFileDevice * m_fileDev;
Mixer::qualitySettings m_qualitySettings;
Mixer::qualitySettings m_oldQualitySettings;
volatile int m_progress;
volatile bool m_abort;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -57,6 +57,7 @@ public:
private slots:
void changedSampleRate();
void changedPlaybackState();
private:
FlangerEffect* m_effect;

View File

@@ -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"
{

View File

@@ -44,6 +44,7 @@ public:
return &m_flangerControls;
}
void changeSampleRate();
void restartLFO();
private:
FlangerControls m_flangerControls;

View File

@@ -53,6 +53,14 @@ public:
inline void restart()
{
m_phase = 0;
}
inline void setSampleRate ( int samplerate )
{
m_samplerate = samplerate;

View File

@@ -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 ));

View File

@@ -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();
}
}

View File

@@ -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 );
} ;

View File

@@ -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 )

View File

@@ -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

View File

@@ -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 );
}

View File

@@ -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;
}
}

View File

@@ -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() );

View File

@@ -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;
}

View File

@@ -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 )

View File

@@ -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;
} ;

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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)

View File

@@ -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;

View File

@@ -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;

View File

@@ -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

View File

@@ -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,

View File

@@ -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 ;-)

View File

@@ -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

View File

@@ -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)

View File

@@ -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 );
}

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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 );
}
}

View File

@@ -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;
}

View File

@@ -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" );
}

View File

@@ -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;

View File

@@ -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 )

View File

@@ -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" );

View File

@@ -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 );
}

View File

@@ -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 );
}

View File

@@ -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();

View File

@@ -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() );

View File

@@ -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();

View File

@@ -38,6 +38,10 @@ MidiClient::MidiClient()
MidiClient::~MidiClient()
{
//TODO: noteOffAll(); / clear all ports
for (MidiPort* port : m_midiPorts)
{
port->invalidateCilent();
}
}

View File

@@ -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;
}

View File

@@ -115,6 +115,8 @@ void ExportProjectDialog::accept()
m_renderManager = NULL;
QDialog::accept();
gui->mainWindow()->resetWindowTitle();
}

View File

@@ -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 );

View File

@@ -102,6 +102,7 @@
<customwidgets>
<customwidget>
<class>RowTableView</class>
<extends>QTableView</extends>
<header>RowTableView.h</header>
</customwidget>
</customwidgets>

View File

@@ -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" ),

View File

@@ -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 );
}
}

View File

@@ -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;
}

View File

@@ -1525,9 +1525,7 @@ void SetupDialog::setDefaultSoundfont( const QString & _sf )
void SetupDialog::setBackgroundArtwork( const QString & _ba )
{
#ifdef LMMS_HAVE_FLUIDSYNTH
m_backgroundArtwork = _ba;
#endif
}

View File

@@ -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();
}
}

View File

@@ -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,

View File

@@ -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 );
}
}

View File

@@ -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 );

View File

@@ -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
}

View File

@@ -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();
}
}

View File

@@ -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();
}

View File

@@ -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