diff --git a/.travis/linux..install.sh b/.travis/linux..install.sh
index 95c073284..3563257cb 100644
--- a/.travis/linux..install.sh
+++ b/.travis/linux..install.sh
@@ -3,4 +3,4 @@ sudo apt-get install -y pkg-config \
libasound2-dev libpulse-dev libmagic-dev libx11-dev libxft-dev \
libgl1-mesa-dev libglu1-mesa-dev \
liblo-static fftw3-static mxml-static zlib-static ntk-static \
- fluidsynth-static linuxsampler-static
+ fluidsynth-static
diff --git a/.travis/linux.win32.install.sh b/.travis/linux.win32.install.sh
index 81bc4fea7..00fdcc1c6 100644
--- a/.travis/linux.win32.install.sh
+++ b/.travis/linux.win32.install.sh
@@ -3,4 +3,4 @@ sudo apt-get install -y pkg-config \
# mingw32-x-gcc mingw32-x-pkgconfig
# mingw32-x-liblo mingw32-x-fftw3 mingw32-x-mxml mingw32-x-zlib
-# mingw32-x-fluidsynth mingw32-x-linuxsampler
+# mingw32-x-fluidsynth
diff --git a/.travis/linux.win64.install.sh b/.travis/linux.win64.install.sh
index fe4cc4580..1bd477759 100644
--- a/.travis/linux.win64.install.sh
+++ b/.travis/linux.win64.install.sh
@@ -3,4 +3,4 @@ sudo apt-get install -y pkg-config \
# mingw64-x-gcc mingw64-x-pkgconfig
# mingw64-x-liblo mingw64-x-fftw3 mingw64-x-mxml mingw64-x-zlib
-# mingw64-x-fluidsynth mingw64-x-linuxsampler
+# mingw64-x-fluidsynth
diff --git a/INSTALL.md b/INSTALL.md
index 51e634b8f..ade166396 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -9,7 +9,7 @@ $ [sudo] make install
You can run it without installing, by using instead:
```
$ make
-$ ./source/carla`
+$ ./source/carla
```
Packagers can make use of the `PREFIX` and `DESTDIR` variable during install, like this:
@@ -19,11 +19,9 @@ $ make install PREFIX=/usr DESTDIR=./test-dir
## BUILD DEPENDENCIES
-The required build dependencies are: *(devel packages of these)*
+There are no required build dependencies.
- - PyQt4/5 (python3 version)
-
-Optional for extra engine features:
+But if you want the frontend (which is likely), you will need PyQt4/5 (python3 version)
- libmagic (for auto-detection of binary types, needed for plugin-bridges)
- liblo (for OSC support)
@@ -32,7 +30,7 @@ Optional for extra Linux-only engine features:
- ALSA
- PulseAudio
- - X11 (internal/LV2/VST2 X11 UI support)
+ - X11 (internal/LV2/VST X11 UI support)
Optional for extended LV2 UIs support: (Linux only)
@@ -43,20 +41,11 @@ Optional for extended LV2 UIs support: (Linux only)
Optional for extra samplers support:
- - FluidSynth (SF2)
- - LinuxSampler (GIG and SFZ)
-
-Optional for extra native plugins:
- - fftw3
- - mxml
- - zlib
- - NTK
- - OpenGL
- - ProjectM
+ - FluidSynth (SF2/3)
-Optional but recommended:
+Optional for extra LADSPA plugin information:
- - python3-rdflib (for LADSPA-RDF support)
+ - python3-rdflib
You can use:
@@ -64,3 +53,42 @@ You can use:
$ make features
```
To find out which dependencies are missing.
+
+
+Under debian based systems, you can use this command to install all dependencies:
+```
+sudo apt install python3-pyqt5.qtsvg python3-rdflib pyqt5-dev-tools \
+ libmagic-dev liblo-dev libasound2-dev libpulse-dev libx11-dev \
+ libgtk2.0-dev libgtk-3-dev libqt4-dev qtbase5-dev libfluidsynth-dev
+```
+
+## BUILD BRIDGES
+
+Carla can make use of plugin bridges to load additional plugin types.
+
+### 32bit plugins on 64bit systems
+
+Simply run `make posix32` after a regular Carla build, and install or run Carla locally.
+This feature requires a compiler capable of building 32bit binaries.
+
+### JACK Applications inside Carla
+
+This is built by default on Linux systems.
+Requires LD_PRELOAD support by the OS and the GCC compiler.
+Does not work with clang. (if you discover why, please let me know!)
+
+### Windows plugins (via Wine)
+
+Requires a mingw compiler, and winegcc.
+
+First, we build the Windows bridges using mingw, like this: (adjust as needed)
+```
+make win32 CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++
+make win64 CC=x86_64-w64-mingw32-gcc CXX=x86_64-w64-mingw32-g++
+```
+
+To finalize, we build the wine<->native bridges using winegcc:
+```
+make wine32
+make wine64
+```
diff --git a/data/carla-single b/data/carla-single
index b5bf58a2f..b44398b72 100755
--- a/data/carla-single
+++ b/data/carla-single
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
# Script to start carla plugin bridges
-# Copyright (C) 2015 Filipe Coelho
+# Copyright (C) 2015-2018 Filipe Coelho
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
@@ -210,7 +210,6 @@ LADSPA_PATH = os.getenv("LADSPA_PATH")
DSSI_PATH = os.getenv("DSSI_PATH")
LV2_PATH = os.getenv("LV2_PATH")
VST2_PATH = os.getenv("VST_PATH")
-GIG_PATH = os.getenv("GIG_PATH")
SF2_PATH = os.getenv("SF2_PATH")
SFZ_PATH = os.getenv("SFZ_PATH")
@@ -218,7 +217,6 @@ if LADSPA_PATH is not None: os.environ["ENGINE_OPTION_PLUGIN_PATH_LADSPA"] = LAD
if DSSI_PATH is not None: os.environ["ENGINE_OPTION_PLUGIN_PATH_DSSI"] = DSSI_PATH
if LV2_PATH is not None: os.environ["ENGINE_OPTION_PLUGIN_PATH_LV2"] = LV2_PATH
if VST2_PATH is not None: os.environ["ENGINE_OPTION_PLUGIN_PATH_VST2"] = VST2_PATH
-if GIG_PATH is not None: os.environ["ENGINE_OPTION_PLUGIN_PATH_GIG"] = GIG_PATH
if SF2_PATH is not None: os.environ["ENGINE_OPTION_PLUGIN_PATH_SF2"] = SF2_PATH
if SFZ_PATH is not None: os.environ["ENGINE_OPTION_PLUGIN_PATH_SFZ"] = SFZ_PATH
diff --git a/data/linux/README b/data/linux/README
index a99d1da7f..ba8102746 100644
--- a/data/linux/README
+++ b/data/linux/README
@@ -10,7 +10,7 @@ Features
---------
* LADSPA, DSSI, LV2 and VST plugin formats
-* GIG, SF2 and SFZ sound banks
+* SF2/3 and SFZ sound banks
* Internal audio and midi file player
* Automation of plugin parameters via MIDI CC
* Remote control over OSC
diff --git a/data/linux/build-deps.sh b/data/linux/build-deps.sh
index 59c2652f0..8344c11b8 100755
--- a/data/linux/build-deps.sh
+++ b/data/linux/build-deps.sh
@@ -28,12 +28,10 @@ rm -rf file-*
rm -rf flac-*
rm -rf fltk-*
rm -rf fluidsynth-*
-rm -rf libgig-*
rm -rf liblo-*
rm -rf libogg-*
rm -rf libsndfile-*
rm -rf libvorbis-*
-rm -rf linuxsampler-*
rm -rf pkg-config-*
rm -rf zlib-*
@@ -208,58 +206,6 @@ if [ ! -f libsndfile-${LIBSNDFILE_VERSION}/build-done ]; then
cd ..
fi
-# ---------------------------------------------------------------------------------------------------------------------
-# libgig
-
-if [ ! -d libgig-${LIBGIG_VERSION} ]; then
- wget http://download.linuxsampler.org/packages/libgig-${LIBGIG_VERSION}.tar.bz2
- tar -xf libgig-${LIBGIG_VERSION}.tar.bz2
-fi
-
-if [ ! -f libgig-${LIBGIG_VERSION}/build-done ]; then
- cd libgig-${LIBGIG_VERSION}
- if [ ! -f patched ]; then
- patch -p1 -i ../patches/libgig_fix-build.patch
- touch patched
- fi
- ./configure --enable-static --disable-shared --prefix=${PREFIX}
- make ${MAKE_ARGS}
- make install
- touch build-done
- cd ..
-fi
-
-# ---------------------------------------------------------------------------------------------------------------------
-# linuxsampler
-
-if [ ! -d linuxsampler-${LINUXSAMPLER_VERSION} ]; then
- wget http://download.linuxsampler.org/packages/linuxsampler-${LINUXSAMPLER_VERSION}.tar.bz2
- tar -xf linuxsampler-${LINUXSAMPLER_VERSION}.tar.bz2
-fi
-
-if [ ! -f linuxsampler-${LINUXSAMPLER_VERSION}/build-done ]; then
- cd linuxsampler-${LINUXSAMPLER_VERSION}
- if [ ! -f patched ]; then
- patch -p1 -i ../patches/linuxsampler_allow-no-drivers-build.patch
- patch -p1 -i ../patches/linuxsampler_disable-ladspa-fx.patch
- touch patched
- fi
- rm -f configure
- make -f Makefile.svn configure
- ./configure \
- --enable-static --disable-shared --prefix=${PREFIX} \
- --enable-signed-triang-algo=diharmonic --enable-unsigned-triang-algo=diharmonic --enable-subfragment-size=8 \
- --disable-alsa-driver --disable-arts-driver --disable-jack-driver \
- --disable-asio-driver --disable-midishare-driver --disable-mmemidi-driver \
- --disable-coreaudio-driver --disable-coremidi-driver \
- --disable-instruments-db --disable-sf2-engine
- make ${MAKE_ARGS}
- make install
- sed -i -e "s|-llinuxsampler|-llinuxsampler -L${PREFIX}/lib/libgig -lgig -lsndfile -lFLAC -lvorbisenc -lvorbis -logg -lpthread -lm|" ${PREFIX}/lib/pkgconfig/linuxsampler.pc
- touch build-done
- cd ..
-fi
-
# ---------------------------------------------------------------------------------------------------------------------
# glib
diff --git a/data/linux/common.env b/data/linux/common.env
index 75efc49c9..984bba7ee 100644
--- a/data/linux/common.env
+++ b/data/linux/common.env
@@ -8,8 +8,6 @@ LIBOGG_VERSION=1.3.3
LIBVORBIS_VERSION=1.3.5
FLAC_VERSION=1.3.2
LIBSNDFILE_VERSION=1.0.28
-LIBGIG_VERSION=4.0.0
-LINUXSAMPLER_VERSION=2.0.0
FLUIDSYNTH_VERSION=1.1.6
MXML_VERSION=2.11
FFTW3_VERSION=3.3.7
diff --git a/data/linux/patches/libgig_fix-build.patch b/data/linux/patches/libgig_fix-build.patch
deleted file mode 100644
index 6ba32959e..000000000
--- a/data/linux/patches/libgig_fix-build.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-diff --git a/src/DLS.h b/src/DLS.h
-index 065bfe6..6c9d76c 100644
---- a/src/DLS.h
-+++ b/src/DLS.h
-@@ -515,10 +515,10 @@ namespace DLS {
- virtual void Save(const String& Path, progress_t* pProgress = NULL);
- virtual void Save(progress_t* pProgress = NULL);
- virtual ~File();
-- protected:
- typedef std::list SampleList;
- typedef std::list InstrumentList;
-
-+ protected:
- RIFF::File* pRIFF;
- std::list ExtensionFiles;
- SampleList* pSamples;
-diff --git a/src/gig.cpp b/src/gig.cpp
-index 6a24f16..902e1ae 100644
---- a/src/gig.cpp
-+++ b/src/gig.cpp
-@@ -4181,7 +4181,7 @@ namespace {
- * @param pGroup - script's new group
- */
- void Script::SetGroup(ScriptGroup* pGroup) {
-- if (this->pGroup = pGroup) return;
-+ if (this->pGroup == pGroup) return;
- if (pChunk)
- pChunk->GetParent()->MoveSubChunk(pChunk, pGroup->pList);
- this->pGroup = pGroup;
diff --git a/data/linux/patches/linuxsampler_allow-no-drivers-build.patch b/data/linux/patches/linuxsampler_allow-no-drivers-build.patch
deleted file mode 100644
index 12a7f3875..000000000
--- a/data/linux/patches/linuxsampler_allow-no-drivers-build.patch
+++ /dev/null
@@ -1,24 +0,0 @@
---- linuxsampler-static-1.0.0+svn2356.orig/configure.ac
-+++ linuxsampler-static-1.0.0+svn2356/configure.ac
-@@ -556,21 +556,6 @@ if test "x$MAC_PLUGIN_INSTALL_DIR" = "x"
- fi
- AC_SUBST(MAC_PLUGIN_INSTALL_DIR)
-
--# have we found at least one MIDI input and one audio output driver ?
--if test "$have_midi_input_driver" = "false"; then
-- echo "No supported MIDI input system found!"
-- echo "Sorry, LinuxSampler only supports the following MIDI drivers at the moment:"
-- echo "ALSA, JACK, MIDIShare, CoreMIDI, MME."
-- echo "If you think you have one of those available on your system, make sure you"
-- echo "also have the respective development (header) files installed."
-- exit -1;
--fi
--if test "$have_audio_output_driver" = "false"; then
-- echo "No supported audio output system found!"
-- echo "Sorry, LinuxSampler only supports ALSA, JACK, ARTS and ASIO as audio output"
-- echo "driver at the moment!"
-- exit -1;
--fi
-
-
-
diff --git a/data/linux/patches/linuxsampler_disable-ladspa-fx.patch b/data/linux/patches/linuxsampler_disable-ladspa-fx.patch
deleted file mode 100644
index 5bc4e9816..000000000
--- a/data/linux/patches/linuxsampler_disable-ladspa-fx.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- linuxsampler-static-1.0.0+svn2497.orig/src/effects/LadspaEffect.cpp
-+++ linuxsampler-static-1.0.0+svn2497/src/effects/LadspaEffect.cpp
-@@ -374,6 +374,7 @@ static String defaultLadspaDir() {
-
- std::vector LadspaEffect::AvailableEffects() {
- std::vector v; // will be filled in callback function _foundLadspaDll()
-+ return v;
-
- char* pcLadspaPath = getenv("LADSPA_PATH");
- String ladspaDir = pcLadspaPath ? pcLadspaPath : defaultLadspaDir();
diff --git a/data/macos/README b/data/macos/README
index f7b5bd92d..d5687f6e2 100644
--- a/data/macos/README
+++ b/data/macos/README
@@ -10,7 +10,7 @@ Features
---------
* LADSPA, DSSI, LV2 and VST plugin formats
-* GIG, SF2 and SFZ sound banks
+* SF2/3 and SFZ sound banks
* Internal audio and midi file player
* Automation of plugin parameters via MIDI CC
* Remote control over OSC
diff --git a/data/macos/build-deps.sh b/data/macos/build-deps.sh
index 22ef35995..a0dd1d0ab 100755
--- a/data/macos/build-deps.sh
+++ b/data/macos/build-deps.sh
@@ -40,12 +40,10 @@ rm -rf fftw-*
rm -rf gettext-*
rm -rf glib-*
rm -rf libffi-*
-rm -rf libgig-*
rm -rf liblo-*
rm -rf libogg-*
rm -rf libsndfile-*
rm -rf libvorbis-*
-rm -rf linuxsampler-*
rm -rf mxml-*
rm -rf pkg-config-*
rm -rf pyliblo-*
@@ -229,64 +227,6 @@ if [ ! -f libsndfile-${LIBSNDFILE_VERSION}/build-done ]; then
cd ..
fi
-# ---------------------------------------------------------------------------------------------------------------------
-# libgig
-
-if [ ! -d libgig-${LIBGIG_VERSION} ]; then
- curl -O http://download.linuxsampler.org/packages/libgig-${LIBGIG_VERSION}.tar.bz2
- tar -xf libgig-${LIBGIG_VERSION}.tar.bz2
-fi
-
-if [ ! -f libgig-${LIBGIG_VERSION}/build-done ]; then
- cd libgig-${LIBGIG_VERSION}
- if [ ! -f patched ]; then
- patch -p1 -i ../patches/libgig_fix-build.patch
- touch patched
- fi
- ./configure --enable-static --disable-shared --prefix=${PREFIX}
- make ${MAKE_ARGS}
- make install
- touch build-done
- cd ..
-fi
-
-# ---------------------------------------------------------------------------------------------------------------------
-# linuxsampler
-
-if [ ! -d linuxsampler-${LINUXSAMPLER_VERSION} ]; then
- curl -O http://download.linuxsampler.org/packages/linuxsampler-${LINUXSAMPLER_VERSION}.tar.bz2
- tar -xf linuxsampler-${LINUXSAMPLER_VERSION}.tar.bz2
-fi
-
-if [ ! -f linuxsampler-${LINUXSAMPLER_VERSION}/build-done ]; then
- cd linuxsampler-${LINUXSAMPLER_VERSION}
- if [ ! -f patched ]; then
- patch -p1 -i ../patches/linuxsampler_allow-no-drivers-build.patch
- patch -p1 -i ../patches/linuxsampler_disable-ladspa-fx.patch
- sed -i -e "s|HAVE_AU|HAVE_VST|" src/hostplugins/Makefile.am
- touch patched
- fi
- env PATH=/opt/local/bin:$PATH /opt/local/bin/aclocal -I /opt/local/share/aclocal
- env PATH=/opt/local/bin:$PATH /opt/local/bin/glibtoolize --force --copy
- env PATH=/opt/local/bin:$PATH /opt/local/bin/autoheader
- env PATH=/opt/local/bin:$PATH /opt/local/bin/automake --add-missing --copy
- env PATH=/opt/local/bin:$PATH /opt/local/bin/autoconf
- env PATH=/opt/local/bin:$PATH ./configure \
- --enable-static --disable-shared --prefix=${PREFIX} \
- --enable-signed-triang-algo=diharmonic --enable-unsigned-triang-algo=diharmonic --enable-subfragment-size=8 \
- --disable-alsa-driver --disable-arts-driver --disable-jack-driver \
- --disable-asio-driver --disable-midishare-driver --disable-mmemidi-driver \
- --disable-coreaudio-driver --disable-coremidi-driver \
- --disable-instruments-db --disable-sf2-engine
- env PATH=/opt/local/bin:$PATH ./scripts/generate_instrument_script_parser.sh
- sed -i -e "s/bison (GNU Bison) //" config.h
- env PATH=/opt/local/bin:$PATH make ${MAKE_ARGS}
- make install
- sed -i -e "s|-llinuxsampler|-llinuxsampler -L${PREFIX}/lib/libgig -lgig -lsndfile -lFLAC -lvorbisenc -lvorbis -logg -lpthread -lm|" ${PREFIX}/lib/pkgconfig/linuxsampler.pc
- touch build-done
- cd ..
-fi
-
# ---------------------------------------------------------------------------------------------------------------------
# libffi
diff --git a/data/macos/common.env b/data/macos/common.env
index 11f27dfb2..6be17247a 100644
--- a/data/macos/common.env
+++ b/data/macos/common.env
@@ -8,8 +8,6 @@ LIBOGG_VERSION=1.3.3
LIBVORBIS_VERSION=1.3.5
FLAC_VERSION=1.3.2
LIBSNDFILE_VERSION=1.0.28
-LIBGIG_VERSION=4.0.0
-LINUXSAMPLER_VERSION=2.0.0
LIBFFI_VERSION=3.2.1
GETTEXT_VERSION=0.18.3.2
GLIB_VERSION=2.44.1
diff --git a/data/macos/patches/libgig_fix-build.patch b/data/macos/patches/libgig_fix-build.patch
deleted file mode 100644
index 6ba32959e..000000000
--- a/data/macos/patches/libgig_fix-build.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-diff --git a/src/DLS.h b/src/DLS.h
-index 065bfe6..6c9d76c 100644
---- a/src/DLS.h
-+++ b/src/DLS.h
-@@ -515,10 +515,10 @@ namespace DLS {
- virtual void Save(const String& Path, progress_t* pProgress = NULL);
- virtual void Save(progress_t* pProgress = NULL);
- virtual ~File();
-- protected:
- typedef std::list SampleList;
- typedef std::list InstrumentList;
-
-+ protected:
- RIFF::File* pRIFF;
- std::list ExtensionFiles;
- SampleList* pSamples;
-diff --git a/src/gig.cpp b/src/gig.cpp
-index 6a24f16..902e1ae 100644
---- a/src/gig.cpp
-+++ b/src/gig.cpp
-@@ -4181,7 +4181,7 @@ namespace {
- * @param pGroup - script's new group
- */
- void Script::SetGroup(ScriptGroup* pGroup) {
-- if (this->pGroup = pGroup) return;
-+ if (this->pGroup == pGroup) return;
- if (pChunk)
- pChunk->GetParent()->MoveSubChunk(pChunk, pGroup->pList);
- this->pGroup = pGroup;
diff --git a/data/macos/patches/linuxsampler_allow-no-drivers-build.patch b/data/macos/patches/linuxsampler_allow-no-drivers-build.patch
deleted file mode 100644
index 12a7f3875..000000000
--- a/data/macos/patches/linuxsampler_allow-no-drivers-build.patch
+++ /dev/null
@@ -1,24 +0,0 @@
---- linuxsampler-static-1.0.0+svn2356.orig/configure.ac
-+++ linuxsampler-static-1.0.0+svn2356/configure.ac
-@@ -556,21 +556,6 @@ if test "x$MAC_PLUGIN_INSTALL_DIR" = "x"
- fi
- AC_SUBST(MAC_PLUGIN_INSTALL_DIR)
-
--# have we found at least one MIDI input and one audio output driver ?
--if test "$have_midi_input_driver" = "false"; then
-- echo "No supported MIDI input system found!"
-- echo "Sorry, LinuxSampler only supports the following MIDI drivers at the moment:"
-- echo "ALSA, JACK, MIDIShare, CoreMIDI, MME."
-- echo "If you think you have one of those available on your system, make sure you"
-- echo "also have the respective development (header) files installed."
-- exit -1;
--fi
--if test "$have_audio_output_driver" = "false"; then
-- echo "No supported audio output system found!"
-- echo "Sorry, LinuxSampler only supports ALSA, JACK, ARTS and ASIO as audio output"
-- echo "driver at the moment!"
-- exit -1;
--fi
-
-
-
diff --git a/data/macos/patches/linuxsampler_disable-ladspa-fx.patch b/data/macos/patches/linuxsampler_disable-ladspa-fx.patch
deleted file mode 100644
index 5bc4e9816..000000000
--- a/data/macos/patches/linuxsampler_disable-ladspa-fx.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- linuxsampler-static-1.0.0+svn2497.orig/src/effects/LadspaEffect.cpp
-+++ linuxsampler-static-1.0.0+svn2497/src/effects/LadspaEffect.cpp
-@@ -374,6 +374,7 @@ static String defaultLadspaDir() {
-
- std::vector LadspaEffect::AvailableEffects() {
- std::vector v; // will be filled in callback function _foundLadspaDll()
-+ return v;
-
- char* pcLadspaPath = getenv("LADSPA_PATH");
- String ladspaDir = pcLadspaPath ? pcLadspaPath : defaultLadspaDir();
diff --git a/data/windows/README.txt b/data/windows/README.txt
index 757fced7c..8c7be46f0 100644
--- a/data/windows/README.txt
+++ b/data/windows/README.txt
@@ -10,7 +10,7 @@ Features
---------
* LADSPA, DSSI, LV2 and VST plugin formats
-* GIG, SF2 and SFZ sound banks
+* SF2/3 and SFZ sound banks
* Internal audio and midi file player
* Automation of plugin parameters via MIDI CC
* Remote control over OSC
diff --git a/data/windows/build-deps.sh b/data/windows/build-deps.sh
index 0c8f3c430..b4fc62255 100755
--- a/data/windows/build-deps.sh
+++ b/data/windows/build-deps.sh
@@ -31,12 +31,10 @@ cleanup_pkgs()
rm -rf flac-*
rm -rf fluidsynth-*
rm -rf glib-*
-rm -rf libgig-*
rm -rf liblo-*
rm -rf libogg-*
rm -rf libsndfile-*
rm -rf libvorbis-*
-rm -rf linuxsampler-*
rm -rf pkg-config-*
rm -rf zlib-*
@@ -245,61 +243,6 @@ if [ ! -f libsndfile-${LIBSNDFILE_VERSION}/build-done ]; then
cd ..
fi
-# ---------------------------------------------------------------------------------------------------------------------
-# libgig
-
-if [ ! -d libgig-${LIBGIG_VERSION} ]; then
- wget -c http://download.linuxsampler.org/packages/libgig-${LIBGIG_VERSION}.tar.bz2
- tar -xf libgig-${LIBGIG_VERSION}.tar.bz2
-fi
-
-if [ ! -f libgig-${LIBGIG_VERSION}/build-done ]; then
- cd libgig-${LIBGIG_VERSION}
- if [ ! -f patched ]; then
- patch -p1 -i ../patches/libgig_fix-build.patch
- touch patched
- fi
- ./configure --enable-static --disable-shared --prefix=${PREFIX} \
- --target=${MINGW_PREFIX} --host=${MINGW_PREFIX} --build=${HOST_ARCH}
- make ${MAKE_ARGS}
- make install
- touch build-done
- cd ..
-fi
-
-# ---------------------------------------------------------------------------------------------------------------------
-# linuxsampler
-
-if [ ! -d linuxsampler-${LINUXSAMPLER_VERSION} ]; then
- wget -c http://download.linuxsampler.org/packages/linuxsampler-${LINUXSAMPLER_VERSION}.tar.bz2
- tar -xf linuxsampler-${LINUXSAMPLER_VERSION}.tar.bz2
-fi
-
-if [ ! -f linuxsampler-${LINUXSAMPLER_VERSION}/build-done ]; then
- cd linuxsampler-${LINUXSAMPLER_VERSION}
- if [ ! -f patched ]; then
- patch -p1 -i ../patches/linuxsampler_allow-no-drivers-build.patch
- patch -p1 -i ../patches/linuxsampler_disable-ladspa-fx.patch
- sed -i -e "s|HAVE_LV2|HAVE_AU|" src/hostplugins/Makefile.am
- touch patched
- fi
- rm -f configure
- make -f Makefile.svn configure
- ./configure \
- --enable-static --disable-shared --prefix=${PREFIX} \
- --target=${MINGW_PREFIX} --host=${MINGW_PREFIX} --build=${HOST_ARCH} \
- --enable-signed-triang-algo=diharmonic --enable-unsigned-triang-algo=diharmonic --enable-subfragment-size=8 \
- --disable-alsa-driver --disable-arts-driver --disable-jack-driver \
- --disable-asio-driver --disable-midishare-driver --disable-mmemidi-driver \
- --disable-coreaudio-driver --disable-coremidi-driver \
- --disable-instruments-db --disable-sf2-engine
- make ${MAKE_ARGS}
- make install
- sed -i -e "s|-llinuxsampler|-llinuxsampler -L${PREFIX}/lib/libgig -lgig -lsndfile -lFLAC -lvorbisenc -lvorbis -logg -lm -lrpcrt4|" ${PREFIX}/lib/pkgconfig/linuxsampler.pc
- touch build-done
- cd ..
-fi
-
# ------------------------------------------------------------------------------------
# glib
diff --git a/data/windows/common.env b/data/windows/common.env
index 8ab3e5e37..c9af0da8e 100644
--- a/data/windows/common.env
+++ b/data/windows/common.env
@@ -8,8 +8,6 @@ LIBOGG_VERSION=1.3.3
LIBVORBIS_VERSION=1.3.5
FLAC_VERSION=1.3.2
LIBSNDFILE_VERSION=1.0.28
-LIBGIG_VERSION=4.0.0
-LINUXSAMPLER_VERSION=2.0.0
LIBFFI_VERSION=3.2.1
GETTEXT_VERSION=0.18.3.2
GLIB_VERSION=2.22.5
diff --git a/data/windows/patches/libgig_fix-build.patch b/data/windows/patches/libgig_fix-build.patch
deleted file mode 100644
index 6ba32959e..000000000
--- a/data/windows/patches/libgig_fix-build.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-diff --git a/src/DLS.h b/src/DLS.h
-index 065bfe6..6c9d76c 100644
---- a/src/DLS.h
-+++ b/src/DLS.h
-@@ -515,10 +515,10 @@ namespace DLS {
- virtual void Save(const String& Path, progress_t* pProgress = NULL);
- virtual void Save(progress_t* pProgress = NULL);
- virtual ~File();
-- protected:
- typedef std::list SampleList;
- typedef std::list InstrumentList;
-
-+ protected:
- RIFF::File* pRIFF;
- std::list ExtensionFiles;
- SampleList* pSamples;
-diff --git a/src/gig.cpp b/src/gig.cpp
-index 6a24f16..902e1ae 100644
---- a/src/gig.cpp
-+++ b/src/gig.cpp
-@@ -4181,7 +4181,7 @@ namespace {
- * @param pGroup - script's new group
- */
- void Script::SetGroup(ScriptGroup* pGroup) {
-- if (this->pGroup = pGroup) return;
-+ if (this->pGroup == pGroup) return;
- if (pChunk)
- pChunk->GetParent()->MoveSubChunk(pChunk, pGroup->pList);
- this->pGroup = pGroup;
diff --git a/data/windows/patches/linuxsampler_allow-no-drivers-build.patch b/data/windows/patches/linuxsampler_allow-no-drivers-build.patch
deleted file mode 100644
index 12a7f3875..000000000
--- a/data/windows/patches/linuxsampler_allow-no-drivers-build.patch
+++ /dev/null
@@ -1,24 +0,0 @@
---- linuxsampler-static-1.0.0+svn2356.orig/configure.ac
-+++ linuxsampler-static-1.0.0+svn2356/configure.ac
-@@ -556,21 +556,6 @@ if test "x$MAC_PLUGIN_INSTALL_DIR" = "x"
- fi
- AC_SUBST(MAC_PLUGIN_INSTALL_DIR)
-
--# have we found at least one MIDI input and one audio output driver ?
--if test "$have_midi_input_driver" = "false"; then
-- echo "No supported MIDI input system found!"
-- echo "Sorry, LinuxSampler only supports the following MIDI drivers at the moment:"
-- echo "ALSA, JACK, MIDIShare, CoreMIDI, MME."
-- echo "If you think you have one of those available on your system, make sure you"
-- echo "also have the respective development (header) files installed."
-- exit -1;
--fi
--if test "$have_audio_output_driver" = "false"; then
-- echo "No supported audio output system found!"
-- echo "Sorry, LinuxSampler only supports ALSA, JACK, ARTS and ASIO as audio output"
-- echo "driver at the moment!"
-- exit -1;
--fi
-
-
-
diff --git a/data/windows/patches/linuxsampler_disable-ladspa-fx.patch b/data/windows/patches/linuxsampler_disable-ladspa-fx.patch
deleted file mode 100644
index 5bc4e9816..000000000
--- a/data/windows/patches/linuxsampler_disable-ladspa-fx.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- linuxsampler-static-1.0.0+svn2497.orig/src/effects/LadspaEffect.cpp
-+++ linuxsampler-static-1.0.0+svn2497/src/effects/LadspaEffect.cpp
-@@ -374,6 +374,7 @@ static String defaultLadspaDir() {
-
- std::vector LadspaEffect::AvailableEffects() {
- std::vector v; // will be filled in callback function _foundLadspaDll()
-+ return v;
-
- char* pcLadspaPath = getenv("LADSPA_PATH");
- String ladspaDir = pcLadspaPath ? pcLadspaPath : defaultLadspaDir();
diff --git a/resources/ui/carla_settings.ui b/resources/ui/carla_settings.ui
index ea74228d2..bfaa11442 100644
--- a/resources/ui/carla_settings.ui
+++ b/resources/ui/carla_settings.ui
@@ -1283,19 +1283,6 @@
-
-
-
- 0
-
-
- 0
-
- -
-
-
-
-
diff --git a/source/Makefile.mk b/source/Makefile.mk
index f43be9cf2..e6d19a227 100644
--- a/source/Makefile.mk
+++ b/source/Makefile.mk
@@ -148,6 +148,11 @@ ifeq ($(MACOS_OLD),true)
BUILD_CXX_FLAGS = $(BASE_FLAGS) $(CXXFLAGS) -DHAVE_CPP11_SUPPORT=0
endif
+ifeq ($(WIN32),true)
+# Always build statically on windows
+LINK_FLAGS += -static
+endif
+
# ---------------------------------------------------------------------------------------------------------------------
# Strict test build
diff --git a/source/backend/CarlaEngine.hpp b/source/backend/CarlaEngine.hpp
index 77d42cd93..883cacc02 100644
--- a/source/backend/CarlaEngine.hpp
+++ b/source/backend/CarlaEngine.hpp
@@ -280,8 +280,8 @@ struct CARLA_API EngineTimeInfoBBT {
int32_t bar; //!< current bar
int32_t beat; //!< current beat-within-bar
- int32_t tick; //!< current tick-within-beat
- double barStartTick;
+ double tick; //!< current tick-within-beat
+ double barStartTick;
float beatsPerBar; //!< time signature "numerator"
float beatType; //!< time signature "denominator"
diff --git a/source/backend/CarlaPlugin.hpp b/source/backend/CarlaPlugin.hpp
index a6c38d882..2fc578cf5 100644
--- a/source/backend/CarlaPlugin.hpp
+++ b/source/backend/CarlaPlugin.hpp
@@ -807,11 +807,6 @@ public:
// -------------------------------------------------------------------
// Helper functions
- /*!
- * Check if the plugin can run in rack mode.
- */
- bool canRunInRack() const noexcept;
-
/*!
* Get the plugin's engine, as passed in the constructor.
*/
@@ -940,11 +935,14 @@ protected:
// -------------------------------------------------------------------
// Internal helper functions
+public:
+ // FIXME: remove public exception on 2.1 release
/*!
* Call LV2 restore.
*/
virtual void restoreLV2State() noexcept;
+protected:
/*!
* Give plugin bridges a change to update their custom data sets.
*/
diff --git a/source/backend/CarlaStandalone.cpp b/source/backend/CarlaStandalone.cpp
index 75f38a1c6..08d88a715 100644
--- a/source/backend/CarlaStandalone.cpp
+++ b/source/backend/CarlaStandalone.cpp
@@ -1797,7 +1797,7 @@ const char* carla_get_host_osc_url_tcp()
{
carla_debug("carla_get_host_osc_url_tcp()");
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
if (gStandalone.engine == nullptr)
{
carla_stderr2("carla_get_host_osc_url_tcp() failed, engine is not running");
@@ -1815,7 +1815,7 @@ const char* carla_get_host_osc_url_udp()
{
carla_debug("carla_get_host_osc_url_udp()");
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
if (gStandalone.engine == nullptr)
{
carla_stderr2("carla_get_host_osc_url_udp() failed, engine is not running");
diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp
index 469dd732f..d507ff1df 100644
--- a/source/backend/engine/CarlaEngine.cpp
+++ b/source/backend/engine/CarlaEngine.cpp
@@ -40,6 +40,9 @@
#include "water/xml/XmlDocument.h"
#include "water/xml/XmlElement.h"
+// FIXME Remove on 2.1 release
+#include "lv2/atom.h"
+
using water::Array;
using water::CharPointer_UTF8;
using water::File;
@@ -282,7 +285,7 @@ void CarlaEngine::idle() noexcept
}
}
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
pData->osc.idle();
#endif
}
@@ -402,81 +405,15 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype,
preferBridges = true;
}
}
-# if 0
- else if (ptype == PLUGIN_VST2)
- {
- /*
- char uniqueIdChars[5] = {
- static_cast((uniqueId & 0xFF000000) >> 24),
- static_cast((uniqueId & 0x00FF0000) >> 16),
- static_cast((uniqueId & 0x0000FF00) >> 8),
- static_cast((uniqueId & 0x000000FF) >> 1),
- 0
- };
- */
-
- /**/ if (uniqueId == 1633895765 && std::strstr(filename, "/ACE.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1433421876 && std::strstr(filename, "/Bazille.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1147754081 && std::strstr(filename, "/Diva.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1095583057 && std::strstr(filename, "/Filterscape.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1179866689 && std::strstr(filename, "/Filterscape.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1179865398 && std::strstr(filename, "/Filterscape.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1749636677 && std::strstr(filename, "/Hive.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1296452914 && std::strstr(filename, "/MFM2.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1349477487 && std::strstr(filename, "/Podolski.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1886548821 && std::strstr(filename, "/Presswerk.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1969770582 && std::strstr(filename, "/Protoverb.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1969771348 && std::strstr(filename, "/Satin.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1667388281 && std::strstr(filename, "/TripleCheese.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1952017974 && std::strstr(filename, "/TyrellN6.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1432568113 && std::strstr(filename, "/Uhbik.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1432568881 && std::strstr(filename, "/Uhbik.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1432572209 && std::strstr(filename, "/Uhbik.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1432569393 && std::strstr(filename, "/Uhbik.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1432569649 && std::strstr(filename, "/Uhbik.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1432571953 && std::strstr(filename, "/Uhbik.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1382232375 && std::strstr(filename, "/Uhbik.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1432572721 && std::strstr(filename, "/Uhbik.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1432572977 && std::strstr(filename, "/Uhbik.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1397572658 && std::strstr(filename, "/Zebra2.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1397572659 && std::strstr(filename, "/Zebra2.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1919243824 && std::strstr(filename, "/Zebra2.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1397578034 && std::strstr(filename, "/Zebra2.") != nullptr)
- preferBridges = true;
- else if (uniqueId == 1397573722 && std::strstr(filename, "/ZebraHZ.") != nullptr)
- preferBridges = true;
- }
-# endif
}
#endif // ! BUILD_BRIDGE
- if (ptype != PLUGIN_INTERNAL && (btype != BINARY_NATIVE || (preferBridges && bridgeBinary.isNotEmpty())))
+ const bool canBeBridged = ptype != PLUGIN_INTERNAL
+ && ptype != PLUGIN_SF2
+ && ptype != PLUGIN_SFZ
+ && ptype != PLUGIN_JACK;
+
+ if (canBeBridged && (btype != BINARY_NATIVE || (preferBridges && bridgeBinary.isNotEmpty())))
{
if (bridgeBinary.isNotEmpty())
{
@@ -490,7 +427,9 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype,
}
else
{
+#ifndef BUILD_BRIDGE
bool use16Outs;
+#endif
setLastError("Invalid or unsupported plugin type");
switch (ptype)
@@ -498,10 +437,6 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype,
case PLUGIN_NONE:
break;
- case PLUGIN_INTERNAL:
- plugin = CarlaPlugin::newNative(initializer);
- break;
-
case PLUGIN_LADSPA:
plugin = CarlaPlugin::newLADSPA(initializer, (const LADSPA_RDF_Descriptor*)extra);
break;
@@ -518,6 +453,11 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype,
plugin = CarlaPlugin::newVST2(initializer);
break;
+#ifndef BUILD_BRIDGE
+ case PLUGIN_INTERNAL:
+ plugin = CarlaPlugin::newNative(initializer);
+ break;
+
case PLUGIN_SF2:
use16Outs = (extra != nullptr && std::strcmp((const char*)extra, "true") == 0);
plugin = CarlaPlugin::newFluidSynth(initializer, use16Outs);
@@ -530,6 +470,14 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype,
case PLUGIN_JACK:
plugin = CarlaPlugin::newJackApp(initializer);
break;
+#else
+ case PLUGIN_INTERNAL:
+ case PLUGIN_SF2:
+ case PLUGIN_SFZ:
+ case PLUGIN_JACK:
+ setLastError("Plugin bridges cannot handle this binary");
+ break;
+#endif
}
}
@@ -543,12 +491,7 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype,
/**/ if (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK)
{
- /**/ if (! plugin->canRunInRack())
- {
- setLastError("Carla's rack mode can only work with Mono or Stereo plugins, sorry!");
- canRun = false;
- }
- else if (plugin->getCVInCount() > 0 || plugin->getCVInCount() > 0)
+ if (plugin->getCVInCount() > 0 || plugin->getCVInCount() > 0)
{
setLastError("Carla's rack mode cannot work with plugins that have CV ports, sorry!");
canRun = false;
@@ -1620,7 +1563,7 @@ void CarlaEngine::setOption(const EngineOption option, const int value, const ch
}
}
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
// -----------------------------------------------------------------------
// OSC Stuff
@@ -2114,6 +2057,63 @@ bool CarlaEngine::loadProjectInternal(water::XmlDocument& xmlDoc)
CARLA_SAFE_ASSERT_CONTINUE(stateSave.type != nullptr);
+#ifndef BUILD_BRIDGE
+ // compatibility code to load projects with GIG files
+ // FIXME Remove on 2.1 release
+ if (std::strcmp(stateSave.type, "GIG") == 0)
+ {
+ if (addPlugin(PLUGIN_LV2, "", stateSave.name, "http://linuxsampler.org/plugins/linuxsampler", 0, nullptr))
+ {
+ const uint pluginId = pData->curPluginCount;
+
+ if (CarlaPlugin* const plugin = pData->plugins[pluginId].plugin)
+ {
+ callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);
+
+ if (pData->aboutToClose)
+ return true;
+
+ String lsState;
+ lsState << "0.35\n";
+ lsState << "18 0 Chromatic\n";
+ lsState << "18 1 Drum Kits\n";
+ lsState << "20 0\n";
+ lsState << "0 1 " << stateSave.binary << "\n";
+ lsState << "0 0 0 0 1 0 GIG\n";
+
+ plugin->setCustomData(LV2_ATOM__String, "http://linuxsampler.org/schema#state-string", lsState.toRawUTF8(), true);
+ plugin->restoreLV2State();
+
+ plugin->setDryWet(stateSave.dryWet, true, true);
+ plugin->setVolume(stateSave.volume, true, true);
+ plugin->setBalanceLeft(stateSave.balanceLeft, true, true);
+ plugin->setBalanceRight(stateSave.balanceRight, true, true);
+ plugin->setPanning(stateSave.panning, true, true);
+ plugin->setCtrlChannel(stateSave.ctrlChannel, true, true);
+ plugin->setActive(stateSave.active, true, true);
+
+ ++pData->curPluginCount;
+
+ plugin->setEnabled(true);
+ callback(ENGINE_CALLBACK_PLUGIN_ADDED, pluginId, 0, 0, 0.0f, plugin->getName());
+
+ if (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY)
+ pData->graph.addPlugin(plugin);
+ }
+ else
+ {
+ carla_stderr2("Failed to get new plugin, state will not be restored correctly\n");
+ }
+ }
+ else
+ {
+ carla_stderr2("Failed to load a linuxsampler LV2 plugin, GIG file won't be loaded");
+ }
+
+ continue;
+ }
+#endif
+
const void* extraStuff = nullptr;
static const char kTrue[] = "true";
diff --git a/source/backend/engine/CarlaEngineBridge.cpp b/source/backend/engine/CarlaEngineBridge.cpp
index 63a509dcd..315f713ed 100644
--- a/source/backend/engine/CarlaEngineBridge.cpp
+++ b/source/backend/engine/CarlaEngineBridge.cpp
@@ -1405,12 +1405,6 @@ CarlaEngine* CarlaEngine::newBridge(const char* const audioPoolBaseName, const c
// -----------------------------------------------------------------------
-#ifdef BUILD_BRIDGE_ALTERNATIVE_ARCH
-CarlaPlugin* CarlaPlugin::newNative(const CarlaPlugin::Initializer&) { return nullptr; }
-CarlaPlugin* CarlaPlugin::newFileSF2(const CarlaPlugin::Initializer&, const bool) { return nullptr; }
-CarlaPlugin* CarlaPlugin::newFileSFZ(const CarlaPlugin::Initializer&) { return nullptr; }
-#endif
-
CARLA_BACKEND_END_NAMESPACE
// -----------------------------------------------------------------------
diff --git a/source/backend/engine/CarlaEngineData.cpp b/source/backend/engine/CarlaEngineData.cpp
index 9d266067f..1e8c0524c 100644
--- a/source/backend/engine/CarlaEngineData.cpp
+++ b/source/backend/engine/CarlaEngineData.cpp
@@ -297,7 +297,7 @@ EngineTimeInfoBBT::EngineTimeInfoBBT() noexcept
: valid(false),
bar(0),
beat(0),
- tick(0),
+ tick(0.0),
barStartTick(0.0),
beatsPerBar(0.0f),
beatType(0.0f),
diff --git a/source/backend/engine/CarlaEngineGraph.cpp b/source/backend/engine/CarlaEngineGraph.cpp
index 2d2e8d345..4973e3e81 100644
--- a/source/backend/engine/CarlaEngineGraph.cpp
+++ b/source/backend/engine/CarlaEngineGraph.cpp
@@ -566,18 +566,20 @@ RackGraph::Buffers::Buffers() noexcept
connectedIn1(),
connectedIn2(),
connectedOut1(),
- connectedOut2()
+ connectedOut2(),
#ifdef CARLA_PROPER_CPP11_SUPPORT
- , inBuf{nullptr, nullptr},
+ inBuf{nullptr, nullptr},
inBufTmp{nullptr, nullptr},
- outBuf{nullptr, nullptr} {}
-#else
+ outBuf{nullptr, nullptr},
+#endif
+ unusedBuf(nullptr)
{
+#ifndef CARLA_PROPER_CPP11_SUPPORT
inBuf[0] = inBuf[1] = nullptr;
inBufTmp[0] = inBufTmp[1] = nullptr;
outBuf[0] = outBuf[1] = nullptr;
- }
#endif
+ }
RackGraph::Buffers::~Buffers() noexcept
{
@@ -589,6 +591,7 @@ RackGraph::Buffers::~Buffers() noexcept
if (inBufTmp[1] != nullptr) { delete[] inBufTmp[1]; inBufTmp[1] = nullptr; }
if (outBuf[0] != nullptr) { delete[] outBuf[0]; outBuf[0] = nullptr; }
if (outBuf[1] != nullptr) { delete[] outBuf[1]; outBuf[1] = nullptr; }
+ if (unusedBuf != nullptr) { delete[] unusedBuf; unusedBuf = nullptr; }
connectedIn1.clear();
connectedIn2.clear();
@@ -606,12 +609,14 @@ void RackGraph::Buffers::setBufferSize(const uint32_t bufferSize, const bool cre
if (inBufTmp[1] != nullptr) { delete[] inBufTmp[1]; inBufTmp[1] = nullptr; }
if (outBuf[0] != nullptr) { delete[] outBuf[0]; outBuf[0] = nullptr; }
if (outBuf[1] != nullptr) { delete[] outBuf[1]; outBuf[1] = nullptr; }
+ if (unusedBuf != nullptr) { delete[] unusedBuf; unusedBuf = nullptr; }
CARLA_SAFE_ASSERT_RETURN(bufferSize > 0,);
try {
inBufTmp[0] = new float[bufferSize];
inBufTmp[1] = new float[bufferSize];
+ unusedBuf = new float[bufferSize];
if (createBuffers)
{
@@ -624,6 +629,7 @@ void RackGraph::Buffers::setBufferSize(const uint32_t bufferSize, const bool cre
catch(...) {
if (inBufTmp[0] != nullptr) { delete[] inBufTmp[0]; inBufTmp[0] = nullptr; }
if (inBufTmp[1] != nullptr) { delete[] inBufTmp[1]; inBufTmp[1] = nullptr; }
+ if (unusedBuf != nullptr) { delete[] unusedBuf; unusedBuf = nullptr; }
if (createBuffers)
{
@@ -771,24 +777,24 @@ bool RackGraph::getGroupAndPortIdFromFullName(const char* const fullPortName, ui
return extGraph.getGroupAndPortIdFromFullName(fullPortName, groupId, portId);
}
-void RackGraph::process(CarlaEngine::ProtectedData* const data, const float* inBufReal[2], float* outBuf[2], const uint32_t frames)
+void RackGraph::process(CarlaEngine::ProtectedData* const data, const float* inBufReal[2], float* outBufReal[2], const uint32_t frames)
{
CARLA_SAFE_ASSERT_RETURN(data != nullptr,);
CARLA_SAFE_ASSERT_RETURN(data->events.in != nullptr,);
CARLA_SAFE_ASSERT_RETURN(data->events.out != nullptr,);
// safe copy
- float inBuf0[frames];
- float inBuf1[frames];
- const float* inBuf[2] = { inBuf0, inBuf1 };
+ float* const dummyBuf = audioBuffers.unusedBuf;
+ float* const inBuf0 = audioBuffers.inBufTmp[0];
+ float* const inBuf1 = audioBuffers.inBufTmp[1];
// initialize audio inputs
carla_copyFloats(inBuf0, inBufReal[0], frames);
carla_copyFloats(inBuf1, inBufReal[1], frames);
// initialize audio outputs (zero)
- carla_zeroFloats(outBuf[0], frames);
- carla_zeroFloats(outBuf[1], frames);
+ carla_zeroFloats(outBufReal[0], frames);
+ carla_zeroFloats(outBufReal[1], frames);
// initialize event outputs (zero)
carla_zeroStructs(data->events.out, kMaxEngineEventInternalCount);
@@ -809,12 +815,12 @@ void RackGraph::process(CarlaEngine::ProtectedData* const data, const float* inB
if (processed)
{
// initialize audio inputs (from previous outputs)
- carla_copyFloats(inBuf0, outBuf[0], frames);
- carla_copyFloats(inBuf1, outBuf[1], frames);
+ carla_copyFloats(inBuf0, outBufReal[0], frames);
+ carla_copyFloats(inBuf1, outBufReal[1], frames);
// initialize audio outputs (zero)
- carla_zeroFloats(outBuf[0], frames);
- carla_zeroFloats(outBuf[1], frames);
+ carla_zeroFloats(outBufReal[0], frames);
+ carla_zeroFloats(outBufReal[1], frames);
// if plugin has no midi out, add previous events
if (oldMidiOutCount == 0 && data->events.in[0].type != kEngineEventTypeNull)
@@ -840,6 +846,28 @@ void RackGraph::process(CarlaEngine::ProtectedData* const data, const float* inB
oldAudioOutCount = plugin->getAudioOutCount();
oldMidiOutCount = plugin->getMidiOutCount();
+ const uint32_t numInBufs = std::max(oldAudioInCount, 2U);
+ const uint32_t numOutBufs = std::max(oldAudioOutCount, 2U);
+
+ const float* inBuf[numInBufs];
+ inBuf[0] = inBuf0;
+ inBuf[1] = inBuf1;
+
+ float* outBuf[numOutBufs];
+ outBuf[0] = outBufReal[0];
+ outBuf[1] = outBufReal[1];
+
+ if (numInBufs > 2 || numOutBufs > 2)
+ {
+ carla_zeroFloats(dummyBuf, frames);
+
+ for (uint32_t i=2; iinitBuffers();
plugin->process(inBuf, outBuf, nullptr, nullptr, frames);
@@ -848,14 +876,14 @@ void RackGraph::process(CarlaEngine::ProtectedData* const data, const float* inB
// if plugin has no audio inputs, add input buffer
if (oldAudioInCount == 0)
{
- carla_addFloats(outBuf[0], inBuf0, frames);
- carla_addFloats(outBuf[1], inBuf1, frames);
+ carla_addFloats(outBufReal[0], inBuf0, frames);
+ carla_addFloats(outBufReal[1], inBuf1, frames);
}
// if plugin only has 1 output, copy it to the 2nd
if (oldAudioOutCount == 1)
{
- carla_copyFloats(outBuf[1], outBuf[0], frames);
+ carla_copyFloats(outBufReal[1], outBufReal[0], frames);
}
// set peaks
@@ -875,8 +903,8 @@ void RackGraph::process(CarlaEngine::ProtectedData* const data, const float* inB
if (oldAudioOutCount > 0)
{
- pluginData.outsPeak[0] = carla_findMaxNormalizedFloat(outBuf[0], frames);
- pluginData.outsPeak[1] = carla_findMaxNormalizedFloat(outBuf[1], frames);
+ pluginData.outsPeak[0] = carla_findMaxNormalizedFloat(outBufReal[0], frames);
+ pluginData.outsPeak[1] = carla_findMaxNormalizedFloat(outBufReal[1], frames);
}
else
{
diff --git a/source/backend/engine/CarlaEngineGraph.hpp b/source/backend/engine/CarlaEngineGraph.hpp
index 0bd56eb1c..4279c3e38 100644
--- a/source/backend/engine/CarlaEngineGraph.hpp
+++ b/source/backend/engine/CarlaEngineGraph.hpp
@@ -1,6 +1,6 @@
/*
* Carla Plugin Host
- * Copyright (C) 2011-2017 Filipe Coelho
+ * Copyright (C) 2011-2018 Filipe Coelho
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -114,6 +114,7 @@ struct RackGraph {
float* inBuf[2];
float* inBufTmp[2];
float* outBuf[2];
+ float* unusedBuf;
Buffers() noexcept;
~Buffers() noexcept;
void setBufferSize(const uint32_t bufferSize, const bool createBuffers) noexcept;
@@ -135,7 +136,7 @@ struct RackGraph {
bool getGroupAndPortIdFromFullName(const char* const fullPortName, uint& groupId, uint& portId) const noexcept;
// the base, where plugins run
- void process(CarlaEngine::ProtectedData* const data, const float* inBufReal[2], float* outBuf[2], const uint32_t frames);
+ void process(CarlaEngine::ProtectedData* const data, const float* inBuf[2], float* outBuf[2], const uint32_t frames);
// extended, will call process() in the middle
void processHelper(CarlaEngine::ProtectedData* const data, const float* const* const inBuf, float* const* const outBuf, const uint32_t frames);
diff --git a/source/backend/engine/CarlaEngineInternal.cpp b/source/backend/engine/CarlaEngineInternal.cpp
index edb7a1181..ad38110de 100644
--- a/source/backend/engine/CarlaEngineInternal.cpp
+++ b/source/backend/engine/CarlaEngineInternal.cpp
@@ -245,7 +245,7 @@ void EngineInternalTime::fillEngineTimeInfo(const uint32_t newFrames) noexcept
timeInfo.bbt.beatsPerBar = static_cast(beatsPerBar);
timeInfo.bbt.beatsPerMinute = beatsPerMinute;
- timeInfo.bbt.tick = static_cast(ticktmp);
+ timeInfo.bbt.tick = ticktmp;
tick = ticktmp;
if (transportMode == ENGINE_TRANSPORT_MODE_INTERNAL && timeInfo.playing)
@@ -322,7 +322,7 @@ void EngineInternalTime::fillJackTimeInfo(jack_position_t* const pos, const uint
pos->beats_per_bar = static_cast(beatsPerBar);
pos->beats_per_minute = beatsPerMinute;
- pos->tick = static_cast(ticktmp);
+ pos->tick = ticktmp;
tick = ticktmp;
}
@@ -418,7 +418,7 @@ void EngineNextAction::clearAndReset() noexcept
CarlaEngine::ProtectedData::ProtectedData(CarlaEngine* const engine) noexcept
: thread(engine),
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
osc(engine),
oscData(nullptr),
#endif
@@ -473,7 +473,7 @@ CarlaEngine::ProtectedData::~ProtectedData() noexcept
bool CarlaEngine::ProtectedData::init(const char* const clientName)
{
CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(name.isEmpty(), "Invalid engine internal data (err #1)");
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(oscData == nullptr, "Invalid engine internal data (err #2)");
#endif
CARLA_SAFE_ASSERT_RETURN_INTERNAL_ERR(events.in == nullptr, "Invalid engine internal data (err #4)");
@@ -523,7 +523,7 @@ bool CarlaEngine::ProtectedData::init(const char* const clientName)
timeInfo.clear();
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
osc.init(clientName);
# ifndef BUILD_BRIDGE
oscData = osc.getControlData();
@@ -554,7 +554,7 @@ void CarlaEngine::ProtectedData::close()
thread.stopThread(500);
nextAction.clearAndReset();
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
osc.close();
oscData = nullptr;
#endif
diff --git a/source/backend/engine/CarlaEngineInternal.hpp b/source/backend/engine/CarlaEngineInternal.hpp
index a07471c0a..ae7539373 100644
--- a/source/backend/engine/CarlaEngineInternal.hpp
+++ b/source/backend/engine/CarlaEngineInternal.hpp
@@ -18,11 +18,13 @@
#ifndef CARLA_ENGINE_INTERNAL_HPP_INCLUDED
#define CARLA_ENGINE_INTERNAL_HPP_INCLUDED
-#include "CarlaEngineOsc.hpp"
#include "CarlaEngineThread.hpp"
#include "CarlaEngineUtils.hpp"
-#include "hylia/hylia.h"
+#ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
+# include "CarlaEngineOsc.hpp"
+# include "hylia/hylia.h"
+#endif
// FIXME only use CARLA_PREVENT_HEAP_ALLOCATION for structs
// maybe separate macro
@@ -207,7 +209,7 @@ struct EnginePluginData {
struct CarlaEngine::ProtectedData {
CarlaEngineThread thread;
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
CarlaEngineOsc osc;
# ifdef BUILD_BRIDGE
CarlaOscData* oscData;
diff --git a/source/backend/engine/CarlaEngineNative.cpp b/source/backend/engine/CarlaEngineNative.cpp
index d1dc7672f..b8f7f98d2 100644
--- a/source/backend/engine/CarlaEngineNative.cpp
+++ b/source/backend/engine/CarlaEngineNative.cpp
@@ -1751,7 +1751,8 @@ protected:
if (timeInfo.bbt.valid)
{
- std::sprintf(tmpBuf, P_UINT64 ":%i:%i:%i\n", timeInfo.frame, timeInfo.bbt.bar, timeInfo.bbt.beat, timeInfo.bbt.tick);
+ std::sprintf(tmpBuf, P_UINT64 ":%i:%i:%i\n",
+ timeInfo.frame, timeInfo.bbt.bar, timeInfo.bbt.beat, static_cast(timeInfo.bbt.tick + 0.5));
if (! fUiServer.writeMessage(tmpBuf))
return;
diff --git a/source/backend/engine/CarlaEngineRtAudio.cpp b/source/backend/engine/CarlaEngineRtAudio.cpp
index a89be8b4c..5e3870135 100644
--- a/source/backend/engine/CarlaEngineRtAudio.cpp
+++ b/source/backend/engine/CarlaEngineRtAudio.cpp
@@ -90,7 +90,7 @@ static const char* getRtAudioApiName(const RtAudio::Api api) noexcept
case RtAudio::UNIX_PULSE:
return "PulseAudio";
case RtAudio::UNIX_JACK:
-#if defined(CARLA_OS_LINUX)
+#if defined(CARLA_OS_LINUX) && defined(HAVE_ALSA)
return "JACK with ALSA-MIDI";
#elif defined(CARLA_OS_MAC)
return "JACK with CoreMidi";
@@ -128,7 +128,7 @@ static RtMidi::Api getMatchedAudioMidiAPI(const RtAudio::Api rtApi) noexcept
case RtAudio::UNIX_PULSE:
case RtAudio::UNIX_JACK:
-#if defined(CARLA_OS_LINUX)
+#if defined(CARLA_OS_LINUX) && defined(HAVE_ALSA)
return RtMidi::LINUX_ALSA;
#elif defined(CARLA_OS_MAC)
return RtMidi::MACOSX_CORE;
@@ -286,7 +286,8 @@ public:
fAudio.openStream(oParams.nChannels > 0 ? &oParams : nullptr,
iParams.nChannels > 0 ? &iParams : nullptr,
RTAUDIO_FLOAT32, pData->options.audioSampleRate, &bufferFrames,
- carla_rtaudio_process_callback, this, &rtOptions);
+ carla_rtaudio_process_callback, this, &rtOptions,
+ carla_rtaudio_buffer_size_callback);
}
catch (const RtAudioError& e) {
setLastError(e.what());
@@ -592,8 +593,7 @@ protected:
/* */ float* const outsPtr = (float*)outputBuffer;
// assert rtaudio buffers
- CARLA_SAFE_ASSERT_RETURN(outputBuffer != nullptr,);
- CARLA_SAFE_ASSERT_RETURN(pData->bufferSize == nframes,);
+ CARLA_SAFE_ASSERT_RETURN(outputBuffer != nullptr,);
// set rtaudio buffers as non-interleaved
const float* inBuf[fAudioInCount];
@@ -601,6 +601,7 @@ protected:
if (fAudioInterleaved)
{
+ // FIXME - this looks completely wrong!
float* inBuf2[fAudioInCount];
for (uint i=0, count=fAudioInCount; ibufferSize, newBufferSize);
+ if (pData->bufferSize == newBufferSize)
+ return;
+
+ if (fAudioInCount > 0)
+ {
+ delete[] fAudioIntBufIn;
+ fAudioIntBufIn = new float[fAudioInCount*newBufferSize];
+ }
+
+ if (fAudioOutCount > 0)
+ {
+ delete[] fAudioIntBufOut;
+ fAudioIntBufOut = new float[fAudioOutCount*newBufferSize];
+ }
+
+ pData->bufferSize = newBufferSize;
+ bufferSizeChanged(newBufferSize);
+ }
+
void handleMidiCallback(double timeStamp, std::vector* const message)
{
const size_t messageSize(message->size());
@@ -1056,6 +1079,12 @@ private:
return 0;
}
+ static bool carla_rtaudio_buffer_size_callback(unsigned int bufferSize, void* userData)
+ {
+ handlePtr->handleBufferSizeCallback(bufferSize);
+ return true;
+ }
+
static void carla_rtmidi_callback(double timeStamp, std::vector* message, void* userData)
{
handlePtr->handleMidiCallback(timeStamp, message);
diff --git a/source/backend/engine/CarlaEngineThread.cpp b/source/backend/engine/CarlaEngineThread.cpp
index 78b85d8cb..c4401eff0 100644
--- a/source/backend/engine/CarlaEngineThread.cpp
+++ b/source/backend/engine/CarlaEngineThread.cpp
@@ -1,6 +1,6 @@
/*
* Carla Plugin Host
- * Copyright (C) 2011-2014 Filipe Coelho
+ * Copyright (C) 2011-2018 Filipe Coelho
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -46,7 +46,7 @@ void CarlaEngineThread::run() noexcept
#endif
carla_debug("CarlaEngineThread::run()");
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
const bool isPlugin(kEngine->getType() == kEngineTypePlugin);
#endif
float value;
@@ -63,7 +63,7 @@ void CarlaEngineThread::run() noexcept
const bool oscRegisted = false;
#endif
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
if (isPlugin)
kEngine->idleOsc();
#endif
diff --git a/source/backend/plugin/CarlaPlugin.cpp b/source/backend/plugin/CarlaPlugin.cpp
index da4d31b62..28d1ea43c 100644
--- a/source/backend/plugin/CarlaPlugin.cpp
+++ b/source/backend/plugin/CarlaPlugin.cpp
@@ -2411,11 +2411,6 @@ void CarlaPlugin::uiNoteOff(const uint8_t channel, const uint8_t note) noexcept
CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,);
}
-bool CarlaPlugin::canRunInRack() const noexcept
-{
- return (pData->extraHints & PLUGIN_EXTRA_HINT_CAN_RUN_RACK) != 0;
-}
-
CarlaEngine* CarlaPlugin::getEngine() const noexcept
{
return pData->engine;
diff --git a/source/backend/plugin/CarlaPluginBridge.cpp b/source/backend/plugin/CarlaPluginBridge.cpp
index 7ba633c00..aa5c08995 100644
--- a/source/backend/plugin/CarlaPluginBridge.cpp
+++ b/source/backend/plugin/CarlaPluginBridge.cpp
@@ -161,10 +161,17 @@ protected:
// start with "wine" if needed
if (fBinary.endsWithIgnoreCase(".exe"))
{
+ String wineCMD;
+
if (options.wine.executable != nullptr && options.wine.executable[0] != '\0')
- arguments.add(options.wine.executable);
+ wineCMD = options.wine.executable;
else
- arguments.add("wine");
+ wineCMD = "wine";
+
+ if (fBinary.endsWithIgnoreCase("64.exe"))
+ wineCMD += "64";
+
+ arguments.add(wineCMD);
}
#endif
@@ -260,10 +267,12 @@ protected:
if (options.wine.rtPrio)
{
carla_setenv("STAGING_SHARED_MEMORY", "1");
+ carla_setenv("WINE_RT_POLICY", "FF");
std::snprintf(strBuf, STR_MAX, "%i", options.wine.baseRtPrio);
carla_setenv("STAGING_RT_PRIORITY_BASE", strBuf);
carla_setenv("WINE_RT", strBuf);
+ carla_setenv("WINE_RT_PRIO", strBuf);
std::snprintf(strBuf, STR_MAX, "%i", options.wine.serverRtPrio);
carla_setenv("STAGING_RT_PRIORITY_SERVER", strBuf);
@@ -272,9 +281,11 @@ protected:
else
{
carla_unsetenv("STAGING_SHARED_MEMORY");
+ carla_unsetenv("WINE_RT_POLICY");
carla_unsetenv("STAGING_RT_PRIORITY_BASE");
carla_unsetenv("STAGING_RT_PRIORITY_SERVER");
carla_unsetenv("WINE_RT");
+ carla_unsetenv("WINE_RT_PRIO");
carla_unsetenv("WINE_SVR_RT");
}
@@ -901,8 +912,7 @@ public:
fTimedOut = true;
fTimedError = true;
fInitiated = false;
- pData->engine->callback(ENGINE_CALLBACK_PLUGIN_UNAVAILABLE, pData->id, 0, 0, 0.0f,
- "Plugin bridge has been stopped or crashed");
+ handleProcessStopped();
}
CarlaPlugin::idle();
@@ -1064,9 +1074,6 @@ public:
if (fInfo.mOuts > 0)
pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_OUT;
- if (fInfo.aIns <= 2 && fInfo.aOuts <= 2 && (fInfo.aIns == fInfo.aOuts || fInfo.aIns == 0 || fInfo.aOuts == 0))
- pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
-
bufferSizeChanged(pData->engine->getBufferSize());
reloadPrograms(true);
@@ -1078,7 +1085,10 @@ public:
void activate() noexcept override
{
- CARLA_SAFE_ASSERT_RETURN(! fTimedError,);
+ if (! fBridgeThread.isThreadRunning())
+ {
+ CARLA_SAFE_ASSERT_RETURN(restartBridgeThread(),);
+ }
{
const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
@@ -1824,8 +1834,17 @@ public:
fInfo.aIns = fShmNonRtServerControl.readUInt();
fInfo.aOuts = fShmNonRtServerControl.readUInt();
- CARLA_SAFE_ASSERT(fInfo.aInNames == nullptr);
- CARLA_SAFE_ASSERT(fInfo.aOutNames == nullptr);
+ if (fInfo.aInNames != nullptr)
+ {
+ delete[] fInfo.aInNames;
+ fInfo.aInNames = nullptr;
+ }
+
+ if (fInfo.aOutNames != nullptr)
+ {
+ delete[] fInfo.aOutNames;
+ fInfo.aOutNames = nullptr;
+ }
if (fInfo.aIns > 0)
{
@@ -2318,26 +2337,6 @@ public:
return false;
}
- // ---------------------------------------------------------------
- // initial values
-
- fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientVersion);
- fShmNonRtClientControl.writeUInt(CARLA_PLUGIN_BRIDGE_API_VERSION);
-
- fShmNonRtClientControl.writeUInt(static_cast(sizeof(BridgeRtClientData)));
- fShmNonRtClientControl.writeUInt(static_cast(sizeof(BridgeNonRtClientData)));
- fShmNonRtClientControl.writeUInt(static_cast(sizeof(BridgeNonRtServerData)));
-
- fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientInitialSetup);
- fShmNonRtClientControl.writeUInt(pData->engine->getBufferSize());
- fShmNonRtClientControl.writeDouble(pData->engine->getSampleRate());
-
- fShmNonRtClientControl.commitWrite();
-
- // testing dummy message
- fShmRtClientControl.writeOpcode(kPluginBridgeRtClientNull);
- fShmRtClientControl.commitWrite();
-
#ifndef CARLA_OS_WIN
// ---------------------------------------------------------------
// set wine prefix
@@ -2380,58 +2379,10 @@ public:
fWinePrefix.toRawUTF8(),
#endif
bridgeBinary, label, shmIdsStr);
- fBridgeThread.startThread();
- }
-
- // ---------------------------------------------------------------
- // wait for bridge to start
-
- fInitiated = false;
- fLastPongTime = Time::currentTimeMillis();
- CARLA_SAFE_ASSERT(fLastPongTime > 0);
-
- static bool sFirstInit = true;
-
- int64_t timeoutEnd = 5000;
-
- if (sFirstInit)
- timeoutEnd *= 2;
-#ifndef CARLA_OS_WIN
- if (fBinaryType == BINARY_WIN32 || fBinaryType == BINARY_WIN64)
- timeoutEnd *= 2;
-#endif
- sFirstInit = false;
-
- const bool needsEngineIdle = pData->engine->getType() != kEngineTypePlugin;
-
- for (; Time::currentTimeMillis() < fLastPongTime + timeoutEnd && fBridgeThread.isThreadRunning();)
- {
- pData->engine->callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);
-
- if (needsEngineIdle)
- pData->engine->idle();
-
- idle();
-
- if (fInitiated)
- break;
- if (pData->engine->isAboutToClose())
- break;
-
- carla_msleep(20);
}
- fLastPongTime = -1;
-
- if (fInitError || ! fInitiated)
- {
- fBridgeThread.stopThread(6000);
-
- if (! fInitError)
- pData->engine->setLastError("Timeout while waiting for a response from plugin-bridge\n(or the plugin crashed on initialization?)");
-
+ if (! restartBridgeThread())
return false;
- }
// ---------------------------------------------------------------
// register client
@@ -2578,6 +2529,24 @@ private:
BridgeParamInfo* fParams;
+ void handleProcessStopped() noexcept
+ {
+ const bool wasActive = pData->active;
+ pData->active = false;
+
+ if (wasActive)
+ {
+#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
+ if (pData->engine->isOscControlRegistered())
+ pData->engine->oscSend_control_set_parameter_value(pData->id, PARAMETER_ACTIVE, 0.0f);
+ pData->engine->callback(ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED, pData->id, PARAMETER_ACTIVE, 0, 0.0f, nullptr);
+#endif
+ }
+
+ if (pData->hints & PLUGIN_HAS_CUSTOM_UI)
+ pData->engine->callback(ENGINE_CALLBACK_UI_STATE_CHANGED, pData->id, 0, 0, 0.0f, nullptr);
+ }
+
void resizeAudioPool(const uint32_t bufferSize)
{
fShmAudioPool.resize(bufferSize, fInfo.aIns+fInfo.aOuts, fInfo.cvIns+fInfo.cvOuts);
@@ -2601,6 +2570,127 @@ private:
carla_stderr2("waitForClient(%s) timed out", action);
}
+ bool restartBridgeThread()
+ {
+ fInitiated = false;
+ fInitError = false;
+ fTimedError = false;
+
+ // reset memory
+ fShmRtClientControl.data->procFlags = 0;
+ carla_zeroStruct(fShmRtClientControl.data->timeInfo);
+ carla_zeroBytes(fShmRtClientControl.data->midiOut, kBridgeRtClientDataMidiOutSize);
+
+ fShmRtClientControl.clearData();
+ fShmNonRtClientControl.clearData();
+ fShmNonRtServerControl.clearData();
+
+ fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientVersion);
+ fShmNonRtClientControl.writeUInt(CARLA_PLUGIN_BRIDGE_API_VERSION);
+
+ fShmNonRtClientControl.writeUInt(static_cast(sizeof(BridgeRtClientData)));
+ fShmNonRtClientControl.writeUInt(static_cast(sizeof(BridgeNonRtClientData)));
+ fShmNonRtClientControl.writeUInt(static_cast(sizeof(BridgeNonRtServerData)));
+
+ fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientInitialSetup);
+ fShmNonRtClientControl.writeUInt(pData->engine->getBufferSize());
+ fShmNonRtClientControl.writeDouble(pData->engine->getSampleRate());
+
+ fShmNonRtClientControl.commitWrite();
+
+ if (fShmAudioPool.dataSize != 0)
+ {
+ fShmRtClientControl.writeOpcode(kPluginBridgeRtClientSetAudioPool);
+ fShmRtClientControl.writeULong(static_cast(fShmAudioPool.dataSize));
+ fShmRtClientControl.commitWrite();
+ }
+ else
+ {
+ // testing dummy message
+ fShmRtClientControl.writeOpcode(kPluginBridgeRtClientNull);
+ fShmRtClientControl.commitWrite();
+ }
+
+ fBridgeThread.startThread();
+
+ fLastPongTime = Time::currentTimeMillis();
+ CARLA_SAFE_ASSERT(fLastPongTime > 0);
+
+ static bool sFirstInit = true;
+
+ int64_t timeoutEnd = 5000;
+
+ if (sFirstInit)
+ timeoutEnd *= 2;
+#ifndef CARLA_OS_WIN
+ if (fBinaryType == BINARY_WIN32 || fBinaryType == BINARY_WIN64)
+ timeoutEnd *= 2;
+#endif
+ sFirstInit = false;
+
+ const bool needsEngineIdle = pData->engine->getType() != kEngineTypePlugin;
+
+ for (; Time::currentTimeMillis() < fLastPongTime + timeoutEnd && fBridgeThread.isThreadRunning();)
+ {
+ pData->engine->callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr);
+
+ if (needsEngineIdle)
+ pData->engine->idle();
+
+ idle();
+
+ if (fInitiated)
+ break;
+ if (pData->engine->isAboutToClose())
+ break;
+
+ carla_msleep(20);
+ }
+
+ fLastPongTime = -1;
+
+ if (fInitError || ! fInitiated)
+ {
+ fBridgeThread.stopThread(6000);
+
+ if (! fInitError)
+ pData->engine->setLastError("Timeout while waiting for a response from plugin-bridge\n"
+ "(or the plugin crashed on initialization?)");
+
+ return false;
+ }
+
+ if (const size_t dataSize = fInfo.chunk.size())
+ {
+#ifdef CARLA_PROPER_CPP11_SUPPORT
+ void* data = fInfo.chunk.data();
+#else
+ void* data = &fInfo.chunk.front();
+#endif
+ CarlaString dataBase64(CarlaString::asBase64(data, dataSize));
+ CARLA_SAFE_ASSERT_RETURN(dataBase64.length() > 0, true);
+
+ String filePath(File::getSpecialLocation(File::tempDirectory).getFullPathName());
+
+ filePath += CARLA_OS_SEP_STR ".CarlaChunk_";
+ filePath += fShmAudioPool.getFilenameSuffix();
+
+ if (File(filePath).replaceWithText(dataBase64.buffer()))
+ {
+ const uint32_t ulength(static_cast(filePath.length()));
+
+ const CarlaMutexLocker _cml(fShmNonRtClientControl.mutex);
+
+ fShmNonRtClientControl.writeOpcode(kPluginBridgeNonRtClientSetChunkDataFile);
+ fShmNonRtClientControl.writeUInt(ulength);
+ fShmNonRtClientControl.writeCustomData(filePath.toRawUTF8(), ulength);
+ fShmNonRtClientControl.commitWrite();
+ }
+ }
+
+ return true;
+ }
+
CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPluginBridge)
};
diff --git a/source/backend/plugin/CarlaPluginDSSI.cpp b/source/backend/plugin/CarlaPluginDSSI.cpp
index f5c6df8f3..84598ee3b 100644
--- a/source/backend/plugin/CarlaPluginDSSI.cpp
+++ b/source/backend/plugin/CarlaPluginDSSI.cpp
@@ -21,7 +21,7 @@
#include "CarlaDssiUtils.hpp"
#include "CarlaMathUtils.hpp"
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
# include "CarlaOscUtils.hpp"
# include "CarlaPipeUtils.hpp"
# include "CarlaThread.hpp"
@@ -63,7 +63,7 @@ CARLA_BACKEND_START_NAMESPACE
static const CustomData kCustomDataFallback = { nullptr, nullptr, nullptr };
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
// -------------------------------------------------------------------
class CarlaThreadDSSIUI : public CarlaThread
@@ -283,7 +283,7 @@ public:
fForcedStereoOut(false),
fNeedsFixedBuffers(false),
fUsesCustomData(false)
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
, fOscData(),
fThreadUI(engine, this, fOscData),
fUiFilename(nullptr)
@@ -298,7 +298,7 @@ public:
{
carla_debug("CarlaPluginDSSI::~CarlaPluginDSSI()");
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
// close UI
if (fUiFilename != nullptr)
{
@@ -594,7 +594,7 @@ public:
}
}
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
if (sendGui && fOscData.target != nullptr)
osc_send_configure(fOscData, key, value);
#endif
@@ -632,7 +632,7 @@ public:
}
}
-#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE)
const bool sendOsc(pData->engine->isOscControlRegistered());
#else
const bool sendOsc(false);
@@ -684,7 +684,7 @@ public:
}
}
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
// -------------------------------------------------------------------
// Set ui stuff
@@ -1083,7 +1083,7 @@ public:
if (LADSPA_IS_HARD_RT_CAPABLE(fDescriptor->Properties))
pData->hints |= PLUGIN_IS_RTSAFE;
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
if (fUiFilename != nullptr)
pData->hints |= PLUGIN_HAS_CUSTOM_UI;
#endif
@@ -1100,8 +1100,7 @@ public:
#endif
// extra plugin hints
- pData->extraHints = 0x0;
- pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
+ pData->extraHints = 0x0;
if (mIns > 0)
pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN;
@@ -1219,7 +1218,7 @@ public:
}
}
-#if defined(HAVE_LIBLO) && ! defined(BUILD_BRIDGE)
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE)
// Update OSC Names
if (pData->engine->isOscControlRegistered() && pData->id < pData->engine->getCurrentPluginCount())
{
@@ -2185,7 +2184,7 @@ public:
carla_debug("CarlaPluginDSSI::clearBuffers() - end");
}
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
// -------------------------------------------------------------------
// OSC stuff
@@ -2444,7 +2443,7 @@ public:
osc_send_midi(fOscData, midiData);
#endif
}
-#endif // HAVE_LIBLO
+#endif // HAVE_LIBLO && !BUILD_BRIDGE_ALTERNATIVE_ARCH
// -------------------------------------------------------------------
@@ -2453,7 +2452,7 @@ public:
return fDssiDescriptor;
}
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
uintptr_t getUiBridgeProcessId() const noexcept override
{
return fThreadUI.getProcessId();
@@ -2653,7 +2652,7 @@ public:
}
}
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
// ---------------------------------------------------------------
// check for gui
@@ -2719,7 +2718,7 @@ private:
bool fNeedsFixedBuffers;
bool fUsesCustomData;
-#ifdef HAVE_LIBLO
+#if defined(HAVE_LIBLO) && !defined(BUILD_BRIDGE_ALTERNATIVE_ARCH)
CarlaOscData fOscData;
CarlaThreadDSSIUI fThreadUI;
const char* fUiFilename;
diff --git a/source/backend/plugin/CarlaPluginFluidSynth.cpp b/source/backend/plugin/CarlaPluginFluidSynth.cpp
index 48bbbfb24..611aae1c6 100644
--- a/source/backend/plugin/CarlaPluginFluidSynth.cpp
+++ b/source/backend/plugin/CarlaPluginFluidSynth.cpp
@@ -919,9 +919,6 @@ public:
pData->extraHints = 0x0;
pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN;
- if (! kUse16Outs)
- pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
-
bufferSizeChanged(pData->engine->getBufferSize());
reloadPrograms(true);
diff --git a/source/backend/plugin/CarlaPluginInternal.hpp b/source/backend/plugin/CarlaPluginInternal.hpp
index 805b11302..31709c8cb 100644
--- a/source/backend/plugin/CarlaPluginInternal.hpp
+++ b/source/backend/plugin/CarlaPluginInternal.hpp
@@ -47,9 +47,8 @@ const ushort kPluginMaxMidiEvents = 512;
// -----------------------------------------------------------------------
// Extra plugin hints, hidden from backend
-const uint PLUGIN_EXTRA_HINT_HAS_MIDI_IN = 0x01;
-const uint PLUGIN_EXTRA_HINT_HAS_MIDI_OUT = 0x02;
-const uint PLUGIN_EXTRA_HINT_CAN_RUN_RACK = 0x04;
+const uint PLUGIN_EXTRA_HINT_HAS_MIDI_IN = 0x01;
+const uint PLUGIN_EXTRA_HINT_HAS_MIDI_OUT = 0x02;
// -----------------------------------------------------------------------
// Special parameters
diff --git a/source/backend/plugin/CarlaPluginJack.cpp b/source/backend/plugin/CarlaPluginJack.cpp
index ee72f4326..96c1a1c8d 100644
--- a/source/backend/plugin/CarlaPluginJack.cpp
+++ b/source/backend/plugin/CarlaPluginJack.cpp
@@ -576,9 +576,6 @@ public:
if (fInfo.mOuts > 0)
pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_OUT;
- if (fInfo.aIns <= 2 && fInfo.aOuts <= 2 && (fInfo.aIns == fInfo.aOuts || fInfo.aIns == 0 || fInfo.aOuts == 0))
- pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
-
bufferSizeChanged(pData->engine->getBufferSize());
reloadPrograms(true);
diff --git a/source/backend/plugin/CarlaPluginLADSPA.cpp b/source/backend/plugin/CarlaPluginLADSPA.cpp
index e7fb27e1f..0726e55b5 100644
--- a/source/backend/plugin/CarlaPluginLADSPA.cpp
+++ b/source/backend/plugin/CarlaPluginLADSPA.cpp
@@ -788,8 +788,7 @@ public:
#endif
// extra plugin hints
- pData->extraHints = 0x0;
- pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
+ pData->extraHints = 0x0;
// check initial latency
findInitialLatencyValue(aIns, aOuts);
diff --git a/source/backend/plugin/CarlaPluginLV2.cpp b/source/backend/plugin/CarlaPluginLV2.cpp
index a5153f44c..f742bfc9d 100644
--- a/source/backend/plugin/CarlaPluginLV2.cpp
+++ b/source/backend/plugin/CarlaPluginLV2.cpp
@@ -30,7 +30,6 @@
#include "CarlaPluginUI.hpp"
#include "Lv2AtomRingBuffer.hpp"
-#include "../engine/CarlaEngineOsc.hpp"
#include "../modules/lilv/config/lilv_config.h"
extern "C" {
@@ -519,7 +518,6 @@ public:
fCvInBuffers(nullptr),
fCvOutBuffers(nullptr),
fParamBuffers(nullptr),
- fCanInit2(true),
fNeedsFixedBuffers(false),
fNeedsUiClose(false),
fLatencyIndex(-1),
@@ -841,7 +839,7 @@ public:
if (pData->engine->getOptions().forceStereo)
pass();
// if inputs or outputs are just 1, then yes we can force stereo
- else if (((pData->audioIn.count == 1 || pData->audioOut.count == 1) && fCanInit2) || fHandle2 != nullptr)
+ else if ((pData->audioIn.count == 1 || pData->audioOut.count == 1) || fHandle2 != nullptr)
options |= PLUGIN_OPTION_FORCE_STEREO;
if (fExt.programs != nullptr)
@@ -2381,7 +2379,7 @@ public:
if (fEventsOut.ctrl != nullptr && fEventsOut.ctrl->port == nullptr)
fEventsOut.ctrl->port = pData->event.portOut;
- if (fCanInit2 && (forcedStereoIn || forcedStereoOut))
+ if (forcedStereoIn || forcedStereoOut)
pData->options |= PLUGIN_OPTION_FORCE_STEREO;
else
pData->options &= ~PLUGIN_OPTION_FORCE_STEREO;
@@ -2415,21 +2413,6 @@ public:
// extra plugin hints
pData->extraHints = 0x0;
- if (! fCanInit2)
- {
- // can't run in rack
- }
- else if (fExt.state != nullptr || fExt.worker != nullptr)
- {
- if ((aIns == 0 || aIns == 2) && (aOuts == 0 || aOuts == 2) && evIns.count() <= 1 && evOuts.count() <= 1)
- pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
- }
- else
- {
- if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0) && evIns.count() <= 1 && evOuts.count() <= 1)
- pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
- }
-
// check initial latency
findInitialLatencyValue(aIns, aOuts);
@@ -2804,7 +2787,7 @@ public:
int32_t rindex;
const double barBeat = static_cast(timeInfo.bbt.beat - 1)
- + (static_cast(timeInfo.bbt.tick) / timeInfo.bbt.ticksPerBeat);
+ + (timeInfo.bbt.tick / timeInfo.bbt.ticksPerBeat);
// update input ports
for (uint32_t k=0; k < pData->param.count; ++k)
@@ -4500,7 +4483,10 @@ public:
CARLA_SAFE_ASSERT_RETURN(value != nullptr, LV2_STATE_ERR_NO_PROPERTY);
CARLA_SAFE_ASSERT_RETURN(size > 0, LV2_STATE_ERR_NO_PROPERTY);
CARLA_SAFE_ASSERT_RETURN(type != kUridNull, LV2_STATE_ERR_BAD_TYPE);
- CARLA_SAFE_ASSERT_RETURN(flags & LV2_STATE_IS_POD, LV2_STATE_ERR_BAD_FLAGS);
+
+ // FIXME linuxsampler does not set POD flag
+ // CARLA_SAFE_ASSERT_RETURN(flags & LV2_STATE_IS_POD, LV2_STATE_ERR_BAD_FLAGS);
+
carla_debug("CarlaPluginLV2::handleStateStore(%i:\"%s\", %p, " P_SIZE ", %i:\"%s\", %i)",
key, carla_lv2_urid_unmap(this, key), value, size, type, carla_lv2_urid_unmap(this, type), flags);
@@ -4543,6 +4529,9 @@ public:
pData->custom.append(newData);
return LV2_STATE_SUCCESS;
+
+ // unused
+ (void)flags;
}
const void* handleStateRetrieve(const uint32_t key, size_t* const size, uint32_t* const type, uint32_t* const flags)
@@ -5244,9 +5233,6 @@ public:
return false;
}
- if (std::strcmp(uri, "http://hyperglitch.com/dev/VocProc") == 0)
- fCanInit2 = false;
-
recheckExtensions();
// ---------------------------------------------------------------
@@ -5259,13 +5245,10 @@ public:
else if (options & PLUGIN_OPTION_FIXED_BUFFERS)
pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
- if (fCanInit2)
- {
- if (pData->engine->getOptions().forceStereo)
- pData->options |= PLUGIN_OPTION_FORCE_STEREO;
- else if (options & PLUGIN_OPTION_FORCE_STEREO)
- pData->options |= PLUGIN_OPTION_FORCE_STEREO;
- }
+ if (pData->engine->getOptions().forceStereo)
+ pData->options |= PLUGIN_OPTION_FORCE_STEREO;
+ else if (options & PLUGIN_OPTION_FORCE_STEREO)
+ pData->options |= PLUGIN_OPTION_FORCE_STEREO;
if (getMidiInCount() != 0)
{
@@ -5765,7 +5748,6 @@ private:
float** fCvOutBuffers;
float* fParamBuffers;
- bool fCanInit2; // some plugins don't like 2 instances
bool fNeedsFixedBuffers;
bool fNeedsUiClose;
int32_t fLatencyIndex; // -1 if invalid
diff --git a/source/backend/plugin/CarlaPluginNative.cpp b/source/backend/plugin/CarlaPluginNative.cpp
index b5b2878f3..3e40a6166 100644
--- a/source/backend/plugin/CarlaPluginNative.cpp
+++ b/source/backend/plugin/CarlaPluginNative.cpp
@@ -253,7 +253,8 @@ public:
fIsUiVisible(false),
fAudioInBuffers(nullptr),
fAudioOutBuffers(nullptr),
- fMidiEventCount(0),
+ fMidiEventInCount(0),
+ fMidiEventOutCount(0),
fCurBufferSize(engine->getBufferSize()),
fCurSampleRate(engine->getSampleRate()),
fMidiIn(),
@@ -263,7 +264,8 @@ public:
carla_debug("CarlaPluginNative::CarlaPluginNative(%p, %i)", engine, id);
carla_fill(fCurMidiProgs, 0, MAX_MIDI_CHANNELS);
- carla_zeroStructs(fMidiEvents, kPluginMaxMidiEvents*2);
+ carla_zeroStructs(fMidiInEvents, kPluginMaxMidiEvents);
+ carla_zeroStructs(fMidiOutEvents, kPluginMaxMidiEvents);
carla_zeroStruct(fTimeInfo);
fHost.handle = this;
@@ -410,8 +412,8 @@ public:
uint options = 0x0;
- // can't disable fixed buffers if using MIDI output
- if (fDescriptor->midiOuts == 0 && (fDescriptor->hints & NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS) == 0)
+ // can't disable fixed buffers if required by the plugin
+ if ((fDescriptor->hints & NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS) == 0x0)
options |= PLUGIN_OPTION_FIXED_BUFFERS;
// can't disable forced stereo if enabled in the engine
@@ -1293,9 +1295,6 @@ public:
// extra plugin hints
pData->extraHints = 0x0;
- if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0) && mIns <= 1 && mOuts <= 1)
- pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
-
bufferSizeChanged(pData->engine->getBufferSize());
reloadPrograms(true);
@@ -1495,8 +1494,9 @@ public:
return;
}
- fMidiEventCount = 0;
- carla_zeroStructs(fMidiEvents, kPluginMaxMidiEvents*2);
+ fMidiEventInCount = fMidiEventOutCount = 0;
+ carla_zeroStructs(fMidiInEvents, kPluginMaxMidiEvents);
+ carla_zeroStructs(fMidiOutEvents, kPluginMaxMidiEvents);
// --------------------------------------------------------------------------------------------------------
// Check if needs reset
@@ -1505,31 +1505,31 @@ public:
{
if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
{
- fMidiEventCount = MAX_MIDI_CHANNELS*2;
+ fMidiEventInCount = MAX_MIDI_CHANNELS*2;
for (uint8_t k=0, i=MAX_MIDI_CHANNELS; k < MAX_MIDI_CHANNELS; ++k)
{
- fMidiEvents[k].data[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (k & MIDI_CHANNEL_BIT));
- fMidiEvents[k].data[1] = MIDI_CONTROL_ALL_NOTES_OFF;
- fMidiEvents[k].data[2] = 0;
- fMidiEvents[k].size = 3;
-
- fMidiEvents[k+i].data[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (k & MIDI_CHANNEL_BIT));
- fMidiEvents[k+i].data[1] = MIDI_CONTROL_ALL_SOUND_OFF;
- fMidiEvents[k+i].data[2] = 0;
- fMidiEvents[k+i].size = 3;
+ fMidiInEvents[k].data[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (k & MIDI_CHANNEL_BIT));
+ fMidiInEvents[k].data[1] = MIDI_CONTROL_ALL_NOTES_OFF;
+ fMidiInEvents[k].data[2] = 0;
+ fMidiInEvents[k].size = 3;
+
+ fMidiInEvents[k+i].data[0] = uint8_t(MIDI_STATUS_CONTROL_CHANGE | (k & MIDI_CHANNEL_BIT));
+ fMidiInEvents[k+i].data[1] = MIDI_CONTROL_ALL_SOUND_OFF;
+ fMidiInEvents[k+i].data[2] = 0;
+ fMidiInEvents[k+i].size = 3;
}
}
else if (pData->ctrlChannel >= 0 && pData->ctrlChannel < MAX_MIDI_CHANNELS)
{
- fMidiEventCount = MAX_MIDI_NOTE;
+ fMidiEventInCount = MAX_MIDI_NOTE;
for (uint8_t k=0; k < MAX_MIDI_NOTE; ++k)
{
- fMidiEvents[k].data[0] = uint8_t(MIDI_STATUS_NOTE_OFF | (pData->ctrlChannel & MIDI_CHANNEL_BIT));
- fMidiEvents[k].data[1] = k;
- fMidiEvents[k].data[2] = 0;
- fMidiEvents[k].size = 3;
+ fMidiInEvents[k].data[0] = uint8_t(MIDI_STATUS_NOTE_OFF | (pData->ctrlChannel & MIDI_CHANNEL_BIT));
+ fMidiInEvents[k].data[1] = k;
+ fMidiInEvents[k].data[2] = 0;
+ fMidiInEvents[k].size = 3;
}
}
@@ -1577,13 +1577,13 @@ public:
{
ExternalMidiNote note = { 0, 0, 0 };
- for (; fMidiEventCount < kPluginMaxMidiEvents*2 && ! pData->extNotes.data.isEmpty();)
+ for (; fMidiEventInCount < kPluginMaxMidiEvents && ! pData->extNotes.data.isEmpty();)
{
note = pData->extNotes.data.getFirst(note, true);
CARLA_SAFE_ASSERT_CONTINUE(note.channel >= 0 && note.channel < MAX_MIDI_CHANNELS);
- NativeMidiEvent& nativeEvent(fMidiEvents[fMidiEventCount++]);
+ NativeMidiEvent& nativeEvent(fMidiInEvents[fMidiEventInCount++]);
nativeEvent.data[0] = uint8_t((note.velo > 0 ? MIDI_STATUS_NOTE_ON : MIDI_STATUS_NOTE_OFF) | (note.channel & MIDI_CHANNEL_BIT));
nativeEvent.data[1] = note.note;
@@ -1641,10 +1641,16 @@ public:
else
nextBankId = 0;
- if (fMidiEventCount > 0)
+ if (fMidiEventInCount > 0)
+ {
+ carla_zeroStructs(fMidiInEvents, fMidiEventInCount);
+ fMidiEventInCount = 0;
+ }
+
+ if (fMidiEventOutCount > 0)
{
- carla_zeroStructs(fMidiEvents, fMidiEventCount);
- fMidiEventCount = 0;
+ carla_zeroStructs(fMidiOutEvents, fMidiEventOutCount);
+ fMidiEventOutCount = 0;
}
}
else
@@ -1744,10 +1750,10 @@ public:
if ((pData->options & PLUGIN_OPTION_SEND_CONTROL_CHANGES) != 0 && ctrlEvent.param < MAX_MIDI_CONTROL)
{
- if (fMidiEventCount >= kPluginMaxMidiEvents*2)
+ if (fMidiEventInCount >= kPluginMaxMidiEvents)
continue;
- NativeMidiEvent& nativeEvent(fMidiEvents[fMidiEventCount++]);
+ NativeMidiEvent& nativeEvent(fMidiInEvents[fMidiEventInCount++]);
carla_zeroStruct(nativeEvent);
nativeEvent.time = sampleAccurate ? startTime : eventTime;
@@ -1768,10 +1774,10 @@ public:
}
else if (pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES)
{
- if (fMidiEventCount >= kPluginMaxMidiEvents*2)
+ if (fMidiEventInCount >= kPluginMaxMidiEvents)
continue;
- NativeMidiEvent& nativeEvent(fMidiEvents[fMidiEventCount++]);
+ NativeMidiEvent& nativeEvent(fMidiInEvents[fMidiEventInCount++]);
carla_zeroStruct(nativeEvent);
nativeEvent.time = sampleAccurate ? startTime : eventTime;
@@ -1810,10 +1816,10 @@ public:
}
else if (pData->options & PLUGIN_OPTION_SEND_PROGRAM_CHANGES)
{
- if (fMidiEventCount >= kPluginMaxMidiEvents*2)
+ if (fMidiEventInCount >= kPluginMaxMidiEvents)
continue;
- NativeMidiEvent& nativeEvent(fMidiEvents[fMidiEventCount++]);
+ NativeMidiEvent& nativeEvent(fMidiInEvents[fMidiEventInCount++]);
carla_zeroStruct(nativeEvent);
nativeEvent.time = sampleAccurate ? startTime : eventTime;
@@ -1826,10 +1832,10 @@ public:
case kEngineControlEventTypeAllSoundOff:
if (pData->options & PLUGIN_OPTION_SEND_ALL_SOUND_OFF)
{
- if (fMidiEventCount >= kPluginMaxMidiEvents*2)
+ if (fMidiEventInCount >= kPluginMaxMidiEvents)
continue;
- NativeMidiEvent& nativeEvent(fMidiEvents[fMidiEventCount++]);
+ NativeMidiEvent& nativeEvent(fMidiInEvents[fMidiEventInCount++]);
carla_zeroStruct(nativeEvent);
nativeEvent.time = sampleAccurate ? startTime : eventTime;
@@ -1851,10 +1857,10 @@ public:
}
#endif
- if (fMidiEventCount >= kPluginMaxMidiEvents*2)
+ if (fMidiEventInCount >= kPluginMaxMidiEvents)
continue;
- NativeMidiEvent& nativeEvent(fMidiEvents[fMidiEventCount++]);
+ NativeMidiEvent& nativeEvent(fMidiInEvents[fMidiEventInCount++]);
carla_zeroStruct(nativeEvent);
nativeEvent.time = sampleAccurate ? startTime : eventTime;
@@ -1869,7 +1875,7 @@ public:
}
case kEngineEventTypeMidi: {
- if (fMidiEventCount >= kPluginMaxMidiEvents*2)
+ if (fMidiEventInCount >= kPluginMaxMidiEvents)
continue;
const EngineMidiEvent& midiEvent(event.midi);
@@ -1895,7 +1901,7 @@ public:
if (status == MIDI_STATUS_NOTE_ON && midiEvent.data[2] == 0)
status = MIDI_STATUS_NOTE_OFF;
- NativeMidiEvent& nativeEvent(fMidiEvents[fMidiEventCount++]);
+ NativeMidiEvent& nativeEvent(fMidiInEvents[fMidiEventInCount++]);
carla_zeroStruct(nativeEvent);
nativeEvent.port = midiEvent.port;
@@ -1931,12 +1937,12 @@ public:
} // End of Plugin processing (no events)
+#ifndef BUILD_BRIDGE
// --------------------------------------------------------------------------------------------------------
- // Control and MIDI Output
+ // Control Output
if (pData->event.portOut != nullptr)
{
-#ifndef BUILD_BRIDGE
float value, curValue;
for (uint32_t k=0; k < pData->param.count; ++k)
@@ -1953,24 +1959,8 @@ public:
pData->event.portOut->writeControlEvent(0, pData->param.data[k].midiChannel, kEngineControlEventTypeParameter, static_cast(pData->param.data[k].midiCC), value);
}
}
+ } // End of Control Output
#endif
-
- // reverse lookup MIDI events
- for (uint32_t k = (kPluginMaxMidiEvents*2)-1; k >= fMidiEventCount; --k)
- {
- if (fMidiEvents[k].data[0] == 0)
- break;
-
- const uint8_t channel = uint8_t(MIDI_GET_CHANNEL_FROM_DATA(fMidiEvents[k].data));
- const uint8_t port = fMidiEvents[k].port;
-
- if (fMidiOut.count > 1 && port < fMidiOut.count)
- fMidiOut.ports[port]->writeMidiEvent(fMidiEvents[k].time, channel, fMidiEvents[k].size, fMidiEvents[k].data);
- else
- pData->event.portOut->writeMidiEvent(fMidiEvents[k].time, channel, fMidiEvents[k].size, fMidiEvents[k].data);
- }
-
- } // End of Control and MIDI Output
}
bool processSingle(const float** const audioIn, float** const audioOut, const float** const cvIn, float** const cvOut, const uint32_t frames, const uint32_t timeOffset)
@@ -2044,19 +2034,19 @@ public:
if (fHandle2 == nullptr)
{
- fDescriptor->process(fHandle, fAudioInBuffers, fAudioOutBuffers, frames, fMidiEvents, fMidiEventCount);
+ fDescriptor->process(fHandle, fAudioInBuffers, fAudioOutBuffers, frames, fMidiInEvents, fMidiEventInCount);
}
else
{
fDescriptor->process(fHandle,
(pData->audioIn.count > 0) ? &fAudioInBuffers[0] : nullptr,
(pData->audioOut.count > 0) ? &fAudioOutBuffers[0] : nullptr,
- frames, fMidiEvents, fMidiEventCount);
+ frames, fMidiInEvents, fMidiEventInCount);
fDescriptor->process(fHandle2,
(pData->audioIn.count > 0) ? &fAudioInBuffers[1] : nullptr,
(pData->audioOut.count > 0) ? &fAudioOutBuffers[1] : nullptr,
- frames, fMidiEvents, fMidiEventCount);
+ frames, fMidiInEvents, fMidiEventInCount);
}
fIsProcessing = false;
@@ -2140,6 +2130,23 @@ public:
}
#endif
+ // --------------------------------------------------------------------------------------------------------
+ // MIDI Output
+
+ if (pData->event.portOut != nullptr)
+ {
+ for (uint32_t k = 0; k < fMidiEventOutCount; --k)
+ {
+ const uint8_t channel = uint8_t(MIDI_GET_CHANNEL_FROM_DATA(fMidiOutEvents[k].data));
+ const uint8_t port = fMidiOutEvents[k].port;
+
+ if (fMidiOut.count > 1 && port < fMidiOut.count)
+ fMidiOut.ports[port]->writeMidiEvent(fMidiOutEvents[k].time+timeOffset, channel, fMidiOutEvents[k].size, fMidiOutEvents[k].data);
+ else
+ pData->event.portOut->writeMidiEvent(fMidiOutEvents[k].time+timeOffset, channel, fMidiOutEvents[k].size, fMidiOutEvents[k].data);
+ }
+ }
+
// --------------------------------------------------------------------------------------------------------
pData->singleMutex.unlock();
@@ -2351,18 +2358,14 @@ protected:
CARLA_SAFE_ASSERT_RETURN(event != nullptr, false);
CARLA_SAFE_ASSERT_RETURN(event->data[0] != 0, false);
- // reverse-find first free event, and put it there
- for (uint32_t i=(kPluginMaxMidiEvents*2)-1; i >= fMidiEventCount; --i)
+ if (fMidiEventOutCount == kPluginMaxMidiEvents)
{
- if (fMidiEvents[i].data[0] != 0)
- continue;
-
- std::memcpy(&fMidiEvents[i], event, sizeof(NativeMidiEvent));
- return true;
+ carla_stdout("CarlaPluginNative::handleWriteMidiEvent(%p) - buffer full", event);
+ return false;
}
- carla_stdout("CarlaPluginNative::handleWriteMidiEvent(%p) - buffer full", event);
- return false;
+ std::memcpy(&fMidiOutEvents[fMidiEventOutCount++], event, sizeof(NativeMidiEvent));
+ return true;
}
void handleUiParameterChanged(const uint32_t index, const float value)
@@ -2564,7 +2567,7 @@ public:
pData->options = 0x0;
- if (fDescriptor->midiOuts != 0 || (fDescriptor->hints & NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS) != 0)
+ if (fDescriptor->hints & NATIVE_PLUGIN_NEEDS_FIXED_BUFFERS)
pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
else if (options & PLUGIN_OPTION_FIXED_BUFFERS)
pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
@@ -2614,8 +2617,10 @@ private:
float** fAudioInBuffers;
float** fAudioOutBuffers;
- uint32_t fMidiEventCount;
- NativeMidiEvent fMidiEvents[kPluginMaxMidiEvents*2];
+ uint32_t fMidiEventInCount;
+ uint32_t fMidiEventOutCount;
+ NativeMidiEvent fMidiInEvents[kPluginMaxMidiEvents];
+ NativeMidiEvent fMidiOutEvents[kPluginMaxMidiEvents];
int32_t fCurMidiProgs[MAX_MIDI_CHANNELS];
uint32_t fCurBufferSize;
diff --git a/source/backend/plugin/CarlaPluginSFZero.cpp b/source/backend/plugin/CarlaPluginSFZero.cpp
index cdb696c2f..23a45d9eb 100644
--- a/source/backend/plugin/CarlaPluginSFZero.cpp
+++ b/source/backend/plugin/CarlaPluginSFZero.cpp
@@ -293,7 +293,6 @@ public:
// extra plugin hints
pData->extraHints = 0x0;
pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_IN;
- pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
bufferSizeChanged(pData->engine->getBufferSize());
reloadPrograms(true);
diff --git a/source/backend/plugin/CarlaPluginVST2.cpp b/source/backend/plugin/CarlaPluginVST2.cpp
index 72c2647b8..9b05aa006 100644
--- a/source/backend/plugin/CarlaPluginVST2.cpp
+++ b/source/backend/plugin/CarlaPluginVST2.cpp
@@ -118,7 +118,7 @@ public:
if (fEffect != nullptr)
{
- dispatcher(effClose, 0, 0, nullptr, 0.0f);
+ dispatcher(effClose);
fEffect = nullptr;
}
@@ -161,7 +161,7 @@ public:
{
CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, CarlaPlugin::getCategory());
- const intptr_t category(dispatcher(effGetPlugCategory, 0, 0, nullptr, 0.0f));
+ const intptr_t category = dispatcher(effGetPlugCategory);
switch (category)
{
@@ -209,7 +209,7 @@ public:
*dataPtr = nullptr;
try {
- const intptr_t ret = dispatcher(effGetChunk, 0 /* bank */, 0, dataPtr, 0.0f);
+ const intptr_t ret = dispatcher(effGetChunk, 0 /* bank */, 0, dataPtr);
CARLA_SAFE_ASSERT_RETURN(ret >= 0, 0);
return static_cast(ret);
} CARLA_SAFE_EXCEPTION_RETURN("CarlaPluginVST2::getChunkData", 0);
@@ -260,7 +260,7 @@ public:
CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
strBuf[0] = '\0';
- dispatcher(effGetProductString, 0, 0, strBuf, 0.0f);
+ dispatcher(effGetProductString, 0, 0, strBuf);
}
void getMaker(char* const strBuf) const noexcept override
@@ -268,7 +268,7 @@ public:
CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
strBuf[0] = '\0';
- dispatcher(effGetVendorString, 0, 0, strBuf, 0.0f);
+ dispatcher(effGetVendorString, 0, 0, strBuf);
}
void getCopyright(char* const strBuf) const noexcept override
@@ -281,7 +281,7 @@ public:
CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
strBuf[0] = '\0';
- dispatcher(effGetEffectName, 0, 0, strBuf, 0.0f);
+ dispatcher(effGetEffectName, 0, 0, strBuf);
}
void getParameterName(const uint32_t parameterId, char* const strBuf) const noexcept override
@@ -294,7 +294,7 @@ public:
VstParameterProperties prop;
carla_zeroStruct(prop);
- if (dispatcher(effGetParameterProperties, static_cast(parameterId), 0, &prop, 0) == 1 && prop.label[0] != '\0')
+ if (dispatcher(effGetParameterProperties, static_cast(parameterId), 0, &prop) == 1 && prop.label[0] != '\0')
{
std::strncpy(strBuf, prop.label, 64);
strBuf[64] = '\0';
@@ -302,7 +302,7 @@ public:
}
strBuf[0] = '\0';
- dispatcher(effGetParamName, static_cast(parameterId), 0, strBuf, 0.0f);
+ dispatcher(effGetParamName, static_cast(parameterId), 0, strBuf);
}
void getParameterText(const uint32_t parameterId, char* const strBuf) noexcept override
@@ -311,7 +311,7 @@ public:
CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
strBuf[0] = '\0';
- dispatcher(effGetParamDisplay, static_cast(parameterId), 0, strBuf, 0.0f);
+ dispatcher(effGetParamDisplay, static_cast(parameterId), 0, strBuf);
if (strBuf[0] == '\0')
std::snprintf(strBuf, STR_MAX, "%f", getParameterValue(parameterId));
@@ -323,7 +323,7 @@ public:
CARLA_SAFE_ASSERT_RETURN(parameterId < pData->param.count,);
strBuf[0] = '\0';
- dispatcher(effGetParamLabel, static_cast(parameterId), 0, strBuf, 0.0f);
+ dispatcher(effGetParamLabel, static_cast(parameterId), 0, strBuf);
}
// -------------------------------------------------------------------
@@ -391,7 +391,7 @@ public:
{
const ScopedSingleProcessLocker spl(this, true);
- dispatcher(effSetChunk, 0 /* bank */, static_cast(dataSize), fLastChunk, 0.0f);
+ dispatcher(effSetChunk, 0 /* bank */, static_cast(dataSize), fLastChunk);
}
// simulate an updateDisplay callback
@@ -414,19 +414,19 @@ public:
if (index >= 0)
{
try {
- dispatcher(effBeginSetProgram, 0, 0, nullptr, 0.0f);
+ dispatcher(effBeginSetProgram);
} CARLA_SAFE_EXCEPTION_RETURN("effBeginSetProgram",);
{
const ScopedSingleProcessLocker spl(this, (sendGui || sendOsc || sendCallback));
try {
- dispatcher(effSetProgram, 0, index, nullptr, 0.0f);
+ dispatcher(effSetProgram, 0, index);
} CARLA_SAFE_EXCEPTION("effSetProgram");
}
try {
- dispatcher(effEndSetProgram, 0, 0, nullptr, 0.0f);
+ dispatcher(effEndSetProgram);
} CARLA_SAFE_EXCEPTION("effEndSetProgram");
}
@@ -439,15 +439,15 @@ public:
CARLA_SAFE_ASSERT_RETURN(uindex < pData->prog.count,);
try {
- dispatcher(effBeginSetProgram, 0, 0, nullptr, 0.0f);
+ dispatcher(effBeginSetProgram);
} CARLA_SAFE_EXCEPTION_RETURN("effBeginSetProgram",);
try {
- dispatcher(effSetProgram, 0, static_cast(uindex), nullptr, 0.0f);
+ dispatcher(effSetProgram, 0, static_cast(uindex));
} CARLA_SAFE_EXCEPTION("effSetProgram");
try {
- dispatcher(effEndSetProgram, 0, 0, nullptr, 0.0f);
+ dispatcher(effEndSetProgram);
} CARLA_SAFE_EXCEPTION("effEndSetProgram");
CarlaPlugin::setProgramRT(uindex);
@@ -466,9 +466,8 @@ public:
CarlaString uiTitle(pData->name);
uiTitle += " (GUI)";
- intptr_t value = 0;
- void* vstPtr = nullptr;
- ERect* vstRect = nullptr;
+ intptr_t value = 0;
+ ERect* vstRect = nullptr;
if (fUI.window == nullptr)
{
@@ -491,18 +490,13 @@ public:
fUI.window->setTitle(uiTitle.buffer());
}
- vstPtr = fUI.window->getPtr();
-
- dispatcher(effEditGetRect, 0, 0, &vstRect, 0.0f);
-
#ifdef HAVE_X11
value = (intptr_t)fUI.window->getDisplay();
#endif
- if (dispatcher(effEditOpen, 0, value, vstPtr, 0.0f) != 0)
+ if (dispatcher(effEditOpen, 0, value, fUI.window->getPtr()) != 0)
{
- if (vstRect == nullptr || vstRect->right - vstRect->left < 2)
- dispatcher(effEditGetRect, 0, 0, &vstRect, 0.0f);
+ dispatcher(effEditGetRect, 0, 0, &vstRect);
if (vstRect != nullptr)
{
@@ -534,14 +528,14 @@ public:
CARLA_SAFE_ASSERT_RETURN(fUI.window != nullptr,);
fUI.window->hide();
- dispatcher(effEditClose, 0, 0, nullptr, 0.0f);
+ dispatcher(effEditClose);
}
}
void idle() override
{
if (fNeedIdle)
- dispatcher(effIdle, 0, 0, nullptr, 0.0f);
+ dispatcher(effIdle);
CarlaPlugin::idle();
}
@@ -553,7 +547,7 @@ public:
fUI.window->idle();
if (fUI.isVisible)
- dispatcher(effEditIdle, 0, 0, nullptr, 0.0f);
+ dispatcher(effEditIdle);
}
CarlaPlugin::uiIdle();
@@ -690,7 +684,7 @@ public:
double vrange[2] = { 0.0, 1.0 };
bool isInteger = false;
- if (static_cast(dispatcher(effVendorSpecific, static_cast(0xdeadbef0), ij, vrange, 0.0f)) >= 0xbeef)
+ if (static_cast(dispatcher(effVendorSpecific, static_cast(0xdeadbef0), ij, vrange)) >= 0xbeef)
{
min = static_cast(vrange[0]);
max = static_cast(vrange[1]);
@@ -708,7 +702,7 @@ public:
// only use values as integer if we have a proper range
if (max - min >= 1.0f)
- isInteger = dispatcher(effVendorSpecific, kVstParameterUsesIntStep, ij, nullptr, 0.0f) >= 0xbeef;
+ isInteger = dispatcher(effVendorSpecific, kVstParameterUsesIntStep, ij) >= 0xbeef;
}
else
{
@@ -730,7 +724,7 @@ public:
stepLarge = range/10.0f;
}
}
- else if (dispatcher(effGetParameterProperties, ij, 0, &prop, 0) == 1)
+ else if (dispatcher(effGetParameterProperties, ij, 0, &prop) == 1)
{
#if 0
if (prop.flags & kVstParameterUsesIntegerMinMax)
@@ -799,7 +793,7 @@ public:
pData->param.data[j].hints |= PARAMETER_IS_ENABLED;
pData->param.data[j].hints |= PARAMETER_USES_CUSTOM_TEXT;
- if ((pData->hints & PLUGIN_USES_OLD_VSTSDK) != 0 || dispatcher(effCanBeAutomated, ij, 0, nullptr, 0.0f) == 1)
+ if ((pData->hints & PLUGIN_USES_OLD_VSTSDK) != 0 || dispatcher(effCanBeAutomated, ij) == 1)
pData->param.data[j].hints |= PARAMETER_IS_AUTOMABLE;
// no such thing as VST default parameters
@@ -851,7 +845,7 @@ public:
}
// plugin hints
- const intptr_t vstCategory = dispatcher(effGetPlugCategory, 0, 0, nullptr, 0.0f);
+ const intptr_t vstCategory = dispatcher(effGetPlugCategory);
pData->hints = 0x0;
@@ -864,7 +858,7 @@ public:
pData->hints |= PLUGIN_NEEDS_UI_MAIN_THREAD;
}
- if (dispatcher(effGetVstVersion, 0, 0, nullptr, 0.0f) < kVstVersion)
+ if (dispatcher(effGetVstVersion) < kVstVersion)
pData->hints |= PLUGIN_USES_OLD_VSTSDK;
if ((fEffect->flags & effFlagsCanReplacing) != 0 && fEffect->processReplacing != fEffect->process)
@@ -891,9 +885,6 @@ public:
if (mOuts > 0)
pData->extraHints |= PLUGIN_EXTRA_HINT_HAS_MIDI_OUT;
- if (aIns <= 2 && aOuts <= 2 && (aIns == aOuts || aIns == 0 || aOuts == 0))
- pData->extraHints |= PLUGIN_EXTRA_HINT_CAN_RUN_RACK;
-
// dummy pre-start to get latency and wantEvents() on old plugins
{
activate();
@@ -966,7 +957,7 @@ public:
if (newCount > 0)
setProgram(0, false, false, false, true);
else
- dispatcher(effSetProgram, 0, 0, nullptr, 0.0f);
+ dispatcher(effSetProgram);
}
else
{
@@ -1025,21 +1016,20 @@ public:
{
CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
- dispatcher(effSetProcessPrecision, 0, kVstProcessPrecision32, nullptr, 0.0f);
-
- dispatcher(effSetBlockSizeAndSampleRate, 0,
- static_cast(pData->engine->getBufferSize()), nullptr,
- static_cast(pData->engine->getSampleRate()));
+ const int32_t iBufferSize = static_cast(pData->engine->getBufferSize());
+ const float fSampleRate = static_cast(pData->engine->getSampleRate());
- dispatcher(effSetSampleRate, 0, 0, nullptr, static_cast(pData->engine->getSampleRate()));
- dispatcher(effSetBlockSize, 0, static_cast(pData->engine->getBufferSize()), nullptr, 0.0f);
+ dispatcher(effSetProcessPrecision, 0, kVstProcessPrecision32);
+ dispatcher(effSetBlockSizeAndSampleRate, 0, iBufferSize, nullptr, fSampleRate);
+ dispatcher(effSetSampleRate, 0, 0, nullptr, fSampleRate);
+ dispatcher(effSetBlockSize, 0, iBufferSize);
try {
- dispatcher(effMainsChanged, 0, 1, nullptr, 0.0f);
+ dispatcher(effMainsChanged, 0, 1);
} catch(...) {}
try {
- dispatcher(effStartProcess, 0, 0, nullptr, 0.0f);
+ dispatcher(effStartProcess, 0, 0);
} catch(...) {}
}
@@ -1048,11 +1038,11 @@ public:
CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr,);
try {
- dispatcher(effStopProcess, 0, 0, nullptr, 0.0f);
+ dispatcher(effStopProcess);
} catch(...) {}
try {
- dispatcher(effMainsChanged, 0, 0, nullptr, 0.0f);
+ dispatcher(effMainsChanged);
} catch(...) {}
}
@@ -1138,7 +1128,7 @@ public:
const double ppqBar = double(timeInfo.bbt.bar - 1) * timeInfo.bbt.beatsPerBar;
const double ppqBeat = double(timeInfo.bbt.beat - 1);
- const double ppqTick = double(timeInfo.bbt.tick) / timeInfo.bbt.ticksPerBeat;
+ const double ppqTick = timeInfo.bbt.tick / timeInfo.bbt.ticksPerBeat;
// PPQ Pos
fTimeInfo.ppqPos = ppqBar + ppqBeat + ppqTick;
@@ -1750,7 +1740,7 @@ protected:
// -------------------------------------------------------------------
- intptr_t dispatcher(int32_t opcode, int32_t index, intptr_t value, void* ptr, float opt) const noexcept
+ intptr_t dispatcher(int32_t opcode, int32_t index = 0, intptr_t value = 0, void* ptr = nullptr, float opt = 0.0f) const noexcept
{
CARLA_SAFE_ASSERT_RETURN(fEffect != nullptr, 0);
#ifdef DEBUG
@@ -1920,8 +1910,8 @@ protected:
if (m_active)
{
- effect->dispatcher(effect, effStopProcess, 0, 0, nullptr, 0.0f);
- effect->dispatcher(effect, effMainsChanged, 0, 0, nullptr, 0.0f);
+ effect->dispatcher(effect, effStopProcess);
+ effect->dispatcher(effect, effMainsChanged, 0, 0);
}
reload();
@@ -1929,7 +1919,7 @@ protected:
if (m_active)
{
effect->dispatcher(effect, effMainsChanged, 0, 1, nullptr, 0.0f);
- effect->dispatcher(effect, effStartProcess, 0, 0, nullptr, 0.0f);
+ effect->dispatcher(effect, effStartProcess);
}
x_engine->callback(CALLBACK_RELOAD_ALL, m_id, 0, 0, 0.0, nullptr);
@@ -2051,17 +2041,17 @@ protected:
case audioMasterUpdateDisplay:
// Idle UI if visible
if (fUI.isVisible)
- dispatcher(effEditIdle, 0, 0, nullptr, 0.0f);
+ dispatcher(effEditIdle);
// Update current program
if (pData->prog.count > 0)
{
- const int32_t current = static_cast(dispatcher(effGetProgram, 0, 0, nullptr, 0.0f));
+ const int32_t current = static_cast(dispatcher(effGetProgram));
if (current >= 0 && current < static_cast(pData->prog.count))
{
char strBuf[STR_MAX+1] = { '\0' };
- dispatcher(effGetProgramName, 0, 0, strBuf, 0.0f);
+ dispatcher(effGetProgramName, 0, 0, strBuf);
if (pData->prog.names[current] != nullptr)
delete[] pData->prog.names[current];
@@ -2121,7 +2111,7 @@ protected:
bool canDo(const char* const feature) const noexcept
{
try {
- return (fEffect->dispatcher(fEffect, effCanDo, 0, 0, const_cast(feature), 0.0f) == 1);
+ return (dispatcher(effCanDo, 0, 0, const_cast(feature)) == 1);
} CARLA_SAFE_EXCEPTION_RETURN("vstPluginCanDo", false);
}
@@ -2260,18 +2250,16 @@ public:
fEffect->ptr1 = this;
- dispatcher(effIdentify, 0, 0, 0, 0);
-
- dispatcher(effSetProcessPrecision, 0, kVstProcessPrecision32, nullptr, 0.0f);
-
- dispatcher(effSetBlockSizeAndSampleRate, 0,
- static_cast(pData->engine->getBufferSize()), nullptr,
- static_cast(pData->engine->getSampleRate()));
+ const int32_t iBufferSize = static_cast(pData->engine->getBufferSize());
+ const float fSampleRate = static_cast(pData->engine->getSampleRate());
- dispatcher(effSetSampleRate, 0, 0, nullptr, static_cast(pData->engine->getSampleRate()));
- dispatcher(effSetBlockSize, 0, static_cast(pData->engine->getBufferSize()), nullptr, 0.0f);
+ dispatcher(effIdentify);
+ dispatcher(effSetProcessPrecision, 0, kVstProcessPrecision32);
+ dispatcher(effSetBlockSizeAndSampleRate, 0, iBufferSize, nullptr, fSampleRate);
+ dispatcher(effSetSampleRate, 0, 0, nullptr, fSampleRate);
+ dispatcher(effSetBlockSize, 0, iBufferSize);
- dispatcher(effOpen, 0, 0, nullptr, 0.0f);
+ dispatcher(effOpen);
// ---------------------------------------------------------------
// get info
@@ -2284,7 +2272,7 @@ public:
{
char strBuf[STR_MAX+1];
carla_zeroChars(strBuf, STR_MAX+1);
- dispatcher(effGetEffectName, 0, 0, strBuf, 0.0f);
+ dispatcher(effGetEffectName, 0, 0, strBuf);
if (strBuf[0] != '\0')
pData->name = pData->engine->getUniquePluginName(strBuf);
@@ -2310,15 +2298,15 @@ public:
// ---------------------------------------------------------------
// initialize plugin (part 2)
- for (int i = fEffect->numInputs; --i >= 0;) dispatcher(effConnectInput, i, 1, 0, 0);
- for (int i = fEffect->numOutputs; --i >= 0;) dispatcher(effConnectOutput, i, 1, 0, 0);
+ for (int i = fEffect->numInputs; --i >= 0;) dispatcher(effConnectInput, i, 1);
+ for (int i = fEffect->numOutputs; --i >= 0;) dispatcher(effConnectOutput, i, 1);
- if (dispatcher(effGetVstVersion, 0, 0, nullptr, 0.0f) < kVstVersion)
+ if (dispatcher(effGetVstVersion) < kVstVersion)
pData->hints |= PLUGIN_USES_OLD_VSTSDK;
static const char kHasCockosExtensions[] = "hasCockosExtensions";
- if (static_cast(dispatcher(effCanDo, 0, 0, const_cast(kHasCockosExtensions), 0.0f)) == 0xbeef0000)
+ if (static_cast(dispatcher(effCanDo, 0, 0, const_cast(kHasCockosExtensions))) == 0xbeef0000)
pData->hints |= PLUGIN_HAS_COCKOS_EXTENSIONS;
// ---------------------------------------------------------------
diff --git a/source/bridges-plugin/Makefile b/source/bridges-plugin/Makefile
index a0bed13e8..7b10097c3 100644
--- a/source/bridges-plugin/Makefile
+++ b/source/bridges-plugin/Makefile
@@ -24,7 +24,6 @@ endif
BUILD_CXX_FLAGS += -DBUILD_BRIDGE -I. -I$(CWD) -I$(CWD)/backend -I$(CWD)/includes -I$(CWD)/modules -I$(CWD)/utils
BUILD_CXX_FLAGS += -I$(CWD)/backend/engine -I$(CWD)/backend/plugin
-BUILD_CXX_FLAGS += $(LIBLO_FLAGS)
32BIT_FLAGS += -DBUILD_BRIDGE_ALTERNATIVE_ARCH
64BIT_FLAGS += -DBUILD_BRIDGE_ALTERNATIVE_ARCH
@@ -64,13 +63,12 @@ LIBS_win32 += $(MODULEDIR)/water.win32.a
LIBS_win64 += $(MODULEDIR)/water.win64.a
LINK_FLAGS += $(WATER_LIBS)
-LINK_FLAGS += $(LIBLO_LIBS)
LINK_FLAGS += $(X11_LIBS)
# ----------------------------------------------------------------------------------------------------------------------
-NATIVE_BUILD_FLAGS = $(NATIVE_PLUGINS_FLAGS)
-NATIVE_LINK_FLAGS =
+NATIVE_BUILD_FLAGS = $(NATIVE_PLUGINS_FLAGS) $(LIBLO_FLAGS)
+NATIVE_LINK_FLAGS = $(LIBLO_LIBS)
NATIVE_BUILD_FLAGS += $(FLUIDSYNTH_FLAGS)
NATIVE_LINK_FLAGS += $(FLUIDSYNTH_LIBS)
@@ -126,8 +124,6 @@ OBJS_arch = \
$(OBJDIR)/CarlaEngineClient.cpp.arch.o \
$(OBJDIR)/CarlaEngineData.cpp.arch.o \
$(OBJDIR)/CarlaEngineInternal.cpp.arch.o \
- $(OBJDIR)/CarlaEngineOsc.cpp.arch.o \
- $(OBJDIR)/CarlaEngineOscSend.cpp.arch.o \
$(OBJDIR)/CarlaEnginePorts.cpp.arch.o \
$(OBJDIR)/CarlaEngineThread.cpp.arch.o \
$(OBJDIR)/CarlaEngineJack.cpp.arch.o \
@@ -135,7 +131,6 @@ OBJS_arch = \
$(OBJDIR)/CarlaPlugin.cpp.arch.o \
$(OBJDIR)/CarlaPluginBridge.cpp.arch.o \
$(OBJDIR)/CarlaPluginInternal.cpp.arch.o \
- $(OBJDIR)/CarlaPluginJack.cpp.arch.o \
$(OBJDIR)/CarlaPluginLADSPA.cpp.arch.o \
$(OBJDIR)/CarlaPluginDSSI.cpp.arch.o \
$(OBJDIR)/CarlaPluginLV2.cpp.arch.o \
diff --git a/source/carla_backend.pro b/source/carla_backend.pro
index dfd3dc4a8..dc59f8c59 100644
--- a/source/carla_backend.pro
+++ b/source/carla_backend.pro
@@ -24,7 +24,6 @@ DEFINES += HAVE_ZYN_UI_DEPS
PKGCONFIG += liblo
PKGCONFIG += fftw3
PKGCONFIG += fluidsynth
-PKGCONFIG += linuxsampler
PKGCONFIG += mxml
PKGCONFIG += zlib
diff --git a/source/carla_database.py b/source/carla_database.py
index c493953fd..7c0a014f6 100755
--- a/source/carla_database.py
+++ b/source/carla_database.py
@@ -191,8 +191,13 @@ def runCarlaDiscovery(itype, stype, filename, tool, wineSettings=None):
else:
winePrefix = os.path.expanduser("~/.wine")
+ wineCMD = wineSettings['executable'] if wineSettings['executable'] else "wine"
+
+ if tool.endswith("64.exe"):
+ wineCMD += "64"
+
command.append("WINEPREFIX=" + winePrefix)
- command.append(wineSettings['executable'] if wineSettings['executable'] else "wine")
+ command.append(wineCMD)
command.append(tool)
command.append(stype)
@@ -465,14 +470,6 @@ class SearchPluginsThread(QThread):
else:
self.fCheckLV2 = False
- # Special case for AU, only search native and posix32
- if self.fCheckAU:
- if self.fCheckNative or self.fCheckPosix32:
- if self.fCheckNative: self.fCurCount += 1
- if self.fCheckPosix32: self.fCurCount += 1
- else:
- self.fCheckAU = False
-
# Special case for Sound Kits, only search native
if self.fCheckNative and self.fToolNative:
if self.fCheckSF2: self.fCurCount += 1
diff --git a/source/includes/CarlaNative.h b/source/includes/CarlaNative.h
index a24cae949..806e79ad4 100644
--- a/source/includes/CarlaNative.h
+++ b/source/includes/CarlaNative.h
@@ -157,8 +157,8 @@ typedef struct {
int32_t bar; /** current bar */
int32_t beat; /** current beat-within-bar */
- int32_t tick; /** current tick-within-beat */
- double barStartTick;
+ double tick; /** current tick-within-beat */
+ double barStartTick;
float beatsPerBar; /** time signature "numerator" */
float beatType; /** time signature "denominator" */
diff --git a/source/jackbridge/Makefile b/source/jackbridge/Makefile
index 411349f06..83fb94e53 100644
--- a/source/jackbridge/Makefile
+++ b/source/jackbridge/Makefile
@@ -10,14 +10,14 @@ include ../modules/Makefile.mk
# ----------------------------------------------------------------------------------------------------------------------------
-WINECXX ?= wineg++
+WINECC ?= winegcc
BUILD_CXX_FLAGS += $(JACKBRIDGE_FLAGS)
LINK_FLAGS += $(JACKBRIDGE_LIBS)
WINE_32BIT_FLAGS = $(32BIT_FLAGS)
WINE_64BIT_FLAGS = $(64BIT_FLAGS)
-WINE_LINK_FLAGS = $(LINK_FLAGS) $(LIBDL_LIBS) -lpthread
+WINE_LINK_FLAGS = $(LINK_FLAGS) $(LIBDL_LIBS) -lpthread -lstdc++
ifneq ($(MACOS),true)
WINE_32BIT_FLAGS += -I/usr/include/wine/wine/windows
@@ -151,12 +151,12 @@ $(MODULEDIR)/$(MODULENAME).win64e.a: $(OBJS_win64e)
$(MODULEDIR)/$(MODULENAME)-wine32.dll$(LIB_EXT): $(OBJS_wine32) JackBridgeExport.def
-@mkdir -p $(MODULEDIR)
@echo "Linking $(MODULENAME)-wine32.dll$(LIB_EXT)"
- @$(WINECXX) $^ $(WINE_32BIT_FLAGS) $(WINE_LINK_FLAGS) $(SHARED) -o $@
+ @$(WINECC) $^ $(WINE_32BIT_FLAGS) $(WINE_LINK_FLAGS) $(SHARED) -o $@
$(MODULEDIR)/$(MODULENAME)-wine64.dll$(LIB_EXT): $(OBJS_wine64) JackBridgeExport.def
-@mkdir -p $(MODULEDIR)
@echo "Linking $(MODULENAME)-wine64.dll$(LIB_EXT)"
- @$(WINECXX) $^ $(WINE_64BIT_FLAGS) $(WINE_LINK_FLAGS) $(SHARED) -o $@
+ @$(WINECC) $^ $(WINE_64BIT_FLAGS) $(WINE_LINK_FLAGS) $(SHARED) -o $@
# ----------------------------------------------------------------------------------------------------------------------------
@@ -207,12 +207,12 @@ $(OBJDIR)/%.cpp.win64.o: %.cpp
$(OBJDIR)/%.cpp.wine32.o: %.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling $< (wine32)"
- @$(WINECXX) $< $(BUILD_CXX_FLAGS) $(32BIT_FLAGS) -c -o $@
+ @$(WINECC) $< $(BUILD_CXX_FLAGS) $(32BIT_FLAGS) -c -o $@
$(OBJDIR)/%.cpp.wine64.o: %.cpp
-@mkdir -p $(OBJDIR)
@echo "Compiling $< (wine64)"
- @$(WINECXX) $< $(BUILD_CXX_FLAGS) $(64BIT_FLAGS) -c -o $@
+ @$(WINECC) $< $(BUILD_CXX_FLAGS) $(64BIT_FLAGS) -c -o $@
# ----------------------------------------------------------------------------------------------------------------------------
diff --git a/source/libjack/libjack.cpp b/source/libjack/libjack.cpp
index 9b0ef5be0..1201181c2 100644
--- a/source/libjack/libjack.cpp
+++ b/source/libjack/libjack.cpp
@@ -602,7 +602,7 @@ bool CarlaJackAppClient::handleRtData()
fServer.position.bar = bridgeTimeInfo.bar;
fServer.position.beat = bridgeTimeInfo.beat;
- fServer.position.tick = bridgeTimeInfo.tick;
+ fServer.position.tick = static_cast(bridgeTimeInfo.tick + 0.5);
fServer.position.beats_per_bar = bridgeTimeInfo.beatsPerBar;
fServer.position.beat_type = bridgeTimeInfo.beatType;
diff --git a/source/modules/rtaudio/RtAudio.cpp b/source/modules/rtaudio/RtAudio.cpp
index f846b4315..d06e03b41 100644
--- a/source/modules/rtaudio/RtAudio.cpp
+++ b/source/modules/rtaudio/RtAudio.cpp
@@ -222,11 +222,12 @@ void RtAudio :: openStream( RtAudio::StreamParameters *outputParameters,
unsigned int *bufferFrames,
RtAudioCallback callback, void *userData,
RtAudio::StreamOptions *options,
+ RtAudioBufferSizeCallback bufSizeCallback,
RtAudioErrorCallback errorCallback )
{
return rtapi_->openStream( outputParameters, inputParameters, format,
sampleRate, bufferFrames, callback,
- userData, options, errorCallback );
+ userData, options, bufSizeCallback, errorCallback );
}
// *************************************************** //
@@ -259,6 +260,7 @@ void RtApi :: openStream( RtAudio::StreamParameters *oParams,
unsigned int *bufferFrames,
RtAudioCallback callback, void *userData,
RtAudio::StreamOptions *options,
+ RtAudioBufferSizeCallback bufSizeCallback,
RtAudioErrorCallback errorCallback )
{
if ( stream_.state != STREAM_CLOSED ) {
@@ -340,6 +342,7 @@ void RtApi :: openStream( RtAudio::StreamParameters *oParams,
stream_.callbackInfo.callback = (void *) callback;
stream_.callbackInfo.userData = userData;
+ stream_.callbackInfo.bufSizeCallback = (void *) bufSizeCallback;
stream_.callbackInfo.errorCallback = (void *) errorCallback;
if ( options ) options->numberOfBuffers = stream_.nBuffers;
@@ -1936,7 +1939,6 @@ const char* RtApiCore :: getErrorCode( OSStatus code )
struct JackHandle {
jack_client_t *client;
jack_port_t **ports[2];
- std::string deviceName[2];
bool xrun[2];
pthread_cond_t condition;
int drainCounter; // Tracks callback counts when draining
@@ -1958,128 +1960,40 @@ RtApiJack :: ~RtApiJack()
unsigned int RtApiJack :: getDeviceCount( void )
{
- // See if we can become a jack client.
- jack_options_t options = (jack_options_t) ( JackNoStartServer ); //JackNullOption;
- jack_status_t *status = NULL;
- jack_client_t *client = jackbridge_client_open( "CarlaJackCount", options, status );
- if ( client == 0 ) return 0;
-
- const char **ports;
- std::string port, previousPort;
- unsigned int nChannels = 0, nDevices = 0;
- ports = jackbridge_get_ports( client, NULL, NULL, 0 );
- if ( ports ) {
- // Parse the port names up to the first colon (:).
- size_t iColon = 0;
- do {
- port = (char *) ports[ nChannels ];
- iColon = port.find(":");
- if ( iColon != std::string::npos ) {
- port = port.substr( 0, iColon + 1 );
- if ( port != previousPort ) {
- nDevices++;
- previousPort = port;
- }
- }
- } while ( ports[++nChannels] );
- jackbridge_free( ports );
- }
-
- jackbridge_client_close( client );
- return nDevices;
+ return 2;
}
RtAudio::DeviceInfo RtApiJack :: getDeviceInfo( unsigned int device )
{
- RtAudio::DeviceInfo info;
- info.probed = false;
+ static RtAudio::DeviceInfo devInfo[3];
- jack_options_t options = (jack_options_t) ( JackNoStartServer ); //JackNullOption
- jack_status_t *status = NULL;
- jack_client_t *client = jackbridge_client_open( "CarlaJackInfo", options, status );
- if ( client == 0 ) {
- errorText_ = "RtApiJack::getDeviceInfo: Jack server not found or connection error!";
- error( RtAudioError::WARNING );
- return info;
- }
-
- const char **ports;
- std::string port, previousPort;
- unsigned int nPorts = 0, nDevices = 0;
- ports = jackbridge_get_ports( client, NULL, NULL, 0 );
- if ( ports ) {
- // Parse the port names up to the first colon (:).
- size_t iColon = 0;
- do {
- port = (char *) ports[ nPorts ];
- iColon = port.find(":");
- if ( iColon != std::string::npos ) {
- port = port.substr( 0, iColon );
- if ( port != previousPort ) {
- if ( nDevices == device ) info.name = port;
- nDevices++;
- previousPort = port;
- }
- }
- } while ( ports[++nPorts] );
- jackbridge_free( ports );
- }
-
- if ( device >= nDevices ) {
- jackbridge_client_close( client );
- errorText_ = "RtApiJack::getDeviceInfo: device ID is invalid!";
- error( RtAudioError::INVALID_USE );
- return info;
- }
-
- // Get the current jack server sample rate.
- info.sampleRates.clear();
-
- info.preferredSampleRate = jackbridge_get_sample_rate( client );
- info.sampleRates.push_back( info.preferredSampleRate );
-
- // Count the available ports containing the client name as device
- // channels. Jack "input ports" equal RtAudio output channels.
- unsigned int nChannels = 0;
- ports = jackbridge_get_ports( client, info.name.c_str(), NULL, JackPortIsInput );
- if ( ports ) {
- while ( ports[ nChannels ] ) nChannels++;
- jackbridge_free( ports );
- info.outputChannels = nChannels;
- }
-
- // Jack "output ports" equal RtAudio input channels.
- nChannels = 0;
- ports = jackbridge_get_ports( client, info.name.c_str(), NULL, JackPortIsOutput );
- if ( ports ) {
- while ( ports[ nChannels ] ) nChannels++;
- jackbridge_free( ports );
- info.inputChannels = nChannels;
+ if (! devInfo[0].probed)
+ {
+ devInfo[0].probed = devInfo[1].probed = true;
+ devInfo[0].outputChannels = devInfo[1].outputChannels = 2;
+ devInfo[0].inputChannels = devInfo[1].inputChannels = 2;
+ devInfo[0].duplexChannels = devInfo[1].duplexChannels = 2;
+ devInfo[0].isDefaultOutput = devInfo[1].isDefaultOutput = true;
+ devInfo[0].isDefaultInput = devInfo[1].isDefaultInput = true;
+ devInfo[0].nativeFormats = devInfo[1].nativeFormats = RTAUDIO_FLOAT32;
+ devInfo[0].name = "Auto-connect ON";
+ devInfo[1].name = "Auto-connect OFF";
}
- if ( info.outputChannels == 0 && info.inputChannels == 0 ) {
- jackbridge_client_close(client);
- errorText_ = "RtApiJack::getDeviceInfo: error determining Jack input/output channels!";
- error( RtAudioError::WARNING );
- return info;
- }
+ if (device > 2)
+ device = 2;
- // If device opens for both playback and capture, we determine the channels.
- if ( info.outputChannels > 0 && info.inputChannels > 0 )
- info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels;
+ return devInfo[device];
+}
- // Jack always uses 32-bit floats.
- info.nativeFormats = RTAUDIO_FLOAT32;
+static int jackBufferSizeHandler( jack_nframes_t nframes, void *infoPointer )
+{
+ CallbackInfo *info = (CallbackInfo *) infoPointer;
- // Jack doesn't provide default devices so we'll use the first available one.
- if ( device == 0 && info.outputChannels > 0 )
- info.isDefaultOutput = true;
- if ( device == 0 && info.inputChannels > 0 )
- info.isDefaultInput = true;
+ RtApiJack *object = (RtApiJack *) info->object;
+ if ( object->bufferSizeEvent( (unsigned long) nframes ) == false ) return 1;
- jackbridge_client_close(client);
- info.probed = true;
- return info;
+ return 0;
}
static int jackCallbackHandler( jack_nframes_t nframes, void *infoPointer )
@@ -2149,7 +2063,7 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
if ( options && !options->streamName.empty() )
client = jackbridge_client_open( options->streamName.c_str(), jackoptions, status );
else
- client = jackbridge_client_open( "CarlaJack", jackoptions, status );
+ client = jackbridge_client_open( "Carla", jackoptions, status );
if ( client == 0 ) {
errorText_ = "RtApiJack::probeDeviceOpen: Jack server not found or connection error!";
error( RtAudioError::WARNING );
@@ -2161,51 +2075,6 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
client = handle->client;
}
- const char **ports;
- std::string port, previousPort, deviceName;
- unsigned int nPorts = 0, nDevices = 0;
- ports = jackbridge_get_ports( client, NULL, NULL, 0 );
- if ( ports ) {
- // Parse the port names up to the first colon (:).
- size_t iColon = 0;
- do {
- port = (char *) ports[ nPorts ];
- iColon = port.find(":");
- if ( iColon != std::string::npos ) {
- port = port.substr( 0, iColon );
- if ( port != previousPort ) {
- if ( nDevices == device ) deviceName = port;
- nDevices++;
- previousPort = port;
- }
- }
- } while ( ports[++nPorts] );
- jackbridge_free( ports );
- }
-
- if ( device >= nDevices ) {
- errorText_ = "RtApiJack::probeDeviceOpen: device ID is invalid!";
- return FAILURE;
- }
-
- // Count the available ports containing the client name as device
- // channels. Jack "input ports" equal RtAudio output channels.
- unsigned int nChannels = 0;
- unsigned long flag = JackPortIsInput;
- if ( mode == INPUT ) flag = JackPortIsOutput;
- ports = jackbridge_get_ports( client, deviceName.c_str(), NULL, flag );
- if ( ports ) {
- while ( ports[ nChannels ] ) nChannels++;
- jackbridge_free( ports );
- }
-
- // Compare the jack ports for specified client to the requested number of channels.
- if ( nChannels < (channels + firstChannel) ) {
- errorStream_ << "RtApiJack::probeDeviceOpen: requested number of channels (" << channels << ") + offset (" << firstChannel << ") not found for specified device (" << device << ":" << deviceName << ").";
- errorText_ = errorStream_.str();
- return FAILURE;
- }
-
// Check the jack server sample rate.
unsigned int jackRate = jackbridge_get_sample_rate( client );
if ( sampleRate != jackRate ) {
@@ -2214,7 +2083,8 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
stream_.sampleRate = jackRate;
// Get the latency of the JACK port.
- ports = jackbridge_get_ports( client, deviceName.c_str(), NULL, flag );
+ const char **ports;
+ ports = jackbridge_get_ports( client, "system:", NULL, JackPortIsInput );
if ( ports[ firstChannel ] ) {
// Added by Ge Wang
jack_latency_callback_mode_t cbmode = (mode == INPUT ? JackCaptureLatency : JackPlaybackLatency);
@@ -2274,11 +2144,10 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
stream_.apiHandle = (void *) handle;
handle->client = client;
}
- handle->deviceName[mode] = deviceName;
// Allocate necessary internal buffers.
unsigned long bufferBytes;
- bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat );
+ bufferBytes = stream_.nUserChannels[mode] * 8192 * formatBytes( stream_.userFormat );
stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 );
if ( stream_.userBuffer[mode] == NULL ) {
errorText_ = "RtApiJack::probeDeviceOpen: error allocating user buffer memory.";
@@ -2299,7 +2168,7 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
}
if ( makeBuffer ) {
- bufferBytes *= *bufferSize;
+ bufferBytes *= 8192;
if ( stream_.deviceBuffer ) free( stream_.deviceBuffer );
stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 );
if ( stream_.deviceBuffer == NULL ) {
@@ -2326,6 +2195,7 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
stream_.mode = DUPLEX;
else {
stream_.mode = mode;
+ jackbridge_set_buffer_size_callback( handle->client, jackBufferSizeHandler, (void *) &stream_.callbackInfo );
jackbridge_set_process_callback( handle->client, jackCallbackHandler, (void *) &stream_.callbackInfo );
jackbridge_set_xrun_callback( handle->client, jackXrun, (void *) &stream_.apiHandle );
jackbridge_on_shutdown( handle->client, jackShutdown, (void *) &stream_.callbackInfo );
@@ -2348,6 +2218,9 @@ bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne
}
}
+ // auto-connect "device" is #1
+ shouldAutoconnect_ = device == 0;
+
// Setup the buffer conversion information structure. We don't use
// buffers to do channel offsets, so we override that parameter
// here.
@@ -2446,7 +2319,7 @@ void RtApiJack :: startStream( void )
// Get the list of available ports.
if ( shouldAutoconnect_ && (stream_.mode == OUTPUT || stream_.mode == DUPLEX) ) {
result = false;
- ports = jackbridge_get_ports( handle->client, handle->deviceName[0].c_str(), NULL, JackPortIsInput);
+ ports = jackbridge_get_ports( handle->client, "system:", NULL, JackPortIsInput);
if ( ports == NULL) {
errorText_ = "RtApiJack::startStream(): error determining available JACK input ports!";
goto unlock;
@@ -2470,7 +2343,7 @@ void RtApiJack :: startStream( void )
if ( shouldAutoconnect_ && (stream_.mode == INPUT || stream_.mode == DUPLEX) ) {
result = false;
- ports = jackbridge_get_ports( handle->client, handle->deviceName[1].c_str(), NULL, JackPortIsOutput );
+ ports = jackbridge_get_ports( handle->client, "system:", NULL, JackPortIsOutput );
if ( ports == NULL) {
errorText_ = "RtApiJack::startStream(): error determining available JACK output ports!";
goto unlock;
@@ -2560,8 +2433,8 @@ bool RtApiJack :: callbackEvent( unsigned long nframes )
error( RtAudioError::WARNING );
return FAILURE;
}
- if ( stream_.bufferSize != nframes ) {
- errorText_ = "RtApiCore::callbackEvent(): the JACK buffer size has changed ... cannot process!";
+ if ( nframes > 8192 ) {
+ errorText_ = "RtApiCore::callbackEvent(): the JACK buffer size is too big ... cannot process!";
error( RtAudioError::WARNING );
return FAILURE;
}
@@ -2595,7 +2468,7 @@ bool RtApiJack :: callbackEvent( unsigned long nframes )
handle->xrun[1] = false;
}
int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1],
- stream_.bufferSize, streamTime, status, info->userData );
+ nframes, streamTime, status, info->userData );
if ( cbReturnValue == 2 ) {
stream_.state = STREAM_STOPPING;
handle->drainCounter = 2;
@@ -2665,6 +2538,26 @@ bool RtApiJack :: callbackEvent( unsigned long nframes )
RtApi::tickStreamTime();
return SUCCESS;
}
+
+bool RtApiJack :: bufferSizeEvent( unsigned long nframes )
+{
+ if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) return SUCCESS;
+ if ( stream_.state == STREAM_CLOSED ) {
+ errorText_ = "RtApiCore::callbackEvent(): the stream is closed ... this shouldn't happen!";
+ error( RtAudioError::WARNING );
+ return FAILURE;
+ }
+ if ( nframes > 8192 ) {
+ errorText_ = "RtApiCore::callbackEvent(): the JACK buffer size is too big ... cannot process!";
+ error( RtAudioError::WARNING );
+ return FAILURE;
+ }
+
+ CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo;
+
+ RtAudioBufferSizeCallback callback = (RtAudioBufferSizeCallback) info->bufSizeCallback;
+ return callback( nframes, info->userData );
+}
//******************** End of __UNIX_JACK__ *********************//
#endif
diff --git a/source/modules/rtaudio/RtAudio.h b/source/modules/rtaudio/RtAudio.h
index c28fefc85..cd24ec600 100644
--- a/source/modules/rtaudio/RtAudio.h
+++ b/source/modules/rtaudio/RtAudio.h
@@ -246,6 +246,9 @@ class RTAUDIO_DLL_PUBLIC RtAudioError : public std::runtime_error
*/
typedef void (*RtAudioErrorCallback)( RtAudioError::Type type, const std::string &errorText );
+//! RtAudio buffer size change callback.
+typedef bool (*RtAudioBufferSizeCallback)( unsigned int bufferSize, void* userData );
+
// **************************************************************** //
//
// RtAudio class declaration.
@@ -494,7 +497,9 @@ class RTAUDIO_DLL_PUBLIC RtAudio
RtAudio::StreamParameters *inputParameters,
RtAudioFormat format, unsigned int sampleRate,
unsigned int *bufferFrames, RtAudioCallback callback,
- void *userData = NULL, RtAudio::StreamOptions *options = NULL, RtAudioErrorCallback errorCallback = NULL );
+ void *userData = NULL, RtAudio::StreamOptions *options = NULL,
+ RtAudioBufferSizeCallback bufSizeCallback = NULL,
+ RtAudioErrorCallback errorCallback = NULL );
//! A function that closes a stream and frees any associated stream memory.
/*!
@@ -611,6 +616,7 @@ struct CallbackInfo {
ThreadHandle thread;
void *callback;
void *userData;
+ void *bufSizeCallback;
void *errorCallback;
void *apiInfo; // void pointer for API specific callback information
bool isRunning;
@@ -619,7 +625,7 @@ struct CallbackInfo {
// Default constructor.
CallbackInfo()
- :object(0), callback(0), userData(0), errorCallback(0), apiInfo(0), isRunning(false), doRealtime(false), priority(0) {}
+ :object(0), callback(0), userData(0), bufSizeCallback(0), errorCallback(0), apiInfo(0), isRunning(false), doRealtime(false), priority(0) {}
};
// **************************************************************** //
@@ -688,6 +694,7 @@ public:
RtAudioFormat format, unsigned int sampleRate,
unsigned int *bufferFrames, RtAudioCallback callback,
void *userData, RtAudio::StreamOptions *options,
+ RtAudioBufferSizeCallback bufSizeCallback,
RtAudioErrorCallback errorCallback );
virtual void closeStream( void );
virtual void startStream( void ) = 0;
@@ -909,6 +916,9 @@ public:
// will most likely produce highly undesireable results!
bool callbackEvent( unsigned long nframes );
+ // Buffer size change callback
+ bool bufferSizeEvent( unsigned long nframes );
+
private:
bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels,
diff --git a/source/native-plugins/_data.base.cpp b/source/native-plugins/_data.base.cpp
index d678a0884..1d89fa1ac 100644
--- a/source/native-plugins/_data.base.cpp
+++ b/source/native-plugins/_data.base.cpp
@@ -164,6 +164,29 @@ static const NativePluginDescriptor sNativePluginDescriptors[] = {
DESCFUNCS
},
+// --------------------------------------------------------------------------------------------------------------------
+// Audio file
+
+{
+ /* category */ NATIVE_PLUGIN_CATEGORY_UTILITY,
+ /* hints */ static_cast(NATIVE_PLUGIN_IS_RTSAFE
+ |NATIVE_PLUGIN_HAS_UI
+ |NATIVE_PLUGIN_NEEDS_UI_OPEN_SAVE
+ |NATIVE_PLUGIN_USES_TIME),
+ /* supports */ NATIVE_PLUGIN_SUPPORTS_NOTHING,
+ /* audioIns */ 0,
+ /* audioOuts */ 2,
+ /* midiIns */ 0,
+ /* midiOuts */ 0,
+ /* paramIns */ 1,
+ /* paramOuts */ 0,
+ /* name */ "Audio File",
+ /* label */ "audiofile",
+ /* maker */ "falkTX",
+ /* copyright */ "GNU GPL v2+",
+ DESCFUNCS
+},
+
// --------------------------------------------------------------------------------------------------------------------
// MIDI sequencer
diff --git a/source/native-plugins/audio-base.hpp b/source/native-plugins/audio-base.hpp
index a4648c26b..aa751ee51 100644
--- a/source/native-plugins/audio-base.hpp
+++ b/source/native-plugins/audio-base.hpp
@@ -1,6 +1,6 @@
/*
* Carla Native Plugins
- * Copyright (C) 2013-2017 Filipe Coelho
+ * Copyright (C) 2013-2018 Filipe Coelho
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -29,17 +29,20 @@ typedef struct adinfo ADInfo;
struct AudioFilePool {
float* buffer[2];
+ uint32_t sampleRate;
uint32_t startFrame;
uint32_t size;
#ifdef CARLA_PROPER_CPP11_SUPPORT
AudioFilePool()
: buffer{nullptr},
+ sampleRate(0),
startFrame(0),
size(0) {}
#else
AudioFilePool()
: startFrame(0),
+ sampleRate(0),
size(0)
{
buffer[0] = buffer[1] = nullptr;
@@ -54,14 +57,15 @@ struct AudioFilePool {
CARLA_ASSERT(size == 0);
}
- void create(const uint32_t sampleRate)
+ void create(const uint32_t srate)
{
CARLA_ASSERT(buffer[0] == nullptr);
CARLA_ASSERT(buffer[1] == nullptr);
CARLA_ASSERT(startFrame == 0);
CARLA_ASSERT(size == 0);
- size = sampleRate * 2;
+ size = srate * 8;
+ sampleRate = srate;
buffer[0] = new float[size];
buffer[1] = new float[size];
@@ -114,9 +118,13 @@ public:
AudioFileThread(AbstractAudioPlayer* const player, const double sampleRate)
: CarlaThread("AudioFileThread"),
kPlayer(player),
+ fLoopingMode(true),
fNeedsRead(false),
fQuitNow(true),
- fFilePtr(nullptr)
+ fFilePtr(nullptr),
+ fMaxPlayerFrame(0),
+ fPollTempData(nullptr),
+ fPollTempSize(0)
{
CARLA_ASSERT(kPlayer != nullptr);
@@ -139,7 +147,17 @@ public:
CARLA_ASSERT(! isThreadRunning());
if (fFilePtr != nullptr)
+ {
ad_close(fFilePtr);
+ fFilePtr = nullptr;
+ }
+
+ if (fPollTempData != nullptr)
+ {
+ delete[] fPollTempData;
+ fPollTempData = nullptr;
+ fPollTempSize = 0;
+ }
fPool.destroy();
}
@@ -162,20 +180,25 @@ public:
fPool.reset();
}
- uint32_t getMaxFrame() const
+ uint32_t getMaxFrame() const noexcept
+ {
+ return fMaxPlayerFrame;
+ }
+
+ void setLoopingMode(const bool on) noexcept
{
- return fFileNfo.frames > 0 ? fFileNfo.frames : 0;
+ fLoopingMode = on;
}
- void setNeedsRead()
+ void setNeedsRead() noexcept
{
fNeedsRead = true;
}
bool loadFilename(const char* const filename)
{
- CARLA_ASSERT(! isThreadRunning());
- CARLA_ASSERT(filename != nullptr);
+ CARLA_SAFE_ASSERT_RETURN(! isThreadRunning(), false);
+ CARLA_SAFE_ASSERT_RETURN(filename != nullptr && *filename != '\0', false);
fPool.startFrame = 0;
@@ -185,6 +208,13 @@ public:
ad_close(fFilePtr);
fFilePtr = nullptr;
}
+ if (fPollTempData != nullptr)
+ {
+ delete[] fPollTempData;
+ fPollTempData = nullptr;
+ fPollTempSize = 0;
+ fMaxPlayerFrame = 0;
+ }
ad_clear_nfo(&fFileNfo);
@@ -196,16 +226,30 @@ public:
ad_dump_nfo(99, &fFileNfo);
- if (fFileNfo.frames == 0)
- carla_stderr("L: filename \"%s\" has 0 frames", filename);
-
// Fix for misinformation using libsndfile
if (fFileNfo.frames % fFileNfo.channels)
--fFileNfo.frames;
+ if (fFileNfo.frames <= 0)
+ carla_stderr("L: filename \"%s\" has 0 frames", filename);
+
if ((fFileNfo.channels == 1 || fFileNfo.channels == 2) && fFileNfo.frames > 0)
{
// valid
+ const size_t pollTempSize = std::min(static_cast(fFileNfo.frames),
+ fPool.size * fFileNfo.channels);
+
+ try {
+ fPollTempData = new float[pollTempSize];
+ } catch (...) {
+ ad_close(fFilePtr);
+ fFilePtr = nullptr;
+ return false;
+ }
+
+ fMaxPlayerFrame = fFileNfo.frames/fFileNfo.channels;
+ fPollTempSize = pollTempSize;
+
readPoll();
return true;
}
@@ -221,10 +265,8 @@ public:
void tryPutData(AudioFilePool& pool)
{
- CARLA_ASSERT(pool.size == fPool.size);
+ CARLA_SAFE_ASSERT_RETURN(pool.size == fPool.size,);
- if (pool.size != fPool.size)
- return;
if (! fMutex.tryLock())
return;
@@ -253,24 +295,12 @@ public:
if (lastFrame >= maxFrame)
{
-#if 0
- if (false)
- //if (handlePtr->loopMode)
+ if (fLoopingMode)
{
- carla_stderr("R: DEBUG read loop, lastFrame:%i, maxFrame:%i", lastFrame, maxFrame);
-
- if (maxFrame >= static_cast(fPool.size))
- {
- readFrame %= maxFrame;
- }
- else
- {
- readFrame = 0;
- lastFrame -= lastFrame % maxFrame;
- }
+ carla_debug("R: transport out of bounds for loop");
+ readFrame %= fMaxPlayerFrame;
}
else
-#endif
{
carla_stderr("R: transport out of bounds");
fNeedsRead = false;
@@ -279,82 +309,81 @@ public:
}
// temp data buffer
- const size_t tmpSize = fPool.size * fFileNfo.channels;
-
- float tmpData[tmpSize];
- carla_zeroFloats(tmpData, tmpSize);
+ carla_zeroFloats(fPollTempData, fPollTempSize);
{
- carla_stderr("R: poll data - reading at %li:%02li", readFrame/44100/60, (readFrame/44100) % 60);
+ carla_debug("R: poll data - reading at %li:%02li", readFrame/fPool.sampleRate/60, (readFrame/fPool.sampleRate) % 60);
ad_seek(fFilePtr, readFrame);
size_t i = 0;
ssize_t j = 0;
- ssize_t rv = ad_read(fFilePtr, tmpData, tmpSize);
+ ssize_t rv = ad_read(fFilePtr, fPollTempData, fPollTempSize);
+
+ if (rv < 0)
+ {
+ carla_stderr("R: ad_read failed");
+ fNeedsRead = false;
+ return;
+ }
+
+ // see if we can read more
+ if (readFrame + rv >= static_cast(fFileNfo.frames) && static_cast(rv) < fPollTempSize)
+ {
+ carla_debug("R: from start");
+ ad_seek(fFilePtr, 0);
+ rv += ad_read(fFilePtr, fPollTempData+rv, fPollTempSize-rv);
+ }
// lock, and put data asap
const CarlaMutexLocker cml(fMutex);
- for (; i < fPool.size && j < rv; ++j)
- {
- if (fFileNfo.channels == 1)
+ do {
+ for (; i < fPool.size && j < rv; ++j)
{
- fPool.buffer[0][i] = tmpData[j];
- fPool.buffer[1][i] = tmpData[j];
- i++;
- }
- else
- {
- if (j % 2 == 0)
- {
- fPool.buffer[0][i] = tmpData[j];
- }
- else
+ if (fFileNfo.channels == 1)
{
- fPool.buffer[1][i] = tmpData[j];
+ fPool.buffer[0][i] = fPollTempData[j];
+ fPool.buffer[1][i] = fPollTempData[j];
i++;
}
- }
- }
-
-#if 0
- if (false)
- //if (handlePtr->loopMode && i < fPool.size)
- {
- while (i < fPool.size)
- {
- for (j=0; i < fPool.size && j < rv; ++j)
+ else
{
- if (fFileNfo.channels == 1)
+ if (j % 2 == 0)
{
- fPool.buffer[0][i] = tmpData[j];
- fPool.buffer[1][i] = tmpData[j];
- i++;
+ fPool.buffer[0][i] = fPollTempData[j];
}
else
{
- if (j % 2 == 0)
- {
- fPool.buffer[0][i] = tmpData[j];
- }
- else
- {
- fPool.buffer[1][i] = tmpData[j];
- i++;
- }
+ fPool.buffer[1][i] = fPollTempData[j];
+ i++;
}
}
}
- }
- else
-#endif
- {
- for (; i < fPool.size; ++i)
+
+ if (i >= fPool.size)
+ break;
+
+ if (rv == fFileNfo.frames)
{
- fPool.buffer[0][i] = 0.0f;
- fPool.buffer[1][i] = 0.0f;
+ // full file read
+ j = 0;
+ carla_debug("R: full file was read, filling buffers again");
}
- }
+ else
+ {
+ carla_debug("read break, not enough space");
+
+ // FIXME use carla_zeroFloats
+ for (; i < fPool.size; ++i)
+ {
+ fPool.buffer[0][i] = 0.0f;
+ fPool.buffer[1][i] = 0.0f;
+ }
+
+ break;
+ }
+
+ } while (i < fPool.size);
fPool.startFrame = lastFrame;
}
@@ -367,9 +396,10 @@ protected:
{
while (! fQuitNow)
{
- const uint32_t lastFrame(kPlayer->getLastFrame());
+ const uint32_t lastFrame = kPlayer->getLastFrame();
+ const uint32_t loopedFrame = fLoopingMode ? lastFrame % fMaxPlayerFrame : lastFrame;
- if (fNeedsRead || lastFrame < fPool.startFrame || (lastFrame - fPool.startFrame >= fPool.size*3/4 && lastFrame < fFileNfo.frames))
+ if (fNeedsRead || lastFrame < fPool.startFrame || (lastFrame - fPool.startFrame >= fPool.size*3/4 && loopedFrame < fMaxPlayerFrame))
readPoll();
else
carla_msleep(50);
@@ -379,12 +409,18 @@ protected:
private:
AbstractAudioPlayer* const kPlayer;
+ bool fLoopingMode;
bool fNeedsRead;
bool fQuitNow;
void* fFilePtr;
ADInfo fFileNfo;
+ uint32_t fMaxPlayerFrame;
+
+ float* fPollTempData;
+ size_t fPollTempSize;
+
AudioFilePool fPool;
CarlaMutex fMutex;
};
diff --git a/source/native-plugins/audio-file.cpp b/source/native-plugins/audio-file.cpp
index 14dbc1574..7aaaf3957 100644
--- a/source/native-plugins/audio-file.cpp
+++ b/source/native-plugins/audio-file.cpp
@@ -1,6 +1,6 @@
/*
* Carla Native Plugins
- * Copyright (C) 2013 Filipe Coelho
+ * Copyright (C) 2013-2018 Filipe Coelho
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -29,7 +29,7 @@ public:
AudioFilePlugin(const NativeHostDescriptor* const host)
: NativePluginClass(host),
AbstractAudioPlayer(),
- fLoopMode(false),
+ fLoopMode(true),
fDoProcess(false),
fLastFrame(0),
fMaxFrame(0),
@@ -55,7 +55,7 @@ protected:
uint32_t getParameterCount() const override
{
- return 0; // TODO - loopMode
+ return 1;
}
const NativeParameter* getParameterInfo(const uint32_t index) const override
@@ -67,7 +67,7 @@ protected:
param.name = "Loop Mode";
param.unit = nullptr;
- param.hints = static_cast(NATIVE_PARAMETER_IS_ENABLED|NATIVE_PARAMETER_IS_BOOLEAN);
+ param.hints = static_cast(NATIVE_PARAMETER_IS_AUTOMABLE|NATIVE_PARAMETER_IS_ENABLED|NATIVE_PARAMETER_IS_BOOLEAN);
param.ranges.def = 1.0f;
param.ranges.min = 0.0f;
param.ranges.max = 1.0f;
@@ -102,6 +102,7 @@ protected:
return;
fLoopMode = b;
+ fThread.setLoopingMode(b);
fThread.setNeedsRead();
}
@@ -149,9 +150,12 @@ protected:
fThread.tryPutData(fPool);
// out of reach
- if (timePos->frame + frames < fPool.startFrame || timePos->frame >= fMaxFrame) /*&& ! loopMode)*/
+ if (timePos->frame + frames < fPool.startFrame || (timePos->frame >= fMaxFrame && !fLoopMode))
{
- //carla_stderr("P: out of reach");
+ if (fLoopMode) {
+ carla_stderr("P: out of reach");
+ }
+
fLastFrame = timePos->frame;
if (timePos->frame + frames < fPool.startFrame)
@@ -254,7 +258,7 @@ static const NativePluginDescriptor audiofileDesc = {
/* audioOuts */ 2,
/* midiIns */ 0,
/* midiOuts */ 0,
- /* paramIns */ 0, // TODO - loopMode
+ /* paramIns */ 1,
/* paramOuts */ 0,
/* name */ "Audio File",
/* label */ "audiofile",
diff --git a/source/tests/Makefile b/source/tests/Makefile
index 0bc406a62..4a6605e1f 100644
--- a/source/tests/Makefile
+++ b/source/tests/Makefile
@@ -215,7 +215,7 @@ Engine: Engine.cpp
../backend/carla_engine.a ../backend/carla_plugin.a $(MODULEDIR)/native-plugins.a \
$(MODULEDIR)/dgl.a $(MODULEDIR)/jackbridge.a $(MODULEDIR)/lilv.a $(MODULEDIR)/rtmempool.a \
-Wl,--end-group \
- $(PEDANTIC_CXX_FLAGS) $(shell pkg-config --libs alsa libpulse-simple liblo QtCore QtXml fluidsynth linuxsampler x11 gl smf fftw3 mxml zlib ntk_images ntk) -o $@
+ $(PEDANTIC_CXX_FLAGS) $(shell pkg-config --libs alsa libpulse-simple liblo QtCore QtXml fluidsynth x11 gl smf fftw3 mxml zlib ntk_images ntk) -o $@
env LD_LIBRARY_PATH=../backend valgrind --leak-check=full ./$@
# $(MODULEDIR)/juce_audio_basics.a $(MODULEDIR)/juce_core.a \
diff --git a/source/utils/CarlaBridgeDefines.hpp b/source/utils/CarlaBridgeDefines.hpp
index 25ea95dba..152fc2d70 100644
--- a/source/utils/CarlaBridgeDefines.hpp
+++ b/source/utils/CarlaBridgeDefines.hpp
@@ -20,7 +20,7 @@
#include "CarlaRingBuffer.hpp"
-#define CARLA_PLUGIN_BRIDGE_API_VERSION 3
+#define CARLA_PLUGIN_BRIDGE_API_VERSION 4
// -------------------------------------------------------------------------------------------------------------------
@@ -141,9 +141,9 @@ struct BridgeTimeInfo {
uint64_t usecs;
uint32_t validFlags;
// bbt
- int32_t bar, beat, tick;
+ int32_t bar, beat;
float beatsPerBar, beatType;
- double barStartTick, ticksPerBeat, beatsPerMinute;
+ double tick, barStartTick, ticksPerBeat, beatsPerMinute;
};
// -------------------------------------------------------------------------------------------------------------------