@@ -4,7 +4,7 @@ dist: trusty
|
||||
sudo: required
|
||||
cache:
|
||||
directories:
|
||||
- apt_mingw_cache
|
||||
- $HOME/apt_mingw_cache
|
||||
- $HOME/.ccache
|
||||
- $HOME/pbuilder-bases
|
||||
matrix:
|
||||
@@ -14,9 +14,15 @@ matrix:
|
||||
- env: TARGET_OS=win32
|
||||
- env: TARGET_OS=win64
|
||||
- env: TARGET_OS=debian-sid TARGET_DEPLOY=True
|
||||
git:
|
||||
depth: false
|
||||
- env: TARGET_OS=debian-sid TARGET_ARCH=i386
|
||||
git:
|
||||
depth: false
|
||||
- compiler: clang
|
||||
env: TARGET_OS=debian-sid
|
||||
git:
|
||||
depth: false
|
||||
- os: osx
|
||||
osx_image: xcode8.3
|
||||
install: ${TRAVIS_BUILD_DIR}/.travis/install.sh
|
||||
|
||||
@@ -23,4 +23,4 @@ sudo apt-get install -y $PACKAGES
|
||||
sudo add-apt-repository -y ppa:kxstudio-debian/libs
|
||||
sudo add-apt-repository -y ppa:kxstudio-debian/apps
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y carla-git
|
||||
sudo apt-get install -y carla
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
: "${TARGET_ARCH:=amd64}"
|
||||
@@ -21,19 +21,50 @@ fi
|
||||
if [ ! -e "$BASETGZ.stamp" ]
|
||||
then
|
||||
mkdir -p "$HOME/pbuilder-bases"
|
||||
# debootstrap fails to resolve dependencies which are virtual packages
|
||||
# e.g. perl-openssl-abi-1.1 provided by perl-openssl-defaults, needed for building SWH
|
||||
# See also: https://bugs.launchpad.net/ubuntu/+source/debootstrap/+bug/86536
|
||||
sudo pbuilder --create --basetgz "$BASETGZ" --mirror $MIRROR \
|
||||
--distribution sid --architecture $TARGET_ARCH \
|
||||
--debootstrapopts --variant=buildd \
|
||||
--debootstrapopts --keyring=$KEYRING \
|
||||
--debootstrapopts --include=perl,libxml2-utils,libxml-perl,liblist-moreutils-perl,perl-openssl-defaults
|
||||
--debootstrapopts --include=perl
|
||||
touch "$BASETGZ.stamp"
|
||||
else
|
||||
sudo pbuilder --update --basetgz "$BASETGZ"
|
||||
fi
|
||||
|
||||
sync_version() {
|
||||
local VERSION
|
||||
local MMR
|
||||
local STAGE
|
||||
local EXTRA
|
||||
|
||||
VERSION=$(git describe --tags --match v[0-9].[0-9].[0-9]*)
|
||||
VERSION=${VERSION#v}
|
||||
MMR=${VERSION%%-*}
|
||||
case $VERSION in
|
||||
*-*-*-*)
|
||||
VERSION=${VERSION%-*}
|
||||
STAGE=${VERSION#*-}
|
||||
STAGE=${STAGE%-*}
|
||||
EXTRA=${VERSION##*-}
|
||||
VERSION=$MMR~$STAGE.$EXTRA
|
||||
;;
|
||||
*-*-*)
|
||||
VERSION=${VERSION%-*}
|
||||
EXTRA=${VERSION##*-}
|
||||
VERSION=$MMR.$EXTRA
|
||||
;;
|
||||
*-*)
|
||||
STAGE=${VERSION#*-}
|
||||
VERSION=$MMR~$STAGE
|
||||
;;
|
||||
esac
|
||||
|
||||
sed "1 s/@VERSION@/$VERSION/" -i debian/changelog
|
||||
echo "Set Debian version to $VERSION"
|
||||
}
|
||||
|
||||
sync_version
|
||||
|
||||
DIR="$PWD"
|
||||
cd ..
|
||||
dpkg-source -b "$DIR"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
set -e
|
||||
|
||||
CACHE_DIR=$TRAVIS_BUILD_DIR/apt_mingw_cache/$1
|
||||
CACHE_DIR=$HOME/apt_mingw_cache/$1
|
||||
mkdir -p "$CACHE_DIR"
|
||||
|
||||
pushd "$CACHE_DIR"
|
||||
|
||||
@@ -67,7 +67,8 @@ OPTION(WANT_STK "Include Stk (Synthesis Toolkit) support" ON)
|
||||
OPTION(WANT_SWH "Include Steve Harris's LADSPA plugins" ON)
|
||||
OPTION(WANT_TAP "Include Tom's Audio Processing LADSPA plugins" ON)
|
||||
OPTION(WANT_VST "Include VST support" ON)
|
||||
OPTION(WANT_VST_NOWINE "Include partial VST support (without wine)" OFF)
|
||||
OPTION(WANT_VST_32 "Include 32-bit VST support" ON)
|
||||
OPTION(WANT_VST_64 "Include 64-bit VST support" ON)
|
||||
OPTION(WANT_WINMM "Include WinMM MIDI support" OFF)
|
||||
OPTION(WANT_DEBUG_FPE "Debug floating point exceptions" OFF)
|
||||
|
||||
@@ -75,6 +76,7 @@ OPTION(WANT_DEBUG_FPE "Debug floating point exceptions" OFF)
|
||||
IF(LMMS_BUILD_APPLE)
|
||||
# Fix linking on 10.14+. See issue #4762 on github
|
||||
LINK_DIRECTORIES(/usr/local/lib)
|
||||
SET(WANT_SOUNDIO OFF)
|
||||
SET(WANT_ALSA OFF)
|
||||
SET(WANT_PULSEAUDIO OFF)
|
||||
SET(WANT_VST OFF)
|
||||
|
||||
@@ -101,6 +101,7 @@ mv "${APPDIR}usr/bin/lmms" "${APPDIR}usr/bin/lmms.real"
|
||||
cat >"${APPDIR}usr/bin/lmms" <<EOL
|
||||
#!/usr/bin/env bash
|
||||
DIR="\$( cd "\$( dirname "\${BASH_SOURCE[0]}" )" && pwd )"
|
||||
export PATH="$PATH:/sbin"
|
||||
if which carla > /dev/null 2>&1; then
|
||||
CARLAPATH="\$(which carla)"
|
||||
CARLAPREFIX="\${CARLAPATH%/bin*}"
|
||||
@@ -134,15 +135,15 @@ export LD_LIBRARY_PATH="${APPDIR}usr/lib/lmms/":$LD_LIBRARY_PATH
|
||||
|
||||
# Handle wine linking
|
||||
if [ -d "@WINE_32_LIBRARY_DIR@" ]; then
|
||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LD_LIBRARY_PATH/wine/:@WINE_32_LIBRARY_DIR@:@WINE_32_LIBRARY_DIR@wine/
|
||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:@WINE_32_LIBRARY_DIRS@
|
||||
fi
|
||||
if [ -d "@WINE_64_LIBRARY_DIR@" ]; then
|
||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$LD_LIBRARY_PATH/wine/:@WINE_64_LIBRARY_DIR@:@WINE_64_LIBRARY_DIR@wine/
|
||||
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:@WINE_64_LIBRARY_DIRS@
|
||||
fi
|
||||
|
||||
# Move executables so linuxdeployqt can find them
|
||||
ZYNLIB="${APPDIR}usr/lib/lmms/RemoteZynAddSubFx"
|
||||
VSTLIB32="${APPDIR}usr/lib/lmms/RemoteVstPlugin32.exe.so"
|
||||
VSTLIB32="${APPDIR}usr/lib/lmms/32/RemoteVstPlugin32.exe.so"
|
||||
VSTLIB64="${APPDIR}usr/lib/lmms/RemoteVstPlugin64.exe.so"
|
||||
|
||||
ZYNBIN="${APPDIR}usr/bin/RemoteZynAddSubFx"
|
||||
@@ -172,8 +173,10 @@ executables="${executables} -executable=${APPDIR}usr/lib/lmms/ladspa/pitch_scale
|
||||
# Bundle both qt and non-qt dependencies into appimage format
|
||||
echo -e "\nBundling and relinking system dependencies..."
|
||||
echo -e ">>>>> linuxdeployqt" > "$LOGFILE"
|
||||
# FIXME: -unsupported-allow-new-glibc may result in an AppImage which is unusable on old systems.
|
||||
|
||||
# shellcheck disable=SC2086
|
||||
"$LINUXDEPLOYQT" "$DESKTOPFILE" $executables -bundle-non-qt-libs -verbose=$VERBOSITY $STRIP >> "$LOGFILE" 2>&1
|
||||
"$LINUXDEPLOYQT" "$DESKTOPFILE" $executables -unsupported-allow-new-glibc -bundle-non-qt-libs -verbose=$VERBOSITY $STRIP >> "$LOGFILE" 2>&1
|
||||
success "Bundled and relinked dependencies"
|
||||
|
||||
# Link to original location so lmms can find them
|
||||
|
||||
27
cmake/modules/CheckWineGcc.cmake
Normal file
@@ -0,0 +1,27 @@
|
||||
INCLUDE(CheckCXXSourceCompiles)
|
||||
|
||||
FUNCTION(CheckWineGcc BITNESS WINEGCC_EXECUTABLE RESULT)
|
||||
FILE(WRITE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test.cxx" "
|
||||
#include <iostream>
|
||||
#define USE_WS_PREFIX
|
||||
#include <windows.h>
|
||||
int main(int argc, const char* argv[]) {
|
||||
return 0;
|
||||
}
|
||||
")
|
||||
EXECUTE_PROCESS(COMMAND ${WINEGCC_EXECUTABLE} "-m${BITNESS}"
|
||||
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test.cxx"
|
||||
"-o" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test"
|
||||
OUTPUT_QUIET ERROR_QUIET
|
||||
RESULT_VARIABLE WINEGCC_RESULT
|
||||
)
|
||||
FILE(REMOVE "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test.cxx"
|
||||
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test"
|
||||
"${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/winegcc_test.exe.so"
|
||||
)
|
||||
IF(WINEGCC_RESULT EQUAL 0)
|
||||
SET(${RESULT} True PARENT_SCOPE)
|
||||
ELSE()
|
||||
SET(${RESULT} False PARENT_SCOPE)
|
||||
ENDIF()
|
||||
ENDFUNCTION()
|
||||
@@ -7,46 +7,89 @@
|
||||
# WINE_DEFINITIONS - Compiler switches required for using wine
|
||||
#
|
||||
|
||||
MACRO(_findwine_find_flags output expression result)
|
||||
STRING(REPLACE " " ";" WINEBUILD_FLAGS "${output}")
|
||||
FOREACH(FLAG ${WINEBUILD_FLAGS})
|
||||
IF("${FLAG}" MATCHES "${expression}")
|
||||
SET(${result} "${FLAG}")
|
||||
ENDIF()
|
||||
ENDFOREACH()
|
||||
ENDMACRO()
|
||||
|
||||
LIST(APPEND CMAKE_PREFIX_PATH /opt/wine-stable /opt/wine-devel /opt/wine-staging /usr/lib/wine/)
|
||||
|
||||
|
||||
FIND_PATH(WINE_INCLUDE_DIR wine/exception.h PATH_SUFFIXES wine)
|
||||
FIND_PROGRAM(WINE_CXX
|
||||
NAMES wineg++ winegcc winegcc64 winegcc32 winegcc-stable
|
||||
PATHS /usr/lib/wine)
|
||||
PATHS /usr/lib/wine
|
||||
)
|
||||
FIND_PROGRAM(WINE_BUILD NAMES winebuild)
|
||||
# Detect wine paths and handle linking problems
|
||||
IF(WINE_CXX)
|
||||
EXEC_PROGRAM(${WINE_CXX} ARGS "-m32 -v /dev/zero" OUTPUT_VARIABLE WINEBUILD_OUTPUT_32)
|
||||
EXEC_PROGRAM(${WINE_CXX} ARGS "-m64 -v /dev/zero" OUTPUT_VARIABLE WINEBUILD_OUTPUT_64)
|
||||
_findwine_find_flags("${WINEBUILD_OUTPUT_32}" "^-isystem/usr/include$" BUGGED_WINEGCC)
|
||||
_findwine_find_flags("${WINEBUILD_OUTPUT_32}" "^-isystem" WINEGCC_INCLUDE_DIR)
|
||||
_findwine_find_flags("${WINEBUILD_OUTPUT_32}" "libwinecrt0\\.a.*" WINECRT_32)
|
||||
_findwine_find_flags("${WINEBUILD_OUTPUT_64}" "libwinecrt0\\.a.*" WINECRT_64)
|
||||
STRING(REGEX REPLACE "^-isystem" "" WINE_INCLUDE_HINT "${WINEGCC_INCLUDE_DIR}")
|
||||
STRING(REGEX REPLACE "/wine/windows$" "" WINE_INCLUDE_HINT "${WINE_INCLUDE_HINT}")
|
||||
STRING(REGEX REPLACE "libwinecrt0\\.a.*" "" WINE_32_LIBRARY_DIR "${WINECRT_32}")
|
||||
STRING(REGEX REPLACE "libwinecrt0\\.a.*" "" WINE_64_LIBRARY_DIR "${WINECRT_64}")
|
||||
|
||||
IF(BUGGED_WINEGCC)
|
||||
MESSAGE(WARNING "Your winegcc is unusable due to https://bugs.winehq.org/show_bug.cgi?id=46293,\n
|
||||
Consider either upgrading or downgrading wine.")
|
||||
RETURN()
|
||||
ENDIF()
|
||||
IF(WINE_32_LIBRARY_DIR STREQUAL WINE_64_LIBRARY_DIR)
|
||||
MESSAGE(STATUS "Old winegcc detected, trying to use workaround linking")
|
||||
# Fix library search directory according to the target bitness
|
||||
IF(WINE_32_LIBRARY_DIR MATCHES "/lib/(x86_64|i386)-")
|
||||
# Debian systems
|
||||
STRING(REPLACE "/lib/x86_64-" "/lib/i386-" WINE_32_LIBRARY_DIR "${WINE_32_LIBRARY_DIR}")
|
||||
STRING(REPLACE "/lib/i386-" "/lib/x86_64-" WINE_64_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}")
|
||||
ELSEIF(WINE_32_LIBRARY_DIR MATCHES "/(lib|lib64)/wine/$")
|
||||
# WineHQ (/opt/wine-stable, /opt/wine-devel, /opt/wine-staging)
|
||||
STRING(REGEX REPLACE "/lib64/wine/$" "/lib/wine/" WINE_32_LIBRARY_DIR "${WINE_32_LIBRARY_DIR}")
|
||||
STRING(REGEX REPLACE "/lib/wine/$" "/lib64/wine/" WINE_64_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}")
|
||||
ELSEIF(WINE_32_LIBRARY_DIR MATCHES "/lib32/.*/wine/")
|
||||
# Systems with old multilib layout
|
||||
STRING(REPLACE "/lib32/" "/lib/" WINE_64_LIBRARY_DIR "${WINE_32_LIBRARY_DIR}")
|
||||
ELSEIF(WINE_32_LIBRARY_DIR MATCHES "/lib64/.*/wine/")
|
||||
# We need to test if the corresponding 64bit library directory is lib or lib32
|
||||
STRING(REPLACE "/lib64/" "/lib32/" WINE_32_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}")
|
||||
IF(NOT EXISTS "${WINE_32_LIBRARY_DIR}")
|
||||
STRING(REPLACE "/lib64/" "/lib/" WINE_32_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}")
|
||||
ENDIF()
|
||||
ELSEIF(WINE_32_LIBRARY_DIR MATCHES "/lib/.*/wine/")
|
||||
# Test if this directory is for 32bit or 64bit
|
||||
STRING(REPLACE "/lib/" "/lib32/" WINE_32_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}")
|
||||
IF(NOT EXISTS "${WINE_32_LIBRARY_DIR}")
|
||||
SET(WINE_32_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}")
|
||||
STRING(REPLACE "/lib/" "/lib64/" WINE_64_LIBRARY_DIR "${WINE_64_LIBRARY_DIR}")
|
||||
ENDIF()
|
||||
ELSE()
|
||||
MESSAGE(WARNING "Can't detect wine installation layout. You may get some build errors.")
|
||||
ENDIF()
|
||||
SET(WINE_LIBRARY_FIX "${WINE_32_LIBRARY_DIR} and ${WINE_64_LIBRARY_DIR}")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
FIND_PATH(WINE_INCLUDE_DIR wine/exception.h
|
||||
HINTS "${WINE_INCLUDE_HINT}"
|
||||
)
|
||||
|
||||
SET(_ARCHITECTURE ${CMAKE_LIBRARY_ARCHITECTURE})
|
||||
|
||||
FIND_LIBRARY(WINE_LIBRARY NAMES wine PATH_SUFFIXES wine i386-linux-gnu/wine)
|
||||
FIND_LIBRARY(WINE_LIBRARY NAMES wine
|
||||
PATH_SUFFIXES wine i386-linux-gnu/wine
|
||||
HINTS "${WINE_32_LIBRARY_DIR}" "${WINE_64_LIBRARY_DIR}"
|
||||
)
|
||||
|
||||
SET(CMAKE_LIBRARY_ARCHITECTURE ${_ARCHITECTURE})
|
||||
|
||||
SET(WINE_INCLUDE_DIRS ${WINE_INCLUDE_DIR} )
|
||||
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}")
|
||||
|
||||
FOREACH(FLAG ${WINEBUILD_FLAGS})
|
||||
IF("${FLAG}" MATCHES "libwinecrt0.a.*")
|
||||
STRING(REGEX REPLACE "/wine/libwinecrt0.a.*" "" FLAG "${FLAG}")
|
||||
|
||||
SET(WINE_64_LIBRARY_DIR "${FLAG}/")
|
||||
|
||||
# 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(REGEX REPLACE "/lib64$" "/lib" FLAG "${FLAG}")
|
||||
|
||||
SET(WINE_32_LIBRARY_DIR "${FLAG}/")
|
||||
ENDIF()
|
||||
ENDFOREACH()
|
||||
SET(WINE_LIBRARIES ${WINE_LIBRARY})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Wine DEFAULT_MSG WINE_CXX WINE_LIBRARIES WINE_INCLUDE_DIRS)
|
||||
@@ -54,7 +97,23 @@ find_package_handle_standard_args(Wine DEFAULT_MSG WINE_CXX WINE_LIBRARIES WINE_
|
||||
mark_as_advanced(WINE_INCLUDE_DIR WINE_LIBRARY WINE_CXX WINE_BUILD)
|
||||
|
||||
IF(WINE_32_LIBRARY_DIR)
|
||||
SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR}wine/ -L${WINE_32_LIBRARY_DIR}")
|
||||
IF(WINE_32_LIBRARY_DIR MATCHES "wine*/lib")
|
||||
SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR} -L${WINE_32_LIBRARY_DIR}../")
|
||||
SET(WINE_32_LIBRARY_DIRS "${WINE_32_LIBRARY_DIR}:${WINE_32_LIBRARY_DIR}/..")
|
||||
ELSE()
|
||||
SET(WINE_32_FLAGS "-L${WINE_32_LIBRARY_DIR}")
|
||||
SET(WINE_32_LIBRARY_DIRS "${WINE_32_LIBRARY_DIR}")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
IF(WINE_64_LIBRARY_DIR)
|
||||
IF(WINE_64_LIBRARY_DIR MATCHES "wine*/lib")
|
||||
SET(WINE_64_FLAGS "-L${WINE_64_LIBRARY_DIR} -L${WINE_64_LIBRARY_DIR}../")
|
||||
SET(WINE_64_LIBRARY_DIRS "${WINE_64_LIBRARY_DIR}:${WINE_64_LIBRARY_DIR}/..")
|
||||
ELSE()
|
||||
SET(WINE_64_FLAGS "-L${WINE_64_LIBRARY_DIR}")
|
||||
SET(WINE_64_LIBRARY_DIRS "${WINE_64_LIBRARY_DIR}")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
# Create winegcc wrapper
|
||||
|
||||
@@ -22,6 +22,9 @@ while [ $# -gt 0 ]; do
|
||||
-m32)
|
||||
win32=true
|
||||
;;
|
||||
-m64)
|
||||
win64=true
|
||||
;;
|
||||
*)
|
||||
|
||||
;;
|
||||
@@ -42,11 +45,19 @@ fi
|
||||
# by FindWine.cmake
|
||||
extra_args="-I@WINE_INCLUDE_DIR@ -I@WINE_INCLUDE_DIR@/wine/windows"
|
||||
|
||||
# Apply manually specified flags
|
||||
extra_args="$extra_args @WINE_CXX_FLAGS@"
|
||||
|
||||
# Apply -m32 library fix if necessary
|
||||
if [ "$win32" = true ] && [ "$no_link" != true ]; then
|
||||
extra_args="$extra_args @WINE_32_FLAGS@"
|
||||
fi
|
||||
|
||||
# Apply -m64 library fix if necessary
|
||||
if [ "$win64" = true ] && [ "$no_link" != true ]; then
|
||||
extra_args="$extra_args @WINE_64_FLAGS@"
|
||||
fi
|
||||
|
||||
# Run winegcc
|
||||
export WINEBUILD=@WINE_BUILD@
|
||||
@WINE_CXX@ $extra_args $args
|
||||
|
||||
1
debian/calf-ladspa.install
vendored
@@ -1 +0,0 @@
|
||||
usr/lib/*/lmms/ladspa/calf.so usr/lib/ladspa
|
||||
2
debian/changelog
vendored
@@ -1,4 +1,4 @@
|
||||
lmms (1.2.0~rc7.1) unstable; urgency=low
|
||||
lmms (@VERSION@) unstable; urgency=low
|
||||
|
||||
* Upstream integration.
|
||||
* Drop Debian menu entry (policy 9.6).
|
||||
|
||||
31
debian/control
vendored
@@ -17,6 +17,7 @@ Build-Depends:
|
||||
libfluidsynth-dev,
|
||||
libgig-dev,
|
||||
libjack-jackd2-dev,
|
||||
liblist-moreutils-perl,
|
||||
libmp3lame-dev,
|
||||
libpulse-dev,
|
||||
libqt5x11extras5-dev,
|
||||
@@ -29,10 +30,12 @@ Build-Depends:
|
||||
libvorbis-dev,
|
||||
libxcb-keysyms1-dev,
|
||||
libxcb-util0-dev,
|
||||
libxml-perl,
|
||||
libxml2-utils,
|
||||
portaudio19-dev,
|
||||
qtbase5-private-dev,
|
||||
qttools5-dev,
|
||||
wine32-tools [i386]
|
||||
wine64-tools [amd64] | wine32-tools [i386]
|
||||
Standards-Version: 4.2.1.4
|
||||
Homepage: http://lmms.io/
|
||||
Vcs-Browser: https://salsa.debian.org/debian-edu-pkg-team/lmms.git
|
||||
@@ -41,8 +44,9 @@ Package: lmms-bin
|
||||
Architecture: any
|
||||
Depends: lmms-common (>= ${source:Version}), ${shlibs:Depends}, ${misc:Depends},
|
||||
stk
|
||||
Recommends: calf-ladspa, tap-plugins, caps,
|
||||
lmms-vst-server:i386 (>= ${source:Version})
|
||||
Recommends: tap-plugins, caps,
|
||||
lmms-vst-server:i386 (>= ${source:Version}),
|
||||
lmms-vst-server:amd64 (>= ${source:Version})
|
||||
Suggests: fil-plugins, mcp-plugins, omins, freepats, fluid-soundfont-gm,
|
||||
ladspa-plugin
|
||||
Replaces: lmms-common (<< 1.0.0-1)
|
||||
@@ -63,7 +67,7 @@ Description: Linux Multimedia Studio - minimal installation
|
||||
|
||||
Package: lmms
|
||||
Architecture: any
|
||||
Depends: calf-ladspa, lmms-bin, ${misc:Depends}
|
||||
Depends: lmms-bin, ${misc:Depends}
|
||||
Description: Linux Multimedia Studio
|
||||
LMMS aims to be a free alternative to popular (but commercial and closed-
|
||||
source) programs like FruityLoops, Cubase and Logic giving you the ability of
|
||||
@@ -96,23 +100,8 @@ Description: Linux Multimedia Studio - common files
|
||||
and some example projects.
|
||||
|
||||
Package: lmms-vst-server
|
||||
Architecture: i386
|
||||
# Order matters to avoid wine64
|
||||
Depends: wine32, wine, ${shlibs:Depends}, ${misc:Depends}
|
||||
Architecture: amd64 i386
|
||||
Depends: wine64 [amd64] | wine64-development [amd64] | wine32 [i386] | wine32-development [i386], ${shlibs:Depends}, ${misc:Depends}
|
||||
Recommends: lmms-bin:any
|
||||
Description: Linux Multimedia Studio - VST server
|
||||
This package contains a helper application that loads VST plugins.
|
||||
|
||||
Package: calf-ladspa
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Replaces: calf-plugins (<< 0.0.19)
|
||||
Provides: ladspa-plugin
|
||||
Description: Linux Multimedia Studio - Calf LADSPA plugins
|
||||
Calf is a pack of audio plugins - effects and instruments. The goal is to
|
||||
create a set of plugins using decent algorithms and parameter settings,
|
||||
available in a form which is compatible with as many open source applications
|
||||
as possible.
|
||||
.
|
||||
These plugins are distributed as part of Linux Multimedia Studio, but may be
|
||||
used by other applications.
|
||||
|
||||
5
debian/lmms-bin.install
vendored
@@ -1,7 +1,4 @@
|
||||
usr/bin/lmms
|
||||
usr/lib/*/lmms/ladspa/[a-b]*
|
||||
usr/lib/*/lmms/ladspa/caps.so
|
||||
usr/lib/*/lmms/ladspa/c[b-z]*
|
||||
usr/lib/*/lmms/ladspa/[d-z]*
|
||||
usr/lib/*/lmms/ladspa/*
|
||||
usr/lib/*/lmms/lib*
|
||||
usr/lib/*/lmms/RemoteZynAddSubFx
|
||||
|
||||
2
debian/lmms-vst-server.install
vendored
@@ -1 +1 @@
|
||||
usr/lib/*/lmms/RemoteVstPlugin*
|
||||
usr/lib/*/lmms/{32/,}RemoteVstPlugin*
|
||||
|
||||
14
debian/rules
vendored
@@ -6,6 +6,7 @@ DH_CMAKE_BUILD_DIR=obj -${DEB_BUILD_GNU_TYPE}
|
||||
DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)
|
||||
DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
|
||||
DEB_HOST_ARCH_OS ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_OS)
|
||||
DEB_HOST_ARCH_BIT ?= $(shell dpkg-architecture -qDEB_HOST_ARCH_BITS)
|
||||
|
||||
CMAKE_OPTS= -DCONTRIBUTORS=$(CURDIR)/doc/CONTRIBUTORS -DFORCE_VERSION=internal \
|
||||
-DWANT_QT5=1
|
||||
@@ -13,13 +14,18 @@ ifneq ($(DEB_HOST_ARCH_OS),linux)
|
||||
CMAKE_OPTS+= -DWANT_ALSA=0
|
||||
endif
|
||||
|
||||
ifeq ($(DEB_HOST_ARCH),i386)
|
||||
ifeq ($(DEB_HOST_ARCH),amd64)
|
||||
export PATH := $(PATH):/usr/lib/wine
|
||||
WINE_PATH := /usr/lib/$(DEB_HOST_MULTIARCH)/wine
|
||||
CMAKE_OPTS+= -DWINE_CXX_FLAGS=-Wl,--enable-new-dtags,-rpath=$(WINE_PATH)
|
||||
CMAKE_OPTS+= -DWANT_VST_32=OFF -DREMOTE_VST_PLUGIN_FILEPATH_32=../../i386-linux-gnu/lmms/32/RemoteVstPlugin32 \
|
||||
-DWINE_CXX_FLAGS=-Wl,--enable-new-dtags,-rpath=$(WINE_PATH)
|
||||
else ifeq ($(DEB_HOST_ARCH),i386)
|
||||
export PATH := $(PATH):/usr/lib/wine
|
||||
WINE_PATH := /usr/lib/$(DEB_HOST_MULTIARCH)/wine
|
||||
CMAKE_OPTS+= -DWANT_VST_64=OFF -DREMOTE_VST_PLUGIN_FILEPATH_64=../../x86_64-linux-gnu/lmms/RemoteVstPlugin64 \
|
||||
-DWINE_CXX_FLAGS=-Wl,--enable-new-dtags,-rpath=$(WINE_PATH)
|
||||
else
|
||||
CMAKE_OPTS+= -DWANT_VST_NOWINE=1 \
|
||||
-DREMOTE_VST_PLUGIN_FILEPATH=../../i386-linux-gnu/lmms/RemoteVstPlugin
|
||||
CMAKE_OPTS+= -DWANT_VST=OFF
|
||||
endif
|
||||
|
||||
# Define NDEBUG. This helps with reproducible builds.
|
||||
|
||||
@@ -47,6 +47,7 @@ protected:
|
||||
DropToolBar * addDropToolBar(Qt::ToolBarArea whereToAdd, QString const & windowTitle);
|
||||
DropToolBar * addDropToolBar(QWidget * parent, Qt::ToolBarArea whereToAdd, QString const & windowTitle);
|
||||
|
||||
virtual void closeEvent( QCloseEvent * _ce );
|
||||
protected slots:
|
||||
virtual void play() {}
|
||||
virtual void record() {}
|
||||
|
||||
@@ -148,11 +148,6 @@ public:
|
||||
m_noRun = _state;
|
||||
}
|
||||
|
||||
inline const Descriptor::SubPluginFeatures::Key & key() const
|
||||
{
|
||||
return m_key;
|
||||
}
|
||||
|
||||
EffectChain * effectChain() const
|
||||
{
|
||||
return m_parent;
|
||||
@@ -201,8 +196,6 @@ private:
|
||||
sampleFrame * _dst_buf, sample_rate_t _dst_sr,
|
||||
const f_cnt_t _frames );
|
||||
|
||||
Descriptor::SubPluginFeatures::Key m_key;
|
||||
|
||||
ch_cnt_t m_processors;
|
||||
|
||||
bool m_okay;
|
||||
|
||||
@@ -111,6 +111,9 @@ public:
|
||||
return s_instanceOfMe;
|
||||
}
|
||||
|
||||
static void setDndPluginKey(void* newKey);
|
||||
static void* pickDndPluginKey();
|
||||
|
||||
signals:
|
||||
void initProgress(const QString &msg);
|
||||
|
||||
@@ -137,6 +140,7 @@ private:
|
||||
static DummyTrackContainer * s_dummyTC;
|
||||
|
||||
static Ladspa2LMMS * s_ladspaManager;
|
||||
static void* s_dndPluginKey;
|
||||
|
||||
// even though most methods are static, an instance is needed for Qt slots/signals
|
||||
static LmmsCore * s_instanceOfMe;
|
||||
|
||||
53
include/FxLineLcdSpinBox.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* FxLineLcdSpinBox.h - a specialization of LcdSpnBox for setting FX channels
|
||||
*
|
||||
* Copyright (c) 2004-2014 Tobias Doerffel <tobydox/at/users.sourceforge.net>
|
||||
*
|
||||
* This file is part of LMMS - https://lmms.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public
|
||||
* License along with this program (see COPYING); if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FX_LINE_LCD_SPIN_BOX_H
|
||||
#define FX_LINE_LCD_SPIN_BOX_H
|
||||
|
||||
#include "LcdSpinBox.h"
|
||||
|
||||
class TrackView;
|
||||
|
||||
|
||||
class FxLineLcdSpinBox : public LcdSpinBox
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FxLineLcdSpinBox(int numDigits, QWidget * parent, const QString& name, TrackView * tv = NULL) :
|
||||
LcdSpinBox(numDigits, parent, name), m_tv(tv)
|
||||
{}
|
||||
virtual ~FxLineLcdSpinBox() {}
|
||||
|
||||
void setTrackView(TrackView * tv);
|
||||
|
||||
protected:
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent* event);
|
||||
virtual void contextMenuEvent(QContextMenuEvent* event);
|
||||
|
||||
private:
|
||||
TrackView * m_tv;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -55,14 +55,17 @@ public:
|
||||
|
||||
Q_DECLARE_FLAGS(Flags, Flag);
|
||||
|
||||
Instrument( InstrumentTrack * _instrument_track,
|
||||
const Descriptor * _descriptor );
|
||||
Instrument(InstrumentTrack * _instrument_track,
|
||||
const Descriptor * _descriptor,
|
||||
const Descriptor::SubPluginFeatures::Key * key = nullptr);
|
||||
virtual ~Instrument() = default;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// functions that can/should be re-implemented:
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
virtual bool hasNoteInput() const { return true; }
|
||||
|
||||
// if the plugin doesn't play each note, it can create an instrument-
|
||||
// play-handle and re-implement this method, so that it mixes its
|
||||
// output buffer only once per mixer-period
|
||||
@@ -113,10 +116,12 @@ public:
|
||||
// provided functions:
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
// instantiate instrument-plugin with given name or return NULL
|
||||
// on failure
|
||||
static Instrument * instantiate( const QString & _plugin_name,
|
||||
InstrumentTrack * _instrument_track );
|
||||
//! instantiate instrument-plugin with given name or return NULL
|
||||
//! on failure
|
||||
static Instrument * instantiate(const QString & _plugin_name,
|
||||
InstrumentTrack * _instrument_track,
|
||||
const Plugin::Descriptor::SubPluginFeatures::Key* key,
|
||||
bool keyFromDnd = false);
|
||||
|
||||
virtual bool isFromTrack( const Track * _track ) const;
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "Piano.h"
|
||||
#include "PianoView.h"
|
||||
#include "Pitch.h"
|
||||
#include "Plugin.h"
|
||||
#include "Track.h"
|
||||
|
||||
|
||||
@@ -52,6 +53,7 @@ class InstrumentTrackWindow;
|
||||
class InstrumentMidiIOView;
|
||||
class InstrumentMiscView;
|
||||
class Knob;
|
||||
class FxLineLcdSpinBox;
|
||||
class LcdSpinBox;
|
||||
class LeftRightNav;
|
||||
class midiPortMenu;
|
||||
@@ -146,7 +148,9 @@ public:
|
||||
|
||||
|
||||
// load instrument whose name matches given one
|
||||
Instrument * loadInstrument( const QString & _instrument_name );
|
||||
Instrument * loadInstrument(const QString & _instrument_name,
|
||||
const Plugin::Descriptor::SubPluginFeatures::Key* key = nullptr,
|
||||
bool keyFromDnd = false);
|
||||
|
||||
AudioPort * audioPort()
|
||||
{
|
||||
@@ -440,7 +444,7 @@ private:
|
||||
QLabel * m_pitchLabel;
|
||||
LcdSpinBox* m_pitchRangeSpinBox;
|
||||
QLabel * m_pitchRangeLabel;
|
||||
LcdSpinBox * m_effectChannelNumber;
|
||||
FxLineLcdSpinBox * m_effectChannelNumber;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ class LMMS_EXPORT Knob : public QWidget, public FloatModelView
|
||||
public:
|
||||
Knob( knobTypes _knob_num, QWidget * _parent = NULL, const QString & _name = QString() );
|
||||
Knob( QWidget * _parent = NULL, const QString & _name = QString() ); //!< default ctor
|
||||
Knob( const Knob& other ) = delete;
|
||||
virtual ~Knob();
|
||||
|
||||
// TODO: remove
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "LadspaManager.h"
|
||||
|
||||
|
||||
//! Class responsible for sorting found plugins (by LadspaManager)
|
||||
//! into categories
|
||||
class LMMS_EXPORT Ladspa2LMMS : public LadspaManager
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -41,10 +41,6 @@ public:
|
||||
m_displayName( _display_name ),
|
||||
m_defaultConstructed( _default_constructed )
|
||||
{
|
||||
#if QT_VERSION < 0x050000
|
||||
connect( this, SIGNAL( dataChanged() ), this,
|
||||
SLOT( thisDataChanged() ), Qt::DirectConnection );
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual ~Model()
|
||||
@@ -89,19 +85,6 @@ signals:
|
||||
// emitted if properties of the model (e.g. ranges) have changed
|
||||
void propertiesChanged();
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
// emitted along with dataChanged(), but with this model as an argument
|
||||
// workaround for when QObject::sender() and Qt5 are unavailable
|
||||
void dataChanged( Model * );
|
||||
|
||||
private slots:
|
||||
void thisDataChanged()
|
||||
{
|
||||
emit dataChanged( this );
|
||||
}
|
||||
|
||||
signals:
|
||||
#endif
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
167
include/Plugin.h
@@ -40,7 +40,27 @@ class PixmapLoader;
|
||||
class PluginView;
|
||||
class AutomatableModel;
|
||||
|
||||
/**
|
||||
Abstract representation of a plugin
|
||||
|
||||
Such a plugin can be an Instrument, Effect, Tool plugin etc.
|
||||
|
||||
Plugins have descriptors, containing meta info, which is used especially
|
||||
by PluginFactory and friends.
|
||||
|
||||
There are also Plugin keys (class Key, confusingly under
|
||||
SubPluginFeatures), which contain pointers to the plugin descriptor.
|
||||
|
||||
Some plugins have sub plugins, e.g. there is one CALF Plugin and for
|
||||
each CALF effect, there is a CALF sub plugin. For those plugins, there
|
||||
are keys for each sub plugin. These keys also link to the superior
|
||||
Plugin::Descriptor. Additionally, they contain attributes that help the
|
||||
superior Plugin saving them and recognizing them when loading.
|
||||
|
||||
In case of sub plugins, the Descriptor has SubPluginFeatures. Those
|
||||
are a bit like values to the sub plugins' keys (in terms of a key-value-
|
||||
map).
|
||||
*/
|
||||
class LMMS_EXPORT Plugin : public Model, public JournallingObject
|
||||
{
|
||||
MM_OPERATORS
|
||||
@@ -59,9 +79,9 @@ public:
|
||||
Undefined = 255
|
||||
} ;
|
||||
|
||||
// descriptor holds information about a plugin - every external plugin
|
||||
// has to instantiate such a descriptor in an extern "C"-section so that
|
||||
// the plugin-loader is able to access information about the plugin
|
||||
//! Descriptor holds information about a plugin - every external plugin
|
||||
//! has to instantiate such a Descriptor in an extern "C"-section so that
|
||||
//! the plugin-loader is able to access information about the plugin
|
||||
struct Descriptor
|
||||
{
|
||||
const char * name;
|
||||
@@ -71,23 +91,49 @@ public:
|
||||
int version;
|
||||
PluginTypes type;
|
||||
const PixmapLoader * logo;
|
||||
const char * supportedFileTypes;
|
||||
const char * supportedFileTypes; //!< csv list of extensions
|
||||
|
||||
inline bool supportsFileType( const QString& extension ) const
|
||||
{
|
||||
return QString( supportedFileTypes ).split( QChar( ',' ) ).contains( extension );
|
||||
}
|
||||
|
||||
/**
|
||||
Access to non-key-data of a sub plugin
|
||||
|
||||
If you consider sub plugin keys as keys in a
|
||||
key-value-map, this is the lookup for the corresponding
|
||||
values. In order to have flexibility between different
|
||||
plugin APIs, this is rather an array of fixed data,
|
||||
but a bunch of virtual functions taking the key and
|
||||
returning some values (or modifying objects of other
|
||||
classes).
|
||||
*/
|
||||
class LMMS_EXPORT SubPluginFeatures
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Key reference a Plugin::Descriptor, and,
|
||||
if the plugin has sub plugins, also reference
|
||||
its sub plugin (using the attributes).
|
||||
When keys are saved, those attributes are
|
||||
written to XML in order to find the right sub
|
||||
plugin when realoading.
|
||||
|
||||
@note Any data that is not required to reference
|
||||
the right Plugin or sub plugin should
|
||||
not be here (but rather in
|
||||
SubPluginFeatures, which are like values
|
||||
in a key-value map).
|
||||
*/
|
||||
struct Key
|
||||
{
|
||||
typedef QMap<QString, QString> AttributeMap;
|
||||
|
||||
inline Key( const Plugin::Descriptor * desc = NULL,
|
||||
const QString & name = QString(),
|
||||
const AttributeMap & am = AttributeMap() )
|
||||
const QString & name = QString(),
|
||||
const AttributeMap & am = AttributeMap()
|
||||
)
|
||||
:
|
||||
desc( desc ),
|
||||
name( name ),
|
||||
@@ -101,12 +147,28 @@ public:
|
||||
|
||||
inline bool isValid() const
|
||||
{
|
||||
return desc != NULL && name.isNull() == false;
|
||||
return desc != nullptr;
|
||||
}
|
||||
|
||||
//! Key to subplugin: reference to parent descriptor
|
||||
//! Key to plugin: reference to its descriptor
|
||||
const Plugin::Descriptor* desc;
|
||||
//! Descriptive name like "Calf Phaser".
|
||||
//! Not required for key lookup and not saved
|
||||
//! only used sometimes to temporary store descriptive names
|
||||
//! @todo This is a bug, there should be a function
|
||||
//! in SubPluginFeatures (to get the name) instead
|
||||
QString name;
|
||||
//! Attributes that make up the key and identify
|
||||
//! the sub plugin. They are being loaded and saved
|
||||
AttributeMap attributes;
|
||||
|
||||
// helper functions to retrieve data that is
|
||||
// not part of the key, but mapped via desc->subPluginFeatures
|
||||
QString additionalFileExtensions() const;
|
||||
QString displayName() const;
|
||||
QString description() const;
|
||||
const PixmapLoader* logo() const;
|
||||
} ;
|
||||
|
||||
typedef QList<Key> KeyList;
|
||||
@@ -125,11 +187,40 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
//! While PluginFactory only collects the plugins,
|
||||
//! this function is used by widgets like EffectSelectDialog
|
||||
//! to find all possible sub plugins
|
||||
virtual void listSubPluginKeys( const Plugin::Descriptor *, KeyList & ) const
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
// You can add values mapped by "Key" below
|
||||
// The defaults are sane, i.e. redirect to sub plugin's
|
||||
// supererior descriptor
|
||||
|
||||
virtual QString additionalFileExtensions(const Key&) const
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
virtual QString displayName(const Key& k) const
|
||||
{
|
||||
return k.isValid() ? k.name : QString();
|
||||
}
|
||||
|
||||
virtual QString description(const Key& k) const
|
||||
{
|
||||
return k.isValid() ? k.desc->description : QString();
|
||||
}
|
||||
|
||||
virtual const PixmapLoader* logo(const Key& k) const
|
||||
{
|
||||
Q_ASSERT(k.desc);
|
||||
return k.desc->logo;
|
||||
}
|
||||
|
||||
protected:
|
||||
const Plugin::PluginTypes m_type;
|
||||
} ;
|
||||
@@ -140,48 +231,66 @@ public:
|
||||
// typedef a list so we can easily work with list of plugin descriptors
|
||||
typedef QList<Descriptor*> DescriptorList;
|
||||
|
||||
// contructor of a plugin
|
||||
Plugin( const Descriptor * descriptor, Model * parent );
|
||||
//! Constructor of a plugin
|
||||
//! @param key Sub plugins must pass a key here, optional otherwise.
|
||||
//! See the key() function
|
||||
Plugin(const Descriptor * descriptor, Model * parent,
|
||||
const Descriptor::SubPluginFeatures::Key *key = nullptr);
|
||||
virtual ~Plugin();
|
||||
|
||||
// returns display-name out of descriptor
|
||||
virtual QString displayName() const
|
||||
{
|
||||
return Model::displayName().isEmpty()
|
||||
? m_descriptor->displayName
|
||||
: Model::displayName();
|
||||
}
|
||||
//! Return display-name out of sub plugin or descriptor
|
||||
virtual QString displayName() const;
|
||||
|
||||
// return plugin-type
|
||||
//! Return logo out of sub plugin or descriptor
|
||||
const PixmapLoader *logo() const;
|
||||
|
||||
//! Return plugin type
|
||||
inline PluginTypes type( void ) const
|
||||
{
|
||||
return m_descriptor->type;
|
||||
}
|
||||
|
||||
// return plugin-descriptor for further information
|
||||
//! Return plugin Descriptor
|
||||
inline const Descriptor * descriptor() const
|
||||
{
|
||||
return m_descriptor;
|
||||
}
|
||||
|
||||
// can be called if a file matching supportedFileTypes should be
|
||||
// loaded/processed with the help of this plugin
|
||||
//! Return the key referencing this plugin. If the Plugin has no
|
||||
//! sub plugin features, the key is pretty useless. If it has,
|
||||
//! this key will also contain the sub plugin attributes, and will be
|
||||
//! a key to those SubPluginFeatures.
|
||||
inline const Descriptor::SubPluginFeatures::Key & key() const
|
||||
{
|
||||
return m_key;
|
||||
}
|
||||
|
||||
//! Can be called if a file matching supportedFileTypes should be
|
||||
//! loaded/processed with the help of this plugin
|
||||
virtual void loadFile( const QString & file );
|
||||
|
||||
// Called if external source needs to change something but we cannot
|
||||
// reference the class header. Should return null if not key not found.
|
||||
//! Called if external source needs to change something but we cannot
|
||||
//! reference the class header. Should return null if not key not found.
|
||||
virtual AutomatableModel* childModel( const QString & modelName );
|
||||
|
||||
// returns an instance of a plugin whose name matches to given one
|
||||
// if specified plugin couldn't be loaded, it creates a dummy-plugin
|
||||
static Plugin * instantiate( const QString& pluginName, Model * parent, void * data );
|
||||
//! Overload if the argument passed to the plugin is a subPluginKey
|
||||
//! If you can not pass the key and are aware that it's stored in
|
||||
//! Engine::pickDndPluginKey(), use this function, too
|
||||
static Plugin * instantiateWithKey(const QString& pluginName, Model * parent,
|
||||
const Descriptor::SubPluginFeatures::Key *key,
|
||||
bool keyFromDnd = false);
|
||||
|
||||
// create a view for the model
|
||||
//! Return an instance of a plugin whose name matches to given one
|
||||
//! if specified plugin couldn't be loaded, it creates a dummy-plugin
|
||||
//! @param data Anything the plugin expects. If this is a pointer to a sub plugin key,
|
||||
//! use instantiateWithKey instead
|
||||
static Plugin * instantiate(const QString& pluginName, Model * parent, void *data);
|
||||
|
||||
//! Create a view for the model
|
||||
PluginView * createView( QWidget * parent );
|
||||
|
||||
|
||||
protected:
|
||||
// create a view for the model
|
||||
//! Create a view for the model
|
||||
virtual PluginView* instantiateView( QWidget * ) = 0;
|
||||
void collectErrorForUI( QString errMsg );
|
||||
|
||||
@@ -189,6 +298,8 @@ protected:
|
||||
private:
|
||||
const Descriptor * m_descriptor;
|
||||
|
||||
Descriptor::SubPluginFeatures::Key m_key;
|
||||
|
||||
// pointer to instantiation-function in plugin
|
||||
typedef Plugin * ( * InstantiationHook )( Model * , void * );
|
||||
|
||||
|
||||
@@ -31,6 +31,10 @@
|
||||
#include "SideBarWidget.h"
|
||||
#include "Plugin.h"
|
||||
|
||||
class QLineEdit;
|
||||
class QTreeWidget;
|
||||
class QTreeWidgetItem;
|
||||
|
||||
|
||||
class PluginBrowser : public SideBarWidget
|
||||
{
|
||||
@@ -39,18 +43,18 @@ public:
|
||||
PluginBrowser( QWidget * _parent );
|
||||
virtual ~PluginBrowser() = default;
|
||||
|
||||
private slots:
|
||||
void onFilterChanged( const QString & filter );
|
||||
|
||||
private:
|
||||
void addPlugins();
|
||||
void updateRootVisibility( int index );
|
||||
void updateRootVisibilities();
|
||||
|
||||
QWidget * m_view;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class PluginDescList : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PluginDescList(QWidget* parent);
|
||||
QTreeWidget * m_descTree;
|
||||
QTreeWidgetItem * m_lmmsRoot;
|
||||
QTreeWidgetItem * m_lv2Root;
|
||||
};
|
||||
|
||||
|
||||
@@ -60,7 +64,9 @@ class PluginDescWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PluginDescWidget( const Plugin::Descriptor & _pd, QWidget * _parent );
|
||||
typedef Plugin::Descriptor::SubPluginFeatures::Key PluginKey;
|
||||
PluginDescWidget( const PluginKey & _pk, QWidget * _parent );
|
||||
QString name() const;
|
||||
|
||||
|
||||
protected:
|
||||
@@ -72,7 +78,7 @@ protected:
|
||||
private:
|
||||
constexpr static int DEFAULT_HEIGHT{24};
|
||||
|
||||
const Plugin::Descriptor & m_pluginDescriptor;
|
||||
PluginKey m_pluginKey;
|
||||
QPixmap m_logo;
|
||||
|
||||
bool m_mouseOver;
|
||||
|
||||
@@ -26,10 +26,13 @@
|
||||
#define PLUGINFACTORY_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QHash>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QVector>
|
||||
|
||||
#include "lmms_export.h"
|
||||
#include "Plugin.h"
|
||||
@@ -41,12 +44,10 @@ class LMMS_EXPORT PluginFactory
|
||||
public:
|
||||
struct PluginInfo
|
||||
{
|
||||
PluginInfo() : library(nullptr), descriptor(nullptr) {}
|
||||
|
||||
const QString name() const;
|
||||
QFileInfo file;
|
||||
std::shared_ptr<QLibrary> library;
|
||||
Plugin::Descriptor* descriptor;
|
||||
std::shared_ptr<QLibrary> library = nullptr;
|
||||
Plugin::Descriptor* descriptor = nullptr;
|
||||
|
||||
bool isNull() const {return ! library;}
|
||||
};
|
||||
@@ -56,6 +57,8 @@ public:
|
||||
PluginFactory();
|
||||
~PluginFactory();
|
||||
|
||||
static void setupSearchPaths();
|
||||
|
||||
/// Returns the singleton instance of PluginFactory. You won't need to call
|
||||
/// this directly, use pluginFactory instead.
|
||||
static PluginFactory* instance();
|
||||
@@ -64,10 +67,17 @@ public:
|
||||
const Plugin::DescriptorList descriptors() const;
|
||||
const Plugin::DescriptorList descriptors(Plugin::PluginTypes type) const;
|
||||
|
||||
struct PluginInfoAndKey
|
||||
{
|
||||
PluginInfo info;
|
||||
Plugin::Descriptor::SubPluginFeatures::Key key;
|
||||
bool isNull() const { return info.isNull(); }
|
||||
};
|
||||
|
||||
/// Returns a list of all found plugins' PluginFactory::PluginInfo objects.
|
||||
const PluginInfoList& pluginInfos() const;
|
||||
/// Returns a plugin that support the given file extension
|
||||
const PluginInfo pluginSupportingExtension(const QString& ext);
|
||||
const PluginInfoAndKey pluginSupportingExtension(const QString& ext);
|
||||
|
||||
/// Returns the PluginInfo object of the plugin with the given name.
|
||||
/// If the plugin is not found, an empty PluginInfo is returned (use
|
||||
@@ -84,7 +94,9 @@ public slots:
|
||||
private:
|
||||
DescriptorMap m_descriptors;
|
||||
PluginInfoList m_pluginInfos;
|
||||
QMap<QString, PluginInfo> m_pluginByExt;
|
||||
|
||||
QMap<QString, PluginInfoAndKey> m_pluginByExt;
|
||||
QVector<std::string> m_garbage; //!< cleaned up at destruction
|
||||
|
||||
QHash<QString, QString> m_errors;
|
||||
|
||||
|
||||
@@ -26,13 +26,19 @@
|
||||
#define SAMPLE_TRACK_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QLayout>
|
||||
|
||||
#include "AudioPort.h"
|
||||
#include "FxMixer.h"
|
||||
#include "FxLineLcdSpinBox.h"
|
||||
#include "Track.h"
|
||||
|
||||
class EffectRackView;
|
||||
class Knob;
|
||||
class SampleBuffer;
|
||||
class SampleTrackWindow;
|
||||
class TrackLabelButton;
|
||||
class QLineEdit;
|
||||
|
||||
|
||||
class SampleTCO : public TrackContentObject
|
||||
@@ -140,6 +146,11 @@ public:
|
||||
QDomElement & _parent );
|
||||
virtual void loadTrackSpecificSettings( const QDomElement & _this );
|
||||
|
||||
inline IntModel * effectChannelModel()
|
||||
{
|
||||
return &m_effectChannelModel;
|
||||
}
|
||||
|
||||
inline AudioPort * audioPort()
|
||||
{
|
||||
return &m_audioPort;
|
||||
@@ -153,15 +164,18 @@ public:
|
||||
public slots:
|
||||
void updateTcos();
|
||||
void setPlayingTcos( bool isPlaying );
|
||||
void updateEffectChannel();
|
||||
|
||||
private:
|
||||
FloatModel m_volumeModel;
|
||||
FloatModel m_panningModel;
|
||||
IntModel m_effectChannelModel;
|
||||
AudioPort m_audioPort;
|
||||
|
||||
|
||||
|
||||
friend class SampleTrackView;
|
||||
friend class SampleTrackWindow;
|
||||
|
||||
} ;
|
||||
|
||||
@@ -174,6 +188,24 @@ public:
|
||||
SampleTrackView( SampleTrack* Track, TrackContainerView* tcv );
|
||||
virtual ~SampleTrackView();
|
||||
|
||||
SampleTrackWindow * getSampleTrackWindow()
|
||||
{
|
||||
return m_window;
|
||||
}
|
||||
|
||||
SampleTrack * model()
|
||||
{
|
||||
return castModel<SampleTrack>();
|
||||
}
|
||||
|
||||
const SampleTrack * model() const
|
||||
{
|
||||
return castModel<SampleTrack>();
|
||||
}
|
||||
|
||||
|
||||
virtual QMenu * createFxMenu( QString title, QString newFxLabel );
|
||||
|
||||
|
||||
public slots:
|
||||
void showEffects();
|
||||
@@ -187,12 +219,77 @@ protected:
|
||||
}
|
||||
|
||||
|
||||
private slots:
|
||||
void assignFxLine( int channelIndex );
|
||||
void createFxLine();
|
||||
|
||||
|
||||
private:
|
||||
EffectRackView * m_effectRack;
|
||||
QWidget * m_effWindow;
|
||||
SampleTrackWindow * m_window;
|
||||
Knob * m_volumeKnob;
|
||||
Knob * m_panningKnob;
|
||||
|
||||
TrackLabelButton * m_tlb;
|
||||
|
||||
|
||||
friend class SampleTrackWindow;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
class SampleTrackWindow : public QWidget, public ModelView, public SerializingObjectHook
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SampleTrackWindow(SampleTrackView * tv);
|
||||
virtual ~SampleTrackWindow();
|
||||
|
||||
SampleTrack * model()
|
||||
{
|
||||
return castModel<SampleTrack>();
|
||||
}
|
||||
|
||||
const SampleTrack * model() const
|
||||
{
|
||||
return castModel<SampleTrack>();
|
||||
}
|
||||
|
||||
void setSampleTrackView(SampleTrackView * tv);
|
||||
|
||||
SampleTrackView *sampleTrackView()
|
||||
{
|
||||
return m_stv;
|
||||
}
|
||||
|
||||
|
||||
public slots:
|
||||
void textChanged(const QString & new_name);
|
||||
void toggleVisibility(bool on);
|
||||
void updateName();
|
||||
|
||||
|
||||
protected:
|
||||
// capture close-events for toggling sample-track-button
|
||||
virtual void closeEvent(QCloseEvent * ce);
|
||||
|
||||
virtual void saveSettings(QDomDocument & doc, QDomElement & element);
|
||||
virtual void loadSettings(const QDomElement & element);
|
||||
|
||||
private:
|
||||
virtual void modelChanged();
|
||||
|
||||
SampleTrack * m_track;
|
||||
SampleTrackView * m_stv;
|
||||
|
||||
// widgets on the top of an sample-track-window
|
||||
QLineEdit * m_nameLineEdit;
|
||||
Knob * m_volumeKnob;
|
||||
Knob * m_panningKnob;
|
||||
FxLineLcdSpinBox * m_effectChannelNumber;
|
||||
|
||||
EffectRackView * m_effectRack;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -122,6 +122,9 @@ private slots:
|
||||
void toggleDisplayWaveform( bool en );
|
||||
void toggleDisableAutoquit( bool en );
|
||||
|
||||
void vstEmbedMethodChanged();
|
||||
void toggleVSTAlwaysOnTop( bool en );
|
||||
|
||||
void setLanguage( int lang );
|
||||
|
||||
|
||||
@@ -203,6 +206,8 @@ private:
|
||||
|
||||
QComboBox* m_vstEmbedComboBox;
|
||||
QString m_vstEmbedMethod;
|
||||
LedCheckBox * m_vstAlwaysOnTopCheckBox;
|
||||
bool m_vstAlwaysOnTop;
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
@@ -352,7 +352,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool canPasteSelection( MidiTime tcoPos, const QMimeData * mimeData );
|
||||
bool canPasteSelection( MidiTime tcoPos, const QDropEvent *de );
|
||||
bool pasteSelection( MidiTime tcoPos, QDropEvent * de );
|
||||
|
||||
MidiTime endPosition( const MidiTime & posStart );
|
||||
@@ -675,6 +675,10 @@ public:
|
||||
|
||||
virtual void update();
|
||||
|
||||
// Create a menu for assigning/creating channels for this track
|
||||
// Currently instrument track and sample track supports it
|
||||
virtual QMenu * createFxMenu(QString title, QString newFxLabel);
|
||||
|
||||
|
||||
public slots:
|
||||
virtual bool close();
|
||||
|
||||
@@ -41,10 +41,10 @@
|
||||
|
||||
struct VstSyncData
|
||||
{
|
||||
bool isPlaying;
|
||||
double ppqPos;
|
||||
int timeSigNumer;
|
||||
int timeSigDenom;
|
||||
bool isPlaying;
|
||||
bool isCycle;
|
||||
bool hasSHM;
|
||||
float cycleStart;
|
||||
|
||||
@@ -45,11 +45,11 @@ EqAnalyser::EqAnalyser() :
|
||||
const float a2 = 0.14128;
|
||||
const float a3 = 0.01168;
|
||||
|
||||
for(int i = 0; i < FFT_BUFFER_SIZE; i++)
|
||||
for (int i = 0; i < FFT_BUFFER_SIZE; i++)
|
||||
{
|
||||
m_fftWindow[i] = ( a0 - a1 * cosf( 2 * F_PI * i / (float)FFT_BUFFER_SIZE - 1 )
|
||||
+ a2 * cosf( 4 * F_PI * i / (float)FFT_BUFFER_SIZE-1)
|
||||
- a3 * cos( 6 * F_PI * i / (float)FFT_BUFFER_SIZE - 1.0 ));
|
||||
m_fftWindow[i] = (a0 - a1 * cos(2 * F_PI * i / ((float)FFT_BUFFER_SIZE - 1.0))
|
||||
+ a2 * cos(4 * F_PI * i / ((float)FFT_BUFFER_SIZE - 1.0))
|
||||
- a3 * cos(6 * F_PI * i / ((float)FFT_BUFFER_SIZE - 1.0)));
|
||||
}
|
||||
clear();
|
||||
}
|
||||
|
||||
@@ -728,10 +728,10 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return( new FreeBoyInstrument(
|
||||
static_cast<InstrumentTrack *>( _data ) ) );
|
||||
static_cast<InstrumentTrack *>( m ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1390,9 +1390,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return new GigInstrument( static_cast<InstrumentTrack *>( _data ) );
|
||||
return new GigInstrument( static_cast<InstrumentTrack *>( m ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -153,6 +153,9 @@ void LadspaControls::linkPort( int _port, bool _state )
|
||||
{
|
||||
first->unlinkControls( m_controls[proc][_port] );
|
||||
}
|
||||
|
||||
// m_stereoLinkModel.setValue() will call updateLinkStatesFromGlobal()
|
||||
// m_noLink will make sure that this will not unlink any other ports
|
||||
m_noLink = true;
|
||||
m_stereoLinkModel.setValue( false );
|
||||
}
|
||||
|
||||
@@ -44,6 +44,16 @@ LadspaSubPluginFeatures::LadspaSubPluginFeatures( Plugin::PluginTypes _type ) :
|
||||
|
||||
|
||||
|
||||
QString LadspaSubPluginFeatures::displayName(const Plugin::Descriptor::SubPluginFeatures::Key &k) const
|
||||
{
|
||||
const ladspa_key_t & lkey = subPluginKeyToLadspaKey(&k);
|
||||
Ladspa2LMMS * lm = Engine::getLADSPAManager();
|
||||
return lm->getName(lkey);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void LadspaSubPluginFeatures::fillDescriptionWidget( QWidget * _parent,
|
||||
const Key * _key ) const
|
||||
{
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LADSPA_SUBPLUGIN_FEATURES_H
|
||||
#define _LADSPA_SUBPLUGIN_FEATURES_H
|
||||
#ifndef LADSPA_SUBPLUGIN_FEATURES_H
|
||||
#define LADSPA_SUBPLUGIN_FEATURES_H
|
||||
|
||||
#include "LadspaManager.h"
|
||||
#include "Plugin.h"
|
||||
@@ -37,11 +37,13 @@ class LadspaSubPluginFeatures : public Plugin::Descriptor::SubPluginFeatures
|
||||
public:
|
||||
LadspaSubPluginFeatures( Plugin::PluginTypes _type );
|
||||
|
||||
virtual void fillDescriptionWidget( QWidget * _parent,
|
||||
const Key * _key ) const;
|
||||
QString displayName(const Key& k) const override;
|
||||
void fillDescriptionWidget( QWidget * _parent,
|
||||
const Key * _key ) const override;
|
||||
|
||||
virtual void listSubPluginKeys( const Plugin::Descriptor * _desc,
|
||||
KeyList & _kl ) const;
|
||||
KeyList & _kl ) const override;
|
||||
|
||||
|
||||
static ladspa_key_t subPluginKeyToLadspaKey( const Key * _key );
|
||||
|
||||
|
||||
@@ -79,9 +79,9 @@ Plugin::Descriptor PLUGIN_EXPORT opulenz_plugin_descriptor =
|
||||
};
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return( new OpulenzInstrument( static_cast<InstrumentTrack *>( _data ) ) );
|
||||
return( new OpulenzInstrument( static_cast<InstrumentTrack *>( m ) ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -90,13 +90,8 @@ void VstEffectControls::loadSettings( const QDomElement & _this )
|
||||
knobFModel[ i ]->setInitValue(LocaleHelper::toFloat(s_dumpValues.at(2)));
|
||||
}
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
connect( knobFModel[i], SIGNAL( dataChanged( Model * ) ),
|
||||
this, SLOT( setParameter( Model * ) ), Qt::DirectConnection );
|
||||
#else
|
||||
connect( knobFModel[i], &FloatModel::dataChanged, this,
|
||||
[this, i]() { setParameter( knobFModel[i] ); }, Qt::DirectConnection);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
@@ -383,13 +378,8 @@ manageVSTEffectView::manageVSTEffectView( VstEffect * _eff, VstEffectControls *
|
||||
}
|
||||
|
||||
FloatModel * model = m_vi->knobFModel[i];
|
||||
#if QT_VERSION < 0x050000
|
||||
connect( model, SIGNAL( dataChanged( Model * ) ), this,
|
||||
SLOT( setParameter( Model * ) ), Qt::DirectConnection );
|
||||
#else
|
||||
connect( model, &FloatModel::dataChanged, this,
|
||||
[this, model]() { setParameter( model ); }, Qt::DirectConnection);
|
||||
#endif
|
||||
vstKnobs[ i ] ->setModel( model );
|
||||
}
|
||||
|
||||
|
||||
@@ -877,8 +877,8 @@ void XpressiveView::helpClicked() {
|
||||
extern "C" {
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main(Model *, void * _data) {
|
||||
return (new Xpressive(static_cast<InstrumentTrack *>(_data)));
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main(Model *m, void *) {
|
||||
return (new Xpressive(static_cast<InstrumentTrack *>(m)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -505,7 +505,7 @@ AudioFileProcessorView::AudioFileProcessorView( Instrument * _instrument,
|
||||
"loop_pingpong_on" ) );
|
||||
m_loopPingPongButton->setInactiveGraphic( PLUGIN_NAME::getIconPixmap(
|
||||
"loop_pingpong_off" ) );
|
||||
ToolTip::add( m_loopPingPongButton, tr( "Enable loop" ) );
|
||||
ToolTip::add( m_loopPingPongButton, tr( "Enable ping-pong loop" ) );
|
||||
|
||||
m_loopGroup = new automatableButtonGroup( this );
|
||||
m_loopGroup->addButton( m_loopOffButton );
|
||||
@@ -753,6 +753,7 @@ AudioFileProcessorWaveView::AudioFileProcessorWaveView( QWidget * _parent, int _
|
||||
|
||||
m_graph.fill( Qt::transparent );
|
||||
update();
|
||||
updateCursor();
|
||||
}
|
||||
|
||||
|
||||
@@ -769,7 +770,7 @@ void AudioFileProcessorWaveView::isPlaying( f_cnt_t _current_frame )
|
||||
|
||||
void AudioFileProcessorWaveView::enterEvent( QEvent * _e )
|
||||
{
|
||||
QApplication::setOverrideCursor( Qt::OpenHandCursor );
|
||||
updateCursor();
|
||||
}
|
||||
|
||||
|
||||
@@ -777,10 +778,7 @@ void AudioFileProcessorWaveView::enterEvent( QEvent * _e )
|
||||
|
||||
void AudioFileProcessorWaveView::leaveEvent( QEvent * _e )
|
||||
{
|
||||
while( QApplication::overrideCursor() )
|
||||
{
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
updateCursor();
|
||||
}
|
||||
|
||||
|
||||
@@ -808,7 +806,7 @@ void AudioFileProcessorWaveView::mousePressEvent( QMouseEvent * _me )
|
||||
else
|
||||
{
|
||||
m_draggingType = wave;
|
||||
QApplication::setOverrideCursor( Qt::ClosedHandCursor );
|
||||
updateCursor(_me);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -820,7 +818,7 @@ void AudioFileProcessorWaveView::mouseReleaseEvent( QMouseEvent * _me )
|
||||
m_isDragging = false;
|
||||
if( m_draggingType == wave )
|
||||
{
|
||||
QApplication::restoreOverrideCursor();
|
||||
updateCursor(_me);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -831,22 +829,7 @@ void AudioFileProcessorWaveView::mouseMoveEvent( QMouseEvent * _me )
|
||||
{
|
||||
if( ! m_isDragging )
|
||||
{
|
||||
const bool is_size_cursor =
|
||||
QApplication::overrideCursor()->shape() == Qt::SizeHorCursor;
|
||||
|
||||
if( isCloseTo( _me->x(), m_startFrameX ) ||
|
||||
isCloseTo( _me->x(), m_endFrameX ) ||
|
||||
isCloseTo( _me->x(), m_loopFrameX ) )
|
||||
{
|
||||
if( ! is_size_cursor )
|
||||
{
|
||||
QApplication::setOverrideCursor( Qt::SizeHorCursor );
|
||||
}
|
||||
}
|
||||
else if( is_size_cursor )
|
||||
{
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
updateCursor(_me);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1219,6 +1202,24 @@ void AudioFileProcessorWaveView::reverse()
|
||||
|
||||
|
||||
|
||||
void AudioFileProcessorWaveView::updateCursor( QMouseEvent * _me )
|
||||
{
|
||||
bool const waveIsDragged = m_isDragging && (m_draggingType == wave);
|
||||
bool const pointerCloseToStartEndOrLoop = (_me != nullptr ) &&
|
||||
( isCloseTo( _me->x(), m_startFrameX ) ||
|
||||
isCloseTo( _me->x(), m_endFrameX ) ||
|
||||
isCloseTo( _me->x(), m_loopFrameX ) );
|
||||
|
||||
if( !m_isDragging && pointerCloseToStartEndOrLoop)
|
||||
setCursor(Qt::SizeHorCursor);
|
||||
else if( waveIsDragged )
|
||||
setCursor(Qt::ClosedHandCursor);
|
||||
else
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void AudioFileProcessorWaveView::knob::slideTo( double _v, bool _check_bound )
|
||||
{
|
||||
@@ -1277,10 +1278,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main(Model * model, void *)
|
||||
{
|
||||
return new audioFileProcessor(
|
||||
static_cast<InstrumentTrack *>( _data ) );
|
||||
return new audioFileProcessor(static_cast<InstrumentTrack *>(model));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -211,7 +211,6 @@ public:
|
||||
|
||||
private:
|
||||
bool checkBound( double _v ) const;
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
@@ -276,6 +275,7 @@ private:
|
||||
|
||||
void updateGraph();
|
||||
void reverse();
|
||||
void updateCursor( QMouseEvent * _me = nullptr );
|
||||
|
||||
static bool isCloseTo( int _a, int _b )
|
||||
{
|
||||
|
||||
@@ -566,9 +566,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return( new bitInvader( static_cast<InstrumentTrack *>( _data ) ) );
|
||||
return( new bitInvader( static_cast<InstrumentTrack *>( m ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "carla.h"
|
||||
|
||||
#include "embed.h"
|
||||
#include "InstrumentTrack.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@@ -43,9 +44,9 @@ Plugin::Descriptor PLUGIN_EXPORT carlapatchbay_plugin_descriptor =
|
||||
NULL
|
||||
} ;
|
||||
|
||||
PLUGIN_EXPORT Plugin* lmms_plugin_main(Model*, void* data)
|
||||
PLUGIN_EXPORT Plugin* lmms_plugin_main(Model* m, void*)
|
||||
{
|
||||
return new CarlaInstrument(static_cast<InstrumentTrack*>(data), &carlapatchbay_plugin_descriptor, true);
|
||||
return new CarlaInstrument(static_cast<InstrumentTrack*>(m), &carlapatchbay_plugin_descriptor, true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "carla.h"
|
||||
|
||||
#include "embed.h"
|
||||
#include "InstrumentTrack.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
@@ -43,9 +44,9 @@ Plugin::Descriptor PLUGIN_EXPORT carlarack_plugin_descriptor =
|
||||
NULL
|
||||
} ;
|
||||
|
||||
PLUGIN_EXPORT Plugin* lmms_plugin_main(Model*, void* data)
|
||||
PLUGIN_EXPORT Plugin* lmms_plugin_main(Model* m, void*)
|
||||
{
|
||||
return new CarlaInstrument(static_cast<InstrumentTrack*>(data), &carlarack_plugin_descriptor, false);
|
||||
return new CarlaInstrument(static_cast<InstrumentTrack*>(m), &carlarack_plugin_descriptor, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -367,9 +367,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model * m, void * )
|
||||
{
|
||||
return new kickerInstrument( static_cast<InstrumentTrack *>( _data ) );
|
||||
return new kickerInstrument( static_cast<InstrumentTrack *>( m ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1029,11 +1029,11 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model * m, void * )
|
||||
{
|
||||
|
||||
return( new lb302Synth(
|
||||
static_cast<InstrumentTrack *>( _data ) ) );
|
||||
static_cast<InstrumentTrack *>( m ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1828,9 +1828,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return new MonstroInstrument( static_cast<InstrumentTrack *>( _data ) );
|
||||
return new MonstroInstrument( static_cast<InstrumentTrack *>( m ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 522 B After Width: | Height: | Size: 539 B |
|
Before Width: | Height: | Size: 599 B After Width: | Height: | Size: 498 B |
|
Before Width: | Height: | Size: 563 B After Width: | Height: | Size: 711 B |
|
Before Width: | Height: | Size: 520 B After Width: | Height: | Size: 443 B |
|
Before Width: | Height: | Size: 529 B After Width: | Height: | Size: 489 B |
|
Before Width: | Height: | Size: 578 B After Width: | Height: | Size: 596 B |
|
Before Width: | Height: | Size: 468 B After Width: | Height: | Size: 530 B |
|
Before Width: | Height: | Size: 427 B After Width: | Height: | Size: 345 B |
|
Before Width: | Height: | Size: 539 B After Width: | Height: | Size: 453 B |
|
Before Width: | Height: | Size: 602 B After Width: | Height: | Size: 566 B |
@@ -918,9 +918,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * _data )
|
||||
{
|
||||
return( new NesInstrument( static_cast<InstrumentTrack *>( _data ) ) );
|
||||
return( new NesInstrument( static_cast<InstrumentTrack *>( m ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -636,9 +636,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return( new organicInstrument( static_cast<InstrumentTrack *>( _data ) ) );
|
||||
return( new organicInstrument( static_cast<InstrumentTrack *>( m ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -66,9 +66,9 @@ Plugin::Descriptor PLUGIN_EXPORT patman_plugin_descriptor =
|
||||
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return new patmanInstrument( static_cast<InstrumentTrack *>( _data ) );
|
||||
return new patmanInstrument( static_cast<InstrumentTrack *>( m ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1150,9 +1150,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return new sf2Instrument( static_cast<InstrumentTrack *>( _data ) );
|
||||
return new sf2Instrument( static_cast<InstrumentTrack *>( m ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1122,9 +1122,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model*, void* data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model* m, void* )
|
||||
{
|
||||
return new sfxrInstrument( static_cast<InstrumentTrack *>( data ) );
|
||||
return new sfxrInstrument( static_cast<InstrumentTrack *>( m ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -794,10 +794,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return( new sidInstrument(
|
||||
static_cast<InstrumentTrack *>( _data ) ) );
|
||||
return( new sidInstrument( static_cast<InstrumentTrack *>( m ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -756,9 +756,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model * m, void * )
|
||||
{
|
||||
return new malletsInstrument( static_cast<InstrumentTrack *>( _data ) );
|
||||
return new malletsInstrument( static_cast<InstrumentTrack *>( m ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -723,9 +723,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model* model, void * )
|
||||
{
|
||||
return new TripleOscillator( static_cast<InstrumentTrack *>( _data ) );
|
||||
return new TripleOscillator( static_cast<InstrumentTrack *>( model ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -186,7 +186,13 @@ vestigeInstrument::~vestigeInstrument()
|
||||
|
||||
void vestigeInstrument::loadSettings( const QDomElement & _this )
|
||||
{
|
||||
loadFile( _this.attribute( "plugin" ) );
|
||||
QString plugin = _this.attribute( "plugin" );
|
||||
if( plugin.isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
loadFile( plugin );
|
||||
m_pluginMutex.lock();
|
||||
if( m_plugin != NULL )
|
||||
{
|
||||
@@ -217,13 +223,8 @@ void vestigeInstrument::loadSettings( const QDomElement & _this )
|
||||
knobFModel[ i ]->setInitValue(LocaleHelper::toFloat(s_dumpValues.at(2)));
|
||||
}
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
connect( knobFModel[i], SIGNAL( dataChanged( Model * ) ),
|
||||
this, SLOT( setParameter( Model * ) ), Qt::DirectConnection );
|
||||
#else
|
||||
connect( knobFModel[i], &FloatModel::dataChanged, this,
|
||||
[this, i]() { setParameter( knobFModel[i] ); }, Qt::DirectConnection);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
m_pluginMutex.unlock();
|
||||
@@ -978,13 +979,8 @@ manageVestigeInstrumentView::manageVestigeInstrumentView( Instrument * _instrume
|
||||
}
|
||||
|
||||
FloatModel * model = m_vi->knobFModel[i];
|
||||
#if QT_VERSION < 0x050000
|
||||
connect( model, SIGNAL( dataChanged( Model * ) ), this,
|
||||
SLOT( setParameter( Model * ) ), Qt::DirectConnection );
|
||||
#else
|
||||
connect( model, &FloatModel::dataChanged, this,
|
||||
[this, model]() { setParameter( model ); }, Qt::DirectConnection);
|
||||
#endif
|
||||
vstKnobs[i] ->setModel( model );
|
||||
}
|
||||
|
||||
@@ -1180,9 +1176,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
Q_DECL_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
Q_DECL_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return new vestigeInstrument( static_cast<InstrumentTrack *>( _data ) );
|
||||
return new vestigeInstrument( static_cast<InstrumentTrack *>( m ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -682,9 +682,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return( new vibed( static_cast<InstrumentTrack *>( _data ) ) );
|
||||
return( new vibed( static_cast<InstrumentTrack *>( m ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@ ENDIF()
|
||||
INCLUDE(BuildPlugin)
|
||||
INCLUDE(ExternalProject)
|
||||
|
||||
ADD_SUBDIRECTORY(vstbase)
|
||||
# These variables are not meant to be used normally, except packaging
|
||||
SET(REMOTE_VST_PLUGIN_FILEPATH_32 "32/RemoteVstPlugin32" CACHE STRING "Relative file path to RemoteVstPlugin32")
|
||||
SET(REMOTE_VST_PLUGIN_FILEPATH_64 "RemoteVstPlugin64" CACHE STRING "Relative file path to RemoteVstPlugin64")
|
||||
|
||||
IF(LMMS_BUILD_LINUX AND WANT_VST_NOWINE)
|
||||
RETURN()
|
||||
ENDIF()
|
||||
ADD_SUBDIRECTORY(vstbase)
|
||||
|
||||
SET(LMMS_BINARY_DIR ${CMAKE_BINARY_DIR})
|
||||
SET(LMMS_SOURCE_DIR ${CMAKE_SOURCE_DIR})
|
||||
@@ -29,6 +29,10 @@ SET(EXTERNALPROJECT_CMAKE_ARGS
|
||||
)
|
||||
|
||||
# build 32 bit version of RemoteVstPlugin
|
||||
INCLUDE("${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin32.cmake")
|
||||
IF(WANT_VST_32)
|
||||
INCLUDE("${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin32.cmake")
|
||||
ENDIF()
|
||||
# build 64 bit version of RemoteVstPlugin
|
||||
INCLUDE("${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin64.cmake")
|
||||
IF(WANT_VST_64)
|
||||
INCLUDE("${CMAKE_CURRENT_LIST_DIR}/RemoteVstPlugin64.cmake")
|
||||
ENDIF()
|
||||
|
||||
@@ -791,10 +791,6 @@ void RemoteVstPlugin::initEditor()
|
||||
SWP_NOMOVE | SWP_NOZORDER );
|
||||
pluginDispatch( effEditTop );
|
||||
|
||||
if (! EMBED) {
|
||||
showEditor();
|
||||
}
|
||||
|
||||
#ifdef LMMS_BUILD_LINUX
|
||||
m_windowID = (intptr_t) GetProp( m_window, "__wine_x11_whole_window" );
|
||||
#else
|
||||
|
||||
@@ -18,6 +18,7 @@ if(IS_WIN64 OR CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(BITNESS 64)
|
||||
else()
|
||||
set(BITNESS 32)
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/32")
|
||||
endif()
|
||||
|
||||
FOREACH( OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES} )
|
||||
|
||||
@@ -8,7 +8,7 @@ IF(LMMS_BUILD_WIN32 AND NOT LMMS_BUILD_WIN64)
|
||||
INSTALL(FILES "${MINGW_PREFIX}/bin/Qt5Core.dll" DESTINATION "${PLUGIN_DIR}/32")
|
||||
INSTALL(FILES "${MINGW_PREFIX}/bin/zlib1.dll" DESTINATION "${PLUGIN_DIR}/32")
|
||||
ENDIF(MSVC)
|
||||
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32")
|
||||
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../32/RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32")
|
||||
ELSEIF(LMMS_BUILD_WIN64 AND MSVC)
|
||||
SET(MSVC_VER ${CMAKE_CXX_COMPILER_VERSION})
|
||||
|
||||
@@ -46,7 +46,7 @@ ELSEIF(LMMS_BUILD_WIN64 AND MSVC)
|
||||
"-DCMAKE_PREFIX_PATH=${QT_32_PREFIX}"
|
||||
)
|
||||
|
||||
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32")
|
||||
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../32/RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32")
|
||||
|
||||
#TODO: find a solution when not using vcpkg for qt
|
||||
SET(VCPKG_ROOT_32 "${CMAKE_FIND_ROOT_PATH}/../x86-windows")
|
||||
@@ -58,6 +58,12 @@ ELSEIF(LMMS_BUILD_WIN64 AND MSVC)
|
||||
|
||||
ELSEIF(LMMS_BUILD_LINUX)
|
||||
# Use winegcc
|
||||
INCLUDE(CheckWineGcc)
|
||||
CheckWineGcc(32 "${WINEGCC}" WINEGCC_WORKING)
|
||||
IF(NOT WINEGCC_WORKING)
|
||||
MESSAGE(WARNING "winegcc fails to complie 32-bit binaries, please make sure you have 32-bit GCC libraries")
|
||||
RETURN()
|
||||
ENDIF()
|
||||
ExternalProject_Add(RemoteVstPlugin32
|
||||
"${EXTERNALPROJECT_ARGS}"
|
||||
CMAKE_ARGS
|
||||
@@ -66,7 +72,7 @@ ELSEIF(LMMS_BUILD_LINUX)
|
||||
"-DCMAKE_CXX_FLAGS=-m32"
|
||||
)
|
||||
|
||||
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32" "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe.so" DESTINATION "${PLUGIN_DIR}/32")
|
||||
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../32/RemoteVstPlugin32" "${CMAKE_CURRENT_BINARY_DIR}/../32/RemoteVstPlugin32.exe.so" DESTINATION "${PLUGIN_DIR}/32")
|
||||
|
||||
ELSEIF(CMAKE_TOOLCHAIN_FILE_32)
|
||||
ExternalProject_Add(RemoteVstPlugin32
|
||||
@@ -78,7 +84,7 @@ ELSEIF(CMAKE_TOOLCHAIN_FILE_32)
|
||||
)
|
||||
INSTALL(FILES "${CMAKE_PREFIX_PATH_32}/bin/Qt5Core.dll" DESTINATION "${PLUGIN_DIR}/32")
|
||||
INSTALL(FILES "${CMAKE_PREFIX_PATH_32}/bin/zlib1.dll" DESTINATION "${PLUGIN_DIR}/32")
|
||||
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32")
|
||||
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../32/RemoteVstPlugin32.exe" DESTINATION "${PLUGIN_DIR}/32")
|
||||
ELSE()
|
||||
MESSAGE(WARNING "Can't build RemoteVstPlugin32, unknown environment. Please supply CMAKE_TOOLCHAIN_FILE_32 and optionally CMAKE_PREFIX_PATH_32")
|
||||
RETURN()
|
||||
|
||||
@@ -2,6 +2,12 @@ IF(LMMS_BUILD_WIN64)
|
||||
ADD_SUBDIRECTORY(RemoteVstPlugin)
|
||||
INSTALL(PROGRAMS "${CMAKE_CURRENT_BINARY_DIR}/../RemoteVstPlugin64.exe" DESTINATION "${PLUGIN_DIR}")
|
||||
ELSEIF(LMMS_BUILD_LINUX)
|
||||
INCLUDE(CheckWineGcc)
|
||||
CheckWineGcc(64 "${WINEGCC}" WINEGCC_WORKING)
|
||||
IF(NOT WINEGCC_WORKING)
|
||||
MESSAGE(WARNING "winegcc fails to compile 64-bit binaries, please make sure you have 64-bit GCC libraries")
|
||||
RETURN()
|
||||
ENDIF()
|
||||
ExternalProject_Add(RemoteVstPlugin64
|
||||
"${EXTERNALPROJECT_ARGS}"
|
||||
CMAKE_ARGS
|
||||
|
||||
@@ -149,10 +149,10 @@ VstPlugin::VstPlugin( const QString & _plugin ) :
|
||||
switch(machineType)
|
||||
{
|
||||
case PE::MachineType::amd64:
|
||||
tryLoad( "RemoteVstPlugin64" );
|
||||
tryLoad( REMOTE_VST_PLUGIN_FILEPATH_64 ); // Default: RemoteVstPlugin64
|
||||
break;
|
||||
case PE::MachineType::i386:
|
||||
tryLoad( "32/RemoteVstPlugin32" );
|
||||
tryLoad( REMOTE_VST_PLUGIN_FILEPATH_32 ); // Default: 32/RemoteVstPlugin32
|
||||
break;
|
||||
default:
|
||||
m_failed = true;
|
||||
@@ -386,7 +386,9 @@ bool VstPlugin::processMessage( const message & _m )
|
||||
{
|
||||
case IdVstPluginWindowID:
|
||||
m_pluginWindowID = _m.getInt();
|
||||
if( m_embedMethod == "none" )
|
||||
if( m_embedMethod == "none"
|
||||
&& ConfigManager::inst()->value(
|
||||
"ui", "vstalwaysontop" ).toInt() )
|
||||
{
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
// We're changing the owner, not the parent,
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
ADD_DEFINITIONS(-DREMOTE_VST_PLUGIN_FILEPATH_32="${REMOTE_VST_PLUGIN_FILEPATH_32}")
|
||||
ADD_DEFINITIONS(-DREMOTE_VST_PLUGIN_FILEPATH_64="${REMOTE_VST_PLUGIN_FILEPATH_64}")
|
||||
|
||||
BUILD_PLUGIN(vstbase
|
||||
../vst_base.cpp ../VstPlugin.cpp ../VstPlugin.h ../communication.h
|
||||
MOCFILES ../VstPlugin.h
|
||||
|
||||
@@ -1279,9 +1279,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *m, void * )
|
||||
{
|
||||
return( new WatsynInstrument( static_cast<InstrumentTrack *>( _data ) ) );
|
||||
return( new WatsynInstrument( static_cast<InstrumentTrack *>( m ) ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <QDir>
|
||||
#include <QDomDocument>
|
||||
#include <QTemporaryFile>
|
||||
#include <QtGlobal>
|
||||
#include <QDropEvent>
|
||||
#include <QGridLayout>
|
||||
#include <QPushButton>
|
||||
@@ -290,6 +291,7 @@ void ZynAddSubFxInstrument::loadSettings( const QDomElement & _this )
|
||||
|
||||
emit settingsChanged();
|
||||
}
|
||||
emit instrumentTrack()->pitchModel()->dataChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -659,10 +661,9 @@ extern "C"
|
||||
{
|
||||
|
||||
// necessary for getting instance out of shared lib
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
|
||||
PLUGIN_EXPORT Plugin * lmms_plugin_main(Model * m, void *)
|
||||
{
|
||||
|
||||
return new ZynAddSubFxInstrument( static_cast<InstrumentTrack *>( _data ) );
|
||||
return new ZynAddSubFxInstrument(static_cast<InstrumentTrack *>(m));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ INCLUDE(GenQrc)
|
||||
ADD_GEN_QRC(LMMS_RCC_OUT lmms.qrc
|
||||
"${CMAKE_SOURCE_DIR}/doc/AUTHORS"
|
||||
"${CMAKE_SOURCE_DIR}/LICENSE.txt"
|
||||
"${CMAKE_BINARY_DIR}/CONTRIBUTORS"
|
||||
"${CONTRIBUTORS}"
|
||||
)
|
||||
|
||||
# Paths relative to lmms executable
|
||||
|
||||
@@ -511,8 +511,9 @@ void ConfigManager::loadConfigFile( const QString & configFile )
|
||||
cfg_file.close();
|
||||
}
|
||||
|
||||
|
||||
// Plugins are searched recursively, blacklist problematic locations
|
||||
if( m_vstDir.isEmpty() || m_vstDir == QDir::separator() || m_vstDir == "/" ||
|
||||
m_vstDir == ensureTrailingSlash( QDir::homePath() ) ||
|
||||
!QDir( m_vstDir ).exists() )
|
||||
{
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
|
||||
@@ -124,7 +124,10 @@ void DrumSynth::GetEnv(int env, const char *sec, const char *key, QString ini)
|
||||
char en[256], s[8];
|
||||
int i=0, o=0, ep=0;
|
||||
GetPrivateProfileString(sec, key, "0,0 100,0", en, sizeof(en), ini);
|
||||
en[255]=0; //be safe!
|
||||
|
||||
//be safe!
|
||||
en[255]=0;
|
||||
s[0]=0;
|
||||
|
||||
while(en[i]!=0)
|
||||
{
|
||||
|
||||
@@ -36,9 +36,8 @@
|
||||
Effect::Effect( const Plugin::Descriptor * _desc,
|
||||
Model * _parent,
|
||||
const Descriptor::SubPluginFeatures::Key * _key ) :
|
||||
Plugin( _desc, _parent ),
|
||||
Plugin( _desc, _parent, _key ),
|
||||
m_parent( NULL ),
|
||||
m_key( _key ? *_key : Descriptor::SubPluginFeatures::Key() ),
|
||||
m_processors( 1 ),
|
||||
m_okay( true ),
|
||||
m_noRun( false ),
|
||||
@@ -117,7 +116,7 @@ Effect * Effect::instantiate( const QString& pluginName,
|
||||
Model * _parent,
|
||||
Descriptor::SubPluginFeatures::Key * _key )
|
||||
{
|
||||
Plugin * p = Plugin::instantiate( pluginName, _parent, _key );
|
||||
Plugin * p = Plugin::instantiateWithKey( pluginName, _parent, _key );
|
||||
// check whether instantiated plugin is an effect
|
||||
if( dynamic_cast<Effect *>( p ) != NULL )
|
||||
{
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "FxMixer.h"
|
||||
#include "Ladspa2LMMS.h"
|
||||
#include "Mixer.h"
|
||||
#include "Plugin.h"
|
||||
#include "PresetPreviewPlayHandle.h"
|
||||
#include "ProjectJournal.h"
|
||||
#include "Song.h"
|
||||
@@ -41,6 +42,7 @@ BBTrackContainer * LmmsCore::s_bbTrackContainer = NULL;
|
||||
Song * LmmsCore::s_song = NULL;
|
||||
ProjectJournal * LmmsCore::s_projectJournal = NULL;
|
||||
Ladspa2LMMS * LmmsCore::s_ladspaManager = NULL;
|
||||
void* LmmsCore::s_dndPluginKey = nullptr;
|
||||
DummyTrackContainer * LmmsCore::s_dummyTC = NULL;
|
||||
|
||||
|
||||
@@ -112,4 +114,24 @@ void LmmsCore::updateFramesPerTick()
|
||||
DefaultTicksPerTact / s_song->getTempo();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void LmmsCore::setDndPluginKey(void *newKey)
|
||||
{
|
||||
Q_ASSERT(static_cast<Plugin::Descriptor::SubPluginFeatures::Key*>(newKey));
|
||||
s_dndPluginKey = newKey;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void *LmmsCore::pickDndPluginKey()
|
||||
{
|
||||
return s_dndPluginKey;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
LmmsCore * LmmsCore::s_instanceOfMe = NULL;
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "Song.h"
|
||||
|
||||
#include "InstrumentTrack.h"
|
||||
#include "SampleTrack.h"
|
||||
#include "BBTrackContainer.h"
|
||||
|
||||
FxRoute::FxRoute( FxChannel * from, FxChannel * to, float amount ) :
|
||||
@@ -305,6 +306,22 @@ void FxMixer::deleteChannel( int index )
|
||||
inst->effectChannelModel()->setValue(val-1);
|
||||
}
|
||||
}
|
||||
else if( t->type() == Track::SampleTrack )
|
||||
{
|
||||
SampleTrack* strk = dynamic_cast<SampleTrack *>( t );
|
||||
int val = strk->effectChannelModel()->value(0);
|
||||
if( val == index )
|
||||
{
|
||||
// we are deleting this track's fx send
|
||||
// send to master
|
||||
strk->effectChannelModel()->setValue(0);
|
||||
}
|
||||
else if( val > index )
|
||||
{
|
||||
// subtract 1 to make up for the missing channel
|
||||
strk->effectChannelModel()->setValue(val-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FxChannel * ch = m_fxChannels[index];
|
||||
@@ -379,6 +396,19 @@ void FxMixer::moveChannelLeft( int index )
|
||||
inst->effectChannelModel()->setValue(a);
|
||||
}
|
||||
}
|
||||
else if( trackList[i]->type() == Track::SampleTrack )
|
||||
{
|
||||
SampleTrack * strk = (SampleTrack *) trackList[i];
|
||||
int val = strk->effectChannelModel()->value(0);
|
||||
if( val == a )
|
||||
{
|
||||
strk->effectChannelModel()->setValue(b);
|
||||
}
|
||||
else if( val == b )
|
||||
{
|
||||
strk->effectChannelModel()->setValue(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -780,4 +810,3 @@ void FxMixer::validateChannelName( int index, int oldIndex )
|
||||
m_fxChannels[index]->m_name = tr( "FX %1" ).arg( index );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,9 +27,10 @@
|
||||
#include "DummyInstrument.h"
|
||||
|
||||
|
||||
Instrument::Instrument( InstrumentTrack * _instrument_track,
|
||||
const Descriptor * _descriptor ) :
|
||||
Plugin( _descriptor, NULL/* _instrument_track*/ ),
|
||||
Instrument::Instrument(InstrumentTrack * _instrument_track,
|
||||
const Descriptor * _descriptor,
|
||||
const Descriptor::SubPluginFeatures::Key *key) :
|
||||
Plugin(_descriptor, NULL/* _instrument_track*/, key),
|
||||
m_instrumentTrack( _instrument_track )
|
||||
{
|
||||
}
|
||||
@@ -56,19 +57,15 @@ f_cnt_t Instrument::beatLen( NotePlayHandle * ) const
|
||||
|
||||
|
||||
|
||||
Instrument * Instrument::instantiate( const QString & _plugin_name,
|
||||
InstrumentTrack * _instrument_track )
|
||||
Instrument *Instrument::instantiate(const QString &_plugin_name,
|
||||
InstrumentTrack *_instrument_track, const Descriptor::SubPluginFeatures::Key *key, bool keyFromDnd)
|
||||
{
|
||||
Plugin * p = Plugin::instantiate( _plugin_name, _instrument_track,
|
||||
_instrument_track );
|
||||
// check whether instantiated plugin is an instrument
|
||||
if( dynamic_cast<Instrument *>( p ) != NULL )
|
||||
{
|
||||
// everything ok, so return pointer
|
||||
return dynamic_cast<Instrument *>( p );
|
||||
}
|
||||
|
||||
// not quite... so delete plugin and return dummy instrument
|
||||
if(keyFromDnd)
|
||||
Q_ASSERT(!key);
|
||||
// copy from above // TODO! common cleaner func
|
||||
Plugin * p = Plugin::instantiateWithKey(_plugin_name, _instrument_track, key, keyFromDnd);
|
||||
if(dynamic_cast<Instrument *>(p))
|
||||
return dynamic_cast<Instrument *>(p);
|
||||
delete p;
|
||||
return( new DummyInstrument( _instrument_track ) );
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
LadspaManager::LadspaManager()
|
||||
{
|
||||
// Make sure plugin search paths are set up
|
||||
PluginFactory::instance();
|
||||
PluginFactory::setupSearchPaths();
|
||||
|
||||
QStringList ladspaDirectories = QString( getenv( "LADSPA_PATH" ) ).
|
||||
split( LADSPA_PATH_SEPERATOR );
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
*/
|
||||
|
||||
#include "MixHelpers.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "lmms_math.h"
|
||||
#include "ValueBuffer.h"
|
||||
|
||||
|
||||
@@ -186,8 +186,8 @@ Mixer::~Mixer()
|
||||
}
|
||||
delete m_fifo;
|
||||
|
||||
delete m_audioDev;
|
||||
delete m_midiClient;
|
||||
delete m_audioDev;
|
||||
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
|
||||
@@ -22,12 +22,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Plugin.h"
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QLibrary>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "Plugin.h"
|
||||
#include "embed.h"
|
||||
#include "Engine.h"
|
||||
#include "GuiApplication.h"
|
||||
@@ -53,10 +55,12 @@ static Plugin::Descriptor dummyPluginDescriptor =
|
||||
|
||||
|
||||
|
||||
Plugin::Plugin( const Descriptor * descriptor, Model * parent ) :
|
||||
Model( parent ),
|
||||
Plugin::Plugin(const Descriptor * descriptor, Model * parent, const
|
||||
Descriptor::SubPluginFeatures::Key* key) :
|
||||
Model(parent),
|
||||
JournallingObject(),
|
||||
m_descriptor( descriptor )
|
||||
m_descriptor(descriptor),
|
||||
m_key(key ? *key : Descriptor::SubPluginFeatures::Key(m_descriptor))
|
||||
{
|
||||
if( m_descriptor == NULL )
|
||||
{
|
||||
@@ -74,6 +78,97 @@ Plugin::~Plugin()
|
||||
|
||||
|
||||
|
||||
template<class T>
|
||||
T use_this_or(T this_param, T or_param)
|
||||
{
|
||||
return this_param ? this_param : or_param;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString use_this_or(QString this_param, QString or_param)
|
||||
{
|
||||
return this_param.isNull() ? or_param : this_param;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString Plugin::displayName() const
|
||||
{
|
||||
return Model::displayName().isEmpty() // currently always empty
|
||||
? (m_descriptor->subPluginFeatures && m_key.isValid())
|
||||
// get from sub plugin
|
||||
? m_key.displayName()
|
||||
// get from plugin
|
||||
: m_descriptor->displayName
|
||||
: Model::displayName();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const PixmapLoader* Plugin::logo() const
|
||||
{
|
||||
return (m_descriptor->subPluginFeatures && m_key.isValid())
|
||||
? m_key.logo()
|
||||
: m_descriptor->logo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString Plugin::Descriptor::SubPluginFeatures::Key::additionalFileExtensions() const
|
||||
{
|
||||
Q_ASSERT(isValid());
|
||||
return desc->subPluginFeatures
|
||||
// get from sub plugin
|
||||
? desc->subPluginFeatures->additionalFileExtensions(*this)
|
||||
// no sub plugin, so no *additional* file extensions
|
||||
: QString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString Plugin::Descriptor::SubPluginFeatures::Key::displayName() const
|
||||
{
|
||||
Q_ASSERT(isValid());
|
||||
return desc->subPluginFeatures
|
||||
// get from sub plugin
|
||||
? use_this_or(desc->subPluginFeatures->displayName(*this),
|
||||
QString::fromUtf8(desc->displayName))
|
||||
// get from plugin
|
||||
: desc->displayName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const PixmapLoader* Plugin::Descriptor::SubPluginFeatures::Key::logo() const
|
||||
{
|
||||
Q_ASSERT(isValid());
|
||||
return desc->subPluginFeatures
|
||||
? use_this_or(desc->subPluginFeatures->logo(*this), desc->logo)
|
||||
: desc->logo;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
QString Plugin::Descriptor::SubPluginFeatures::Key::description() const
|
||||
{
|
||||
Q_ASSERT(isValid());
|
||||
return desc->subPluginFeatures
|
||||
? use_this_or(desc->subPluginFeatures->description(*this),
|
||||
QString::fromUtf8(desc->description))
|
||||
: desc->description;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Plugin::loadFile( const QString & )
|
||||
{
|
||||
}
|
||||
@@ -90,10 +185,38 @@ AutomatableModel * Plugin::childModel( const QString & )
|
||||
|
||||
|
||||
#include "PluginFactory.h"
|
||||
Plugin * Plugin::instantiate( const QString& pluginName, Model * parent,
|
||||
void * data )
|
||||
Plugin * Plugin::instantiateWithKey(const QString& pluginName, Model * parent,
|
||||
const Descriptor::SubPluginFeatures::Key *key,
|
||||
bool keyFromDnd)
|
||||
{
|
||||
if(keyFromDnd)
|
||||
Q_ASSERT(!key);
|
||||
const Descriptor::SubPluginFeatures::Key *keyPtr = keyFromDnd
|
||||
? static_cast<Plugin::Descriptor::SubPluginFeatures::Key*>(Engine::pickDndPluginKey())
|
||||
: key;
|
||||
const PluginFactory::PluginInfo& pi = pluginFactory->pluginInfo(pluginName.toUtf8());
|
||||
if(keyPtr)
|
||||
{
|
||||
// descriptor is not yet set when loading - set it now
|
||||
Descriptor::SubPluginFeatures::Key keyCopy = *keyPtr;
|
||||
keyCopy.desc = pi.descriptor;
|
||||
return Plugin::instantiate(pluginName, parent, &keyCopy);
|
||||
}
|
||||
else
|
||||
return Plugin::instantiate(pluginName, parent,
|
||||
// the keys are never touched anywhere
|
||||
const_cast<Descriptor::SubPluginFeatures::Key *>(keyPtr));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Plugin * Plugin::instantiate(const QString& pluginName, Model * parent,
|
||||
void *data)
|
||||
{
|
||||
const PluginFactory::PluginInfo& pi = pluginFactory->pluginInfo(pluginName.toUtf8());
|
||||
|
||||
Plugin* inst;
|
||||
if( pi.isNull() )
|
||||
{
|
||||
if( gui )
|
||||
@@ -104,23 +227,31 @@ Plugin * Plugin::instantiate( const QString& pluginName, Model * parent,
|
||||
arg( pluginName ).arg( pluginFactory->errorString(pluginName) ),
|
||||
QMessageBox::Ok | QMessageBox::Default );
|
||||
}
|
||||
return new DummyPlugin();
|
||||
inst = new DummyPlugin();
|
||||
}
|
||||
|
||||
InstantiationHook instantiationHook = ( InstantiationHook ) pi.library->resolve( "lmms_plugin_main" );
|
||||
if( instantiationHook == NULL )
|
||||
else
|
||||
{
|
||||
if( gui )
|
||||
InstantiationHook instantiationHook;
|
||||
if ((instantiationHook = ( InstantiationHook ) pi.library->resolve( "lmms_plugin_main" )))
|
||||
{
|
||||
QMessageBox::information( NULL,
|
||||
tr( "Error while loading plugin" ),
|
||||
tr( "Failed to load plugin \"%1\"!").arg( pluginName ),
|
||||
QMessageBox::Ok | QMessageBox::Default );
|
||||
inst = instantiationHook(parent, data);
|
||||
if(!inst) {
|
||||
inst = new DummyPlugin();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( gui )
|
||||
{
|
||||
QMessageBox::information( NULL,
|
||||
tr( "Error while loading plugin" ),
|
||||
tr( "Failed to load plugin \"%1\"!").arg( pluginName ),
|
||||
QMessageBox::Ok | QMessageBox::Default );
|
||||
}
|
||||
inst = new DummyPlugin();
|
||||
}
|
||||
return new DummyPlugin();
|
||||
}
|
||||
|
||||
Plugin * inst = instantiationHook( parent, data );
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,8 +28,11 @@
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QLibrary>
|
||||
#include "lmmsconfig.h"
|
||||
|
||||
#include "ConfigManager.h"
|
||||
#include "Plugin.h"
|
||||
#include "embed.h"
|
||||
|
||||
#ifdef LMMS_BUILD_WIN32
|
||||
QStringList nameFilters("*.dll");
|
||||
@@ -45,6 +48,16 @@ qint64 qHash(const QFileInfo& fi)
|
||||
std::unique_ptr<PluginFactory> PluginFactory::s_instance;
|
||||
|
||||
PluginFactory::PluginFactory()
|
||||
{
|
||||
setupSearchPaths();
|
||||
discoverPlugins();
|
||||
}
|
||||
|
||||
PluginFactory::~PluginFactory()
|
||||
{
|
||||
}
|
||||
|
||||
void PluginFactory::setupSearchPaths()
|
||||
{
|
||||
// Adds a search path relative to the main executable if the path exists.
|
||||
auto addRelativeIfExists = [](const QString & path) {
|
||||
@@ -76,12 +89,6 @@ PluginFactory::PluginFactory()
|
||||
QDir::addSearchPath("plugins", env_path);
|
||||
|
||||
QDir::addSearchPath("plugins", ConfigManager::inst()->workingDir() + "plugins");
|
||||
|
||||
discoverPlugins();
|
||||
}
|
||||
|
||||
PluginFactory::~PluginFactory()
|
||||
{
|
||||
}
|
||||
|
||||
PluginFactory* PluginFactory::instance()
|
||||
@@ -107,9 +114,9 @@ const PluginFactory::PluginInfoList& PluginFactory::pluginInfos() const
|
||||
return m_pluginInfos;
|
||||
}
|
||||
|
||||
const PluginFactory::PluginInfo PluginFactory::pluginSupportingExtension(const QString& ext)
|
||||
const PluginFactory::PluginInfoAndKey PluginFactory::pluginSupportingExtension(const QString& ext)
|
||||
{
|
||||
return m_pluginByExt.value(ext, PluginInfo());
|
||||
return m_pluginByExt.value(ext, PluginInfoAndKey());
|
||||
}
|
||||
|
||||
const PluginFactory::PluginInfo PluginFactory::pluginInfo(const char* name) const
|
||||
@@ -150,42 +157,78 @@ void PluginFactory::discoverPlugins()
|
||||
for (const QFileInfo& file : files)
|
||||
{
|
||||
auto library = std::make_shared<QLibrary>(file.absoluteFilePath());
|
||||
|
||||
if (! library->load()) {
|
||||
m_errors[file.baseName()] = library->errorString();
|
||||
qWarning("%s", library->errorString().toLocal8Bit().data());
|
||||
continue;
|
||||
}
|
||||
if (library->resolve("lmms_plugin_main") == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QString descriptorName = file.baseName() + "_plugin_descriptor";
|
||||
if( descriptorName.left(3) == "lib" )
|
||||
Plugin::Descriptor* pluginDescriptor = nullptr;
|
||||
if (library->resolve("lmms_plugin_main"))
|
||||
{
|
||||
descriptorName = descriptorName.mid(3);
|
||||
QString descriptorName = file.baseName() + "_plugin_descriptor";
|
||||
if( descriptorName.left(3) == "lib" )
|
||||
{
|
||||
descriptorName = descriptorName.mid(3);
|
||||
}
|
||||
|
||||
pluginDescriptor = reinterpret_cast<Plugin::Descriptor*>(library->resolve(descriptorName.toUtf8().constData()));
|
||||
if(pluginDescriptor == nullptr)
|
||||
{
|
||||
qWarning() << qApp->translate("PluginFactory", "LMMS plugin %1 does not have a plugin descriptor named %2!").
|
||||
arg(file.absoluteFilePath()).arg(descriptorName);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Plugin::Descriptor* pluginDescriptor = reinterpret_cast<Plugin::Descriptor*>(library->resolve(descriptorName.toUtf8().constData()));
|
||||
if(pluginDescriptor == nullptr)
|
||||
if(pluginDescriptor)
|
||||
{
|
||||
qWarning() << qApp->translate("PluginFactory", "LMMS plugin %1 does not have a plugin descriptor named %2!").
|
||||
arg(file.absoluteFilePath()).arg(descriptorName);
|
||||
continue;
|
||||
PluginInfo info;
|
||||
info.file = file;
|
||||
info.library = library;
|
||||
info.descriptor = pluginDescriptor;
|
||||
pluginInfos << info;
|
||||
|
||||
auto addSupportedFileTypes =
|
||||
[this](QString supportedFileTypes,
|
||||
const PluginInfo& info,
|
||||
const Plugin::Descriptor::SubPluginFeatures::Key* key = nullptr)
|
||||
{
|
||||
if(!supportedFileTypes.isNull())
|
||||
{
|
||||
for (const QString& ext : supportedFileTypes.split(','))
|
||||
{
|
||||
//qDebug() << "Plugin " << info.name()
|
||||
// << "supports" << ext;
|
||||
PluginInfoAndKey infoAndKey;
|
||||
infoAndKey.info = info;
|
||||
infoAndKey.key = key
|
||||
? *key
|
||||
: Plugin::Descriptor::SubPluginFeatures::Key();
|
||||
m_pluginByExt.insert(ext, infoAndKey);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (info.descriptor->supportedFileTypes)
|
||||
addSupportedFileTypes(QString(info.descriptor->supportedFileTypes), info);
|
||||
|
||||
if (info.descriptor->subPluginFeatures)
|
||||
{
|
||||
Plugin::Descriptor::SubPluginFeatures::KeyList
|
||||
subPluginKeys;
|
||||
info.descriptor->subPluginFeatures->listSubPluginKeys(
|
||||
info.descriptor,
|
||||
subPluginKeys);
|
||||
for(const Plugin::Descriptor::SubPluginFeatures::Key& key
|
||||
: subPluginKeys)
|
||||
{
|
||||
addSupportedFileTypes(key.additionalFileExtensions(), info, &key);
|
||||
}
|
||||
}
|
||||
|
||||
descriptors.insert(info.descriptor->type, info.descriptor);
|
||||
}
|
||||
|
||||
PluginInfo info;
|
||||
info.file = file;
|
||||
info.library = library;
|
||||
info.descriptor = pluginDescriptor;
|
||||
pluginInfos << info;
|
||||
|
||||
for (const QString& ext : QString(info.descriptor->supportedFileTypes).split(','))
|
||||
{
|
||||
m_pluginByExt.insert(ext, info);
|
||||
}
|
||||
|
||||
descriptors.insert(info.descriptor->type, info.descriptor);
|
||||
}
|
||||
|
||||
m_pluginInfos = pluginInfos;
|
||||
|
||||
@@ -137,8 +137,10 @@ PresetPreviewPlayHandle::PresetPreviewPlayHandle( const QString & _preset_file,
|
||||
suffix().toLower();
|
||||
if( i == NULL || !i->descriptor()->supportsFileType( ext ) )
|
||||
{
|
||||
const PluginFactory::PluginInfoAndKey& infoAndKey =
|
||||
pluginFactory->pluginSupportingExtension(ext);
|
||||
i = s_previewTC->previewInstrumentTrack()->
|
||||
loadInstrument(pluginFactory->pluginSupportingExtension(ext).name());
|
||||
loadInstrument(infoAndKey.info.name(), &infoAndKey.key);
|
||||
}
|
||||
if( i != NULL )
|
||||
{
|
||||
|
||||
@@ -525,7 +525,7 @@ void TrackContentObjectView::dragEnterEvent( QDragEnterEvent * dee )
|
||||
{
|
||||
TrackContentWidget * tcw = getTrackView()->getTrackContentWidget();
|
||||
MidiTime tcoPos = MidiTime( m_tco->startPosition().getTact(), 0 );
|
||||
if( tcw->canPasteSelection( tcoPos, dee->mimeData() ) == false )
|
||||
if( tcw->canPasteSelection( tcoPos, dee ) == false )
|
||||
{
|
||||
dee->ignore();
|
||||
}
|
||||
@@ -630,9 +630,12 @@ DataFile TrackContentObjectView::createTCODataFiles(
|
||||
it != tcoViews.end(); ++it )
|
||||
{
|
||||
// Insert into the dom under the "tcos" element
|
||||
int trackIndex = tc->tracks().indexOf( ( *it )->m_trackView->getTrack() );
|
||||
Track* tcoTrack = ( *it )->m_trackView->getTrack();
|
||||
int trackIndex = tc->tracks().indexOf( tcoTrack );
|
||||
QDomElement tcoElement = dataFile.createElement( "tco" );
|
||||
tcoElement.setAttribute( "trackIndex", trackIndex );
|
||||
tcoElement.setAttribute( "trackType", tcoTrack->type() );
|
||||
tcoElement.setAttribute( "trackName", tcoTrack->name() );
|
||||
( *it )->m_tco->saveState( dataFile, tcoElement );
|
||||
tcoParent.appendChild( tcoElement );
|
||||
}
|
||||
@@ -649,6 +652,7 @@ DataFile TrackContentObjectView::createTCODataFiles(
|
||||
QDomElement metadata = dataFile.createElement( "copyMetadata" );
|
||||
// initialTrackIndex is the index of the track that was touched
|
||||
metadata.setAttribute( "initialTrackIndex", initialTrackIndex );
|
||||
metadata.setAttribute( "trackContainerId", tc->id() );
|
||||
// grabbedTCOPos is the pos of the tact containing the TCO we grabbed
|
||||
metadata.setAttribute( "grabbedTCOPos", m_tco->startPosition() );
|
||||
|
||||
@@ -1387,7 +1391,7 @@ MidiTime TrackContentWidget::getPosition( int mouseX )
|
||||
void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee )
|
||||
{
|
||||
MidiTime tcoPos = MidiTime( getPosition( dee->pos().x() ).getTact(), 0 );
|
||||
if( canPasteSelection( tcoPos, dee->mimeData() ) == false )
|
||||
if( canPasteSelection( tcoPos, dee ) == false )
|
||||
{
|
||||
dee->ignore();
|
||||
}
|
||||
@@ -1406,8 +1410,10 @@ void TrackContentWidget::dragEnterEvent( QDragEnterEvent * dee )
|
||||
* \param tcoPos the position of the TCO slot being pasted on
|
||||
* \param de the DropEvent generated
|
||||
*/
|
||||
bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * mimeData )
|
||||
bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QDropEvent* de )
|
||||
{
|
||||
const QMimeData * mimeData = de->mimeData();
|
||||
|
||||
Track * t = getTrack();
|
||||
QString type = StringPairDrag::decodeMimeKey( mimeData );
|
||||
QString value = StringPairDrag::decodeMimeValue( mimeData );
|
||||
@@ -1437,7 +1443,9 @@ bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * m
|
||||
const int currentTrackIndex = tracks.indexOf( t );
|
||||
|
||||
// Don't paste if we're on the same tact
|
||||
if( tcoPos == grabbedTCOTact && currentTrackIndex == initialTrackIndex )
|
||||
auto sourceTrackContainerId = metadata.attributeNode( "trackContainerId" ).value().toUInt();
|
||||
if( de->source() && sourceTrackContainerId == t->trackContainer()->id() &&
|
||||
tcoPos == grabbedTCOTact && currentTrackIndex == initialTrackIndex )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1460,9 +1468,9 @@ bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * m
|
||||
}
|
||||
|
||||
// Track must be of the same type
|
||||
Track * startTrack = tracks.at( trackIndex );
|
||||
auto startTrackType = tcoElement.attributeNode("trackType").value().toInt();
|
||||
Track * endTrack = tracks.at( finalTrackIndex );
|
||||
if( startTrack->type() != endTrack->type() )
|
||||
if( startTrackType != endTrack->type() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1478,7 +1486,7 @@ bool TrackContentWidget::canPasteSelection( MidiTime tcoPos, const QMimeData * m
|
||||
*/
|
||||
bool TrackContentWidget::pasteSelection( MidiTime tcoPos, QDropEvent * de )
|
||||
{
|
||||
if( canPasteSelection( tcoPos, de->mimeData() ) == false )
|
||||
if( canPasteSelection( tcoPos, de ) == false )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -1548,7 +1556,8 @@ bool TrackContentWidget::pasteSelection( MidiTime tcoPos, QDropEvent * de )
|
||||
}
|
||||
|
||||
//check tco name, if the same as source track name dont copy
|
||||
if( tco->name() == tracks[trackIndex]->name() )
|
||||
QString sourceTrackName = outerTCOElement.attributeNode( "trackName" ).value();
|
||||
if( tco->name() == sourceTrackName )
|
||||
{
|
||||
tco->setName( "" );
|
||||
}
|
||||
@@ -1924,13 +1933,15 @@ void TrackOperationsWidget::updateMenu()
|
||||
{
|
||||
toMenu->addAction( tr( "Clear this track" ), this, SLOT( clearTrack() ) );
|
||||
}
|
||||
if( InstrumentTrackView * trackView = dynamic_cast<InstrumentTrackView *>( m_trackView ) )
|
||||
if (QMenu *fxMenu = m_trackView->createFxMenu(tr("FX %1: %2"), tr("Assign to new FX Channel")))
|
||||
{
|
||||
QMenu *fxMenu = trackView->createFxMenu( tr( "FX %1: %2" ), tr( "Assign to new FX Channel" ));
|
||||
toMenu->addMenu(fxMenu);
|
||||
}
|
||||
|
||||
if (InstrumentTrackView * trackView = dynamic_cast<InstrumentTrackView *>(m_trackView))
|
||||
{
|
||||
toMenu->addSeparator();
|
||||
toMenu->addMenu( trackView->midiMenu() );
|
||||
toMenu->addMenu(trackView->midiMenu());
|
||||
}
|
||||
if( dynamic_cast<AutomationTrackView *>( m_trackView ) )
|
||||
{
|
||||
@@ -2677,6 +2688,19 @@ void TrackView::update()
|
||||
|
||||
|
||||
|
||||
/*! \brief Create a menu for assigning/creating channels for this track.
|
||||
*
|
||||
*/
|
||||
QMenu * TrackView::createFxMenu(QString title, QString newFxLabel)
|
||||
{
|
||||
Q_UNUSED(title)
|
||||
Q_UNUSED(newFxLabel)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*! \brief Close this track View.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -61,6 +61,7 @@ static void JackMidiShutdown(void *arg)
|
||||
|
||||
MidiJack::MidiJack() :
|
||||
MidiClientRaw(),
|
||||
m_jackClient( nullptr ),
|
||||
m_input_port( NULL ),
|
||||
m_output_port( NULL ),
|
||||
m_quit( false )
|
||||
|
||||
@@ -56,6 +56,7 @@ SET(LMMS_SRCS
|
||||
gui/widgets/FadeButton.cpp
|
||||
gui/widgets/Fader.cpp
|
||||
gui/widgets/FxLine.cpp
|
||||
gui/widgets/FxLineLcdSpinBox.cpp
|
||||
gui/widgets/Graph.cpp
|
||||
gui/widgets/GroupBox.cpp
|
||||
gui/widgets/InstrumentFunctionViews.cpp
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "ui_EffectSelectDialog.h"
|
||||
|
||||
#include "gui_templates.h"
|
||||
#include "DummyEffect.h"
|
||||
#include "embed.h"
|
||||
#include "PluginFactory.h"
|
||||
|
||||
@@ -53,11 +54,6 @@ EffectSelectDialog::EffectSelectDialog( QWidget * _parent ) :
|
||||
if( desc->subPluginFeatures )
|
||||
{
|
||||
desc->subPluginFeatures->listSubPluginKeys(
|
||||
// as iterators are always stated to be not
|
||||
// equal with pointers, we dereference the
|
||||
// iterator and take the address of the item,
|
||||
// so we're on the safe side and the compiler
|
||||
// likely will reduce that to just "it"
|
||||
desc,
|
||||
subPluginEffectKeys );
|
||||
}
|
||||
@@ -79,14 +75,14 @@ EffectSelectDialog::EffectSelectDialog( QWidget * _parent ) :
|
||||
{
|
||||
QString name;
|
||||
QString type;
|
||||
if( ( *it ).desc->subPluginFeatures )
|
||||
if( it->desc->subPluginFeatures )
|
||||
{
|
||||
name = ( *it ).name;
|
||||
type = ( *it ).desc->displayName;
|
||||
name = it->displayName();
|
||||
type = it->desc->displayName;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = ( *it ).desc->displayName;
|
||||
name = it->desc->displayName;
|
||||
type = "LMMS";
|
||||
}
|
||||
m_sourceModel.setItem( row, 0, new QStandardItem( name ) );
|
||||
@@ -147,12 +143,17 @@ EffectSelectDialog::~EffectSelectDialog()
|
||||
|
||||
Effect * EffectSelectDialog::instantiateSelectedPlugin( EffectChain * _parent )
|
||||
{
|
||||
if( !m_currentSelection.name.isEmpty() && m_currentSelection.desc )
|
||||
Effect* result = nullptr;
|
||||
if(!m_currentSelection.name.isEmpty() && m_currentSelection.desc)
|
||||
{
|
||||
return Effect::instantiate( m_currentSelection.desc->name,
|
||||
_parent, &m_currentSelection );
|
||||
result = Effect::instantiate(m_currentSelection.desc->name,
|
||||
_parent, &m_currentSelection);
|
||||
}
|
||||
return NULL;
|
||||
if(!result)
|
||||
{
|
||||
result = new DummyEffect(_parent, QDomElement());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -184,62 +185,63 @@ void EffectSelectDialog::rowChanged( const QModelIndex & _idx,
|
||||
{
|
||||
m_currentSelection = m_effectKeys[m_model.mapToSource( _idx ).row()];
|
||||
}
|
||||
if( m_currentSelection.desc )
|
||||
if( m_currentSelection.desc )
|
||||
{
|
||||
m_descriptionWidget = new QWidget;
|
||||
|
||||
QHBoxLayout *hbox = new QHBoxLayout( m_descriptionWidget );
|
||||
QHBoxLayout *hbox = new QHBoxLayout( m_descriptionWidget );
|
||||
|
||||
Plugin::Descriptor const & descriptor = *( m_currentSelection.desc );
|
||||
Plugin::Descriptor const & descriptor = *( m_currentSelection.desc );
|
||||
|
||||
if ( descriptor.logo )
|
||||
{
|
||||
QLabel *logoLabel = new QLabel( m_descriptionWidget );
|
||||
logoLabel->setPixmap( descriptor.logo->pixmap() );
|
||||
logoLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
const PixmapLoader* pixLoa = m_currentSelection.logo();
|
||||
if (pixLoa)
|
||||
{
|
||||
QLabel *logoLabel = new QLabel( m_descriptionWidget );
|
||||
logoLabel->setPixmap(pixLoa->pixmap());
|
||||
logoLabel->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
|
||||
hbox->addWidget( logoLabel );
|
||||
hbox->setAlignment( logoLabel, Qt::AlignTop);
|
||||
}
|
||||
hbox->addWidget( logoLabel );
|
||||
hbox->setAlignment( logoLabel, Qt::AlignTop);
|
||||
}
|
||||
|
||||
QWidget *textualInfoWidget = new QWidget( m_descriptionWidget );
|
||||
QWidget *textualInfoWidget = new QWidget( m_descriptionWidget );
|
||||
|
||||
hbox->addWidget(textualInfoWidget);
|
||||
hbox->addWidget(textualInfoWidget);
|
||||
|
||||
QVBoxLayout * textWidgetLayout = new QVBoxLayout( textualInfoWidget);
|
||||
textWidgetLayout->setMargin( 4 );
|
||||
textWidgetLayout->setSpacing( 0 );
|
||||
QVBoxLayout * textWidgetLayout = new QVBoxLayout( textualInfoWidget);
|
||||
textWidgetLayout->setMargin( 4 );
|
||||
textWidgetLayout->setSpacing( 0 );
|
||||
|
||||
if ( m_currentSelection.desc->subPluginFeatures )
|
||||
{
|
||||
QWidget *subWidget = new QWidget(textualInfoWidget);
|
||||
QVBoxLayout * subLayout = new QVBoxLayout( subWidget );
|
||||
subLayout->setMargin( 4 );
|
||||
subLayout->setSpacing( 0 );
|
||||
m_currentSelection.desc->subPluginFeatures->
|
||||
fillDescriptionWidget( subWidget, &m_currentSelection );
|
||||
for( QWidget * w : subWidget->findChildren<QWidget *>() )
|
||||
{
|
||||
if( w->parent() == subWidget )
|
||||
{
|
||||
subLayout->addWidget( w );
|
||||
}
|
||||
}
|
||||
if ( m_currentSelection.desc->subPluginFeatures )
|
||||
{
|
||||
QWidget *subWidget = new QWidget(textualInfoWidget);
|
||||
QVBoxLayout * subLayout = new QVBoxLayout( subWidget );
|
||||
subLayout->setMargin( 4 );
|
||||
subLayout->setSpacing( 0 );
|
||||
m_currentSelection.desc->subPluginFeatures->
|
||||
fillDescriptionWidget( subWidget, &m_currentSelection );
|
||||
for( QWidget * w : subWidget->findChildren<QWidget *>() )
|
||||
{
|
||||
if( w->parent() == subWidget )
|
||||
{
|
||||
subLayout->addWidget( w );
|
||||
}
|
||||
}
|
||||
|
||||
textWidgetLayout->addWidget(subWidget);
|
||||
}
|
||||
else
|
||||
{
|
||||
QLabel *label = new QLabel(m_descriptionWidget);
|
||||
QString labelText = "<p><b>" + tr("Name") + ":</b> " + QString::fromUtf8(descriptor.displayName) + "</p>";
|
||||
labelText += "<p><b>" + tr("Description") + ":</b> " + qApp->translate( "pluginBrowser", descriptor.description ) + "</p>";
|
||||
labelText += "<p><b>" + tr("Author") + ":</b> " + QString::fromUtf8(descriptor.author) + "</p>";
|
||||
textWidgetLayout->addWidget(subWidget);
|
||||
}
|
||||
else
|
||||
{
|
||||
QLabel *label = new QLabel(m_descriptionWidget);
|
||||
QString labelText = "<p><b>" + tr("Name") + ":</b> " + QString::fromUtf8(descriptor.displayName) + "</p>";
|
||||
labelText += "<p><b>" + tr("Description") + ":</b> " + qApp->translate( "pluginBrowser", descriptor.description ) + "</p>";
|
||||
labelText += "<p><b>" + tr("Author") + ":</b> " + QString::fromUtf8(descriptor.author) + "</p>";
|
||||
|
||||
label->setText(labelText);
|
||||
textWidgetLayout->addWidget(label);
|
||||
}
|
||||
label->setText(labelText);
|
||||
textWidgetLayout->addWidget(label);
|
||||
}
|
||||
|
||||
ui->scrollArea->setWidget( m_descriptionWidget );
|
||||
ui->scrollArea->setWidget( m_descriptionWidget );
|
||||
m_descriptionWidget->show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ void FileBrowser::reloadTree( void )
|
||||
|
||||
void FileBrowser::expandItems( QTreeWidgetItem * item )
|
||||
{
|
||||
int numChildren = item ? item->childCount() : m_fileBrowserTreeWidget->topLevelItemCount();
|
||||
int numChildren = item ? item->childCount() : m_fileBrowserTreeWidget->topLevelItemCount();
|
||||
for( int i = 0; i < numChildren; ++i )
|
||||
{
|
||||
QTreeWidgetItem * it = item ? item->child( i ) : m_fileBrowserTreeWidget->topLevelItem(i);
|
||||
@@ -241,7 +241,7 @@ void FileBrowser::addItems(const QString & path )
|
||||
Directory *dd = new Directory( cur_file, path,
|
||||
m_filter );
|
||||
m_fileBrowserTreeWidget->insertTopLevelItem( i,dd );
|
||||
dd->update();
|
||||
dd->update(); // add files to the directory
|
||||
orphan = false;
|
||||
break;
|
||||
}
|
||||
@@ -406,7 +406,7 @@ void FileBrowserTreeWidget::mousePressEvent(QMouseEvent * me )
|
||||
delete tf;
|
||||
}
|
||||
else if( ( f->extension ()== "xiz" || f->extension() == "sf2" || f->extension() == "sf3" || f->extension() == "gig" || f->extension() == "pat" ) &&
|
||||
! pluginFactory->pluginSupportingExtension(f->extension()).isNull() )
|
||||
! pluginFactory->pluginSupportingExtension(f->extension()).info.isNull() )
|
||||
{
|
||||
m_previewPlayHandle = new PresetPreviewPlayHandle( f->fullName(), f->handling() == FileItem::LoadByPlugin );
|
||||
}
|
||||
@@ -549,8 +549,9 @@ void FileBrowserTreeWidget::handleFile(FileItem * f, InstrumentTrack * it )
|
||||
if( i == NULL ||
|
||||
!i->descriptor()->supportsFileType( e ) )
|
||||
{
|
||||
i = it->loadInstrument(
|
||||
pluginFactory->pluginSupportingExtension(e).name() );
|
||||
PluginFactory::PluginInfoAndKey piakn =
|
||||
pluginFactory->pluginSupportingExtension(e);
|
||||
i = it->loadInstrument(piakn.info.name(), &piakn.key);
|
||||
}
|
||||
i->loadFile( f->fullName() );
|
||||
break;
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "Mixer.h"
|
||||
#include "gui_templates.h"
|
||||
#include "InstrumentTrack.h"
|
||||
#include "SampleTrack.h"
|
||||
#include "Song.h"
|
||||
#include "BBTrackContainer.h"
|
||||
|
||||
@@ -251,6 +252,12 @@ void FxMixerView::updateMaxChannelSelector()
|
||||
inst->effectChannelModel()->setRange(0,
|
||||
m_fxChannelViews.size()-1,1);
|
||||
}
|
||||
else if( trackList[i]->type() == Track::SampleTrack )
|
||||
{
|
||||
SampleTrack * strk = (SampleTrack *) trackList[i];
|
||||
strk->effectChannelModel()->setRange(0,
|
||||
m_fxChannelViews.size()-1,1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ void InstrumentView::setModel( Model * _model, bool )
|
||||
if( dynamic_cast<Instrument *>( _model ) != NULL )
|
||||
{
|
||||
ModelView::setModel( _model );
|
||||
instrumentTrackWindow()->setWindowIcon( model()->descriptor()->logo->pixmap() );
|
||||
instrumentTrackWindow()->setWindowIcon( model()->logo()->pixmap() );
|
||||
connect( model(), SIGNAL( destroyed( QObject * ) ), this, SLOT( close() ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,13 +24,16 @@
|
||||
|
||||
#include "PluginBrowser.h"
|
||||
|
||||
#include <QHeaderView>
|
||||
#include <QLabel>
|
||||
#include <QPainter>
|
||||
#include <QLineEdit>
|
||||
#include <QMouseEvent>
|
||||
#include <QScrollArea>
|
||||
#include <QPainter>
|
||||
#include <QStyleOption>
|
||||
#include <QTreeWidget>
|
||||
|
||||
#include "embed.h"
|
||||
#include "Engine.h"
|
||||
#include "templates.h"
|
||||
#include "gui_templates.h"
|
||||
#include "StringPairDrag.h"
|
||||
@@ -59,23 +62,91 @@ PluginBrowser::PluginBrowser( QWidget * _parent ) :
|
||||
m_view );
|
||||
hint->setWordWrap( true );
|
||||
|
||||
QScrollArea* scrollarea = new QScrollArea( m_view );
|
||||
PluginDescList* descList = new PluginDescList( m_view );
|
||||
scrollarea->setWidget(descList);
|
||||
scrollarea->setWidgetResizable(true);
|
||||
QLineEdit * searchBar = new QLineEdit( m_view );
|
||||
searchBar->setPlaceholderText( "Search" );
|
||||
searchBar->setMaxLength( 64 );
|
||||
searchBar->setClearButtonEnabled( true );
|
||||
|
||||
view_layout->addWidget(hint);
|
||||
view_layout->addWidget(scrollarea);
|
||||
m_descTree = new QTreeWidget( m_view );
|
||||
m_descTree->setColumnCount( 1 );
|
||||
m_descTree->header()->setVisible( false );
|
||||
m_descTree->setIndentation( 10 );
|
||||
m_descTree->setSelectionMode( QAbstractItemView::NoSelection );
|
||||
|
||||
connect( searchBar, SIGNAL( textEdited( const QString & ) ),
|
||||
this, SLOT( onFilterChanged( const QString & ) ) );
|
||||
|
||||
view_layout->addWidget( hint );
|
||||
view_layout->addWidget( searchBar );
|
||||
view_layout->addWidget( m_descTree );
|
||||
|
||||
// Add LMMS root to the tree
|
||||
m_lmmsRoot = new QTreeWidgetItem();
|
||||
m_lmmsRoot->setText( 0, "LMMS" );
|
||||
m_descTree->insertTopLevelItem( 0, m_lmmsRoot );
|
||||
m_lmmsRoot->setExpanded( true );
|
||||
|
||||
// Add LV2 root to the tree
|
||||
m_lv2Root = new QTreeWidgetItem();
|
||||
m_lv2Root->setText( 0, "LV2" );
|
||||
m_descTree->insertTopLevelItem( 1, m_lv2Root );
|
||||
|
||||
// Add plugins to the tree roots
|
||||
addPlugins();
|
||||
|
||||
// Resize
|
||||
m_descTree->header()->setSectionResizeMode( QHeaderView::ResizeToContents );
|
||||
|
||||
// Hide empty roots
|
||||
updateRootVisibilities();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PluginDescList::PluginDescList(QWidget *parent) :
|
||||
QWidget(parent)
|
||||
void PluginBrowser::updateRootVisibility( int rootIndex )
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout(this);
|
||||
QTreeWidgetItem * root = m_descTree->topLevelItem( rootIndex );
|
||||
root->setHidden( !root->childCount() );
|
||||
}
|
||||
|
||||
|
||||
void PluginBrowser::updateRootVisibilities()
|
||||
{
|
||||
int rootCount = m_descTree->topLevelItemCount();
|
||||
for (int rootIndex = 0; rootIndex < rootCount; ++rootIndex)
|
||||
{
|
||||
updateRootVisibility( rootIndex );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PluginBrowser::onFilterChanged( const QString & filter )
|
||||
{
|
||||
int rootCount = m_descTree->topLevelItemCount();
|
||||
for (int rootIndex = 0; rootIndex < rootCount; ++rootIndex)
|
||||
{
|
||||
QTreeWidgetItem * root = m_descTree->topLevelItem( rootIndex );
|
||||
|
||||
int itemCount = root->childCount();
|
||||
for (int itemIndex = 0; itemIndex < itemCount; ++itemIndex)
|
||||
{
|
||||
QTreeWidgetItem * item = root->child( itemIndex );
|
||||
PluginDescWidget * descWidget = static_cast<PluginDescWidget *>
|
||||
(m_descTree->itemWidget( item, 0));
|
||||
if (descWidget->name().contains(filter, Qt::CaseInsensitive))
|
||||
{
|
||||
item->setHidden( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
item->setHidden( true );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PluginBrowser::addPlugins()
|
||||
{
|
||||
QList<Plugin::Descriptor*> descs = pluginFactory->descriptors(Plugin::Instrument);
|
||||
std::sort(
|
||||
descs.begin(),
|
||||
@@ -85,37 +156,71 @@ PluginDescList::PluginDescList(QWidget *parent) :
|
||||
return qstricmp( d1->displayName, d2->displayName ) < 0 ? true : false;
|
||||
}
|
||||
);
|
||||
for (const Plugin::Descriptor* desc : descs)
|
||||
|
||||
typedef Plugin::Descriptor::SubPluginFeatures::KeyList PluginKeyList;
|
||||
typedef Plugin::Descriptor::SubPluginFeatures::Key PluginKey;
|
||||
PluginKeyList subPluginKeys, pluginKeys;
|
||||
|
||||
for (const Plugin::Descriptor* desc: descs)
|
||||
{
|
||||
PluginDescWidget* p = new PluginDescWidget( *desc, this );
|
||||
p->show();
|
||||
layout->addWidget(p);
|
||||
if ( desc->subPluginFeatures )
|
||||
{
|
||||
desc->subPluginFeatures->listSubPluginKeys(
|
||||
desc,
|
||||
subPluginKeys );
|
||||
}
|
||||
else
|
||||
{
|
||||
pluginKeys << PluginKey( desc, desc->name );
|
||||
}
|
||||
}
|
||||
|
||||
setLayout(layout);
|
||||
layout->addStretch();
|
||||
pluginKeys += subPluginKeys;
|
||||
|
||||
for (const PluginKey& key : pluginKeys)
|
||||
{
|
||||
QTreeWidgetItem * item = new QTreeWidgetItem();
|
||||
if ( key.desc->name == QStringLiteral("lv2instrument") )
|
||||
{
|
||||
m_lv2Root->addChild( item );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_lmmsRoot->addChild( item );
|
||||
}
|
||||
PluginDescWidget* p = new PluginDescWidget( key, m_descTree );
|
||||
m_descTree->setItemWidget( item, 0, p );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
PluginDescWidget::PluginDescWidget( const Plugin::Descriptor & _pd,
|
||||
PluginDescWidget::PluginDescWidget(const PluginKey &_pk,
|
||||
QWidget * _parent ) :
|
||||
QWidget( _parent ),
|
||||
m_pluginDescriptor( _pd ),
|
||||
m_logo( _pd.logo->pixmap() ),
|
||||
m_pluginKey( _pk ),
|
||||
m_logo( _pk.logo()->pixmap() ),
|
||||
m_mouseOver( false )
|
||||
{
|
||||
setFixedHeight( DEFAULT_HEIGHT );
|
||||
setMouseTracking( true );
|
||||
setCursor( Qt::PointingHandCursor );
|
||||
setToolTip(_pd.description);
|
||||
setToolTip(_pk.description());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void PluginDescWidget::paintEvent( QPaintEvent * e )
|
||||
QString PluginDescWidget::name() const
|
||||
{
|
||||
return m_pluginKey.displayName();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void PluginDescWidget::paintEvent( QPaintEvent * )
|
||||
{
|
||||
|
||||
QPainter p( this );
|
||||
@@ -140,8 +245,7 @@ void PluginDescWidget::paintEvent( QPaintEvent * e )
|
||||
}
|
||||
|
||||
p.setFont( f );
|
||||
p.drawText( 10 + logo_size.width(), 15,
|
||||
m_pluginDescriptor.displayName );
|
||||
p.drawText( 10 + logo_size.width(), 15, m_pluginKey.displayName());
|
||||
}
|
||||
|
||||
|
||||
@@ -169,10 +273,11 @@ void PluginDescWidget::leaveEvent( QEvent * _e )
|
||||
|
||||
void PluginDescWidget::mousePressEvent( QMouseEvent * _me )
|
||||
{
|
||||
if( _me->button() == Qt::LeftButton )
|
||||
if ( _me->button() == Qt::LeftButton )
|
||||
{
|
||||
new StringPairDrag( "instrument", m_pluginDescriptor.name,
|
||||
m_logo, this );
|
||||
Engine::setDndPluginKey(&m_pluginKey);
|
||||
new StringPairDrag("instrument",
|
||||
QString::fromUtf8(m_pluginKey.desc->name), m_logo, this);
|
||||
leaveEvent( _me );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,7 +139,9 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
|
||||
"displaywaveform").toInt() ),
|
||||
m_disableAutoQuit(ConfigManager::inst()->value( "ui",
|
||||
"disableautoquit", "1" ).toInt() ),
|
||||
m_vstEmbedMethod( ConfigManager::inst()->vstEmbedMethod() )
|
||||
m_vstEmbedMethod( ConfigManager::inst()->vstEmbedMethod() ),
|
||||
m_vstAlwaysOnTop( ConfigManager::inst()->value( "ui",
|
||||
"vstalwaysontop" ).toInt() )
|
||||
{
|
||||
setWindowIcon( embed::getIconPixmap( "setup_general" ) );
|
||||
setWindowTitle( tr( "Setup LMMS" ) );
|
||||
@@ -259,7 +261,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
|
||||
}
|
||||
|
||||
TabWidget* embed_tw = new TabWidget( tr( "PLUGIN EMBEDDING" ), general);
|
||||
embed_tw->setFixedHeight( 48 );
|
||||
embed_tw->setFixedHeight( 66 );
|
||||
m_vstEmbedComboBox = new QComboBox( embed_tw );
|
||||
m_vstEmbedComboBox->move( XDelta, YDelta );
|
||||
|
||||
@@ -278,6 +280,17 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
|
||||
m_vstEmbedComboBox->addItem( tr( "Embed using XEmbed protocol" ), "xembed" );
|
||||
}
|
||||
m_vstEmbedComboBox->setCurrentIndex( m_vstEmbedComboBox->findData( m_vstEmbedMethod ) );
|
||||
connect( m_vstEmbedComboBox, SIGNAL( currentIndexChanged( int ) ),
|
||||
this, SLOT( vstEmbedMethodChanged() ) );
|
||||
|
||||
m_vstAlwaysOnTopCheckBox = new LedCheckBox(
|
||||
tr( "Keep plugin windows on top when not embedded" ),
|
||||
embed_tw );
|
||||
m_vstAlwaysOnTopCheckBox->move( 20, 44 );
|
||||
m_vstAlwaysOnTopCheckBox->setChecked( m_vstAlwaysOnTop );
|
||||
m_vstAlwaysOnTopCheckBox->setVisible( m_vstEmbedMethod == "none" );
|
||||
connect( m_vstAlwaysOnTopCheckBox, SIGNAL( toggled( bool ) ),
|
||||
this, SLOT( toggleVSTAlwaysOnTop( bool ) ) );
|
||||
|
||||
TabWidget * lang_tw = new TabWidget( tr( "LANGUAGE" ), general );
|
||||
lang_tw->setFixedHeight( 48 );
|
||||
@@ -427,7 +440,7 @@ SetupDialog::SetupDialog( ConfigTabs _tab_to_open ) :
|
||||
#endif
|
||||
addPathEntry("Themes directory", m_artworkDir,
|
||||
SLOT(setArtworkDir(const QString &)),
|
||||
SLOT(openArtwortDir()),
|
||||
SLOT(openArtworkDir()),
|
||||
m_adLineEdit, pathSelectors);
|
||||
pathSelectorLayout->addStretch();
|
||||
addPathEntry("Background artwork", m_backgroundArtwork,
|
||||
@@ -854,7 +867,9 @@ void SetupDialog::accept()
|
||||
QString::number( m_disableAutoQuit ) );
|
||||
ConfigManager::inst()->setValue( "app", "language", m_lang );
|
||||
ConfigManager::inst()->setValue( "ui", "vstembedmethod",
|
||||
m_vstEmbedComboBox->currentData().toString() );
|
||||
m_vstEmbedMethod );
|
||||
ConfigManager::inst()->setValue( "ui", "vstalwaysontop",
|
||||
QString::number( m_vstAlwaysOnTop ) );
|
||||
|
||||
|
||||
ConfigManager::inst()->setWorkingDir(QDir::fromNativeSeparators(m_workingDir));
|
||||
@@ -1057,6 +1072,20 @@ void SetupDialog::toggleOneInstrumentTrackWindow( bool _enabled )
|
||||
m_oneInstrumentTrackWindow = _enabled;
|
||||
}
|
||||
|
||||
|
||||
void SetupDialog::vstEmbedMethodChanged()
|
||||
{
|
||||
m_vstEmbedMethod = m_vstEmbedComboBox->currentData().toString();
|
||||
m_vstAlwaysOnTopCheckBox->setVisible( m_vstEmbedMethod == "none" );
|
||||
}
|
||||
|
||||
|
||||
void SetupDialog::toggleVSTAlwaysOnTop( bool en )
|
||||
{
|
||||
m_vstAlwaysOnTop = en;
|
||||
}
|
||||
|
||||
|
||||
void SetupDialog::setLanguage( int lang )
|
||||
{
|
||||
m_lang = m_languages[lang];
|
||||
|
||||