FROM registry.fedoraproject.org/fedora:${FEDORA_VERSION} AS builder
# install tools require to build jacktrip
-RUN dnf install -y --nodocs gcc gcc-c++ meson python3-pyyaml python3-jinja2 qt5-qtbase-devel jack-audio-connection-kit-devel
+RUN dnf install -y --nodocs gcc gcc-c++ meson git python3-pyyaml python3-jinja2 glib2-devel jack-audio-connection-kit-devel
+
+ENV QT_VERSION=6.5.3
+RUN if [ "$(uname -m)" = "x86_64" ]; then export ARCH=amd64; else export ARCH=arm64; fi \
+ && curl -L -s -o /root/qt.tar.gz "https://files.jacktrip.org/contrib/qt/qt-${QT_VERSION}-static-linux-${ARCH}.tar.gz" \
+ && tar -C /opt -xzf /root/qt.tar.gz \
+ && rm -f /root/qt.tar.gz
# copy files from repository to build container
COPY . /root
# configure and run the build
RUN cd /root \
- && PKG_CONFIG_PATH=/usr/local/lib/pkgconfig meson setup -Ddefault_library=static -Dnogui=true --buildtype release builddir \
+ && export QT_PATH=/opt/qt-${QT_VERSION}-static \
+ && export PATH=${QT_PATH}/bin:${PATH} \
+ && export LDFLAGS="-L${QT_PATH}/lib -L${QT_PATH}/plugins/tls" \
+ && meson setup -Ddefault_library=static -Dnogui=true --buildtype release builddir \
&& meson compile -C builddir
# stage files in INSTALLDIR
-ENV INSTALLDIR=/opt
-RUN mkdir -p ${INSTALLDIR}/usr/local/bin/ ${INSTALLDIR}/usr/lib64/ ${INSTALLDIR}/etc/systemd/system/ \
- && cp /lib64/libQt5Core.so.5 /lib64/libQt5Network.so.5 ${INSTALLDIR}/usr/lib64/ \
+ENV INSTALLDIR=/artifacts
+RUN mkdir -p ${INSTALLDIR}/usr/local/bin/ ${INSTALLDIR}/etc/systemd/system/ \
&& cp /root/builddir/jacktrip ${INSTALLDIR}/usr/local/bin/ \
&& strip ${INSTALLDIR}/usr/local/bin/jacktrip
COPY linux/container/jacktrip.service ${INSTALLDIR}/etc/systemd/system/
# use the jack ubi-init container
FROM jacktrip/jack:${JACK_VERSION}
-# install libraries that we need for things to run
-RUN dnf install -y --nodocs libicu pcre libstdc++ compat-openssl11 pcre2-utf16
-
# add jacktrip user, enable service and allow access to jackd
RUN useradd -r -m -N -G audio -s /usr/sbin/nologin jacktrip \
&& chown -R jacktrip.audio /home/jacktrip \
&& echo 'echo "JACKTRIP_OPTS=\"$JACKTRIP_OPTS\"" > /etc/default/jacktrip' >> /usr/sbin/defaults.sh
# copy the artifacts we built into the final container image
-COPY --from=builder /opt /
+COPY --from=builder /artifacts /
# jacktrip hub server listens on 4464 and uses 61000+ for clients
EXPOSE 4464/tcp
+- Version: "2.3.0"
+ Date: 2024-05-15
+ Description:
+ - (added) Static Qt 5.15.13 nogui (CLI) builds for all platforms
+ - (added) VS Mode learn more buttons and warning links
+ - (updated) Significant PLC performance and quality improvements
+ - (updated) Reduced amount of latency added for PLC strategy
+ - (updated) Merged PLC buffer strategies (3 is now identical to 4)
+ - (updated) Automatically start PLC worker for slower predictions
+ - (updated) Builds now use Qt 6.2.8 for OSX and 5.15.13 for Linux
+ - (updated) Linux containers now use static builds with Qt 6.5.3
+ - (updated) VS Mode help links go to support.jacktrip.com
+ - (updated) VS Mode manage button goes to new studio dashboard
+ - (fixed) PLC degradation when peer != local buffer sizes
+ - (fixed) Port binding on machines that don't support IPv6
+ - (fixed) Command line interface debug logging improvements
+ - (fixed) VS Mode truncation of invite copied tooltip message
- Version: "2.2.5"
Date: 2024-03-28
Description:
c_defines = []
incdirs = []
-if get_option('buildtype') == 'release'
- defines += ['-DNDEBUG']
- c_defines += ['-DNDEBUG']
+if get_option('debug') == false
+ defines += ['-DNDEBUG', '-DQT_NO_DEBUG']
+ c_defines += ['-DNDEBUG', '-DQT_NO_DEBUG']
endif
build_info = get_option('buildinfo')
endif
endif
-if qt_version == '6' and get_option('default_library') == 'static'
- deps += dependency('qt6', modules: ['BundledLibpng', 'BundledPcre2', 'BundledHarfbuzz'], include_type: 'system')
+if get_option('default_library') == 'static'
+ # use qmake to get paths for qt libraries and plugins
+ # seems like qt module should have a method for this, but it doesn't
+ qmake = find_program('qmake', required: true)
+ qt_libdir = run_command(qmake, '-query', 'QT_INSTALL_LIBS', check : true).stdout().strip()
+ qt_plugindir = run_command(qmake, '-query', 'QT_INSTALL_PLUGINS', check : true).stdout().strip()
+ if qt_version == '6'
+ # qt6 requires "Bundled*" modules for linking
+ deps += dependency('qt6', modules: ['BundledLibpng', 'BundledPcre2', 'BundledHarfbuzz', 'BundledZLIB'], include_type: 'system')
+ else
+ deps += compiler.find_library('qtpcre2', required : true, dirs : [qt_libdir])
+ endif
+ if (host_machine.system() == 'linux')
+ # linux static
+ deps += compiler.find_library('ssl', required : true, dirs : [qt_libdir])
+ deps += compiler.find_library('crypto', required : true, dirs : [qt_libdir])
+ deps += compiler.find_library('dl', required : true)
+ deps += compiler.find_library('glib-2.0', required : true)
+ if qt_version == '6'
+ # we need a Q_IMPORT_LIBRARY for the openssl backend on linux
+ deps += compiler.find_library('qopensslbackend', required : true, dirs : [qt_plugindir+'/tls'])
+ src += ['src/QtStaticPlugins.cpp']
+ endif
+ else
+ if (host_machine.system() == 'windows')
+ # windows static
+ deps += compiler.find_library('bcrypt', required : true)
+ deps += compiler.find_library('winmm', required : true)
+ deps += compiler.find_library('Crypt32', required : true)
+ if qt_version == '6'
+ deps += compiler.find_library('Authz', required : true)
+ endif
+ else
+ # mac static
+ # this approach fails for universal builds, so we have to just append to link_args
+ #deps += dependency('CoreServices', required : true)
+ link_args += ['-framework', 'CoreServices']
+ link_args += ['-framework', 'CFNetwork']
+ link_args += ['-framework', 'AppKit']
+ link_args += ['-framework', 'IOKit']
+ link_args += ['-framework', 'Security']
+ link_args += ['-framework', 'GSS']
+ link_args += ['-framework', 'SystemConfiguration']
+ deps += dependency('zlib', required : true)
+ endif
+ endif
endif
# TODO: QT_OPENSOURCE should only be defined for open source Qt distribution
summary({'Application ID': application_id,
'GUI': not get_option('nogui'),
'WAIR': get_option('wair'),
- 'Manpage': help2man.found()}, bool_yn: true, section: 'Configuration')
\ No newline at end of file
+ 'Manpage': help2man.found()}, bool_yn: true, section: 'Configuration')
{
"app_name": "JackTrip",
"releases": [
+ {
+ "version": "2.2.5",
+ "changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.2.5",
+ "download": {
+ "date": "2024-03-29T00:00:00Z",
+ "url": "https://files.jacktrip.org/app-builds/JackTrip-v2.2.5-macOS-x64-signed-installer.pkg",
+ "downloadSize": "177374940",
+ "sha256": "4e1ae62b5717141c27b3a569311b3c17f7daa3065ee7bb69c18faf5c28ba5e8e"
+ }
+ },
{
"version": "2.2.4",
"changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.2.4",
{
"app_name": "JackTrip",
"releases": [
+ {
+ "version": "2.2.5",
+ "changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.2.5",
+ "download": {
+ "date": "2024-03-29T00:00:00Z",
+ "url": "https://files.jacktrip.org/app-builds/JackTrip-v2.2.5-Windows-x64-signed-installer.msi",
+ "downloadSize": "116228096",
+ "sha256": "903343959992733001d4e7db30c83fc4ff8120903aeca0eb86b1601c9d21e15b"
+ }
+ },
{
"version": "2.2.4",
"changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.2.4",
{
"app_name": "JackTrip",
"releases": [
+ {
+ "version": "2.2.5",
+ "changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.2.5",
+ "download": {
+ "date": "2024-03-29T00:00:00Z",
+ "url": "https://files.jacktrip.org/app-builds/JackTrip-v2.2.5-Linux-x64-binary.zip",
+ "downloadSize": "1250262",
+ "sha256": "3995fb1c56983ee72f3a51c10ea1b94c635f3ee52308a376a0357a861b0a9e37"
+ }
+ },
{
"version": "2.2.4",
"changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.2.4",
{
"app_name": "JackTrip",
"releases": [
+ {
+ "version": "2.2.5",
+ "changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.2.5",
+ "download": {
+ "date": "2024-03-29T00:00:00Z",
+ "url": "https://files.jacktrip.org/app-builds/JackTrip-v2.2.5-macOS-x64-signed-installer.pkg",
+ "downloadSize": "177374940",
+ "sha256": "4e1ae62b5717141c27b3a569311b3c17f7daa3065ee7bb69c18faf5c28ba5e8e"
+ }
+ },
{
"version": "2.2.4",
"changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.2.4",
{
"app_name": "JackTrip",
"releases": [
+ {
+ "version": "2.2.5",
+ "changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.2.5",
+ "download": {
+ "date": "2024-03-29T00:00:00Z",
+ "url": "https://files.jacktrip.org/app-builds/JackTrip-v2.2.5-Windows-x64-signed-installer.msi",
+ "downloadSize": "116228096",
+ "sha256": "903343959992733001d4e7db30c83fc4ff8120903aeca0eb86b1601c9d21e15b"
+ }
+ },
{
"version": "2.2.4",
"changelog": "Full changelog at https://github.com/jacktrip/jacktrip/releases/tag/v2.2.4",
out_buffer.data());
// compute ap2 into aob2
- //#define ADD_DIRECT
+ // #define ADD_DIRECT
#ifdef ADD_DIRECT
for (int i = 0; i < nChansIn; i++) {
sample_t* mix_sample = out_buffer[i];
mWarningMsg =
"The buffer size setting for your audio device will cause high latency "
"or audio delay. Use an audio device that supports small buffer sizes "
- "to reduce audio delays.";
- mWarningHelpUrl = "";
+ "to reduce audio delays. Click for more info.";
+ mWarningHelpUrl = "https://support.jacktrip.com/recommended-audio-interfaces";
mHighLatencyFlag = true;
break;
case DEVICE_WARN_ASIO_LATENCY:
mWarningMsg =
"You audio device drivers may cause high latency or audio delay. Install "
"and use ASIO drivers provided by your device's manufacturer to reduce "
- "audio delays.";
- mWarningHelpUrl = "https://help.jacktrip.org/hc/en-us/articles/4409919243155";
+ "audio delays. Click for more info.";
+ mWarningHelpUrl =
+ "https://support.jacktrip.com/troubleshooting-windows-drivers-and-asio";
mHighLatencyFlag = true;
break;
case DEVICE_WARN_ALSA_LATENCY:
"The two devices you have selected are not compatible. Please select a "
"different pair of devices.";
#ifdef _WIN32
- mErrorHelpUrl = "https://help.jacktrip.org/hc/en-us/articles/4409919243155";
+ mErrorHelpUrl =
+ "https://support.jacktrip.com/troubleshooting-windows-drivers-and-asio";
#else
mErrorHelpUrl = "";
#endif
case DEVICE_ERR_SAME_ASIO:
mErrorMsg =
"When using ASIO, please select the same device for your input and output.";
- mErrorHelpUrl = "https://help.jacktrip.org/hc/en-us/articles/4409919243155";
+ mErrorHelpUrl =
+ "https://support.jacktrip.com/troubleshooting-windows-drivers-and-asio";
break;
#endif
default:
#include <iostream>
#include "jacktrip_types.h" // sample_t
-//#include <ctime>
+// #include <ctime>
#include <QVarLengthArray>
#include <chrono>
#include <cmath>
#include <arpa/inet.h> //inet(3) functions
#include <netdb.h>
#include <netinet/in.h> //sockaddr_in{} and other Internet defns
-//#include <tr1/memory> //for shared_ptr
+// #include <tr1/memory> //for shared_ptr
#endif
#include <QHostAddress>
///////////////////////////////
// test NUC as server
-//#define HARDWIRED_AUDIO_PROCESS_ON_SERVER "par20straightWire"
-//#define ENUMERATE ""
-//#define HARDWIRED_AUDIO_PROCESS_ON_SERVER_IN ":in_"
-//#define HARDWIRED_AUDIO_PROCESS_ON_SERVER_OUT ":out_"
+// #define HARDWIRED_AUDIO_PROCESS_ON_SERVER "par20straightWire"
+// #define ENUMERATE ""
+// #define HARDWIRED_AUDIO_PROCESS_ON_SERVER_IN ":in_"
+// #define HARDWIRED_AUDIO_PROCESS_ON_SERVER_OUT ":out_"
///////////////////////////////
// test Riviera as server
#include "jacktrip_globals.h"
///************PROTORYPE FOR CELT**************************
-//#include <celt/celt.h>
-//#include <celt/celt_header.h>
-//#include <celt/celt_types.h>
+// #include <celt/celt.h>
+// #include <celt/celt_header.h>
+// #include <celt/celt_types.h>
///********************************************************
#include <QMutexLocker>
QMutexLocker locker(&sJackMutex);
// TODO: this needs a timeout because it will hang indefinitely
// if the Jack server is not running
-//#ifndef WAIR // WAIR
-// mClient = jack_client_open (client_name, options, &status, server_name);
-//#else
-// mClient = jack_client_open (client_name, JackUseExactName, &status,
-// server_name);
-//#endif // endwhere
+// #ifndef WAIR // WAIR
+// mClient = jack_client_open (client_name, options, &status, server_name);
+// #else
+// mClient = jack_client_open (client_name, JackUseExactName, &status,
+// server_name);
+// #endif // endwhere
#ifndef WAIR // WAIR
mClient = jack_client_open(clientName.constData(), options, &status);
#else
JackTrip: A System for High-Quality Audio Network Performance
over the Internet
- Copyright (c) 2008-2021 Juan-Pablo Caceres, Chris Chafe.
+ Copyright (c) 2008-2024 Juan-Pablo Caceres, Chris Chafe.
SoundWIRE group at CCRMA, Stanford University.
Permission is hereby granted, free of charge, to any person
#endif // endwhere
, mBufferQueueLength(BufferQueueLength)
, mBufferStrategy(1)
- , mRegulatorThreadPtr(NULL)
, mBroadcastQueueLength(0)
, mSampleRate(gDefaultSampleRate)
, mDeviceID(gDefaultDeviceID)
new RingBuffer(audio_output_slot_size, mBufferQueueLength);
mPacketHeader->setBufferRequiresSameSettings(true);
} else if ((mBufferStrategy == 3) || (mBufferStrategy == 4)) {
- bool use_worker_thread = (mBufferStrategy == 3);
cout << "Using experimental buffer strategy " << mBufferStrategy
- << "-- Regulator with PLC (worker="
- << (use_worker_thread ? "true" : "false") << ")" << endl;
+ << "-- Regulator with PLC" << endl;
Regulator* regulator_ptr =
new Regulator(mNumAudioChansOut, mAudioBitResolution, mAudioBufferSize,
mBufferQueueLength, mBroadcastQueueLength, mSampleRate);
mReceiveRingBuffer = regulator_ptr;
- if (use_worker_thread) {
-#ifdef REGULATOR_SHARED_WORKER_THREAD
- regulator_ptr->enableWorkerThread(mRegulatorThreadPtr);
-#else
- regulator_ptr->enableWorkerThread();
-#endif
- }
// bufStrategy 3 or 4, mBufferQueueLength is in integer msec not packets
mPacketHeader->setBufferRequiresSameSettings(false); // = asym is default
// pkt_stat.lost << "/"
// << pkt_stat.outOfOrder << "/" << pkt_stat.revived
<< " \n tot: " << pkt_stat.tot << " \t tol: " << setw(5)
- << INVFLOATFACTOR * recv_io_stat.autoq_corr << " \t dsp (last): " << setw(5)
+ << INVFLOATFACTOR * recv_io_stat.autoq_corr << " \t dsp (max): " << setw(5)
<< INVFLOATFACTOR * recv_io_stat.autoq_rate
// << " sync: " << recv_io_stat.level << "/"
// << recv_io_stat.buf_inc_underrun << "/"
std::map<std::string, QHostAddress::SpecialAddress>::iterator it;
for (it = interfaces.begin(); it != interfaces.end(); it++) {
bool binded = UdpSockTemp.bind(it->second, port, QUdpSocket::DontShareAddress);
- if (!binded) {
- UdpSockTemp.close(); // close the socket
+ QUdpSocket::SocketError err = UdpSockTemp.error();
+ UdpSockTemp.close();
+ if (!binded && err != QUdpSocket::UnsupportedSocketOperationError) {
return true;
}
- UdpSockTemp.close();
}
return false;
}
JackTrip: A System for High-Quality Audio Network Performance
over the Internet
- Copyright (c) 2008-2021 Juan-Pablo Caceres, Chris Chafe.
+ Copyright (c) 2008-2024 Juan-Pablo Caceres, Chris Chafe.
SoundWIRE group at CCRMA, Stanford University.
Permission is hereby granted, free of charge, to any person
{
mBufferStrategy = BufferStrategy;
}
- void setRegulatorThread(QThread* ptr) { mRegulatorThreadPtr = ptr; }
/// \brief Sets (override) Audio Bit Resolution after construction
virtual void setAudioBitResolution(
AudioInterface::audioBitResolutionT AudioBitResolution)
#endif // endwhere
int mBufferQueueLength; ///< Audio Buffer from network queue length
int mBufferStrategy;
- QThread* mRegulatorThreadPtr;
int mBroadcastQueueLength;
uint32_t mSampleRate; ///< Sample Rate
uint32_t mDeviceID; ///< RTAudio DeviceID
#include "JackTrip.h"
#include "UdpHubListener.h"
-//#include "NetKS.h"
+// #include "NetKS.h"
#include "LoopBack.h"
#include "Settings.h"
#ifdef WAIR // wair
mJackTrip->setBindPorts(mServerPort);
// jacktrip.setPeerPorts(mClientPort);
mJackTrip->setBufferStrategy(mBufferStrategy);
- mJackTrip->setRegulatorThread(mRegulatorThreadPtr);
mJackTrip->setNetIssuesSimulation(mSimulatedLossRate, mSimulatedJitterRate,
mSimulatedDelayRel);
mJackTrip->setBroadcast(mBroadcastQueue);
int getID() { return mID; }
void setBufferStrategy(int BufferStrategy) { mBufferStrategy = BufferStrategy; }
- void setRegulatorThread(QThread* ptr) { mRegulatorThreadPtr = ptr; }
void setNetIssuesSimulation(double loss, double jitter, double delay_rel)
{
mSimulatedLossRate = loss;
int mID = 0; ///< ID thread number
- int mBufferStrategy = 1;
- int mBroadcastQueue = 0;
- double mSimulatedLossRate = 0.0;
- double mSimulatedJitterRate = 0.0;
- double mSimulatedDelayRel = 0.0;
- bool mUseRtUdpPriority = false;
- int mIOStatTimeout = 0;
- QThread* mRegulatorThreadPtr = NULL;
+ int mBufferStrategy = 1;
+ int mBroadcastQueue = 0;
+ double mSimulatedLossRate = 0.0;
+ double mSimulatedJitterRate = 0.0;
+ double mSimulatedDelayRel = 0.0;
+ bool mUseRtUdpPriority = false;
+ int mIOStatTimeout = 0;
QSharedPointer<std::ostream> mIOStatStream;
#ifdef WAIR // wair
#ifndef __LIMITER_H__
#define __LIMITER_H__
-//#define SINE_TEST
+// #define SINE_TEST
#ifdef SINE_TEST
#include "limitertest.h"
#endif
#endif
-//#######################################################################
-//####################### PacketHeader ##################################
-//#######################################################################
+// #######################################################################
+// ####################### PacketHeader ##################################
+// #######################################################################
//***********************************************************************
PacketHeader::PacketHeader(JackTrip* jacktrip)
: mBufferRequiresSameSettings(false), mJackTrip(jacktrip), mSeqNumber(0)
(tv.tv_usec)); // plus the microseconds. Type suseconds_t, range [-1, 1000000]
}
-//#######################################################################
-//####################### DefaultHeader #################################
-//#######################################################################
+// #######################################################################
+// ####################### DefaultHeader #################################
+// #######################################################################
//***********************************************************************
DefaultHeader::DefaultHeader(JackTrip* jacktrip) : PacketHeader(jacktrip)
{
return peer_header->NumOutgoingChannelsToNet;
}
-//#######################################################################
-//####################### JamLinkHeader #################################
-//#######################################################################
+// #######################################################################
+// ####################### JamLinkHeader #################################
+// #######################################################################
//***********************************************************************
JamLinkHeader::JamLinkHeader(JackTrip* jacktrip) : PacketHeader(jacktrip)
{
}
}
-//#######################################################################
-//####################### EmptyHeader #################################
-//#######################################################################
+// #######################################################################
+// ####################### EmptyHeader #################################
+// #######################################################################
//***********************************************************************
EmptyHeader::EmptyHeader(JackTrip* jacktrip) : PacketHeader(jacktrip) {}
#define __PACKETHEADER_H__
#include <iostream>
-//#include <tr1/memory> // for shared_ptr
+// #include <tr1/memory> // for shared_ptr
#include <QObject>
#include <QString>
#include <cstring>
uint32_t TimeStamp; ///< Time Stamp
};
-//#######################################################################
-//####################### PacketHeader ##################################
-//#######################################################################
+// #######################################################################
+// ####################### PacketHeader ##################################
+// #######################################################################
/** \brief Base class for header type. Subclass this struct to
* create a new header.
*/
uint16_t mSeqNumber;
};
-//#######################################################################
-//####################### DefaultHeader #################################
-//#######################################################################
+// #######################################################################
+// ####################### DefaultHeader #################################
+// #######################################################################
/** \brief Default Header
*/
class DefaultHeader : public PacketHeader
DefaultHeaderStruct mHeader; ///< Default Header Struct
};
-//#######################################################################
-//####################### JamLinkHeader #################################
-//#######################################################################
+// #######################################################################
+// ####################### JamLinkHeader #################################
+// #######################################################################
/** \brief JamLink Header
*/
JamLinkHeaderStuct mHeader; ///< JamLink Header Struct
};
-//#######################################################################
-//####################### EmptyHeader #################################
-//#######################################################################
+// #######################################################################
+// ####################### EmptyHeader #################################
+// #######################################################################
/** \brief Empty Header to use with systems that don't include a header.
*/
-//#include "ProcessPlugin.h"
+// #include "ProcessPlugin.h"
/*
//----------------------------------------------------------------------------
--- /dev/null
+#include <QtPlugin>
+
+// used to load tls backend for linux static builds
+Q_IMPORT_PLUGIN(QTlsBackendOpenSSL)
JackTrip: A System for High-Quality Audio Network Performance
over the Internet
- Copyright (c) 2021 Juan-Pablo Caceres, Chris Chafe.
+ Copyright (c) 2024 Juan-Pablo Caceres, Chris Chafe.
SoundWIRE group at CCRMA, Stanford University.
Permission is hereby granted, free of charge, to any person
/**
* \file Regulator.cpp
* \author Chris Chafe
- * \date May-Sep 2021
+ * \date May 2021 - May 2024
*/
// EXPERIMENTAL for testing in JackTrip v1.5.<n>
#include "Regulator.h"
+#include <cfloat>
#include <iomanip>
-#include <sstream>
-#include "JitterBuffer.h"
-#include "jacktrip_globals.h"
+#include "JitterBuffer.h" // for broadcast
+
using std::cout;
using std::endl;
using std::setw;
// constants...
-constexpr int HIST = 4; // for mono at FPP 16-128, see below for > mono, > 128
-constexpr int NumSlotsMax = 4096; // mNumSlots looped for recent arrivals
-constexpr double AutoMax = 250.0; // msec bounds on insane IPI, like ethernet unplugged
+constexpr bool PrintDirect = false; // print stats direct from -V not -I
+constexpr int HIST = 2; // mPacketsInThePast setting for
+constexpr int HISTFPP = 128; // default FPP when calibrating burg window
+
+constexpr int NumSlots = 4096; // NumSlots looped for recent arrivals
+constexpr double AutoMax = 250.0; // msec bounds on insane IPI, like ethernet unplugged
constexpr double AutoInitDur = 3000.0; // kick in auto after this many msec
constexpr double AutoInitValFactor =
0.5; // scale for initial mMsecTolerance during init phase if unspecified
// tweak
-constexpr int WindowDivisor = 8; // for faster auto tracking
-constexpr int MaxFPP = 1024; // tested up to this FPP
-constexpr int MaxAutoHeadroom = 5; // maximum auto headroom in milliseconds
+constexpr int WindowDivisor = 8; // for faster auto tracking
constexpr double AutoHeadroomGlitchTolerance =
- 0.007; // Acceptable rate of glitches before auto headroom is increased (0.7%)
+ 0.02; // Acceptable rate of skips before auto headroom is increased (2.0%)
constexpr double AutoHistoryWindow =
60; // rolling window of time (in seconds) over which auto tolerance roughly adjusts
constexpr double AutoSmoothingFactor =
1.0
/ (WindowDivisor * AutoHistoryWindow); // EWMA smoothing factor for auto tolerance
+BurgAlgorithm::BurgAlgorithm(int size) // mUpToNow = mPacketsInThePast * fpp
+{
+ // GET SIZE FROM INPUT VECTORS
+ m = N = size - 1;
+ this->size = size;
+ if (size < m)
+ cout << "time_series should have more elements than the AR order is" << endl;
+ Ak.resize(size);
+ for (int i = 0; i < size; i++)
+ Ak[i] = 0.0;
+ AkReset.resize(size);
+ AkReset = Ak;
+ AkReset[0] = 1.0;
+
+ f.resize(size);
+ b.resize(size);
+}
+
+void BurgAlgorithm::train(std::vector<float>& coeffs, const std::vector<float>& x,
+ int size)
+{
+ // INITIALIZE Ak
+ Ak = AkReset;
+
+ // INITIALIZE f and b
+ for (int i = 0; i < size; i++)
+ f[i] = b[i] = x[i];
+
+ // INITIALIZE Dk
+ float Dk = 0.0;
+
+ for (int j = 0; j <= N; j++)
+ Dk += 2.00002 * f[j] * f[j]; // needs more damping than orig 2.0
+
+ Dk -= f[0] * f[0] + b[N] * b[N];
+
+ // BURG RECURSION
+ for (int k = 0; k < m; k++) {
+ // COMPUTE MU
+ float mu = 0.0;
+ for (int n = 0; n <= N - k - 1; n++) {
+ mu += f[n + k + 1] * b[n];
+ }
+
+ if (Dk == 0.0)
+ Dk = FLT_EPSILON; // 0.0000001 from online testing when it was a double
+ mu *= -2.0 / Dk;
+
+ // UPDATE Ak
+ for (int n = 0; n <= (k + 1) / 2; n++) {
+ float t1 = Ak[n] + mu * Ak[k + 1 - n];
+ float t2 = Ak[k + 1 - n] + mu * Ak[n];
+ Ak[n] = t1;
+ Ak[k + 1 - n] = t2;
+ }
+
+ // UPDATE f and b
+ for (int n = 0; n <= N - k - 1; n++) {
+ float t1 = f[n + k + 1] + mu * b[n]; // were double
+ float t2 = b[n] + mu * f[n + k + 1];
+ f[n + k + 1] = t1;
+ b[n] = t2;
+ }
+
+ // UPDATE Dk
+ Dk = (1.0 - mu * mu) * Dk - f[k + 1] * f[k + 1] - b[N - k - 1] * b[N - k - 1];
+ }
+ // ASSIGN COEFFICIENTS
+ coeffs.assign(++Ak.begin(), Ak.end());
+}
+
+void BurgAlgorithm::predict(std::vector<float>& coeffs, std::vector<float>& tail,
+ int size)
+{
+ for (int i = m; i < size; i++) {
+ tail[i] = 0.0;
+ for (int j = 0; j < m; j++) {
+ tail[i] -= coeffs[j] * tail[i - 1 - j];
+ }
+ }
+}
+
//*******************************************************************************
-Regulator::Regulator(int rcvChannels, int bit_res, int FPP, int qLen, int bqLen,
+Channel::Channel(int fpp, int upToNow, int packetsInThePast) // operates at peer FPP
+{
+ predictedNowPacket.resize(fpp);
+ realNowPacket.resize(fpp);
+ outputNowPacket.resize(fpp);
+ futurePredictedPacket.resize(fpp);
+ mTmpFloatBuf.resize(fpp);
+ mZeros.resize(fpp);
+ for (int i = 0; i < fpp; i++)
+ predictedNowPacket[i] = realNowPacket[i] = outputNowPacket[i] =
+ futurePredictedPacket[i] = mTmpFloatBuf[i] = mZeros[i] = 0.0;
+
+ realPast.resize(upToNow);
+ for (int i = 0; i < upToNow; i++)
+ realPast[i] = 0.0;
+ zeroPast.resize(upToNow);
+ for (int i = 0; i < upToNow; i++)
+ zeroPast[i] = 1.0;
+
+ for (int i = 0; i < packetsInThePast; i++) { // don't resize, using push_back
+ std::vector<float> tmp(fpp);
+ for (int j = 0; j < fpp; j++)
+ tmp[j] = 0.0;
+ predictedPast.push_back(tmp);
+ }
+
+ mCoeffsSize = upToNow - 1;
+ coeffs.resize(mCoeffsSize);
+ for (int i = 0; i < mCoeffsSize; i++) {
+ coeffs[i] = 0.0;
+ }
+
+ mTailSize = upToNow + fpp * 2;
+ prediction.resize(mTailSize);
+ for (int i = 0; i < mTailSize; i++) {
+ prediction[i] = 0.0;
+ }
+
+ // set up ring buffer
+ mRing = packetsInThePast;
+ mWptr = mRing / 2;
+ for (int i = 0; i < mRing; i++) { // don't resize, using push_back
+ std::vector<float> tmp(fpp);
+ for (int j = 0; j < fpp; j++)
+ tmp[j] = 0.0;
+ mPacketRing.push_back(tmp);
+ }
+ lastWasGlitch = false;
+}
+
+// push received packet to ring
+void Channel::ringBufferPush()
+{
+ mPacketRing[mWptr % mRing] = mTmpFloatBuf;
+ mWptr++;
+ mWptr %= mRing;
+}
+
+// pull numbered packet from ring
+void Channel::ringBufferPull(int past)
+{
+ int pastPtr = mWptr - past;
+ if (pastPtr < 0)
+ pastPtr += mRing;
+ mTmpFloatBuf = mPacketRing[pastPtr];
+}
+
+//*******************************************************************************
+Regulator::Regulator(int rcvChannels, int bit_res, int localFPP, int qLen, int bqLen,
int sample_rate)
: RingBuffer(0, 0)
+ , mInitialized(false)
, mNumChannels(rcvChannels)
, mAudioBitRes(bit_res)
- , mFPP(FPP)
+ , mLocalFPP(localFPP)
, mSampleRate(sample_rate)
, mMsecTolerance((double)qLen) // handle non-auto mode, expects positive qLen
- , pushStat(NULL)
- , pullStat(NULL)
- , mAuto(false)
- , mSkipAutoHeadroom(true)
- , mLastGlitches(0)
- , mCurrentHeadroom(0)
- , mUseWorkerThread(false)
, m_b_BroadcastQueueLength(bqLen)
- , mRegulatorThreadPtr(NULL)
- , mRegulatorWorkerPtr(NULL)
{
- // catch settings that are compute bound using long HIST
- // hub client rcvChannels is set from client's settings parameters
- // hub server rcvChannels is set from connecting client, not from hub parameters
- // if (mNumChannels > MaxChans) {
- // std::cerr << "*** Regulator.cpp: receive channels = " << mNumChannels
- // << " larger than max channels = " << MaxChans << "\n";
- // exit(1);
- // }
- if (mFPP > MaxFPP) {
- std::cerr << "*** Regulator.cpp: local FPP = " << mFPP
- << " larger than max FPP = " << MaxFPP << "\n";
- exit(1);
- }
switch (mAudioBitRes) { // int from JitterBuffer to AudioInterface enum
case 1:
mBitResolutionMode = AudioInterface::audioBitResolutionT::BIT8;
mBitResolutionMode = AudioInterface::audioBitResolutionT::BIT32;
break;
}
- mHist = HIST; // HIST (default) is 4
- // as FPP decreases the rate of PLC triggers potentially goes up
- // and load increases so don't use an inverse relation
+ mScale = pow(2.0, (((mBitResolutionMode * 8) - 1.0))) - 1.0;
+ mInvScale = 1.0 / mScale;
+
+ if (gVerboseFlag)
+ cout << "mBitResolutionMode = " << mBitResolutionMode << " scale = " << mScale
+ << endl;
+
+ mIncomingTiming.resize(NumSlots);
+ for (int i = 0; i < NumSlots; i++) {
+ mIncomingTiming[i] = 0.0;
+ }
- // crossfaded prediction is a full packet ahead of predicted
- // packet, so the size of mPrediction needs to account for 2 full packets (2*FPP)
- // but trainSamps = (HIST * FPP) and mPrediction.resize(trainSamps - 1, 0.0) so if
- // hist = 2, then it exceeds the size
+ mLocalFPPdurMsec = 1000.0 * mLocalFPP / mSampleRate;
+ mLocalBytes = mLocalFPP * mNumChannels * mBitResolutionMode;
- if (((mNumChannels > 1) && (mFPP > 64)) || (mFPP > 128))
- mHist = 3; // min packets for prediction, needs at least 3
+ // mPhasor.resize(mNumChannels, 0.0);
+}
+
+Regulator::~Regulator()
+{
+ delete[] mXfrBuffer;
+ delete[] mBroadcastBuffer;
+ delete[] mSlotBuf;
+ delete pushStat;
+ delete pullStat;
+ for (int i = 0; i < mNumChannels; i++)
+ delete mChanData[i];
+ if (m_b_BroadcastRingBuffer)
+ delete m_b_BroadcastRingBuffer;
+ delete mTime;
+ delete ba;
+ if (mWorkerThreadPtr != nullptr) {
+ mWorkerThreadPtr->quit();
+ mWorkerThreadPtr->wait();
+ delete mWorkerThreadPtr;
+ }
+ if (mRegulatorWorkerPtr)
+ delete mRegulatorWorkerPtr;
+ if (mWorkerBuffer)
+ delete[] mWorkerBuffer;
+}
+
+//*******************************************************************************
+void Regulator::setFPPratio(int len)
+{
+ // only for first peer packet
+ if (mInitialized) {
+ return;
+ }
+
+ mPeerBytes = len;
+ mPeerFPP = len / (mNumChannels * mBitResolutionMode);
+ mPeerFPPdurMsec = 1000.0 * mPeerFPP / mSampleRate;
+ mFPPratioNumerator = 1;
+ mFPPratioDenominator = 1;
+
+ //////////////////////////////////////
+
+ mPacketsInThePast = HIST; // HIST is the setting for HISTFPP
+
+ if (mPeerFPP < HISTFPP)
+ mPacketsInThePast *= (HISTFPP / mPeerFPP); // but don't go below 2
+ else if (mPeerFPP > (HISTFPP * 2))
+ mPacketsInThePast = 1; // 1 is enough history @ 512 or greater
if (gVerboseFlag)
- cout << "mHist = " << mHist << " at " << mFPP << "\n";
- mBytes = mFPP * mNumChannels * mBitResolutionMode;
- mXfrBuffer = new int8_t[mBytes];
- mPacketCnt = 0; // burg initialization
- mFadeUp.resize(mFPP, 0.0);
- mFadeDown.resize(mFPP, 0.0);
- for (int i = 0; i < mFPP; i++) {
- mFadeUp[i] = (double)i / (double)mFPP;
+ cout << "mPacketsInThePast = " << mPacketsInThePast << " at " << mPeerFPP << " / "
+ << mLocalFPP << endl;
+
+ mPcnt = 0;
+ mTime = new Time();
+ mTime->start();
+ mUpToNow = mPacketsInThePast * mPeerFPP; // duration
+ mBeyondNow = (mPacketsInThePast + 1) * mPeerFPP; // duration
+
+ ba = new BurgAlgorithm(mUpToNow);
+ mPeerFPPdurMsec = 1000.0 * mPeerFPP / mSampleRate;
+ mPeerBytes = mPeerFPP * mNumChannels * mBitResolutionMode;
+
+ //////////////////////////////////////
+
+ if (mPeerFPP != mLocalFPP) {
+ if (mPeerFPP > mLocalFPP)
+ mFPPratioDenominator = mPeerFPP / mLocalFPP;
+ else
+ mFPPratioNumerator = mLocalFPP / mPeerFPP;
+ }
+
+ // bufstrategy 1 autoq mode overloads qLen with negative val
+ // creates this ugly code
+ if (mMsecTolerance <= 0) { // handle -q auto or, for example, -q auto10
+ mAuto = true;
+ // default is -500 from bufstrategy 1 autoq mode
+ // use mMsecTolerance to set headroom
+ if (mMsecTolerance == -500.0) {
+ mAutoHeadroom = -1;
+ cout << "PLC is in auto mode and has been set with variable headroom" << endl;
+ } else {
+ mAutoHeadroom = std::abs(mMsecTolerance);
+ cout << "PLC is in auto mode and has been set with " << mAutoHeadroom
+ << "ms headroom" << endl;
+ if (mAutoHeadroom > 50.0)
+ cout << "That's a very large value and should be less than, "
+ "for example, 50ms"
+ << endl;
+ }
+ // found an interesting relationship between mPeerFPP and initial
+ // mMsecTolerance mPeerFPP*0.5 is pretty good though that's an oddball
+ // conversion of bufsize directly to msec
+ mMsecTolerance = (mPeerFPP * AutoInitValFactor);
+ } else {
+ cout << "PLC is using a fixed tolerance of " << mMsecTolerance << "ms" << endl;
+ }
+
+ mXfrBuffer = new int8_t[mPeerBytes];
+ memset(mXfrBuffer, 0, mPeerBytes);
+ mBroadcastBuffer = new int8_t[mPeerBytes];
+ memset(mBroadcastBuffer, 0, mPeerBytes);
+
+ mFadeUp.resize(mPeerFPP, 0.0);
+ mFadeDown.resize(mPeerFPP, 0.0);
+ for (int i = 0; i < mPeerFPP; i++) {
+ mFadeUp[i] = (double)i / (double)mPeerFPP;
mFadeDown[i] = 1.0 - mFadeUp[i];
}
- mLastWasGlitch = false;
- mNumSlots = NumSlotsMax;
- for (int i = 0; i < mNumSlots; i++) {
- int8_t* tmp = new int8_t[mBytes];
- mSlots.push_back(tmp);
+ mSlots = new int8_t*[NumSlots];
+ mSlotBuf = new int8_t[NumSlots * mPeerBytes];
+ int8_t* tmp = mSlotBuf;
+ for (int i = 0; i < NumSlots; i++) {
+ mSlots[i] = tmp;
+ tmp += mPeerBytes;
}
+
for (int i = 0; i < mNumChannels; i++) {
- ChanData* tmp = new ChanData(i, mFPP, mHist);
+ Channel* tmp = new Channel(mPeerFPP, mUpToNow, mPacketsInThePast);
mChanData.push_back(tmp);
- for (int s = 0; s < mFPP; s++)
- sampleToBits(0.0, i, s); // zero all channels in mXfrBuffer
- }
- mZeros = new int8_t[mBytes];
- memcpy(mZeros, mXfrBuffer, mBytes);
- mAssembledPacket = new int8_t[mBytes]; // for asym
- memcpy(mAssembledPacket, mXfrBuffer, mBytes);
- mLastLostCount = 0; // for stats
+ }
+
mIncomingTimer.start();
mLastSeqNumIn.store(-1, std::memory_order_relaxed);
- mLastSeqNumOut = -1;
- mPhasor.resize(mNumChannels, 0.0);
- mIncomingTiming.resize(NumSlotsMax);
- mAssemblyCounts.resize(NumSlotsMax);
- for (int i = 0; i < NumSlotsMax; i++) {
- mIncomingTiming[i] = 0.0;
- mAssemblyCounts[i] = 0;
- }
- mFPPratioNumerator = 1;
- mFPPratioDenominator = 1;
- mFPPratioIsSet = false;
- mBytesPeerPacket = mBytes;
- mPeerFPP = mFPP; // use local until first packet arrives
- mAutoHeadroom = 3.0;
- mFPPdurMsec = 1000.0 * mFPP / mSampleRate;
- changeGlobal_2(NumSlotsMax); // need hg if running GUI
if (m_b_BroadcastQueueLength) {
m_b_BroadcastRingBuffer =
- new JitterBuffer(mFPP, qLen, mSampleRate, 1, m_b_BroadcastQueueLength,
+ new JitterBuffer(mPeerFPP, 10, mSampleRate, 1, m_b_BroadcastQueueLength,
mNumChannels, mAudioBitRes);
- qDebug() << "Broadcast started in Regulator with packet queue of"
- << m_b_BroadcastQueueLength;
+ cout << "Broadcast started in Regulator with packet queue of "
+ << m_b_BroadcastQueueLength << endl;
// have not implemented the mJackTrip->queueLengthChanged functionality
}
-}
-void Regulator::enableWorkerThread(QThread* thread_ptr)
-{
- if (thread_ptr == nullptr) {
- // create owned regulator thread (client mode)
- if (mRegulatorThreadPtr == nullptr) {
- mRegulatorThreadPtr = new QThread();
- mRegulatorThreadPtr->setObjectName("RegulatorThread");
- mRegulatorThreadPtr->start();
- }
- thread_ptr = mRegulatorThreadPtr;
- }
- if (mRegulatorWorkerPtr != nullptr) {
- delete mRegulatorWorkerPtr;
- }
- mRegulatorWorkerPtr = new RegulatorWorker(this);
- mRegulatorWorkerPtr->moveToThread(thread_ptr);
- mUseWorkerThread = true;
-}
+ // number of stats tick calls per sec depends on FPP
+ pushStat =
+ new StdDev(1, &mIncomingTimer, (int)(floor(mSampleRate / (double)mPeerFPP)));
+ pullStat =
+ new StdDev(2, &mIncomingTimer, (int)(floor(mSampleRate / (double)mLocalFPP)));
-void Regulator::changeGlobal(double x)
-{
- mMsecTolerance = x;
- printParams();
+ mInitialized = true;
}
-void Regulator::changeGlobal_2(int x)
-{ // mNumSlots
- mNumSlots = x;
- if (!mNumSlots)
- mNumSlots = 1;
- if (mNumSlots > NumSlotsMax)
- mNumSlots = NumSlotsMax;
- printParams();
-}
-
-void Regulator::printParams(){
- // qDebug() << "mMsecTolerance" << mMsecTolerance << "mNumSlots" << mNumSlots;
-};
-
-Regulator::~Regulator()
+//*******************************************************************************
+bool Regulator::enableWorker()
{
- if (mRegulatorThreadPtr != nullptr) {
- // Stop the Regulator thread before deleting other things
- mRegulatorThreadPtr->quit();
- mRegulatorThreadPtr->wait();
- delete mRegulatorThreadPtr;
+ // enable worker thread & queue if a prediction takes longer than
+ // our local audio callback interval (too slow to keep up)
+ const double maxPLCdspAllowed = mLocalFPPdurMsec * 0.7; // 70%
+ if (mStatsMaxPLCdspElapsed >= maxPLCdspAllowed && !isWorkerEnabled()) {
+ cout << "PLC dsp " << mStatsMaxPLCdspElapsed
+ << " is too slow (max=" << maxPLCdspAllowed << "), enabling worker" << endl;
+ mWorkerBuffer = new int8_t[mPeerBytes];
+ memset(mWorkerBuffer, 0, mPeerBytes);
+ mWorkerThreadPtr = new QThread();
+ mWorkerThreadPtr->setObjectName("RegulatorThread");
+ mWorkerThreadPtr->start();
+ mRegulatorWorkerPtr = new RegulatorWorker(this);
+ mRegulatorWorkerPtr->moveToThread(mWorkerThreadPtr);
+ mWorkerEnabled = true;
}
- if (mRegulatorWorkerPtr != nullptr)
- delete mRegulatorWorkerPtr;
- delete[] mXfrBuffer;
- delete[] mZeros;
- delete[] mAssembledPacket;
- delete pushStat;
- delete pullStat;
- for (int i = 0; i < mNumChannels; i++)
- delete mChanData[i];
- for (auto& slot : mSlots) {
- delete[] slot;
- };
- if (m_b_BroadcastQueueLength)
- delete m_b_BroadcastRingBuffer;
+ return mWorkerEnabled;
}
//*******************************************************************************
-void Regulator::updateTolerance()
+void Regulator::updateTolerance(int glitches, int skipped)
{
- // pushes happen when we have new packets received from peer
- // pulls happen when our audio interface triggers a callback
- const double pushStatTol = pushStat->calcAuto();
- const double pullStatTol = pullStat->calcAuto();
+ // update headroom
if (mAutoHeadroom < 0) {
- // auto headroom calculation: use value calculated by pullStats
- // because that is where it counts glitches in the incoming peer stream
- const int glitchesAllowed =
+ // variable headroom: automatically increase to minimize glitch counts
+ // only increase headroom if doing so would have reduced the number of
+ // glitches that occured over the past two seconds by 2% or more.
+ // prevent headroom from growing beyond rolling average of max.
+ const int skipsAllowed =
static_cast<int>(AutoHeadroomGlitchTolerance * mSampleRate / mPeerFPP);
- const int totalGlitches = pullStat->plcUnderruns + pullStat->plcOverruns;
- const int newGlitches = totalGlitches - mLastGlitches;
- mLastGlitches = totalGlitches;
- // require two consecutive periods of glitches exceeding allowed threshold
- if (newGlitches > glitchesAllowed && mCurrentHeadroom < MaxAutoHeadroom) {
+ if (glitches > 0 && skipped > skipsAllowed
+ && mCurrentHeadroom + 1 <= pushStat->longTermMax) {
if (mSkipAutoHeadroom) {
mSkipAutoHeadroom = false;
} else {
mSkipAutoHeadroom = true;
++mCurrentHeadroom;
- qDebug() << "PLC" << newGlitches << "glitches"
- << ">" << glitchesAllowed << "allowed: Increasing headroom to "
- << mCurrentHeadroom;
+ cout << "PLC glitches=" << glitches << " skipped=" << skipped << ">"
+ << skipsAllowed << ", increasing headroom to " << mCurrentHeadroom
+ << " (max=" << pushStat->longTermMax << ")" << endl;
}
} else {
mSkipAutoHeadroom = true;
}
} else {
+ // fixed headroom
mCurrentHeadroom = mAutoHeadroom;
}
- double tmp = std::max<double>(pushStatTol + mCurrentHeadroom, pullStatTol);
- if (tmp > AutoMax)
- tmp = AutoMax;
- if (tmp < mFPPdurMsec)
- tmp = mFPPdurMsec;
- if (tmp < mPeerFPPdurMsec)
- tmp = mPeerFPPdurMsec;
- mMsecTolerance = tmp;
-}
-//*******************************************************************************
-void Regulator::setFPPratio()
-{
- if (mPeerFPP != mFPP) {
- if (mPeerFPP > mFPP)
- mFPPratioDenominator = mPeerFPP / mFPP;
- else
- mFPPratioNumerator = mFPP / mPeerFPP;
- // qDebug() << "peerBuffers / localBuffers" << mFPPratioNumerator << " / "
- // << mFPPratioDenominator;
- }
+ // pushes happen when we have new packets received from peer
+ // pulls happen when our audio interface triggers a callback
+ const double pushStatTol = pushStat->calcAuto();
+ const double pullStatTol = pullStat->calcAuto();
+ double newTolerance = std::max<double>(pushStatTol + mCurrentHeadroom, pullStatTol);
+ if (newTolerance > AutoMax)
+ newTolerance = AutoMax;
+ if (newTolerance < mLocalFPPdurMsec)
+ newTolerance = mLocalFPPdurMsec;
+ if (newTolerance < mPeerFPPdurMsec)
+ newTolerance = mPeerFPPdurMsec;
+ mMsecTolerance = newTolerance;
}
//*******************************************************************************
-void Regulator::shimFPP(const int8_t* buf, int len, int seq_num)
+void Regulator::updatePushStats(int seq_num)
{
- if (seq_num != -1) {
- if (!mFPPratioIsSet) { // first peer packet
- mBytesPeerPacket = len;
- mPeerFPP = len / (mNumChannels * mBitResolutionMode);
- mPeerFPPdurMsec = 1000.0 * mPeerFPP / mSampleRate;
- // bufstrategy 1 autoq mode overloads qLen with negative val
- // creates this ugly code
- if (mMsecTolerance <= 0) { // handle -q auto or, for example, -q auto10
- mAuto = true;
- // default is -500 from bufstrategy 1 autoq mode
- // use mMsecTolerance to set headroom
- if (mMsecTolerance == -500.0) {
- mAutoHeadroom = -1;
- qDebug()
- << "PLC is in auto mode and has been set with variable headroom";
- } else {
- mAutoHeadroom = -mMsecTolerance;
- qDebug() << "PLC is in auto mode and has been set with"
- << mAutoHeadroom << "ms headroom";
- if (mAutoHeadroom > 50.0)
- qDebug() << "That's a very large value and should be less than, "
- "for example, 50ms";
- }
- // found an interesting relationship between mPeerFPP and initial
- // mMsecTolerance mPeerFPP*0.5 is pretty good though that's an oddball
- // conversion of bufsize directly to msec
- mMsecTolerance = (mPeerFPP * AutoInitValFactor);
- };
- setFPPratio();
- // number of stats tick calls per sec depends on FPP
- pushStat = new StdDev(1, &mIncomingTimer,
- (int)(floor(mSampleRate / (double)mPeerFPP)));
- pullStat =
- new StdDev(2, &mIncomingTimer, (int)(floor(mSampleRate / (double)mFPP)));
- mFPPratioIsSet = true;
- }
- if (mFPPratioNumerator == mFPPratioDenominator) {
- // local FPP matches peer
- pushPacket(buf, seq_num);
- } else if (mFPPratioNumerator > 1) {
- // 2/1, 4/1 peer FPP is lower, (local/peer)/1
- assemblePacket(buf, seq_num);
- } else {
- // 1/2, 1/4 peer FPP is higher, 1/(peer/local)
- seq_num *= mFPPratioDenominator;
- for (int i = 0; i < mFPPratioDenominator; i++) {
- memcpy(mAssembledPacket, buf, mBytes);
- pushPacket(mAssembledPacket, seq_num);
- buf += mBytes;
- seq_num++;
- }
- }
- bool pushStatsUpdated = pushStat->tick();
- if (mAuto && pushStatsUpdated && (pushStat->lastTime > AutoInitDur)
- && pushStat->longTermCnt % WindowDivisor == 0) {
+ // use time of last packet pulled as a baseline time for previous packet
+ // this avoids having to search for a previous packet that wasn't missing
+ // pkts is distance of previous packet from mLastSeqNumOut
+ int pkts = seq_num - 1 - mLastSeqNumOut;
+ if (pkts < 0)
+ pkts += NumSlots;
+ double prev_time = mIncomingTiming[mLastSeqNumOut] + (pkts * mPeerFPPdurMsec);
+ if (prev_time >= mIncomingTiming[seq_num])
+ return; // skip edge case where mLastSeqNumOut was very late
+
+ // update push stats
+ bool pushStatsUpdated = pushStat->tick(prev_time, mIncomingTiming[seq_num]);
+ if (pushStatsUpdated && pushStat->longTermCnt % WindowDivisor == 0) {
+ // once per second
+ const int totalGlitches = pullStat->plcUnderruns + pullStat->plcOverruns;
+ const int totalSkipped = mSkipped;
+ const int newGlitches = totalGlitches - mLastGlitches;
+ const int newSkipped = totalSkipped - mLastSkipped;
+ mLastGlitches = totalGlitches;
+ mLastSkipped = totalSkipped;
+ if (mAuto && pushStat->lastTime > AutoInitDur) {
// after AutoInitDur: update auto tolerance once per second
- updateTolerance();
+ updateTolerance(newGlitches, newSkipped);
}
}
-};
+}
//*******************************************************************************
void Regulator::pushPacket(const int8_t* buf, int seq_num)
{
- if (m_b_BroadcastQueueLength)
- m_b_BroadcastRingBuffer->insertSlotNonBlocking(buf, mBytes, 0, seq_num);
- seq_num %= mNumSlots;
+ if (m_b_BroadcastRingBuffer != NULL)
+ m_b_BroadcastRingBuffer->insertSlotNonBlocking(buf, mPeerBytes, 0, seq_num);
+ seq_num %= NumSlots;
// if (seq_num==0) return; // impose regular loss
- mIncomingTiming[seq_num] =
- mMsecTolerance + (double)mIncomingTimer.nsecsElapsed() / 1000000.0;
- memcpy(mSlots[seq_num], buf, mBytes);
+ mIncomingTiming[seq_num] = (double)mIncomingTimer.nsecsElapsed() / 1000000.0;
+ memcpy(mSlots[seq_num], buf, mPeerBytes);
mLastSeqNumIn.store(seq_num, std::memory_order_release);
};
//*******************************************************************************
-void Regulator::assemblePacket(const int8_t* buf, int peer_seq_num)
-{
- // copy packet fragment into slot
- int seq_num = (peer_seq_num / mFPPratioNumerator) % mNumSlots;
- int pkt_pos = (peer_seq_num % mFPPratioNumerator);
- memcpy(&(mSlots[seq_num][pkt_pos * mBytesPeerPacket]), buf, mBytesPeerPacket);
-
- // check if done assembling yet
- if (++mAssemblyCounts[seq_num] < mFPPratioNumerator)
- return;
-
- // complete it
- if (m_b_BroadcastQueueLength)
- m_b_BroadcastRingBuffer->insertSlotNonBlocking(mSlots[seq_num], mBytes, 0,
- seq_num);
- mIncomingTiming[seq_num] =
- mMsecTolerance + (double)mIncomingTimer.nsecsElapsed() / 1000000.0;
- mLastSeqNumIn.store(seq_num, std::memory_order_release);
-};
-
-//*******************************************************************************
-void Regulator::pullPacket()
+bool Regulator::pullPacket()
{
const double now = (double)mIncomingTimer.nsecsElapsed() / 1000000.0;
const int lastSeqNumIn = mLastSeqNumIn.load(std::memory_order_acquire);
- mSkip = 0;
+ int skipped = 0;
- if ((lastSeqNumIn == -1) || (!mFPPratioIsSet)) {
+ if ((lastSeqNumIn == -1) || (!mInitialized)) {
goto ZERO_OUTPUT;
} else if (lastSeqNumIn == mLastSeqNumOut) {
goto UNDERRUN;
// find the next packet to pull
int new_pkts = lastSeqNumIn - mLastSeqNumOut;
if (new_pkts < 0)
- new_pkts += mNumSlots;
+ new_pkts += NumSlots;
// iterate through each new packet
for (int i = new_pkts - 1; i >= 0; i--) {
int next = lastSeqNumIn - i;
if (next < 0)
- next += mNumSlots;
- if (mFPPratioNumerator > 1) {
- // time for assembly has passed; reset for next time
- mAssemblyCounts[next] = 0;
- }
+ next += NumSlots;
if (mLastSeqNumOut != -1) {
// account for missing packets
- if (mIncomingTiming[next] < mIncomingTiming[mLastSeqNumOut])
+ if (mIncomingTiming[next] < mIncomingTiming[mLastSeqNumOut]
+ && mIncomingTiming[mLastSeqNumOut] - mIncomingTiming[next]
+ > mMsecTolerance)
continue;
+ updatePushStats(next);
// count how many we have skipped
- mSkip = next - mLastSeqNumOut - 1;
- if (mSkip < 0)
- mSkip += mNumSlots;
+ skipped = next - mLastSeqNumOut - 1;
+ if (skipped < 0)
+ skipped += NumSlots;
}
- // set next as the best candidate
- mLastSeqNumOut = next;
- // if next timestamp < now, it is too old based upon tolerance
- if (mIncomingTiming[mLastSeqNumOut] >= now) {
+ if (mIncomingTiming[next] + mMsecTolerance >= now) {
// next is the best candidate
- memcpy(mXfrBuffer, mSlots[mLastSeqNumOut], mBytes);
+ memcpy(mXfrBuffer, mSlots[next], mPeerBytes);
+ mLastSeqNumOut = next;
goto PACKETOK;
}
+ // track how many good packets we skipped due to tolerance < 1ms
+ if (mIncomingTiming[next] + mMsecTolerance + 1 >= now) {
+ ++mSkipped;
+ }
}
// no viable candidate
}
PACKETOK : {
- if (mSkip) {
+ if (skipped) {
processPacket(true);
- pullStat->plcOverruns += mSkip;
+ pullStat->plcOverruns += skipped;
+ return true;
} else
processPacket(false);
goto OUTPUT;
}
// "good underrun", not a stuck client
processPacket(true);
- goto OUTPUT;
+ return true;
}
ZERO_OUTPUT:
- memcpy(mXfrBuffer, mZeros, mBytes);
+ memset(mXfrBuffer, 0, mPeerBytes);
OUTPUT:
- pullStat->tick();
- return;
+ return false;
};
//*******************************************************************************
double tmp = 0.0;
if (glitch)
tmp = (double)mIncomingTimer.nsecsElapsed();
- for (int ch = 0; ch < mNumChannels; ch++)
- processChannel(ch, glitch, mPacketCnt, mLastWasGlitch);
- mLastWasGlitch = glitch;
- mPacketCnt++;
- // 32 bit is good for days: (/ (* (- (expt 2 32) 1) (/ 32 48000.0)) (* 60 60 24))
+
+ zeroTmpFloatBuf(); // ahead of either call to burg
+ xfrBufferToFloatBuf();
+ burg(glitch);
+ floatBufToXfrBuffer();
if (glitch) {
double tmp2 = (double)mIncomingTimer.nsecsElapsed() - tmp;
tmp2 /= 1000000.0;
- pullStat->lastPLCdspElapsed = tmp2;
+ if (tmp2 > mStatsMaxPLCdspElapsed)
+ mStatsMaxPLCdspElapsed = tmp2;
}
}
-//*******************************************************************************
-void Regulator::processChannel(int ch, bool glitch, int packetCnt, bool lastWasGlitch)
-{
- // if(glitch) qDebug() << "glitch"; else fprintf(stderr,".");
- ChanData* cd = mChanData[ch];
- for (int s = 0; s < mFPP; s++)
- cd->mTruth[s] = bitsToSample(ch, s);
- if (packetCnt) {
- // always update mTrain
- for (int i = 0; i < mHist; i++) {
- for (int s = 0; s < mFPP; s++)
- cd->mTrain[s + ((mHist - (i + 1)) * mFPP)] = cd->mLastPackets[i][s];
- }
- if (glitch) {
- // GET LINEAR PREDICTION COEFFICIENTS
- ba.train(cd->mCoeffs, cd->mTrain);
-
- // LINEAR PREDICT DATA
- cd->mTail = cd->mTrain;
-
- ba.predict(cd->mCoeffs,
- cd->mTail); // resizes to TRAINSAMPS-2 + TRAINSAMPS
-
- for (int i = 0; i < (cd->trainSamps - 2); i++)
- cd->mPrediction[i] = cd->mTail[i + cd->trainSamps];
- }
- // cross fade last prediction with mTruth
- if (lastWasGlitch)
- for (int s = 0; s < mFPP; s++)
- cd->mXfadedPred[s] =
- cd->mTruth[s] * mFadeUp[s] + cd->mLastPred[s] * mFadeDown[s];
- for (int s = 0; s < mFPP; s++)
- sampleToBits((glitch)
- ? cd->mPrediction[s]
- : ((lastWasGlitch) ? cd->mXfadedPred[s] : cd->mTruth[s]),
- ch, s);
- if (glitch) {
- for (int s = 0; s < mFPP; s++)
- cd->mLastPred[s] = cd->mPrediction[s + mFPP];
- }
- }
-
- // copy down history
-
- for (int i = mHist - 1; i > 0; i--) {
- for (int s = 0; s < mFPP; s++)
- cd->mLastPackets[i][s] = cd->mLastPackets[i - 1][s];
- }
-
- // add prediction or current input to history, the former checking if primed
-
- for (int s = 0; s < mFPP; s++)
- cd->mLastPackets[0][s] =
- // ((!glitch) || (packetCnt < mHist)) ? cd->mTruth[s] :
- // cd->mPrediction[s];
- ((glitch) ? ((packetCnt >= mHist) ? cd->mPrediction[s] : cd->mTruth[s])
- : ((lastWasGlitch) ? cd->mXfadedPred[s] : cd->mTruth[s]));
-
- // diagnostic output
- /////////////////////
- if (false)
- for (int s = 0; s < mFPP; s++) {
- sampleToBits(0.7 * sin(mPhasor[ch]), ch, s);
- mPhasor[ch] += (!ch) ? 0.1 : 0.11;
- }
- /////////////////////
-}
-
//*******************************************************************************
// copped from AudioInterface.cpp
mBitResolutionMode);
}
-//*******************************************************************************
-bool BurgAlgorithm::classify(double d)
+/*
+void Regulator::sineToXfrBuffer()
{
- bool tmp = false;
- switch (fpclassify(d)) {
- case FP_INFINITE:
- qDebug() << ("infinite");
- tmp = true;
- break;
- case FP_NAN:
- qDebug() << ("NaN");
- tmp = true;
- break;
- case FP_ZERO:
- qDebug() << ("zero");
- tmp = true;
- break;
- case FP_SUBNORMAL:
- qDebug() << ("subnormal");
- tmp = true;
- break;
- // case FP_NORMAL: qDebug() << ("normal"); break;
- }
- // if (signbit(d)) qDebug() << (" negative\n"); else qDebug() << (" positive or
- // unsigned\n");
- return tmp;
-}
+ for (int ch = 0; ch < mNumChannels; ch++)
+ for (int s = 0; s < mPeerFPP; s++) {
+ sampleToBits(0.7 * sin(mPhasor[ch]), ch, s);
+ mPhasor[ch] += (!ch) ? 0.1 : 0.11;
+ }
+};
+*/
-void BurgAlgorithm::train(std::vector<double>& coeffs, const std::vector<double>& x)
+void Regulator::floatBufToXfrBuffer()
{
- // GET SIZE FROM INPUT VECTORS
- size_t N = x.size() - 1;
- size_t m = coeffs.size();
-
- // if (x.size() < m) qDebug() << "time_series should have more elements
- // than the AR order is";
-
- // INITIALIZE Ak
- // vector<double> Ak(m + 1, 0.0);
- Ak.assign(m + 1, 0.0);
- Ak[0] = 1.0;
-
- // INITIALIZE f and b
- // vector<double> f;
- f.resize(x.size());
- for (unsigned int i = 0; i < x.size(); i++)
- f[i] = x[i];
- // vector<double> b(f);
- b = f;
-
- // INITIALIZE Dk
- double Dk = 0.0;
- for (size_t j = 0; j <= N; j++) // CC: N is $#x-1 in C++ but $#x in perl
- {
- Dk += 2.00001 * f[j] * f[j]; // CC: needs more damping than orig 2.0
- }
- Dk -= f[0] * f[0] + b[N] * b[N];
-
- // qDebug() << "Dk" << qStringFromLongDouble1(Dk);
- // if ( classify(Dk) )
- // { qDebug() << pCnt << "init";
- // }
-
- // BURG RECURSION
- for (size_t k = 0; k < m; k++) {
- // COMPUTE MU
- double mu = 0.0;
- for (size_t n = 0; n <= N - k - 1; n++) {
- mu += f[n + k + 1] * b[n];
+ for (int ch = 0; ch < mNumChannels; ch++)
+ for (int s = 0; s < mPeerFPP; s++) {
+ double tmpOut = mChanData[ch]->mTmpFloatBuf[s];
+ // if (tmpOut > 1.0) tmpOut = 1.0;
+ // if (tmpOut < -1.0) tmpOut = -1.0;
+ sampleToBits(tmpOut, ch, s);
}
+};
- if (Dk == 0.0)
- Dk = 0.0000001; // CC: from testing, needs eps
- // if ( classify(Dk) ) qDebug() << pCnt << "run";
-
- mu *= -2.0 / Dk;
- // if ( isnan(Dk) ) { qDebug() << "k" << k; }
- // if (Dk==0.0) qDebug() << "k" << k << "Dk==0";
-
- // UPDATE Ak
- for (size_t n = 0; n <= (k + 1) / 2; n++) {
- double t1 = Ak[n] + mu * Ak[k + 1 - n];
- double t2 = Ak[k + 1 - n] + mu * Ak[n];
- Ak[n] = t1;
- Ak[k + 1 - n] = t2;
+void Regulator::xfrBufferToFloatBuf()
+{
+ for (int ch = 0; ch < mNumChannels; ch++)
+ for (int s = 0; s < mPeerFPP; s++) {
+ double tmpIn = bitsToSample(ch, s);
+ mChanData[ch]->mTmpFloatBuf[s] = tmpIn;
}
+};
- // UPDATE f and b
- for (size_t n = 0; n <= N - k - 1; n++) {
- double t1 = f[n + k + 1] + mu * b[n]; // were double
- double t2 = b[n] + mu * f[n + k + 1];
- f[n + k + 1] = t1;
- b[n] = t2;
+void Regulator::toFloatBuf(qint16* in)
+{
+ for (int ch = 0; ch < mNumChannels; ch++)
+ for (int i = 0; i < mPeerFPP; i++) {
+ double tmpIn = ((qint16)*in++) * mInvScale;
+ mChanData[ch]->mTmpFloatBuf[i] = tmpIn;
}
-
- // UPDATE Dk
- Dk = (1.0 - mu * mu) * Dk - f[k + 1] * f[k + 1] - b[N - k - 1] * b[N - k - 1];
- }
- // ASSIGN COEFFICIENTS
- coeffs.assign(++Ak.begin(), Ak.end());
}
-void BurgAlgorithm::predict(std::vector<double>& coeffs, std::vector<double>& tail)
+void Regulator::fromFloatBuf(qint16* out)
{
- size_t m = coeffs.size();
- // qDebug() << "tail.at(0)" << tail[0]*32768;
- // qDebug() << "tail.at(1)" << tail[1]*32768;
- tail.resize(m + tail.size());
- // qDebug() << "tail.at(m)" << tail[m]*32768;
- // qDebug() << "tail.at(...end...)" << tail[tail.size()-1]*32768;
- // qDebug() << "m" << m << "tail.size()" << tail.size();
- for (size_t i = m; i < tail.size(); i++) {
- tail[i] = 0.0;
- for (size_t j = 0; j < m; j++) {
- tail[i] -= coeffs[j] * tail[i - 1 - j];
+ for (int ch = 0; ch < mNumChannels; ch++)
+ for (int i = 0; i < mPeerFPP; i++) {
+ double tmpOut = mChanData[ch]->mTmpFloatBuf[i];
+ if (tmpOut > 1.0)
+ tmpOut = 1.0;
+ if (tmpOut < -1.0)
+ tmpOut = -1.0;
+ *out++ = (qint16)(tmpOut * mScale);
}
- }
}
-//*******************************************************************************
-ChanData::ChanData(int i, int FPP, int hist) : ch(i)
+void Regulator::zeroTmpFloatBuf()
{
- int shrinkCoeffsFactor = 1;
- if (FPP == 1024)
- shrinkCoeffsFactor = 8;
- trainSamps = (hist * FPP);
- mTruth.resize(FPP, 0.0);
- mXfadedPred.resize(FPP, 0.0);
- mLastPred.resize(FPP, 0.0);
- for (int i = 0; i < hist; i++) {
- std::vector<sample_t> tmp(FPP, 0.0);
- mLastPackets.push_back(tmp);
- }
- mTrain.resize(trainSamps, 0.0);
- mPrediction.resize(trainSamps - 1, 0.0); // ORDER
- mCoeffs.resize(trainSamps / shrinkCoeffsFactor - 2, 0.0);
- mCrossFadeDown.resize(FPP, 0.0);
- mCrossFadeUp.resize(FPP, 0.0);
- mCrossfade.resize(FPP, 0.0);
+ for (int ch = 0; ch < mNumChannels; ch++)
+ mChanData[ch]->mTmpFloatBuf = mChanData[ch]->mZeros;
}
//*******************************************************************************
longTermMax = 0.0;
longTermMaxAcc = 0.0;
lastTime = 0.0;
- lastPLCdspElapsed = 0.0;
- lastPlcOverruns = 0;
- lastPlcUnderruns = 0;
plcOverruns = 0;
plcUnderruns = 0;
data.resize(w, 0.0);
double StdDev::calcAuto()
{
- // qDebug() << longTermStdDev << longTermMax << AutoMax << window <<
- // longTermCnt;
if ((longTermStdDev == 0.0) || (longTermMax == 0.0))
return AutoMax;
double tmp = longTermStdDev + ((longTermMax > AutoMax) ? AutoMax : longTermMax);
return avg + AutoSmoothingFactor * (current - avg);
}
-bool StdDev::tick()
+bool StdDev::tick(double prevTime, double curTime)
{
- double now = (double)mTimer->nsecsElapsed() / 1000000.0;
- double msElapsed = now - lastTime;
- lastTime = now;
+ double msElapsed = curTime - prevTime;
+ if (msElapsed > 0) {
+ lastTime = curTime;
+ } else {
+ double now = (double)mTimer->nsecsElapsed() / 1000000.0;
+ msElapsed = now - lastTime;
+ lastTime = now;
+ }
// discard measurements that exceed the max wait time
// this prevents temporary outages from skewing jitter metrics
if (msElapsed > gUdpWaitTimeout)
return false;
- if (ctr != window) {
- data[ctr] = msElapsed;
- if (msElapsed < min)
- min = msElapsed;
- else if (msElapsed > max)
- max = msElapsed;
- acc += msElapsed;
- ctr++;
- /*
- // for debugging startup issues -- you'll see a bunch of pushes
- // UDPDataProtocol all at once, which I imagine were queued up
- // in the kernel's stack
- if (gVerboseFlag && longTermCnt == 0) {
- std::cout << setw(10) << msElapsed << " " << mId << endl;
- }
- */
- return false;
+ data[ctr] = msElapsed;
+ if (msElapsed < min)
+ min = msElapsed;
+ else if (msElapsed > max)
+ max = msElapsed;
+ acc += msElapsed;
+ if (ctr == 0 && longTermCnt % WindowDivisor == 0) {
+ lastMin = msElapsed;
+ lastMax = msElapsed;
+ } else {
+ if (msElapsed < lastMin)
+ lastMin = msElapsed;
+ if (msElapsed > lastMax)
+ lastMax = msElapsed;
}
+ if (++ctr < window)
+ return false;
+ ctr = 0;
// calculate mean and standard deviation
mean = (double)acc / (double)window;
double stdDevTmp = sqrt(var);
if (longTermCnt <= 3) {
- if (longTermCnt == 0 && gVerboseFlag) {
- cout << "printing directly from Regulator->stdDev->tick:\n (mean / min / "
- "max / "
- "stdDev / longTermMax / longTermStdDev) \n";
+ if (longTermCnt == 0 && gVerboseFlag && PrintDirect) {
+ cout << "printing directly from Regulator->stdDev->tick:" << endl
+ << " (mean / min / max / stdDev / longTermMax / longTermStdDev)" << endl;
}
// ignore first few stats because they are unreliable
longTermMax = max;
}
}
- if (gVerboseFlag) {
+ if (gVerboseFlag && PrintDirect) {
cout << setw(10) << mean << setw(10) << min << setw(10) << max << setw(10)
<< stdDevTmp << setw(10) << longTermMax << setw(10) << longTermStdDev << " "
<< mId << endl;
longTermCnt++;
lastMean = mean;
- lastMin = min;
- lastMax = max;
lastStdDev = stdDevTmp;
reset();
+
return true;
}
void Regulator::readSlotNonBlocking(int8_t* ptrToReadSlot)
{
- if (!mFPPratioIsSet) {
+ if (!mInitialized) {
// audio callback before receiving first packet from peer
// nothing is initialized yet, so just return silence
- memcpy(ptrToReadSlot, mZeros, mBytes);
+ memset(ptrToReadSlot, 0, mLocalBytes);
+ return;
+ }
+
+ pullStat->tick();
+
+ bool prediction = false;
+ if (mFPPratioNumerator == mFPPratioDenominator) {
+ // local FPP matches peer
+ if (isWorkerEnabled()) {
+ // we need to use a different buffer here since mXfrBuffer
+ // is used to pass data between the worker and PLC backend
+ mRegulatorWorkerPtr->pop(mWorkerBuffer);
+ memcpy(ptrToReadSlot, mWorkerBuffer, mLocalBytes);
+ } else {
+ prediction = pullPacket();
+ memcpy(ptrToReadSlot, mXfrBuffer, mLocalBytes);
+ if (prediction)
+ enableWorker();
+ // nothing special to do if enabled
+ }
return;
}
- if (mUseWorkerThread) {
- // use separate worker thread for PLC
- mRegulatorWorkerPtr->pop(ptrToReadSlot);
+
+ if (mFPPratioNumerator > 1) {
+ // 2/1, 4/1 peer FPP is lower, (local/peer)/1
+ if (isWorkerEnabled()) {
+ for (int i = 0; i < mFPPratioNumerator; i++) {
+ mRegulatorWorkerPtr->pop(mWorkerBuffer);
+ memcpy(ptrToReadSlot, mWorkerBuffer, mPeerBytes);
+ ptrToReadSlot += mPeerBytes;
+ }
+ } else {
+ for (int i = 0; i < mFPPratioNumerator; i++) {
+ if (pullPacket())
+ prediction = true;
+ memcpy(ptrToReadSlot, mXfrBuffer, mPeerBytes);
+ ptrToReadSlot += mPeerBytes;
+ }
+ if (prediction)
+ enableWorker();
+ // nothing special to do if enabled
+ }
return;
}
- // use jack callback thread to perform PLC
- pullPacket();
- memcpy(ptrToReadSlot, mXfrBuffer, mBytes);
+
+ // 1/2, 1/4 peer FPP is higher, 1/(peer/local)
+ if (isWorkerEnabled()) {
+ if (mXfrPullPtr == NULL || mXfrPullPtr >= (mWorkerBuffer + mPeerBytes)) {
+ mRegulatorWorkerPtr->pop(mWorkerBuffer);
+ mXfrPullPtr = mWorkerBuffer;
+ }
+ } else {
+ if (mXfrPullPtr == NULL || mXfrPullPtr >= (mXfrBuffer + mPeerBytes)) {
+ prediction = pullPacket();
+ mXfrPullPtr = mXfrBuffer;
+ if (prediction) {
+ if (enableWorker()) {
+ // copy result to worker buffer
+ memcpy(mWorkerBuffer, mXfrBuffer, mPeerBytes);
+ mXfrPullPtr = mWorkerBuffer;
+ }
+ }
+ }
+ }
+
+ memcpy(ptrToReadSlot, mXfrPullPtr, mLocalBytes);
+ mXfrPullPtr += mLocalBytes;
+}
+
+void Regulator::readBroadcastSlot(int8_t* ptrToReadSlot)
+{
+ if (!mInitialized || m_b_BroadcastRingBuffer == NULL) {
+ // audio callback before receiving first packet from peer
+ // nothing is initialized yet, so just return silence
+ memset(ptrToReadSlot, 0, mLocalBytes);
+ return;
+ }
+
+ if (mFPPratioNumerator == mFPPratioDenominator) {
+ // local FPP matches peer
+ m_b_BroadcastRingBuffer->readBroadcastSlot(ptrToReadSlot);
+ return;
+ }
+
+ if (mFPPratioNumerator > 1) {
+ // 2/1, 4/1 peer FPP is lower, (local/peer)/1
+ for (int i = 0; i < mFPPratioNumerator; i++) {
+ m_b_BroadcastRingBuffer->readBroadcastSlot(ptrToReadSlot);
+ ptrToReadSlot += mPeerBytes;
+ }
+ return;
+ }
+
+ // 1/2, 1/4 peer FPP is higher, 1/(peer/local)
+ if (mBroadcastPullPtr == NULL
+ || mBroadcastPullPtr >= (mBroadcastBuffer + mPeerBytes)) {
+ m_b_BroadcastRingBuffer->readBroadcastSlot(mBroadcastBuffer);
+ mBroadcastPullPtr = mBroadcastBuffer;
+ }
+ memcpy(ptrToReadSlot, mBroadcastPullPtr, mLocalBytes);
+ mBroadcastPullPtr += mLocalBytes;
+}
+
+//*******************************************************************************
+void Regulator::burg(bool glitch)
+{ // generate next bufferfull and convert to short int
+ bool primed = mPcnt > mPacketsInThePast;
+ for (int ch = 0; ch < mNumChannels; ch++) {
+ Channel* c = mChanData[ch];
+ //////////////////////////////////////
+ if (glitch)
+ mTime->trigger(ch); // if ch == 0, incr glitchCnt
+
+ for (int s = 0; s < mPeerFPP; s++)
+ c->realNowPacket[s] = (!glitch) ? c->mTmpFloatBuf[s] : 0.0;
+
+ if (!glitch) {
+ for (int s = 0; s < mPeerFPP; s++)
+ c->mTmpFloatBuf[s] = c->realNowPacket[s];
+ c->ringBufferPush();
+ }
+
+ if (primed) {
+ int offset = 0;
+ for (int i = 0; i < mPacketsInThePast; i++) {
+ c->ringBufferPull(mPacketsInThePast - i);
+ for (int s = 0; s < mPeerFPP; s++)
+ c->realPast[s + offset] = c->mTmpFloatBuf[s];
+ offset += mPeerFPP;
+ }
+ }
+
+ if (glitch) {
+ for (int s = 0; s < mUpToNow; s++)
+ c->prediction[s] = c->predictedPast[s / mPeerFPP][s % mPeerFPP];
+
+ ba->train(c->coeffs, c->prediction, mUpToNow);
+
+ ba->predict(c->coeffs, c->prediction, c->mTailSize);
+
+ for (int s = 0; s < mPeerFPP; s++)
+ c->predictedNowPacket[s] = c->prediction[mUpToNow + s];
+ }
+
+ for (int s = 0; s < mPeerFPP; s++)
+ c->mTmpFloatBuf[s] = c->outputNowPacket[s] =
+ ((glitch)
+ ? ((primed) ? c->predictedNowPacket[s] : 0.0)
+ : ((c->lastWasGlitch) ? (mFadeDown[s] * c->futurePredictedPacket[s]
+ + mFadeUp[s] * c->realNowPacket[s])
+ : c->realNowPacket[s]));
+
+ for (int s = 0; s < mPeerFPP; s++)
+ c->mTmpFloatBuf[s] = c->outputNowPacket[s];
+
+ c->lastWasGlitch = glitch;
+
+ for (int i = 0; i < mPacketsInThePast - 1; i++) {
+ for (int s = 0; s < mPeerFPP; s++)
+ c->predictedPast[i][s] = c->predictedPast[i + 1][s];
+ }
+ for (int s = 0; s < mPeerFPP; s++)
+ c->predictedPast[mPacketsInThePast - 1][s] = c->outputNowPacket[s];
+
+ for (int s = 0; s < mPeerFPP; s++)
+ c->futurePredictedPacket[s] = c->prediction[mBeyondNow + s - 0];
+
+ if (glitch)
+ mTime->collect();
+ //////////////////////////////////////
+ }
+
+ if ((!(mPcnt % 300)) && (gVerboseFlag))
+ cout << "PLC avg " << mTime->avg() << " glitches " << mTime->glitches()
+ << " skipped " << (mSkipped - mLastSkipped) << " tolerance "
+ << (mMsecTolerance - mCurrentHeadroom) << " +" << mCurrentHeadroom << endl;
+ mPcnt++;
+ // 32 bit is good for days: (/ (* (- (expt 2 32) 1) (/ 32 48000.0)) (* 60 60 24))
}
//*******************************************************************************
bool Regulator::getStats(RingBuffer::IOStat* stat, bool reset)
{
- if (!mFPPratioIsSet) {
+ if (!mInitialized) {
return false;
}
mBroadcastSkew = 0;
}
- if (mUseWorkerThread && mRegulatorWorkerPtr != nullptr) {
+ if (isWorkerEnabled() && mRegulatorWorkerPtr != nullptr) {
mRegulatorWorkerPtr->getStats();
}
// hijack of struct IOStat {
- stat->underruns = (pullStat->plcUnderruns - pullStat->lastPlcUnderruns)
- + (pullStat->plcOverruns - pullStat->lastPlcOverruns);
- pullStat->lastPlcUnderruns = pullStat->plcUnderruns;
- pullStat->lastPlcOverruns = pullStat->plcOverruns;
+ stat->underruns = mLastGlitches - mStatsGlitches;
#define FLOATFACTOR 1000.0
stat->overflows = FLOATFACTOR * pushStat->longTermStdDev;
stat->skew = FLOATFACTOR * pushStat->lastMean;
stat->buf_inc_compensate = FLOATFACTOR * pullStat->lastMin;
stat->broadcast_skew = FLOATFACTOR * pullStat->lastMax;
stat->broadcast_delta = FLOATFACTOR * pullStat->lastStdDev;
- stat->autoq_rate = FLOATFACTOR * pullStat->lastPLCdspElapsed;
+ stat->autoq_rate = FLOATFACTOR * mStatsMaxPLCdspElapsed;
+ // reset a few stats for next time
+ mStatsGlitches = mLastGlitches;
+ mStatsMaxPLCdspElapsed = 0.0;
// none are unused
return true;
}
JackTrip: A System for High-Quality Audio Network Performance
over the Internet
- Copyright (c) 2021 Juan-Pablo Caceres, Chris Chafe.
+ Copyright (c) 2024 Juan-Pablo Caceres, Chris Chafe.
SoundWIRE group at CCRMA, Stanford University.
Permission is hereby granted, free of charge, to any person
/**
* \file Regulator.h
* \author Chris Chafe
- * \date May 2021
+ * \date May 2021 - May 2024
*/
// Initial references and starter code to bring up Burg's recursion
#ifndef __REGULATOR_H__
#define __REGULATOR_H__
-//#define REGULATOR_SHARED_WORKER_THREAD
-
#include <math.h>
#include <QDebug>
#include <QElapsedTimer>
+#include <QThread>
#include <atomic>
#include <cstring>
+#include <vector>
#include "AudioInterface.h"
#include "RingBuffer.h"
class BurgAlgorithm
{
public:
- bool classify(double d);
- void train(std::vector<double>& coeffs, const std::vector<double>& x);
- void predict(std::vector<double>& coeffs, std::vector<double>& tail);
+ BurgAlgorithm(int size);
+ void train(std::vector<float>& coeffs, const std::vector<float>& x, int size);
+ void predict(std::vector<float>& coeffs, std::vector<float>& predicted, int size);
private:
- // the following are class members to minimize heap memory allocations
- std::vector<double> Ak;
- std::vector<double> f;
- std::vector<double> b;
+ int m;
+ int N;
+ int size;
+ std::vector<float> Ak;
+ std::vector<float> AkReset;
+ std::vector<float> f;
+ std::vector<float> b;
};
-class ChanData
+class Time
{
+ double accum = 0.0;
+ int cnt = 0;
+ int glitchCnt = 0;
+ double tmpTime = 0.0;
+
public:
- ChanData(int i, int FPP, int hist);
- int ch;
- int trainSamps;
- std::vector<sample_t> mTruth;
- std::vector<double> mTrain;
- std::vector<double> mTail;
- std::vector<sample_t> mPrediction; // ORDER
- std::vector<double> mCoeffs;
- std::vector<sample_t> mXfadedPred;
- std::vector<sample_t> mLastPred;
- std::vector<std::vector<sample_t>> mLastPackets;
- std::vector<sample_t> mCrossFadeDown;
- std::vector<sample_t> mCrossFadeUp;
- std::vector<sample_t> mCrossfade;
+ QElapsedTimer mCallbackTimer; // for rcvElapsedTime
+ void collect()
+ {
+ double tmp = (mCallbackTimer.nsecsElapsed() - tmpTime) / 1000000.0;
+ accum += tmp;
+ cnt++;
+ }
+ double instantElapsed()
+ {
+ return (mCallbackTimer.nsecsElapsed() - tmpTime) / 1000000.0;
+ }
+ double instantAbsolute() { return (mCallbackTimer.nsecsElapsed()) / 1000000.0; }
+ double avg()
+ {
+ if (!cnt)
+ return 0.0;
+ double tmp = accum / (double)cnt;
+ accum = 0.0;
+ cnt = 0;
+ return tmp;
+ }
+ void start() { mCallbackTimer.start(); }
+ void trigger(int ch)
+ {
+ tmpTime = mCallbackTimer.nsecsElapsed();
+ if (!ch)
+ glitchCnt++;
+ }
+ int glitches()
+ {
+ int tmp = glitchCnt;
+ glitchCnt = 0;
+ return tmp;
+ }
+};
+
+class Channel
+{
+ public:
+ Channel(int fpp, int upToNow, int packetsInThePast);
+ void ringBufferPush();
+ void ringBufferPull(int past);
+ std::vector<float>
+ mTmpFloatBuf; // one bufferfull of audio, used for rcv and send operations
+ std::vector<float> prediction;
+ std::vector<float> predictedNowPacket;
+ std::vector<float> realNowPacket;
+ std::vector<float> outputNowPacket;
+ std::vector<float> futurePredictedPacket;
+ std::vector<float> realPast;
+ std::vector<float> zeroPast;
+ std::vector<std::vector<float>> predictedPast;
+ std::vector<float> coeffs;
+ std::vector<std::vector<float>> mPacketRing;
+ int mWptr;
+ int mRing;
+ std::vector<float> mZeros;
+ bool lastWasGlitch;
+ int mCoeffsSize;
+ int mTailSize;
};
class StdDev
{
public:
StdDev(int id, QElapsedTimer* timer, int w);
- bool tick(); // returns true if stats were updated
+ bool tick(double prevTime = 0,
+ double curTime = 0); // returns true if stats were updated
double calcAuto();
int mId;
int plcOverruns;
double lastMean;
double lastMin;
double lastMax;
- int lastPlcOverruns;
- int lastPlcUnderruns;
- double lastPLCdspElapsed;
double lastStdDev;
double longTermStdDev;
double longTermStdDevAcc;
private:
double smooth(double avg, double current);
void reset();
- QElapsedTimer* mTimer;
+ QElapsedTimer* mTimer = nullptr;
std::vector<double> data;
double mean;
int window;
{
public:
/// construct a new regulator
- Regulator(int rcvChannels, int bit_res, int FPP, int qLen, int bqLen,
+ Regulator(int rcvChannels, int bit_res, int localFPP, int qLen, int bqLen,
int sample_rate);
// virtual destructor
virtual ~Regulator();
- /// @brief enables use of a separate worker thread for pulling packets
- /// @param thread_ptr pointer to shared thread; if null, a unique one will be used
- void enableWorkerThread(QThread* thread_ptr = nullptr);
-
// can hijack unused2 to propagate incoming seq num if needed
// option is in UdpDataProtocol
// if (!mJackTrip->writeAudioBuffer(src, host_buf_size, last_seq_num))
virtual bool insertSlotNonBlocking(const int8_t* ptrToSlot, int len,
[[maybe_unused]] int lostLen, int seq_num)
{
- shimFPP(ptrToSlot, len, seq_num);
+ if (seq_num == -1)
+ return true;
+ setFPPratio(len);
+ pushPacket(ptrToSlot, seq_num);
return (true);
}
/// @brief called by broadcast ports to get the next buffer of samples
/// @param ptrToReadSlot new samples will be copied to this memory block
- virtual void readBroadcastSlot(int8_t* ptrToReadSlot)
- {
- m_b_BroadcastRingBuffer->readBroadcastSlot(ptrToReadSlot);
- }
+ virtual void readBroadcastSlot(int8_t* ptrToReadSlot);
/// @brief returns sample rate
inline int getSampleRate() const { return mSampleRate; }
/// @brief returns number of bytes in an audio "packet"
- inline int getPacketSize() const { return mBytes; }
+ inline int getPacketSize() const { return mLocalBytes; }
/// @brief returns number of samples, or frames per callback period
- inline int getBufferSizeInSamples() const { return mFPP; }
+ inline int getBufferSizeInSamples() const { return mLocalFPP; }
- /// @brief returns time taken for last PLC prediction, in milliseconds
- inline double getLastDspElapsed() const
- {
- return pullStat == nullptr ? 0 : pullStat->lastPLCdspElapsed;
- }
+ /// @brief returns true if worker thread & queue is enabled
+ inline bool isWorkerEnabled() const { return mWorkerEnabled; }
// virtual QString getStats(uint32_t statCount, uint32_t lostCount);
virtual bool getStats(IOStat* stat, bool reset);
private:
- void shimFPP(const int8_t* buf, int len, int seq_num);
void pushPacket(const int8_t* buf, int seq_num);
- void assemblePacket(const int8_t* buf, int peer_seq_num);
- void pullPacket();
- void updateTolerance();
- void setFPPratio();
+ void updatePushStats(int seq_num);
+ bool pullPacket(); // returns true if PLC prediction
+ bool enableWorker(); // returns true if worker was enabled
+ void updateTolerance(int glitches, int skipped);
+ void setFPPratio(int len);
void processPacket(bool glitch);
- void processChannel(int ch, bool glitch, int packetCnt, bool lastWasGlitch);
-
- bool mFPPratioIsSet;
+ void burg(bool glitch);
+ sample_t bitsToSample(int ch, int frame);
+ void sampleToBits(sample_t sample, int ch, int frame);
+ void floatBufToXfrBuffer();
+ void xfrBufferToFloatBuf();
+ void toFloatBuf(qint16* in);
+ void fromFloatBuf(qint16* out);
+ void zeroTmpFloatBuf();
+
+ /*
+ void sineToXfrBuffer(); // keep this around, handy for signal test points
+ std::vector<double> mPhasor;
+ */
+
+ int mPacketsInThePast;
+ bool mInitialized;
int mNumChannels;
int mAudioBitRes;
- int mFPP;
+ int mLocalFPP;
int mPeerFPP;
int mSampleRate;
- uint32_t mLastLostCount;
- int mNumSlots;
- int mHist;
+ int mPcnt;
+ std::vector<float> mTmpFloatBuf;
+ std::vector<Channel*> mChanData;
+ BurgAlgorithm* ba = nullptr;
+ int mUpToNow;
+ int mBeyondNow;
+ std::vector<float> mFadeUp;
+ std::vector<float> mFadeDown;
+ float mScale;
+ float mInvScale;
+ uint32_t mLastLostCount = 0;
AudioInterface::audioBitResolutionT mBitResolutionMode;
- BurgAlgorithm ba;
- int mBytes;
- int mBytesPeerPacket;
- int8_t* mXfrBuffer;
- int8_t* mAssembledPacket;
- int mPacketCnt;
- sample_t bitsToSample(int ch, int frame);
- void sampleToBits(sample_t sample, int ch, int frame);
- std::vector<sample_t> mFadeUp;
- std::vector<sample_t> mFadeDown;
- bool mLastWasGlitch;
- std::vector<int8_t*> mSlots;
- int8_t* mZeros;
- double mMsecTolerance;
- std::vector<ChanData*> mChanData;
- StdDev* pushStat;
- StdDev* pullStat;
- QElapsedTimer mIncomingTimer;
+ int mLocalBytes;
+ int mPeerBytes;
+ double mLocalFPPdurMsec;
+ double mPeerFPPdurMsec;
+ int8_t* mXfrBuffer = nullptr;
+ int8_t* mXfrPullPtr = nullptr;
+ int8_t* mBroadcastBuffer = nullptr;
+ int8_t* mBroadcastPullPtr = nullptr;
+ int8_t** mSlots = nullptr;
+ int8_t* mSlotBuf = nullptr;
+ StdDev* pushStat = nullptr;
+ StdDev* pullStat = nullptr;
+ double mMsecTolerance = 64;
+ int mLastSeqNumOut = -1;
std::atomic<int> mLastSeqNumIn;
- int mLastSeqNumOut;
- std::vector<double> mPhasor;
+ QElapsedTimer mIncomingTimer;
std::vector<double> mIncomingTiming;
- std::vector<int> mAssemblyCounts;
- int mSkip;
int mFPPratioNumerator;
int mFPPratioDenominator;
- bool mAuto;
- bool mSkipAutoHeadroom;
- int mLastGlitches;
- double mCurrentHeadroom;
- double mAutoHeadroom;
- double mFPPdurMsec;
- double mPeerFPPdurMsec;
- bool mUseWorkerThread;
- void changeGlobal(double);
- void changeGlobal_2(int);
- void changeGlobal_3(int);
- void printParams();
+ bool mAuto = false;
+ bool mSkipAutoHeadroom = true;
+ int mSkipped = 0;
+ int mLastSkipped = 0;
+ int mLastGlitches = 0;
+ int mStatsGlitches = 0;
+ double mStatsMaxPLCdspElapsed = 0;
+ double mCurrentHeadroom = 0;
+ double mAutoHeadroom = -1;
+ Time* mTime = nullptr;
/// Pointer for the Broadcast RingBuffer
- RingBuffer* m_b_BroadcastRingBuffer;
+ RingBuffer* m_b_BroadcastRingBuffer = nullptr;
int m_b_BroadcastQueueLength;
- /// thread used to pull packets from Regulator (if mBufferStrategy==3)
- QThread* mRegulatorThreadPtr;
-
- /// worker used to pull packets from Regulator (if mBufferStrategy==3)
- RegulatorWorker* mRegulatorWorkerPtr;
-
+ /// worker thread used to manage queue
+ int8_t* mWorkerBuffer = nullptr;
+ QThread* mWorkerThreadPtr = nullptr;
+ RegulatorWorker* mRegulatorWorkerPtr = nullptr;
+ bool mWorkerEnabled = false;
friend class RegulatorWorker;
};
public:
RegulatorWorker(Regulator* rPtr)
: mRegulatorPtr(rPtr)
- , mPacketQueue(rPtr->getPacketSize())
+ , mPacketQueue(rPtr->mPeerBytes)
, mPacketQueueTarget(1)
, mLastUnderrun(0)
, mSkipQueueUpdate(true)
++mPacketQueueTarget;
std::cout << "PLC worker queue: adjusting target=" << mPacketQueueTarget
<< " (max=" << maxPackets
- << ", lastDspElapsed=" << mRegulatorPtr->getLastDspElapsed() << ")"
+ << ", lastDspElapsed=" << mRegulatorPtr->mStatsMaxPLCdspElapsed << ")"
<< std::endl;
if (mPacketQueueTarget == maxPackets) {
emit signalMaxQueueSize();
* \date June 2008
*/
-//#define MANUAL_POLL
+// #define MANUAL_POLL
#include "UdpDataProtocol.h"
#include "JackTrip.h"
#include "jacktrip_globals.h"
#ifdef _WIN32
-//#include <winsock.h>
+// #include <winsock.h>
#include <stdio.h>
#include <winsock2.h> //cc need SD_SEND
#pragma comment(lib, "ws2_32.lib")
sizeof(mPeerAddr));
}
return n_bytes;
- //#endif
+ // #endif
}
//*******************************************************************************
"client fan out/in, including server", "full mix, including server"})
, m_connectDefaultAudioPorts(false)
, mIOStatTimeout(0)
- , mRegulatorThreadPtr(NULL)
{
// Register JackTripWorker with the hub listener
// mJTWorker = new JackTripWorker(this);
{
mStopCheckTimer.stop();
QMutexLocker lock(&mMutex);
- if (mRegulatorThreadPtr != NULL) {
- mRegulatorThreadPtr->quit();
- mRegulatorThreadPtr->wait();
- delete mRegulatorThreadPtr;
- }
// delete mJTWorker;
for (int i = 0; i < gMaxThreads; i++) {
delete mJTWorkers->at(i);
QString error_message = QStringLiteral("TCP Socket Server on Port %1 ERROR: %2")
.arg(mServerPort)
.arg(mTcpServer.errorString());
- std::cerr << error_message.toStdString() << endl;
emit signalError(error_message);
return;
}
}
if (error) {
- std::cerr << "ERROR: " << error_message.toStdString() << endl;
emit signalError(error_message);
return;
}
mStopCheckTimer.setInterval(200);
connect(&mStopCheckTimer, &QTimer::timeout, this, &UdpHubListener::stopCheck);
mStopCheckTimer.start();
-
-#ifdef REGULATOR_SHARED_WORKER_THREAD
- // Start regulator thread if bufstrategy == 3
- if (mBufferStrategy == 3) {
- // create shared regulator thread
- mRegulatorThreadPtr = new QThread();
- mRegulatorThreadPtr->setObjectName("RegulatorThread");
- mRegulatorThreadPtr->start();
- }
-#endif
-
emit signalStarted();
}
mJTWorkers->at(id)->setIOStatStream(mIOStatStream);
}
mJTWorkers->at(id)->setBufferStrategy(mBufferStrategy);
- mJTWorkers->at(id)->setRegulatorThread(mRegulatorThreadPtr);
mJTWorkers->at(id)->setNetIssuesSimulation(mSimulatedLossRate, mSimulatedJitterRate,
mSimulatedDelayRel);
mJTWorkers->at(id)->setBroadcast(mBroadcastQueue);
iterator.next();
}
}
- if (mRegulatorThreadPtr != nullptr) {
- // Stop the Regulator thread
- mRegulatorThreadPtr->quit();
- mRegulatorThreadPtr->wait();
- }
}
// TODO:
// USE bool QAbstractSocket::isValid () const to check if socket is connect. if not, exit
int mIOStatTimeout;
QSharedPointer<std::ostream> mIOStatStream;
- /// thread used to pull packets from Regulator (if mBufferStrategy==3)
- QThread* mRegulatorThreadPtr;
-
int mBufferStrategy;
int mBroadcastQueue;
double mSimulatedLossRate;
Interpolator fF2A;
public:
- AccUpDownConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
- double fmax)
+ AccUpDownConverter(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
: fA2F(amin, amid, amax, fmin, fmax, fmin)
, fF2A(fmin, fmax, amin,
amax) // Special, pseudo inverse of a non monotonic function
Interpolator fF2A;
public:
- AccDownUpConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
- double fmax)
+ AccDownUpConverter(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
: fA2F(amin, amid, amax, fmax, fmin, fmax)
, fF2A(fmin, fmax, amin,
amax) // Special, pseudo inverse of a non monotonic function
virtual void update(double /*v*/) const {}
- virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/, double /*amax*/,
- double /*min*/, double /*init*/, double /*max*/)
+ virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/,
+ double /*amax*/, double /*min*/, double /*init*/,
+ double /*max*/)
{
}
virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
std::string path = std::string(path_aux);
auto it = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path);
- });
+ });
return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
}
Interpolator fF2A;
public:
- AccUpDownConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
- double fmax)
+ AccUpDownConverter(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
: fA2F(amin, amid, amax, fmin, fmax, fmin)
, fF2A(fmin, fmax, amin,
amax) // Special, pseudo inverse of a non monotonic function
Interpolator fF2A;
public:
- AccDownUpConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
- double fmax)
+ AccDownUpConverter(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
: fA2F(amin, amid, amax, fmax, fmin, fmax)
, fF2A(fmin, fmax, amin,
amax) // Special, pseudo inverse of a non monotonic function
virtual void update(double /*v*/) const {}
- virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/, double /*amax*/,
- double /*min*/, double /*init*/, double /*max*/)
+ virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/,
+ double /*amax*/, double /*min*/, double /*init*/,
+ double /*max*/)
{
}
virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
std::string path = std::string(path_aux);
auto it = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path);
- });
+ });
return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
}
Interpolator fF2A;
public:
- AccUpDownConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
- double fmax)
+ AccUpDownConverter(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
: fA2F(amin, amid, amax, fmin, fmax, fmin)
, fF2A(fmin, fmax, amin,
amax) // Special, pseudo inverse of a non monotonic function
Interpolator fF2A;
public:
- AccDownUpConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
- double fmax)
+ AccDownUpConverter(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
: fA2F(amin, amid, amax, fmax, fmin, fmax)
, fF2A(fmin, fmax, amin,
amax) // Special, pseudo inverse of a non monotonic function
virtual void update(double /*v*/) const {}
- virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/, double /*amax*/,
- double /*min*/, double /*init*/, double /*max*/)
+ virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/,
+ double /*amax*/, double /*min*/, double /*init*/,
+ double /*max*/)
{
}
virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
std::string path = std::string(path_aux);
auto it = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path);
- });
+ });
return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
}
available: modelData.canConnect
connected: false
studioId: modelData.id ? modelData.id : ""
+ streamId: modelData.streamId ? modelData.streamId : ""
inviteKeyString: modelData.inviteKey ? modelData.inviteKey : ""
sampleRate: modelData.sampleRate
}
anchors.top: devicesWarningIcon.top
anchors.bottom: devicesWarningIcon.bottom
anchors.left: devicesWarningIcon.left
- anchors.right: warningOrErrorText.right
+ anchors.right: devicesWarningTooltip.right
hoverEnabled: true
onEntered: devicesWarningTooltip.showToolTip = true
onExited: devicesWarningTooltip.showToolTip = false
+ onClicked: {
+ if (Boolean(audio.devicesError) && audio.devicesErrorHelpUrl !== "") {
+ virtualstudio.openLink(audio.devicesErrorHelpUrl);
+ } else if (Boolean(audio.devicesWarning) && audio.devicesWarningHelpUrl !== "") {
+ virtualstudio.openLink(audio.devicesWarningHelpUrl);
+ }
+ }
}
}
--- /dev/null
+import QtQuick
+import QtQuick.Controls
+
+Button {
+ property string url
+ property string buttonText: "Learn more"
+
+ width: 150 * virtualstudio.uiScale;
+ height: 30 * virtualstudio.uiScale
+
+ onClicked: {
+ virtualstudio.openLink(url);
+ }
+
+ background: Rectangle {
+ radius: 6 * virtualstudio.uiScale
+ color: parent.down ? buttonPressedColour : (parent.hovered ? buttonHoverColour : buttonColour)
+ border.width: 1
+ border.color: parent.down ? buttonPressedStroke : (parent.hovered ? buttonHoverStroke : buttonStroke)
+ }
+
+ Text {
+ text: buttonText
+ font { family: "Poppins"; pixelSize: fontSmall * virtualstudio.fontScale * virtualstudio.uiScale }
+ color: textColour
+ horizontalAlignment: Text.AlignHCenter
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ }
+}
AppIcon {
id: ethernetRecommendationLogo
- y: 120
+ y: 90
anchors.horizontalCenter: parent.horizontalCenter
width: 179
height: 128
+ "WiFi works OK for some people, but generates significantly more latency and audio glitches."
font { family: "Poppins"; pixelSize: fontSmall * virtualstudio.fontScale * virtualstudio.uiScale }
color: textColour
- width: 560
+ width: 600
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 32 * virtualstudio.uiScale
}
+ LearnMoreButton {
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: ethernetRecommendationSubheader1.bottom
+ anchors.topMargin: 32 * virtualstudio.uiScale
+ url: "https://support.jacktrip.com/wired-internet-versus-wi-fi"
+ }
+
Button {
id: okButtonEthernet
background: Rectangle {
AppIcon {
id: fiberRecommendationLogo
- y: 120
+ y: 90
anchors.horizontalCenter: parent.horizontalCenter
width: 179
height: 128
+ "It's OK to use JackTrip with Cable and DSL, but these types of Internet connections introduce significantly more latency."
font { family: "Poppins"; pixelSize: fontSmall * virtualstudio.fontScale * virtualstudio.uiScale }
color: textColour
- width: 560
+ width: 600
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 32 * virtualstudio.uiScale
}
+ LearnMoreButton {
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: fiberRecommendationSubheader.bottom
+ anchors.topMargin: 32 * virtualstudio.uiScale
+ url: "https://support.jacktrip.com/how-to-optimize-latency-when-using-jacktrip"
+ }
Button {
id: okButtonFiber
AppIcon {
id: headphoneWarningLogo
- y: 120
+ y: 90
anchors.horizontalCenter: parent.horizontalCenter
width: 118
height: 128
+ "Wireless and bluetooth headphones introduce higher latency."
font { family: "Poppins"; pixelSize: fontSmall * virtualstudio.fontScale * virtualstudio.uiScale }
color: textColour
- width: 560
+ width: 600
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
anchors.horizontalCenter: parent.horizontalCenter
AppIcon {
id: audioInterfaceRecommendationLogo
- y: 120
+ y: 90
anchors.horizontalCenter: parent.horizontalCenter
width: 118
height: 128
+ "Thunderbolt audio interfaces will usually produce better quality and lower latency."
font { family: "Poppins"; pixelSize: fontSmall * virtualstudio.fontScale * virtualstudio.uiScale }
color: textColour
- width: 560
+ width: 600
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
anchors.horizontalCenter: parent.horizontalCenter
visible: onWindows
text: "Your audio device controls the quality of sound, and can also have a big impact on latency."
+ "<br/><br/>"
- + "Additionally, low latency on Windows requires the use of ASIO drivers. "
- + "Beware that using ASIO drivers which are not made specifically for your device can cause crashes."
+ + "ASIO drivers are required for low latency on Windows. "
+ "<br/><br/>"
+ "It's OK to use the audio device that is built into your computer, but external USB and "
- + "Thunderbolt audio interfaces that provide ASIO drivers will produce better quality and much lower latency."
+ + "Thunderbolt devices will produce better quality and much lower latency."
font { family: "Poppins"; pixelSize: fontSmall * virtualstudio.fontScale * virtualstudio.uiScale }
color: textColour
- width: 560
+ width: 600
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 32 * virtualstudio.uiScale
}
+ LearnMoreButton {
+ width: 250 * virtualstudio.uiScale;
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: onWindows ? audioInterfaceRecommendationSubheaderWindows.bottom : audioInterfaceRecommendationSubheaderNonWindows.bottom
+ anchors.topMargin: 32 * virtualstudio.uiScale
+ buttonText: "See recommended devices"
+ url: "https://support.jacktrip.com/recommended-audio-interfaces"
+ }
+
Button {
id: okButtonAudioInterface
background: Rectangle {
text: "Would you like to review the getting started recommendations again the next time you start JackTrip?"
font { family: "Poppins"; pixelSize: fontSmall * virtualstudio.fontScale * virtualstudio.uiScale }
color: textColour
- width: 560
+ width: 600
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
anchors.horizontalCenter: parent.horizontalCenter
text: "You can change this setting at any time under <b>Settings > Advanced</b>"
font { family: "Poppins"; pixelSize: fontSmall * virtualstudio.fontScale * virtualstudio.uiScale }
color: textColour
- width: 560
+ width: 600
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
anchors.horizontalCenter: parent.horizontalCenter
property string hostname: "app.jacktrip.com"
property string studioName: "Test Studio"
property string studioId: ""
+ property string streamId: ""
property string inviteKeyString: ""
property int sampleRate: 48000
property bool publicStudio: false
property string backgroundColour: virtualstudio.darkMode ? "#494646" : "#F4F6F6"
property string textColour: virtualstudio.darkMode ? "#FAFBFB" : "#0F0D0D"
property string shadowColour: virtualstudio.darkMode ? "#40000000" : "#80A1A1A1"
- property string toolTipBackgroundColour: inviteCopied ? "#57B147" : (virtualstudio.darkMode ? "#323232" : "#F3F3F3")
- property string toolTipTextColour: inviteCopied ? "#FAFBFB" : textColour
+ property string inviteToolTipBackgroundColour: virtualstudio.darkMode ? "#323232" : "#F3F3F3"
+ property string inviteToolTipTextColour: textColour
+ property string inviteCopiedBackgroundColour: "#57B147"
+ property string inviteCopiedTextColour: "#FAFBFB"
property string tooltipStroke: virtualstudio.darkMode ? "#80827D7D" : "#34979797"
property string baseButtonColour: virtualstudio.darkMode ? "#F0F1F1" : "#EAEBEB"
}
Timer {
id: copiedResetTimer
- interval: 2000; running: false; repeat: false
+ interval: 3000; running: false; repeat: false
onTriggered: inviteCopied = false;
}
onClicked: {
}
ToolTip {
parent: inviteButton
- visible: inviteButton.hovered || inviteCopied
+ visible: !inviteCopied && inviteButton.hovered
bottomPadding: bottomToolTipMargin * virtualstudio.uiScale
rightPadding: rightToolTipMargin * virtualstudio.uiScale
delay: 100
contentItem: Rectangle {
- color: toolTipBackgroundColour
+ color: inviteToolTipBackgroundColour
radius: 3
anchors.fill: parent
anchors.bottomMargin: bottomToolTipMargin * virtualstudio.uiScale
Text {
anchors.centerIn: parent
font { family: "Poppins"; pixelSize: fontSmall * virtualstudio.fontScale * virtualstudio.uiScale}
- text: inviteCopied ? qsTr("📋 Copied invitation link to Clipboard") : qsTr("Copy invite link for Studio")
- color: toolTipTextColour
+ text: qsTr("Copy invite link for Studio")
+ color: inviteToolTipTextColour
+ }
+ }
+ background: Rectangle {
+ color: "transparent"
+ }
+ }
+ ToolTip {
+ parent: inviteButton
+ visible: inviteCopied
+ bottomPadding: bottomToolTipMargin * virtualstudio.uiScale
+ rightPadding: rightToolTipMargin * virtualstudio.uiScale
+ delay: 100
+ contentItem: Rectangle {
+ color: inviteCopiedBackgroundColour
+ radius: 3
+ anchors.fill: parent
+ anchors.bottomMargin: bottomToolTipMargin * virtualstudio.uiScale
+ anchors.rightMargin: rightToolTipMargin * virtualstudio.uiScale
+ layer.enabled: true
+ border.width: 1
+ border.color: tooltipStroke
+
+ Text {
+ anchors.centerIn: parent
+ font { family: "Poppins"; pixelSize: fontSmall * virtualstudio.fontScale * virtualstudio.uiScale}
+ text: qsTr("📋 Copied invitation link to Clipboard")
+ color: inviteCopiedTextColour
}
}
background: Rectangle {
}
Button {
- id: manageOrVideoButton
+ id: manageButton
x: parent.width - (65 * virtualstudio.uiScale); y: topMargin * virtualstudio.uiScale
width: 40 * virtualstudio.uiScale; height: width
background: Rectangle {
radius: width / 2
- color: manageOrVideoButton.down ? managePressedColour : (manageOrVideoButton.hovered ? manageHoverColour : manageColour)
- border.width: manageOrVideoButton.down ? 1 : 0
+ color: manageButton.down ? managePressedColour : (manageButton.hovered ? manageHoverColour : manageColour)
+ border.width: manageButton.down ? 1 : 0
border.color: manageStroke
}
onClicked: {
- if (connected) {
- virtualstudio.launchVideo(studioId)
+ var url = "";
+ if (streamId === "") {
+ if (virtualstudio.testMode) {
+ url = "https://test.jacktrip.com/studios/" + studioId;
+ } else {
+ url = "https://app.jacktrip.com/studios/" + studioId;
+ }
} else {
- virtualstudio.manageStudio(studioId);
+ if (virtualstudio.testMode) {
+ url = "https://next-test.jacktrip.com/@" + streamId + "/dashboard";
+ } else {
+ url = "https://www.jacktrip.com/@" + streamId + "/dashboard";
+ }
}
+ virtualstudio.openLink(qsTr(url));
}
visible: admin || connected
Image {
id: manageImg
width: 20 * virtualstudio.uiScale; height: width
anchors { verticalCenter: parent.verticalCenter; horizontalCenter: parent.horizontalCenter }
- source: connected ? "video.svg" : "manage.svg"
+ source: "manage.svg"
sourceSize: Qt.size(manageImg.width,manageImg.height)
fillMode: Image.PreserveAspectFit
smooth: true
}
Text {
- anchors.horizontalCenter: manageOrVideoButton.horizontalCenter
+ anchors.horizontalCenter: manageButton.horizontalCenter
y: 56 * virtualstudio.uiScale
- text: connected ? "Video" : "Manage"
+ text: "Manage"
font { family: "Poppins"; pixelSize: fontMedium * virtualstudio.fontScale * virtualstudio.uiScale }
visible: admin || connected
color: textColour
<file>vs.qml</file>
<file>FirstLaunch.qml</file>
<file>Login.qml</file>
+ <file>LearnMoreButton.qml</file>
<file>Recommendations.qml</file>
<file>Permissions.qml</file>
<file>ChangeDevices.qml</file>
</property>
<item>
<property name="text">
- <string>1</string>
+ <string>1 (adaptable latency)</string>
</property>
</item>
<item>
<property name="text">
- <string>2</string>
+ <string>2 (stable latency)</string>
</property>
</item>
<item>
<property name="text">
- <string>3 (experimental - in own thread) </string>
+ <string>3 (loss concealment)</string>
</property>
</item>
<item>
<property name="text">
- <string>4 (experimental - in callback)</string>
+ <string>4 (same as 3)</string>
</property>
</item>
</widget>
"Click \"OK\" to proceed to classic mode.\n\n"
"Details: JackTrip failed to load the QML view. "
"This is likely caused by missing QML plugins. "
- "Please consult help.jacktrip.org for possible solutions.");
+ "Please consult support.jacktrip.com for possible solutions.");
msgBox.setWindowTitle(QStringLiteral("JackTrip Is Missing QML Modules"));
connect(&msgBox, &QMessageBox::finished, this, &VirtualStudio::toStandard,
Qt::QueuedConnection);
// pop studioToJoin
const QString targetId = m_studioToJoin;
setStudioToJoin("");
- emit studioToJoinChanged();
// stop audio if already running (settings or setup windows)
m_audioConfigPtr->stopAudio(true);
}
logoutURL.setQuery(query);
- launchBrowser(logoutURL);
+ QDesktopServices::openUrl(logoutURL);
m_auth->logout();
// increment buffer_strategy by 1 for array-index mapping
int buffer_strategy = m_audioConfigPtr->getBufferStrategy() + 1;
// adjust buffer_strategy for PLC "auto" mode menu item
- if (buffer_strategy == 3) {
- // run PLC without worker (4)
- buffer_strategy = 4;
- /*
- // I don't believe this is still necessary,
- // after splitting the input and output RtAudio streams
- // See https://github.com/jacktrip/jacktrip/pull/1235
- if (useRtAudio) {
- // if same device for input and output,
- // run PLC without worker (4)
- if (input == output)
- buffer_strategy = 4;
- // else run PLC with worker (3)
- // to reduce crackles
- } else {
- // run PLC without worker (4)
- buffer_strategy = 4;
- }
- */
- } else if (buffer_strategy == 5) {
- buffer_strategy = 3; // run PLC with worker (3)
+ if (buffer_strategy == 4 || buffer_strategy == 5) {
+ buffer_strategy = 3;
}
// create a new JackTrip instance
#endif
}
-void VirtualStudio::manageStudio(const QString& studioId, bool start)
-{
- if (studioId.isEmpty()) {
- processError("Manage requires a unique studio identifier");
- return;
- }
- QUrl url;
- if (!start) {
- url = QUrl(
- QStringLiteral("https://%1/studios/%2").arg(m_api->getApiHost(), studioId));
- } else {
- QString expiration =
- QDateTime::currentDateTimeUtc().addSecs(60 * 30).toString(Qt::ISODate);
- QJsonObject json = {{QLatin1String("enabled"), true},
- {QLatin1String("expiresAt"), expiration}};
- QJsonDocument request = QJsonDocument(json);
-
- QNetworkReply* reply = m_api->updateServer(studioId, request.toJson());
- connect(reply, &QNetworkReply::finished, this, [&, reply]() {
- if (reply->error() != QNetworkReply::NoError) {
- m_connectionState = QStringLiteral("Unable to Start Studio");
- QJsonDocument errorDoc = QJsonDocument::fromJson(reply->readAll());
- if (!errorDoc.isNull()) {
- QJsonObject errorObj = errorDoc.object();
- if (errorObj.contains("error")) {
- QString errorMessage = errorObj.value("error").toString();
- if (errorMessage.contains(
- "Only one studio may be running at a time")) {
- setConnectedErrorMsg("one-studio-limit-reached");
- }
- }
- }
- emit connectionStateChanged();
- } else {
- setConnectedErrorMsg("");
- QByteArray response = reply->readAll();
- QJsonDocument serverState = QJsonDocument::fromJson(response);
- if (serverState.object()[QStringLiteral("status")].toString()
- == QLatin1String("Starting")) {}
- }
- reply->deleteLater();
- });
- }
- QDesktopServices::openUrl(url);
-}
-
-void VirtualStudio::launchVideo(const QString& studioId)
-{
- if (studioId.isEmpty()) {
- processError("Manage requires a unique studio identifier");
- return;
- }
- QUrl url = QUrl(
- QStringLiteral("https://%1/studios/%2/live").arg(m_api->getApiHost(), studioId));
- QDesktopServices::openUrl(url);
-}
-
void VirtualStudio::createStudio()
{
setWindowState(QStringLiteral("create_studio"));
}
}
-void VirtualStudio::launchBrowser(const QUrl& url)
-{
- std::cout << "Launching Browser" << std::endl;
- bool success = QDesktopServices::openUrl(url);
- if (success) {
- std::cout << "Success" << std::endl;
- } else {
- std::cout << "Unable to open URL" << std::endl;
- }
-}
-
void VirtualStudio::updatedStats(const QJsonObject& stats)
{
QJsonObject newStats;
serverInfo->setId(servers.at(i)[QStringLiteral("id")].toString());
serverInfo->setSessionId(
servers.at(i)[QStringLiteral("sessionId")].toString());
+ serverInfo->setStreamId(
+ servers.at(i)[QStringLiteral("streamId")].toString());
serverInfo->setInviteKey(
servers.at(i)[QStringLiteral("inviteKey")].toString());
serverInfo->setCloudId(
void loadSettings();
void saveSettings();
void triggerReconnect(bool refresh);
- void manageStudio(const QString& studioId, bool start = false);
- void launchVideo(const QString& studioId);
void createStudio();
void editProfile();
void showAbout();
void receivedConnectionFromPeer();
void handleWebsocketMessage(const QString& msg);
void restartStudioSocket();
- void launchBrowser(const QUrl& url);
void updatedStats(const QJsonObject& stats);
void processError(const QString& errorMessage);
void detectedFeedbackLoop();
}
setBufferSize(settings.value(QStringLiteral("BufferSize"), 128).toInt());
- setBufferStrategy(settings.value(QStringLiteral("BufferStrategy"), 2).toInt());
+ int buffer_strategy = settings.value(QStringLiteral("BufferStrategy"), 2).toInt();
+ if (buffer_strategy == 3 || buffer_strategy == 4)
+ buffer_strategy = 2;
+ setBufferStrategy(buffer_strategy);
setFeedbackDetectionEnabled(
settings.value(QStringLiteral("FeedbackDetectionEnabled"), true).toBool());
settings.endGroup();
QStringList m_feedbackDetectionComboModel = {"Enabled", "Disabled"};
QStringList m_bufferSizeComboModel = {"16", "32", "64", "128", "256", "512", "1024"};
QStringList m_bufferStrategyComboModel = {
- "Minimal Latency", "Stable Latency", "Loss Concealment (Auto)",
- "Loss Concealment (No Worker)", "Loss Concealment (Use Worker)"};
+ "Adaptable Latency (Old)", "Stable Latency (Old)", "Loss Concealment (Default)"};
friend class VsAudioWorker;
};
m_bannerURL = info.m_bannerURL;
m_id = info.m_id;
m_sessionId = info.m_sessionId;
+ m_streamId = info.m_streamId;
m_status = info.m_status;
m_cloudId = info.m_cloudId;
m_inviteKey = info.m_inviteKey;
m_sessionId = (sessionId == "undefined") ? "" : sessionId;
}
+QString VsServerInfo::streamId() const
+{
+ return m_streamId;
+}
+
+void VsServerInfo::setStreamId(const QString& streamId)
+{
+ m_streamId = (streamId == "undefined") ? "" : streamId;
+}
+
QString VsServerInfo::inviteKey() const
{
return m_inviteKey;
Q_PROPERTY(quint32 sampleRate READ sampleRate CONSTANT)
Q_PROPERTY(quint16 queueBuffer READ queueBuffer CONSTANT)
Q_PROPERTY(QString sessionId READ sessionId CONSTANT)
+ Q_PROPERTY(QString streamId READ streamId CONSTANT)
Q_PROPERTY(QString status READ status CONSTANT)
Q_PROPERTY(bool enabled READ enabled CONSTANT)
Q_PROPERTY(QString cloudId READ cloudId CONSTANT)
void setId(const QString& id);
QString sessionId() const;
void setSessionId(const QString& sessionId);
+ QString streamId() const;
+ void setStreamId(const QString& streamId);
QString status() const;
void setStatus(const QString& status);
QString inviteKey() const;
QString m_bannerURL;
QString m_id;
QString m_sessionId;
+ QString m_streamId;
QString m_status;
QString m_cloudId;
QString m_inviteKey;
#include "AudioInterface.h"
-constexpr const char* const gVersion = "2.2.5"; ///< JackTrip version
+constexpr const char* const gVersion = "2.3.0"; ///< JackTrip version
//*******************************************************************************
/// \name Default Values
#ifndef __JACKTRIP_TYPES_H__
#define __JACKTRIP_TYPES_H__
-//#include <jack/types.h>
+// #include <jack/types.h>
#include <QtGlobal> //For QT4 types
// namespace JackTripNamespace
std::string path = std::string(path_aux);
auto it = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path);
- });
+ });
return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
}
#include <QStandardPaths>
#include <QTextStream>
// TODO: Add support for QtWebView
-//#include <QtWebView>
+// #include <QtWebView>
#include <QtWebEngineQuick/qtwebenginequickglobal.h>
#include "JTApplication.h"
#endif // NO_GUI
}
+void outputError(const QString& msg)
+{
+ std::cerr << "Error: " << msg.toStdString() << std::endl;
+}
+
#ifndef _WIN32
static int setupUnixSignalHandler(void (*handler)(int))
{
} else {
#endif // NO_GUI
// Otherwise use the non-GUI version, and parse our command line.
-#ifndef PSI
- QLoggingCategory::setFilterRules(QStringLiteral("*.debug=true"));
-#endif
try {
Settings settings;
settings.parseInput(argc, argv);
+#ifndef PSI
+ if (gVerboseFlag) {
+ QLoggingCategory::setFilterRules(QStringLiteral("*.debug=true"));
+ }
+#endif
+
// Either start our hub server or our jacktrip process as appropriate.
if (settings.isHubServer()) {
udpHub.reset(settings.getConfiguredHubServer());
QObject::connect(udpHub.data(), &UdpHubListener::signalStopped,
app.data(), &QCoreApplication::quit,
Qt::QueuedConnection);
+ QObject::connect(udpHub.data(), &UdpHubListener::signalError,
+ outputError);
QObject::connect(udpHub.data(), &UdpHubListener::signalError, app.data(),
&QCoreApplication::quit, Qt::QueuedConnection);
#ifndef _WIN32
QObject::connect(jackTrip.data(), &JackTrip::signalProcessesStopped,
app.data(), &QCoreApplication::quit,
Qt::QueuedConnection);
+ QObject::connect(jackTrip.data(), &JackTrip::signalError, outputError);
QObject::connect(jackTrip.data(), &JackTrip::signalError, app.data(),
&QCoreApplication::quit, Qt::QueuedConnection);
#ifndef _WIN32
Interpolator fF2A;
public:
- AccUpDownConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
- double fmax)
+ AccUpDownConverter(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
: fA2F(amin, amid, amax, fmin, fmax, fmin)
, fF2A(fmin, fmax, amin,
amax) // Special, pseudo inverse of a non monotonic function
Interpolator fF2A;
public:
- AccDownUpConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
- double fmax)
+ AccDownUpConverter(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
: fA2F(amin, amid, amax, fmax, fmin, fmax)
, fF2A(fmin, fmax, amin,
amax) // Special, pseudo inverse of a non monotonic function
virtual void update(double /*v*/) const {}
- virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/, double /*amax*/,
- double /*min*/, double /*init*/, double /*max*/)
+ virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/,
+ double /*amax*/, double /*min*/, double /*init*/,
+ double /*max*/)
{
}
virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
std::string path = std::string(path_aux);
auto it = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path);
- });
+ });
return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
}
std::max<float>(9.99999975e-05f, fTemp0)));
float fTemp2 = 100.0f * float(copysignf(float(fTemp1), 1.0f));
output0[i0] = FAUSTFLOAT(float(copysignf(
- float(0.00999999978f
+ float(0.00999999978f
* float(int(fTemp2) + (fTemp2 - std::floor(fTemp2) >= 0.5f))),
- float(fTemp1))));
+ float(fTemp1))));
}
}
};
name: "monitor"
version: "1.0"
Code generated with Faust 2.54.9 (https://faust.grame.fr)
-Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn monitordsp -es 1 -mcd 16 -single -ftz 0
+Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn monitordsp -es 1 -mcd 16
+-single -ftz 0
------------------------------------------------------------ */
-#ifndef __monitordsp_H__
-#define __monitordsp_H__
+#ifndef __monitordsp_H__
+#define __monitordsp_H__
// NOTE: ANY INCLUDE-GUARD HERE MUST BE DERIVED FROM THE CLASS NAME
//
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
#define FAUSTVERSION "2.54.9"
-// Use FAUST_API for code that is part of the external API but is also compiled in faust and libfaust
-// Use LIBFAUST_API for code that is compiled in faust and libfaust
+// Use FAUST_API for code that is part of the external API but is also compiled in faust
+// and libfaust Use LIBFAUST_API for code that is compiled in faust and libfaust
#ifdef _WIN32
- #pragma warning (disable: 4251)
- #ifdef FAUST_EXE
- #define FAUST_API
- #define LIBFAUST_API
- #elif FAUST_LIB
- #define FAUST_API __declspec(dllexport)
- #define LIBFAUST_API __declspec(dllexport)
- #else
- #define FAUST_API
- #define LIBFAUST_API
- #endif
+#pragma warning(disable : 4251)
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#elif FAUST_LIB
+#define FAUST_API __declspec(dllexport)
+#define LIBFAUST_API __declspec(dllexport)
#else
- #ifdef FAUST_EXE
- #define FAUST_API
- #define LIBFAUST_API
- #else
- #define FAUST_API __attribute__((visibility("default")))
- #define LIBFAUST_API __attribute__((visibility("default")))
- #endif
+#define FAUST_API
+#define LIBFAUST_API
+#endif
+#else
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#else
+#define FAUST_API __attribute__((visibility("default")))
+#define LIBFAUST_API __attribute__((visibility("default")))
+#endif
#endif
#endif
*/
struct FAUST_API dsp_memory_manager {
-
virtual ~dsp_memory_manager() {}
-
+
/**
* Inform the Memory Manager with the number of expected memory zones.
* @param count - the number of expected memory zones
*/
virtual void begin(size_t /*count*/) {}
-
+
/**
* Give the Memory Manager information on a given memory zone.
* @param size - the size in bytes of the memory zone
* to possibly start a 'compute the best allocation strategy' step.
*/
virtual void end() {}
-
+
/**
* Allocate a memory zone.
* @param size - the memory zone size in bytes
*/
virtual void* allocate(size_t size) = 0;
-
+
/**
* Destroy a memory zone.
* @param ptr - the memory zone pointer to be deallocated
*/
virtual void destroy(void* ptr) = 0;
-
-};
-
-/**
-* Signal processor definition.
-*/
-
-class FAUST_API dsp {
-
- public:
-
- dsp() {}
- virtual ~dsp() {}
-
- /* Return instance number of audio inputs */
- virtual int getNumInputs() = 0;
-
- /* Return instance number of audio outputs */
- virtual int getNumOutputs() = 0;
-
- /**
- * Trigger the ui_interface parameter with instance specific calls
- * to 'openTabBox', 'addButton', 'addVerticalSlider'... in order to build the UI.
- *
- * @param ui_interface - the user interface builder
- */
- virtual void buildUserInterface(UI* ui_interface) = 0;
-
- /* Return the sample rate currently used by the instance */
- virtual int getSampleRate() = 0;
-
- /**
- * Global init, calls the following methods:
- * - static class 'classInit': static tables initialization
- * - 'instanceInit': constants and instance state initialization
- *
- * @param sample_rate - the sampling rate in Hz
- */
- virtual void init(int sample_rate) = 0;
-
- /**
- * Init instance state
- *
- * @param sample_rate - the sampling rate in Hz
- */
- virtual void instanceInit(int sample_rate) = 0;
-
- /**
- * Init instance constant state
- *
- * @param sample_rate - the sampling rate in Hz
- */
- virtual void instanceConstants(int sample_rate) = 0;
-
- /* Init default control parameters values */
- virtual void instanceResetUserInterface() = 0;
-
- /* Init instance state (like delay lines...) but keep the control parameter values */
- virtual void instanceClear() = 0;
-
- /**
- * Return a clone of the instance.
- *
- * @return a copy of the instance on success, otherwise a null pointer.
- */
- virtual dsp* clone() = 0;
-
- /**
- * Trigger the Meta* parameter with instance specific calls to 'declare' (key, value) metadata.
- *
- * @param m - the Meta* meta user
- */
- virtual void metadata(Meta* m) = 0;
-
- /**
- * DSP instance computation, to be called with successive in/out audio buffers.
- *
- * @param count - the number of frames to compute
- * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT samples (eiher float, double or quad)
- * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT samples (eiher float, double or quad)
- *
- */
- virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) = 0;
-
- /**
- * DSP instance computation: alternative method to be used by subclasses.
- *
- * @param date_usec - the timestamp in microsec given by audio driver.
- * @param count - the number of frames to compute
- * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT samples (either float, double or quad)
- * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT samples (either float, double or quad)
- *
- */
- virtual void compute(double /*date_usec*/, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { compute(count, inputs, outputs); }
-
};
/**
- * Generic DSP decorator.
+ * Signal processor definition.
*/
-class FAUST_API decorator_dsp : public dsp {
+class FAUST_API dsp
+{
+ public:
+ dsp() {}
+ virtual ~dsp() {}
+
+ /* Return instance number of audio inputs */
+ virtual int getNumInputs() = 0;
- protected:
+ /* Return instance number of audio outputs */
+ virtual int getNumOutputs() = 0;
- dsp* fDSP;
+ /**
+ * Trigger the ui_interface parameter with instance specific calls
+ * to 'openTabBox', 'addButton', 'addVerticalSlider'... in order to build the UI.
+ *
+ * @param ui_interface - the user interface builder
+ */
+ virtual void buildUserInterface(UI* ui_interface) = 0;
- public:
+ /* Return the sample rate currently used by the instance */
+ virtual int getSampleRate() = 0;
- decorator_dsp(dsp* dsp = nullptr):fDSP(dsp) {}
- virtual ~decorator_dsp() { delete fDSP; }
+ /**
+ * Global init, calls the following methods:
+ * - static class 'classInit': static tables initialization
+ * - 'instanceInit': constants and instance state initialization
+ *
+ * @param sample_rate - the sampling rate in Hz
+ */
+ virtual void init(int sample_rate) = 0;
+
+ /**
+ * Init instance state
+ *
+ * @param sample_rate - the sampling rate in Hz
+ */
+ virtual void instanceInit(int sample_rate) = 0;
+
+ /**
+ * Init instance constant state
+ *
+ * @param sample_rate - the sampling rate in Hz
+ */
+ virtual void instanceConstants(int sample_rate) = 0;
- virtual int getNumInputs() { return fDSP->getNumInputs(); }
- virtual int getNumOutputs() { return fDSP->getNumOutputs(); }
- virtual void buildUserInterface(UI* ui_interface) { fDSP->buildUserInterface(ui_interface); }
- virtual int getSampleRate() { return fDSP->getSampleRate(); }
- virtual void init(int sample_rate) { fDSP->init(sample_rate); }
- virtual void instanceInit(int sample_rate) { fDSP->instanceInit(sample_rate); }
- virtual void instanceConstants(int sample_rate) { fDSP->instanceConstants(sample_rate); }
- virtual void instanceResetUserInterface() { fDSP->instanceResetUserInterface(); }
- virtual void instanceClear() { fDSP->instanceClear(); }
- virtual decorator_dsp* clone() { return new decorator_dsp(fDSP->clone()); }
- virtual void metadata(Meta* m) { fDSP->metadata(m); }
- // Beware: subclasses usually have to overload the two 'compute' methods
- virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { fDSP->compute(count, inputs, outputs); }
- virtual void compute(double date_usec, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { fDSP->compute(date_usec, count, inputs, outputs); }
-
+ /* Init default control parameters values */
+ virtual void instanceResetUserInterface() = 0;
+
+ /* Init instance state (like delay lines...) but keep the control parameter values */
+ virtual void instanceClear() = 0;
+
+ /**
+ * Return a clone of the instance.
+ *
+ * @return a copy of the instance on success, otherwise a null pointer.
+ */
+ virtual dsp* clone() = 0;
+
+ /**
+ * Trigger the Meta* parameter with instance specific calls to 'declare' (key, value)
+ * metadata.
+ *
+ * @param m - the Meta* meta user
+ */
+ virtual void metadata(Meta* m) = 0;
+
+ /**
+ * DSP instance computation, to be called with successive in/out audio buffers.
+ *
+ * @param count - the number of frames to compute
+ * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT
+ * samples (eiher float, double or quad)
+ * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT
+ * samples (eiher float, double or quad)
+ *
+ */
+ virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) = 0;
+
+ /**
+ * DSP instance computation: alternative method to be used by subclasses.
+ *
+ * @param date_usec - the timestamp in microsec given by audio driver.
+ * @param count - the number of frames to compute
+ * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT
+ * samples (either float, double or quad)
+ * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT
+ * samples (either float, double or quad)
+ *
+ */
+ virtual void compute(double /*date_usec*/, int count, FAUSTFLOAT** inputs,
+ FAUSTFLOAT** outputs)
+ {
+ compute(count, inputs, outputs);
+ }
+};
+
+/**
+ * Generic DSP decorator.
+ */
+
+class FAUST_API decorator_dsp : public dsp
+{
+ protected:
+ dsp* fDSP;
+
+ public:
+ decorator_dsp(dsp* dsp = nullptr) : fDSP(dsp) {}
+ virtual ~decorator_dsp() { delete fDSP; }
+
+ virtual int getNumInputs() { return fDSP->getNumInputs(); }
+ virtual int getNumOutputs() { return fDSP->getNumOutputs(); }
+ virtual void buildUserInterface(UI* ui_interface)
+ {
+ fDSP->buildUserInterface(ui_interface);
+ }
+ virtual int getSampleRate() { return fDSP->getSampleRate(); }
+ virtual void init(int sample_rate) { fDSP->init(sample_rate); }
+ virtual void instanceInit(int sample_rate) { fDSP->instanceInit(sample_rate); }
+ virtual void instanceConstants(int sample_rate)
+ {
+ fDSP->instanceConstants(sample_rate);
+ }
+ virtual void instanceResetUserInterface() { fDSP->instanceResetUserInterface(); }
+ virtual void instanceClear() { fDSP->instanceClear(); }
+ virtual decorator_dsp* clone() { return new decorator_dsp(fDSP->clone()); }
+ virtual void metadata(Meta* m) { fDSP->metadata(m); }
+ // Beware: subclasses usually have to overload the two 'compute' methods
+ virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs)
+ {
+ fDSP->compute(count, inputs, outputs);
+ }
+ virtual void compute(double date_usec, int count, FAUSTFLOAT** inputs,
+ FAUSTFLOAT** outputs)
+ {
+ fDSP->compute(date_usec, count, inputs, outputs);
+ }
};
/**
* to create DSP instances from a compiled DSP program.
*/
-class FAUST_API dsp_factory {
-
- protected:
-
- // So that to force sub-classes to use deleteDSPFactory(dsp_factory* factory);
- virtual ~dsp_factory() {}
-
- public:
-
- virtual std::string getName() = 0;
- virtual std::string getSHAKey() = 0;
- virtual std::string getDSPCode() = 0;
- virtual std::string getCompileOptions() = 0;
- virtual std::vector<std::string> getLibraryList() = 0;
- virtual std::vector<std::string> getIncludePathnames() = 0;
- virtual std::vector<std::string> getWarningMessages() = 0;
-
- virtual dsp* createDSPInstance() = 0;
-
- virtual void setMemoryManager(dsp_memory_manager* manager) = 0;
- virtual dsp_memory_manager* getMemoryManager() = 0;
-
+class FAUST_API dsp_factory
+{
+ protected:
+ // So that to force sub-classes to use deleteDSPFactory(dsp_factory* factory);
+ virtual ~dsp_factory() {}
+
+ public:
+ virtual std::string getName() = 0;
+ virtual std::string getSHAKey() = 0;
+ virtual std::string getDSPCode() = 0;
+ virtual std::string getCompileOptions() = 0;
+ virtual std::vector<std::string> getLibraryList() = 0;
+ virtual std::vector<std::string> getIncludePathnames() = 0;
+ virtual std::vector<std::string> getWarningMessages() = 0;
+
+ virtual dsp* createDSPInstance() = 0;
+
+ virtual void setMemoryManager(dsp_memory_manager* manager) = 0;
+ virtual dsp_memory_manager* getMemoryManager() = 0;
};
// Denormal handling
-#if defined (__SSE__)
+#if defined(__SSE__)
#include <xmmintrin.h>
#endif
-class FAUST_API ScopedNoDenormals {
-
- private:
-
- intptr_t fpsr = 0;
-
- void setFpStatusRegister(intptr_t fpsr_aux) noexcept
- {
- #if defined (__arm64__) || defined (__aarch64__)
- asm volatile("msr fpcr, %0" : : "ri" (fpsr_aux));
- #elif defined (__SSE__)
- // The volatile keyword here is needed to workaround a bug in AppleClang 13.0
- // which aggressively optimises away the variable otherwise
- volatile uint32_t fpsr_w = static_cast<uint32_t>(fpsr_aux);
- _mm_setcsr(fpsr_w);
- #endif
- }
-
- void getFpStatusRegister() noexcept
- {
- #if defined (__arm64__) || defined (__aarch64__)
- asm volatile("mrs %0, fpcr" : "=r" (fpsr));
- #elif defined (__SSE__)
- fpsr = static_cast<intptr_t>(_mm_getcsr());
- #endif
- }
-
- public:
-
- ScopedNoDenormals() noexcept
- {
- #if defined (__arm64__) || defined (__aarch64__)
- intptr_t mask = (1 << 24 /* FZ */);
- #elif defined (__SSE__)
- #if defined (__SSE2__)
- intptr_t mask = 0x8040;
- #else
- intptr_t mask = 0x8000;
- #endif
- #else
- intptr_t mask = 0x0000;
- #endif
- getFpStatusRegister();
- setFpStatusRegister(fpsr | mask);
- }
-
- ~ScopedNoDenormals() noexcept
- {
- setFpStatusRegister(fpsr);
- }
+class FAUST_API ScopedNoDenormals
+{
+ private:
+ intptr_t fpsr = 0;
+
+ void setFpStatusRegister(intptr_t fpsr_aux) noexcept
+ {
+#if defined(__arm64__) || defined(__aarch64__)
+ asm volatile("msr fpcr, %0" : : "ri"(fpsr_aux));
+#elif defined(__SSE__)
+ // The volatile keyword here is needed to workaround a bug in AppleClang 13.0
+ // which aggressively optimises away the variable otherwise
+ volatile uint32_t fpsr_w = static_cast<uint32_t>(fpsr_aux);
+ _mm_setcsr(fpsr_w);
+#endif
+ }
+
+ void getFpStatusRegister() noexcept
+ {
+#if defined(__arm64__) || defined(__aarch64__)
+ asm volatile("mrs %0, fpcr" : "=r"(fpsr));
+#elif defined(__SSE__)
+ fpsr = static_cast<intptr_t>(_mm_getcsr());
+#endif
+ }
+
+ public:
+ ScopedNoDenormals() noexcept
+ {
+#if defined(__arm64__) || defined(__aarch64__)
+ intptr_t mask = (1 << 24 /* FZ */);
+#elif defined(__SSE__)
+#if defined(__SSE2__)
+ intptr_t mask = 0x8040;
+#else
+ intptr_t mask = 0x8000;
+#endif
+#else
+ intptr_t mask = 0x0000;
+#endif
+ getFpStatusRegister();
+ setFpStatusRegister(fpsr | mask);
+ }
+ ~ScopedNoDenormals() noexcept { setFpStatusRegister(fpsr); }
};
#define AVOIDDENORMALS ScopedNoDenormals ftz_scope;
#ifndef API_UI_H
#define API_UI_H
+#include <stdio.h>
+
+#include <map>
#include <sstream>
#include <string>
#include <vector>
-#include <stdio.h>
-#include <map>
/************************** BEGIN meta.h *******************************
FAUST Architecture File
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
#ifndef __meta__
#define __meta__
-
/**
- The base class of Meta handler to be used in dsp::metadata(Meta* m) method to retrieve (key, value) metadata.
+ The base class of Meta handler to be used in dsp::metadata(Meta* m) method to retrieve
+ (key, value) metadata.
*/
struct FAUST_API Meta {
virtual ~Meta() {}
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
#ifndef __UI_H__
#define __UI_H__
-
#ifndef FAUSTFLOAT
#define FAUSTFLOAT float
#endif
struct Soundfile;
-template <typename REAL>
+template<typename REAL>
struct FAUST_API UIReal {
-
UIReal() {}
virtual ~UIReal() {}
-
+
// -- widget's layouts
-
- virtual void openTabBox(const char* label) = 0;
+
+ virtual void openTabBox(const char* label) = 0;
virtual void openHorizontalBox(const char* label) = 0;
- virtual void openVerticalBox(const char* label) = 0;
- virtual void closeBox() = 0;
-
+ virtual void openVerticalBox(const char* label) = 0;
+ virtual void closeBox() = 0;
+
// -- active widgets
-
- virtual void addButton(const char* label, REAL* zone) = 0;
+
+ virtual void addButton(const char* label, REAL* zone) = 0;
virtual void addCheckButton(const char* label, REAL* zone) = 0;
- virtual void addVerticalSlider(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0;
- virtual void addHorizontalSlider(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0;
- virtual void addNumEntry(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0;
-
+ virtual void addVerticalSlider(const char* label, REAL* zone, REAL init, REAL min,
+ REAL max, REAL step) = 0;
+ virtual void addHorizontalSlider(const char* label, REAL* zone, REAL init, REAL min,
+ REAL max, REAL step) = 0;
+ virtual void addNumEntry(const char* label, REAL* zone, REAL init, REAL min, REAL max,
+ REAL step) = 0;
+
// -- passive widgets
-
- virtual void addHorizontalBargraph(const char* label, REAL* zone, REAL min, REAL max) = 0;
- virtual void addVerticalBargraph(const char* label, REAL* zone, REAL min, REAL max) = 0;
-
+
+ virtual void addHorizontalBargraph(const char* label, REAL* zone, REAL min,
+ REAL max) = 0;
+ virtual void addVerticalBargraph(const char* label, REAL* zone, REAL min,
+ REAL max) = 0;
+
// -- soundfiles
-
- virtual void addSoundfile(const char* label, const char* filename, Soundfile** sf_zone) = 0;
-
+
+ virtual void addSoundfile(const char* label, const char* filename,
+ Soundfile** sf_zone) = 0;
+
// -- metadata declarations
-
+
virtual void declare(REAL* /*zone*/, const char* /*key*/, const char* /*val*/) {}
// To be used by LLVM client
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
#ifndef __PathBuilder__
#define __PathBuilder__
-#include <vector>
-#include <set>
-#include <map>
-#include <string>
#include <algorithm>
+#include <map>
#include <regex>
-
+#include <set>
+#include <string>
+#include <vector>
/*******************************************************************************
* PathBuilder : Faust User Interface
* Helper class to build complete hierarchical path for UI items.
******************************************************************************/
-class FAUST_API PathBuilder {
-
- protected:
-
- std::vector<std::string> fControlsLevel;
- std::vector<std::string> fFullPaths;
- std::map<std::string, std::string> fFull2Short; // filled by computeShortNames()
-
- /**
- * @brief check if a character is acceptable for an ID
- *
- * @param c
- * @return true is the character is acceptable for an ID
- */
- bool isIDChar(char c) const
- {
- return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9'));
- }
-
- /**
- * @brief remove all "/0x00" parts
- *
- * @param src
- * @return modified string
- */
- std::string remove0x00(const std::string& src) const
- {
- return std::regex_replace(src, std::regex("/0x00"), "");
- }
-
- /**
- * @brief replace all non ID char with '_' (one '_' may replace several non ID char)
- *
- * @param src
- * @return modified string
- */
- std::string str2ID(const std::string& src) const
- {
- std::string dst;
- bool need_underscore = false;
- for (char c : src) {
- if (isIDChar(c) || (c == '/')) {
- if (need_underscore) {
- dst.push_back('_');
- need_underscore = false;
- }
- dst.push_back(c);
- } else {
- need_underscore = true;
+class FAUST_API PathBuilder
+{
+ protected:
+ std::vector<std::string> fControlsLevel;
+ std::vector<std::string> fFullPaths;
+ std::map<std::string, std::string> fFull2Short; // filled by computeShortNames()
+
+ /**
+ * @brief check if a character is acceptable for an ID
+ *
+ * @param c
+ * @return true is the character is acceptable for an ID
+ */
+ bool isIDChar(char c) const
+ {
+ return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))
+ || ((c >= '0') && (c <= '9'));
+ }
+
+ /**
+ * @brief remove all "/0x00" parts
+ *
+ * @param src
+ * @return modified string
+ */
+ std::string remove0x00(const std::string& src) const
+ {
+ return std::regex_replace(src, std::regex("/0x00"), "");
+ }
+
+ /**
+ * @brief replace all non ID char with '_' (one '_' may replace several non ID char)
+ *
+ * @param src
+ * @return modified string
+ */
+ std::string str2ID(const std::string& src) const
+ {
+ std::string dst;
+ bool need_underscore = false;
+ for (char c : src) {
+ if (isIDChar(c) || (c == '/')) {
+ if (need_underscore) {
+ dst.push_back('_');
+ need_underscore = false;
}
+ dst.push_back(c);
+ } else {
+ need_underscore = true;
}
- return dst;
}
-
- /**
- * @brief Keep only the last n slash-parts
- *
- * @param src
- * @param n : 1 indicates the last slash-part
- * @return modified string
- */
- std::string cut(const std::string& src, int n) const
- {
- std::string rdst;
- for (int i = int(src.length())-1; i >= 0; i--) {
- char c = src[i];
- if (c != '/') {
- rdst.push_back(c);
- } else if (n == 1) {
- std::string dst;
- for (int j = int(rdst.length())-1; j >= 0; j--) {
- dst.push_back(rdst[j]);
- }
- return dst;
- } else {
- n--;
- rdst.push_back(c);
+ return dst;
+ }
+
+ /**
+ * @brief Keep only the last n slash-parts
+ *
+ * @param src
+ * @param n : 1 indicates the last slash-part
+ * @return modified string
+ */
+ std::string cut(const std::string& src, int n) const
+ {
+ std::string rdst;
+ for (int i = int(src.length()) - 1; i >= 0; i--) {
+ char c = src[i];
+ if (c != '/') {
+ rdst.push_back(c);
+ } else if (n == 1) {
+ std::string dst;
+ for (int j = int(rdst.length()) - 1; j >= 0; j--) {
+ dst.push_back(rdst[j]);
}
+ return dst;
+ } else {
+ n--;
+ rdst.push_back(c);
}
- return src;
}
-
- void addFullPath(const std::string& label) { fFullPaths.push_back(buildPath(label)); }
-
- /**
- * @brief Compute the mapping between full path and short names
- */
- void computeShortNames()
- {
- std::vector<std::string> uniquePaths; // all full paths transformed but made unique with a prefix
- std::map<std::string, std::string> unique2full; // all full paths transformed but made unique with a prefix
- char num_buffer[16];
- int pnum = 0;
-
- for (const auto& s : fFullPaths) {
- sprintf(num_buffer, "%d", pnum++);
- std::string u = "/P" + std::string(num_buffer) + str2ID(remove0x00(s));
- uniquePaths.push_back(u);
- unique2full[u] = s; // remember the full path associated to a unique path
- }
-
- std::map<std::string, int> uniquePath2level; // map path to level
- for (const auto& s : uniquePaths) uniquePath2level[s] = 1; // we init all levels to 1
- bool have_collisions = true;
-
- while (have_collisions) {
- // compute collision list
- std::set<std::string> collisionSet;
- std::map<std::string, std::string> short2full;
- have_collisions = false;
- for (const auto& it : uniquePath2level) {
- std::string u = it.first;
- int n = it.second;
- std::string shortName = cut(u, n);
- auto p = short2full.find(shortName);
- if (p == short2full.end()) {
- // no collision
- short2full[shortName] = u;
- } else {
- // we have a collision, add the two paths to the collision set
- have_collisions = true;
- collisionSet.insert(u);
- collisionSet.insert(p->second);
- }
- }
- for (const auto& s : collisionSet) uniquePath2level[s]++; // increase level of colliding path
- }
-
+ return src;
+ }
+
+ void addFullPath(const std::string& label) { fFullPaths.push_back(buildPath(label)); }
+
+ /**
+ * @brief Compute the mapping between full path and short names
+ */
+ void computeShortNames()
+ {
+ std::vector<std::string>
+ uniquePaths; // all full paths transformed but made unique with a prefix
+ std::map<std::string, std::string>
+ unique2full; // all full paths transformed but made unique with a prefix
+ char num_buffer[16];
+ int pnum = 0;
+
+ for (const auto& s : fFullPaths) {
+ sprintf(num_buffer, "%d", pnum++);
+ std::string u = "/P" + std::string(num_buffer) + str2ID(remove0x00(s));
+ uniquePaths.push_back(u);
+ unique2full[u] = s; // remember the full path associated to a unique path
+ }
+
+ std::map<std::string, int> uniquePath2level; // map path to level
+ for (const auto& s : uniquePaths)
+ uniquePath2level[s] = 1; // we init all levels to 1
+ bool have_collisions = true;
+
+ while (have_collisions) {
+ // compute collision list
+ std::set<std::string> collisionSet;
+ std::map<std::string, std::string> short2full;
+ have_collisions = false;
for (const auto& it : uniquePath2level) {
- std::string u = it.first;
- int n = it.second;
- std::string shortName = replaceCharList(cut(u, n), {'/'}, '_');
- fFull2Short[unique2full[u]] = shortName;
+ std::string u = it.first;
+ int n = it.second;
+ std::string shortName = cut(u, n);
+ auto p = short2full.find(shortName);
+ if (p == short2full.end()) {
+ // no collision
+ short2full[shortName] = u;
+ } else {
+ // we have a collision, add the two paths to the collision set
+ have_collisions = true;
+ collisionSet.insert(u);
+ collisionSet.insert(p->second);
+ }
}
+ for (const auto& s : collisionSet)
+ uniquePath2level[s]++; // increase level of colliding path
}
-
- std::string replaceCharList(const std::string& str, const std::vector<char>& ch1, char ch2)
- {
- auto beg = ch1.begin();
- auto end = ch1.end();
- std::string res = str;
- for (size_t i = 0; i < str.length(); ++i) {
- if (std::find(beg, end, str[i]) != end) res[i] = ch2;
- }
- return res;
+
+ for (const auto& it : uniquePath2level) {
+ std::string u = it.first;
+ int n = it.second;
+ std::string shortName = replaceCharList(cut(u, n), {'/'}, '_');
+ fFull2Short[unique2full[u]] = shortName;
}
-
- public:
-
- PathBuilder() {}
- virtual ~PathBuilder() {}
-
- // Return true for the first level of groups
- bool pushLabel(const std::string& label) { fControlsLevel.push_back(label); return fControlsLevel.size() == 1;}
-
- // Return true for the last level of groups
- bool popLabel() { fControlsLevel.pop_back(); return fControlsLevel.size() == 0; }
-
- std::string buildPath(const std::string& label)
- {
- std::string res = "/";
- for (size_t i = 0; i < fControlsLevel.size(); i++) {
- res = res + fControlsLevel[i] + "/";
- }
- res += label;
- return replaceCharList(res, {' ', '#', '*', ',', '?', '[', ']', '{', '}', '(', ')'}, '_');
+ }
+
+ std::string replaceCharList(const std::string& str, const std::vector<char>& ch1,
+ char ch2)
+ {
+ auto beg = ch1.begin();
+ auto end = ch1.end();
+ std::string res = str;
+ for (size_t i = 0; i < str.length(); ++i) {
+ if (std::find(beg, end, str[i]) != end)
+ res[i] = ch2;
+ }
+ return res;
+ }
+
+ public:
+ PathBuilder() {}
+ virtual ~PathBuilder() {}
+
+ // Return true for the first level of groups
+ bool pushLabel(const std::string& label)
+ {
+ fControlsLevel.push_back(label);
+ return fControlsLevel.size() == 1;
+ }
+
+ // Return true for the last level of groups
+ bool popLabel()
+ {
+ fControlsLevel.pop_back();
+ return fControlsLevel.size() == 0;
+ }
+
+ std::string buildPath(const std::string& label)
+ {
+ std::string res = "/";
+ for (size_t i = 0; i < fControlsLevel.size(); i++) {
+ res = res + fControlsLevel[i] + "/";
}
-
+ res += label;
+ return replaceCharList(
+ res, {' ', '#', '*', ',', '?', '[', ']', '{', '}', '(', ')'}, '_');
+ }
};
#endif // __PathBuilder__
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
/***************************************************************************************
ValueConverter.h
(GRAME, Copyright 2015-2019)
-
+
Set of conversion objects used to map user interface values (for example a gui slider
delivering values between 0 and 1) to faust values (for example a vslider between
20 and 20000) using a log scale.
-
+
-- Utilities
-
+
Range(lo,hi) : clip a value x between lo and hi
- Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and v2
- Interpolator3pt(lo,mi,hi,v1,vm,v2) : Map values between lo mid hi to values between v1 vm v2
-
+ Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and
+v2 Interpolator3pt(lo,mi,hi,v1,vm,v2) : Map values between lo mid hi to values between v1
+vm v2
+
-- Value Converters
-
+
ValueConverter::ui2faust(x)
ValueConverter::faust2ui(x)
-
+
-- ValueConverters used for sliders depending of the scale
-
+
LinearValueConverter(umin, umax, fmin, fmax)
LinearValueConverter2(lo, mi, hi, v1, vm, v2) using 2 segments
LogValueConverter(umin, umax, fmin, fmax)
ExpValueConverter(umin, umax, fmin, fmax)
-
+
-- ValueConverters used for accelerometers based on 3 points
-
+
AccUpConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 0
AccDownConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 1
AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 2
AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 3
-
+
-- lists of ZoneControl are used to implement accelerometers metadata for each axes
-
+
ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter
-
+
-- ZoneReader are used to implement screencolor metadata
-
+
ZoneReader(zone, valueConverter) : a zone with a data converter
****************************************************************************************/
+#include <assert.h>
#include <float.h>
-#include <algorithm> // std::max
+
+#include <algorithm> // std::max
#include <cmath>
#include <vector>
-#include <assert.h>
-
//--------------------------------------------------------------------------------------
// Interpolator(lo,hi,v1,v2)
// y = v1 - lo*coef + x*coef
// y = offset + x*coef with offset = v1 - lo*coef
//--------------------------------------------------------------------------------------
-class FAUST_API Interpolator {
-
- private:
-
- //--------------------------------------------------------------------------------------
- // Range(lo,hi) clip a value between lo and hi
- //--------------------------------------------------------------------------------------
- struct Range
- {
- double fLo;
- double fHi;
-
- Range(double x, double y) : fLo(std::min<double>(x,y)), fHi(std::max<double>(x,y)) {}
- double operator()(double x) { return (x<fLo) ? fLo : (x>fHi) ? fHi : x; }
- };
-
-
- Range fRange;
- double fCoef;
- double fOffset;
-
- public:
-
- Interpolator(double lo, double hi, double v1, double v2) : fRange(lo,hi)
- {
- if (hi != lo) {
- // regular case
- fCoef = (v2-v1)/(hi-lo);
- fOffset = v1 - lo*fCoef;
- } else {
- // degenerate case, avoids division by zero
- fCoef = 0;
- fOffset = (v1+v2)/2;
- }
- }
- double operator()(double v)
+class FAUST_API Interpolator
+{
+ private:
+ //--------------------------------------------------------------------------------------
+ // Range(lo,hi) clip a value between lo and hi
+ //--------------------------------------------------------------------------------------
+ struct Range {
+ double fLo;
+ double fHi;
+
+ Range(double x, double y)
+ : fLo(std::min<double>(x, y)), fHi(std::max<double>(x, y))
{
- double x = fRange(v);
- return fOffset + x*fCoef;
}
-
- void getLowHigh(double& amin, double& amax)
- {
- amin = fRange.fLo;
- amax = fRange.fHi;
+ double operator()(double x) { return (x < fLo) ? fLo : (x > fHi) ? fHi : x; }
+ };
+
+ Range fRange;
+ double fCoef;
+ double fOffset;
+
+ public:
+ Interpolator(double lo, double hi, double v1, double v2) : fRange(lo, hi)
+ {
+ if (hi != lo) {
+ // regular case
+ fCoef = (v2 - v1) / (hi - lo);
+ fOffset = v1 - lo * fCoef;
+ } else {
+ // degenerate case, avoids division by zero
+ fCoef = 0;
+ fOffset = (v1 + v2) / 2;
}
+ }
+ double operator()(double v)
+ {
+ double x = fRange(v);
+ return fOffset + x * fCoef;
+ }
+
+ void getLowHigh(double& amin, double& amax)
+ {
+ amin = fRange.fLo;
+ amax = fRange.fHi;
+ }
};
//--------------------------------------------------------------------------------------
// Interpolator3pt(lo,mi,hi,v1,vm,v2)
// Map values between lo mid hi to values between v1 vm v2
//--------------------------------------------------------------------------------------
-class FAUST_API Interpolator3pt {
-
- private:
-
- Interpolator fSegment1;
- Interpolator fSegment2;
- double fMid;
-
- public:
-
- Interpolator3pt(double lo, double mi, double hi, double v1, double vm, double v2) :
- fSegment1(lo, mi, v1, vm),
- fSegment2(mi, hi, vm, v2),
- fMid(mi) {}
- double operator()(double x) { return (x < fMid) ? fSegment1(x) : fSegment2(x); }
-
- void getMappingValues(double& amin, double& amid, double& amax)
- {
- fSegment1.getLowHigh(amin, amid);
- fSegment2.getLowHigh(amid, amax);
- }
+class FAUST_API Interpolator3pt
+{
+ private:
+ Interpolator fSegment1;
+ Interpolator fSegment2;
+ double fMid;
+
+ public:
+ Interpolator3pt(double lo, double mi, double hi, double v1, double vm, double v2)
+ : fSegment1(lo, mi, v1, vm), fSegment2(mi, hi, vm, v2), fMid(mi)
+ {
+ }
+ double operator()(double x) { return (x < fMid) ? fSegment1(x) : fSegment2(x); }
+
+ void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fSegment1.getLowHigh(amin, amid);
+ fSegment2.getLowHigh(amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Abstract ValueConverter class. Converts values between UI and Faust representations
//--------------------------------------------------------------------------------------
-class FAUST_API ValueConverter {
-
- public:
-
- virtual ~ValueConverter() {}
- virtual double ui2faust(double x) { return x; };
- virtual double faust2ui(double x) { return x; };
+class FAUST_API ValueConverter
+{
+ public:
+ virtual ~ValueConverter() {}
+ virtual double ui2faust(double x) { return x; };
+ virtual double faust2ui(double x) { return x; };
};
//--------------------------------------------------------------------------------------
// A converter than can be updated
//--------------------------------------------------------------------------------------
-class FAUST_API UpdatableValueConverter : public ValueConverter {
-
- protected:
-
- bool fActive;
-
- public:
-
- UpdatableValueConverter():fActive(true)
- {}
- virtual ~UpdatableValueConverter()
- {}
-
- virtual void setMappingValues(double amin, double amid, double amax, double min, double init, double max) = 0;
- virtual void getMappingValues(double& amin, double& amid, double& amax) = 0;
-
- void setActive(bool on_off) { fActive = on_off; }
- bool getActive() { return fActive; }
-
+class FAUST_API UpdatableValueConverter : public ValueConverter
+{
+ protected:
+ bool fActive;
+
+ public:
+ UpdatableValueConverter() : fActive(true) {}
+ virtual ~UpdatableValueConverter() {}
+
+ virtual void setMappingValues(double amin, double amid, double amax, double min,
+ double init, double max) = 0;
+ virtual void getMappingValues(double& amin, double& amid, double& amax) = 0;
+
+ void setActive(bool on_off) { fActive = on_off; }
+ bool getActive() { return fActive; }
};
//--------------------------------------------------------------------------------------
// Linear conversion between ui and Faust values
//--------------------------------------------------------------------------------------
-class FAUST_API LinearValueConverter : public ValueConverter {
-
- private:
-
- Interpolator fUI2F;
- Interpolator fF2UI;
-
- public:
-
- LinearValueConverter(double umin, double umax, double fmin, double fmax) :
- fUI2F(umin,umax,fmin,fmax), fF2UI(fmin,fmax,umin,umax)
- {}
-
- LinearValueConverter() : fUI2F(0.,0.,0.,0.), fF2UI(0.,0.,0.,0.)
- {}
- virtual double ui2faust(double x) { return fUI2F(x); }
- virtual double faust2ui(double x) { return fF2UI(x); }
-
+class FAUST_API LinearValueConverter : public ValueConverter
+{
+ private:
+ Interpolator fUI2F;
+ Interpolator fF2UI;
+
+ public:
+ LinearValueConverter(double umin, double umax, double fmin, double fmax)
+ : fUI2F(umin, umax, fmin, fmax), fF2UI(fmin, fmax, umin, umax)
+ {
+ }
+
+ LinearValueConverter() : fUI2F(0., 0., 0., 0.), fF2UI(0., 0., 0., 0.) {}
+ virtual double ui2faust(double x) { return fUI2F(x); }
+ virtual double faust2ui(double x) { return fF2UI(x); }
};
//--------------------------------------------------------------------------------------
// Two segments linear conversion between ui and Faust values
//--------------------------------------------------------------------------------------
-class FAUST_API LinearValueConverter2 : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fUI2F;
- Interpolator3pt fF2UI;
-
- public:
-
- LinearValueConverter2(double amin, double amid, double amax, double min, double init, double max) :
- fUI2F(amin, amid, amax, min, init, max), fF2UI(min, init, max, amin, amid, amax)
- {}
-
- LinearValueConverter2() : fUI2F(0.,0.,0.,0.,0.,0.), fF2UI(0.,0.,0.,0.,0.,0.)
- {}
-
- virtual double ui2faust(double x) { return fUI2F(x); }
- virtual double faust2ui(double x) { return fF2UI(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double min, double init, double max)
- {
- fUI2F = Interpolator3pt(amin, amid, amax, min, init, max);
- fF2UI = Interpolator3pt(min, init, max, amin, amid, amax);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fUI2F.getMappingValues(amin, amid, amax);
- }
-
+class FAUST_API LinearValueConverter2 : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fUI2F;
+ Interpolator3pt fF2UI;
+
+ public:
+ LinearValueConverter2(double amin, double amid, double amax, double min, double init,
+ double max)
+ : fUI2F(amin, amid, amax, min, init, max), fF2UI(min, init, max, amin, amid, amax)
+ {
+ }
+
+ LinearValueConverter2() : fUI2F(0., 0., 0., 0., 0., 0.), fF2UI(0., 0., 0., 0., 0., 0.)
+ {
+ }
+
+ virtual double ui2faust(double x) { return fUI2F(x); }
+ virtual double faust2ui(double x) { return fF2UI(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double min,
+ double init, double max)
+ {
+ fUI2F = Interpolator3pt(amin, amid, amax, min, init, max);
+ fF2UI = Interpolator3pt(min, init, max, amin, amid, amax);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fUI2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Logarithmic conversion between ui and Faust values
//--------------------------------------------------------------------------------------
-class FAUST_API LogValueConverter : public LinearValueConverter {
-
- public:
-
- LogValueConverter(double umin, double umax, double fmin, double fmax) :
- LinearValueConverter(umin, umax, std::log(std::max<double>(DBL_MIN, fmin)), std::log(std::max<double>(DBL_MIN, fmax)))
- {}
-
- virtual double ui2faust(double x) { return std::exp(LinearValueConverter::ui2faust(x)); }
- virtual double faust2ui(double x) { return LinearValueConverter::faust2ui(std::log(std::max<double>(x, DBL_MIN))); }
-
+class FAUST_API LogValueConverter : public LinearValueConverter
+{
+ public:
+ LogValueConverter(double umin, double umax, double fmin, double fmax)
+ : LinearValueConverter(umin, umax, std::log(std::max<double>(DBL_MIN, fmin)),
+ std::log(std::max<double>(DBL_MIN, fmax)))
+ {
+ }
+
+ virtual double ui2faust(double x)
+ {
+ return std::exp(LinearValueConverter::ui2faust(x));
+ }
+ virtual double faust2ui(double x)
+ {
+ return LinearValueConverter::faust2ui(std::log(std::max<double>(x, DBL_MIN)));
+ }
};
//--------------------------------------------------------------------------------------
// Exponential conversion between ui and Faust values
//--------------------------------------------------------------------------------------
-class FAUST_API ExpValueConverter : public LinearValueConverter {
-
- public:
-
- ExpValueConverter(double umin, double umax, double fmin, double fmax) :
- LinearValueConverter(umin, umax, std::min<double>(DBL_MAX, std::exp(fmin)), std::min<double>(DBL_MAX, std::exp(fmax)))
- {}
-
- virtual double ui2faust(double x) { return std::log(LinearValueConverter::ui2faust(x)); }
- virtual double faust2ui(double x) { return LinearValueConverter::faust2ui(std::min<double>(DBL_MAX, std::exp(x))); }
-
+class FAUST_API ExpValueConverter : public LinearValueConverter
+{
+ public:
+ ExpValueConverter(double umin, double umax, double fmin, double fmax)
+ : LinearValueConverter(umin, umax, std::min<double>(DBL_MAX, std::exp(fmin)),
+ std::min<double>(DBL_MAX, std::exp(fmax)))
+ {
+ }
+
+ virtual double ui2faust(double x)
+ {
+ return std::log(LinearValueConverter::ui2faust(x));
+ }
+ virtual double faust2ui(double x)
+ {
+ return LinearValueConverter::faust2ui(std::min<double>(DBL_MAX, std::exp(x)));
+ }
};
//--------------------------------------------------------------------------------------
// Convert accelerometer or gyroscope values to Faust values
// Using an Up curve (curve 0)
//--------------------------------------------------------------------------------------
-class FAUST_API AccUpConverter : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fA2F;
- Interpolator3pt fF2A;
-
- public:
-
- AccUpConverter(double amin, double amid, double amax, double fmin, double fmid, double fmax) :
- fA2F(amin,amid,amax,fmin,fmid,fmax),
- fF2A(fmin,fmid,fmax,amin,amid,amax)
- {}
-
- virtual double ui2faust(double x) { return fA2F(x); }
- virtual double faust2ui(double x) { return fF2A(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double fmin, double fmid, double fmax)
- {
- //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
- fA2F = Interpolator3pt(amin, amid, amax, fmin, fmid, fmax);
- fF2A = Interpolator3pt(fmin, fmid, fmax, amin, amid, amax);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fA2F.getMappingValues(amin, amid, amax);
- }
-
+class FAUST_API AccUpConverter : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fA2F;
+ Interpolator3pt fF2A;
+
+ public:
+ AccUpConverter(double amin, double amid, double amax, double fmin, double fmid,
+ double fmax)
+ : fA2F(amin, amid, amax, fmin, fmid, fmax)
+ , fF2A(fmin, fmid, fmax, amin, amid, amax)
+ {
+ }
+
+ virtual double ui2faust(double x) { return fA2F(x); }
+ virtual double faust2ui(double x) { return fF2A(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double fmin,
+ double fmid, double fmax)
+ {
+ //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpConverter update %f %f %f
+ //%f %f %f", amin,amid,amax,fmin,fmid,fmax);
+ fA2F = Interpolator3pt(amin, amid, amax, fmin, fmid, fmax);
+ fF2A = Interpolator3pt(fmin, fmid, fmax, amin, amid, amax);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fA2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Convert accelerometer or gyroscope values to Faust values
// Using a Down curve (curve 1)
//--------------------------------------------------------------------------------------
-class FAUST_API AccDownConverter : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fA2F;
- Interpolator3pt fF2A;
-
- public:
-
- AccDownConverter(double amin, double amid, double amax, double fmin, double fmid, double fmax) :
- fA2F(amin,amid,amax,fmax,fmid,fmin),
- fF2A(fmin,fmid,fmax,amax,amid,amin)
- {}
-
- virtual double ui2faust(double x) { return fA2F(x); }
- virtual double faust2ui(double x) { return fF2A(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double fmin, double fmid, double fmax)
- {
- //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
- fA2F = Interpolator3pt(amin, amid, amax, fmax, fmid, fmin);
- fF2A = Interpolator3pt(fmin, fmid, fmax, amax, amid, amin);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fA2F.getMappingValues(amin, amid, amax);
- }
+class FAUST_API AccDownConverter : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fA2F;
+ Interpolator3pt fF2A;
+
+ public:
+ AccDownConverter(double amin, double amid, double amax, double fmin, double fmid,
+ double fmax)
+ : fA2F(amin, amid, amax, fmax, fmid, fmin)
+ , fF2A(fmin, fmid, fmax, amax, amid, amin)
+ {
+ }
+
+ virtual double ui2faust(double x) { return fA2F(x); }
+ virtual double faust2ui(double x) { return fF2A(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double fmin,
+ double fmid, double fmax)
+ {
+ //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownConverter update %f %f
+ //%f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+ fA2F = Interpolator3pt(amin, amid, amax, fmax, fmid, fmin);
+ fF2A = Interpolator3pt(fmin, fmid, fmax, amax, amid, amin);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fA2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Convert accelerometer or gyroscope values to Faust values
// Using an Up-Down curve (curve 2)
//--------------------------------------------------------------------------------------
-class FAUST_API AccUpDownConverter : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fA2F;
- Interpolator fF2A;
-
- public:
-
- AccUpDownConverter(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax) :
- fA2F(amin,amid,amax,fmin,fmax,fmin),
- fF2A(fmin,fmax,amin,amax) // Special, pseudo inverse of a non monotonic function
- {}
-
- virtual double ui2faust(double x) { return fA2F(x); }
- virtual double faust2ui(double x) { return fF2A(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax)
- {
- //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpDownConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
- fA2F = Interpolator3pt(amin, amid, amax, fmin, fmax, fmin);
- fF2A = Interpolator(fmin, fmax, amin, amax);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fA2F.getMappingValues(amin, amid, amax);
- }
+class FAUST_API AccUpDownConverter : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fA2F;
+ Interpolator fF2A;
+
+ public:
+ AccUpDownConverter(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
+ : fA2F(amin, amid, amax, fmin, fmax, fmin)
+ , fF2A(fmin, fmax, amin,
+ amax) // Special, pseudo inverse of a non monotonic function
+ {
+ }
+
+ virtual double ui2faust(double x) { return fA2F(x); }
+ virtual double faust2ui(double x) { return fF2A(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
+ {
+ //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpDownConverter update %f %f
+ //%f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+ fA2F = Interpolator3pt(amin, amid, amax, fmin, fmax, fmin);
+ fF2A = Interpolator(fmin, fmax, amin, amax);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fA2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Convert accelerometer or gyroscope values to Faust values
// Using a Down-Up curve (curve 3)
//--------------------------------------------------------------------------------------
-class FAUST_API AccDownUpConverter : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fA2F;
- Interpolator fF2A;
-
- public:
-
- AccDownUpConverter(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax) :
- fA2F(amin,amid,amax,fmax,fmin,fmax),
- fF2A(fmin,fmax,amin,amax) // Special, pseudo inverse of a non monotonic function
- {}
-
- virtual double ui2faust(double x) { return fA2F(x); }
- virtual double faust2ui(double x) { return fF2A(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax)
- {
- //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownUpConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
- fA2F = Interpolator3pt(amin, amid, amax, fmax, fmin, fmax);
- fF2A = Interpolator(fmin, fmax, amin, amax);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fA2F.getMappingValues(amin, amid, amax);
- }
+class FAUST_API AccDownUpConverter : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fA2F;
+ Interpolator fF2A;
+
+ public:
+ AccDownUpConverter(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
+ : fA2F(amin, amid, amax, fmax, fmin, fmax)
+ , fF2A(fmin, fmax, amin,
+ amax) // Special, pseudo inverse of a non monotonic function
+ {
+ }
+
+ virtual double ui2faust(double x) { return fA2F(x); }
+ virtual double faust2ui(double x) { return fF2A(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
+ {
+ //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownUpConverter update %f %f
+ //%f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+ fA2F = Interpolator3pt(amin, amid, amax, fmax, fmin, fmax);
+ fF2A = Interpolator(fmin, fmax, amin, amax);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fA2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Base class for ZoneControl
//--------------------------------------------------------------------------------------
-class FAUST_API ZoneControl {
-
- protected:
-
- FAUSTFLOAT* fZone;
-
- public:
-
- ZoneControl(FAUSTFLOAT* zone) : fZone(zone) {}
- virtual ~ZoneControl() {}
+class FAUST_API ZoneControl
+{
+ protected:
+ FAUSTFLOAT* fZone;
- virtual void update(double /*v*/) const {}
+ public:
+ ZoneControl(FAUSTFLOAT* zone) : fZone(zone) {}
+ virtual ~ZoneControl() {}
- virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/, double /*amax*/, double /*min*/, double /*init*/, double /*max*/) {}
- virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
+ virtual void update(double /*v*/) const {}
- FAUSTFLOAT* getZone() { return fZone; }
+ virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/,
+ double /*amax*/, double /*min*/, double /*init*/,
+ double /*max*/)
+ {
+ }
+ virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
- virtual void setActive(bool /*on_off*/) {}
- virtual bool getActive() { return false; }
+ FAUSTFLOAT* getZone() { return fZone; }
- virtual int getCurve() { return -1; }
+ virtual void setActive(bool /*on_off*/) {}
+ virtual bool getActive() { return false; }
+ virtual int getCurve() { return -1; }
};
//--------------------------------------------------------------------------------------
// Useful to implement accelerometers metadata as a list of ZoneControl for each axes
//--------------------------------------------------------------------------------------
-class FAUST_API ConverterZoneControl : public ZoneControl {
-
- protected:
-
- ValueConverter* fValueConverter;
-
- public:
-
- ConverterZoneControl(FAUSTFLOAT* zone, ValueConverter* converter) : ZoneControl(zone), fValueConverter(converter) {}
- virtual ~ConverterZoneControl() { delete fValueConverter; } // Assuming fValueConverter is not kept elsewhere...
-
- virtual void update(double v) const { *fZone = FAUSTFLOAT(fValueConverter->ui2faust(v)); }
-
- ValueConverter* getConverter() { return fValueConverter; }
-
+class FAUST_API ConverterZoneControl : public ZoneControl
+{
+ protected:
+ ValueConverter* fValueConverter;
+
+ public:
+ ConverterZoneControl(FAUSTFLOAT* zone, ValueConverter* converter)
+ : ZoneControl(zone), fValueConverter(converter)
+ {
+ }
+ virtual ~ConverterZoneControl()
+ {
+ delete fValueConverter;
+ } // Assuming fValueConverter is not kept elsewhere...
+
+ virtual void update(double v) const
+ {
+ *fZone = FAUSTFLOAT(fValueConverter->ui2faust(v));
+ }
+
+ ValueConverter* getConverter() { return fValueConverter; }
};
//--------------------------------------------------------------------------------------
// Association of a zone and a four value converter, each one for each possible curve.
// Useful to implement accelerometers metadata as a list of ZoneControl for each axes
//--------------------------------------------------------------------------------------
-class FAUST_API CurveZoneControl : public ZoneControl {
-
- private:
-
- std::vector<UpdatableValueConverter*> fValueConverters;
- int fCurve;
-
- public:
-
- CurveZoneControl(FAUSTFLOAT* zone, int curve, double amin, double amid, double amax, double min, double init, double max) : ZoneControl(zone), fCurve(0)
- {
- assert(curve >= 0 && curve <= 3);
- fValueConverters.push_back(new AccUpConverter(amin, amid, amax, min, init, max));
- fValueConverters.push_back(new AccDownConverter(amin, amid, amax, min, init, max));
- fValueConverters.push_back(new AccUpDownConverter(amin, amid, amax, min, init, max));
- fValueConverters.push_back(new AccDownUpConverter(amin, amid, amax, min, init, max));
- fCurve = curve;
- }
- virtual ~CurveZoneControl()
- {
- for (const auto& it : fValueConverters) { delete it; }
- }
- void update(double v) const { if (fValueConverters[fCurve]->getActive()) *fZone = FAUSTFLOAT(fValueConverters[fCurve]->ui2faust(v)); }
-
- void setMappingValues(int curve, double amin, double amid, double amax, double min, double init, double max)
- {
- fValueConverters[curve]->setMappingValues(amin, amid, amax, min, init, max);
- fCurve = curve;
- }
-
- void getMappingValues(double& amin, double& amid, double& amax)
- {
- fValueConverters[fCurve]->getMappingValues(amin, amid, amax);
+class FAUST_API CurveZoneControl : public ZoneControl
+{
+ private:
+ std::vector<UpdatableValueConverter*> fValueConverters;
+ int fCurve;
+
+ public:
+ CurveZoneControl(FAUSTFLOAT* zone, int curve, double amin, double amid, double amax,
+ double min, double init, double max)
+ : ZoneControl(zone), fCurve(0)
+ {
+ assert(curve >= 0 && curve <= 3);
+ fValueConverters.push_back(new AccUpConverter(amin, amid, amax, min, init, max));
+ fValueConverters.push_back(
+ new AccDownConverter(amin, amid, amax, min, init, max));
+ fValueConverters.push_back(
+ new AccUpDownConverter(amin, amid, amax, min, init, max));
+ fValueConverters.push_back(
+ new AccDownUpConverter(amin, amid, amax, min, init, max));
+ fCurve = curve;
+ }
+ virtual ~CurveZoneControl()
+ {
+ for (const auto& it : fValueConverters) {
+ delete it;
}
-
- void setActive(bool on_off)
- {
- for (const auto& it : fValueConverters) { it->setActive(on_off); }
+ }
+ void update(double v) const
+ {
+ if (fValueConverters[fCurve]->getActive())
+ *fZone = FAUSTFLOAT(fValueConverters[fCurve]->ui2faust(v));
+ }
+
+ void setMappingValues(int curve, double amin, double amid, double amax, double min,
+ double init, double max)
+ {
+ fValueConverters[curve]->setMappingValues(amin, amid, amax, min, init, max);
+ fCurve = curve;
+ }
+
+ void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fValueConverters[fCurve]->getMappingValues(amin, amid, amax);
+ }
+
+ void setActive(bool on_off)
+ {
+ for (const auto& it : fValueConverters) {
+ it->setActive(on_off);
}
+ }
- int getCurve() { return fCurve; }
+ int getCurve() { return fCurve; }
};
-class FAUST_API ZoneReader {
-
- private:
-
- FAUSTFLOAT* fZone;
- Interpolator fInterpolator;
-
- public:
-
- ZoneReader(FAUSTFLOAT* zone, double lo, double hi) : fZone(zone), fInterpolator(lo, hi, 0, 255) {}
+class FAUST_API ZoneReader
+{
+ private:
+ FAUSTFLOAT* fZone;
+ Interpolator fInterpolator;
- virtual ~ZoneReader() {}
+ public:
+ ZoneReader(FAUSTFLOAT* zone, double lo, double hi)
+ : fZone(zone), fInterpolator(lo, hi, 0, 255)
+ {
+ }
- int getValue()
- {
- return (fZone != nullptr) ? int(fInterpolator(*fZone)) : 127;
- }
+ virtual ~ZoneReader() {}
+ int getValue() { return (fZone != nullptr) ? int(fInterpolator(*fZone)) : 127; }
};
#endif
typedef unsigned int uint;
-class APIUI : public PathBuilder, public Meta, public UI
+class APIUI
+ : public PathBuilder
+ , public Meta
+ , public UI
{
- public:
- enum ItemType { kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry, kHBargraph, kVBargraph };
- enum Type { kAcc = 0, kGyr = 1, kNoType };
-
- protected:
-
- enum Mapping { kLin = 0, kLog = 1, kExp = 2 };
-
- struct Item {
- std::string fLabel;
- std::string fShortname;
- std::string fPath;
- ValueConverter* fConversion;
- FAUSTFLOAT* fZone;
- FAUSTFLOAT fInit;
- FAUSTFLOAT fMin;
- FAUSTFLOAT fMax;
- FAUSTFLOAT fStep;
- ItemType fItemType;
-
- Item(const std::string& label,
- const std::string& short_name,
- const std::string& path,
- ValueConverter* conversion,
- FAUSTFLOAT* zone,
- FAUSTFLOAT init,
- FAUSTFLOAT min,
- FAUSTFLOAT max,
- FAUSTFLOAT step,
- ItemType item_type)
- :fLabel(label), fShortname(short_name), fPath(path), fConversion(conversion),
- fZone(zone), fInit(init), fMin(min), fMax(max), fStep(step), fItemType(item_type)
- {}
- };
- std::vector<Item> fItems;
-
- std::vector<std::map<std::string, std::string> > fMetaData;
- std::vector<ZoneControl*> fAcc[3];
- std::vector<ZoneControl*> fGyr[3];
-
- // Screen color control
- // "...[screencolor:red]..." etc.
- bool fHasScreenControl; // true if control screen color metadata
- ZoneReader* fRedReader;
- ZoneReader* fGreenReader;
- ZoneReader* fBlueReader;
-
- // Current values controlled by metadata
- std::string fCurrentUnit;
- int fCurrentScale;
- std::string fCurrentAcc;
- std::string fCurrentGyr;
- std::string fCurrentColor;
- std::string fCurrentTooltip;
- std::map<std::string, std::string> fCurrentMetadata;
-
- // Add a generic parameter
- virtual void addParameter(const char* label,
- FAUSTFLOAT* zone,
- FAUSTFLOAT init,
- FAUSTFLOAT min,
- FAUSTFLOAT max,
- FAUSTFLOAT step,
- ItemType type)
+ public:
+ enum ItemType {
+ kButton = 0,
+ kCheckButton,
+ kVSlider,
+ kHSlider,
+ kNumEntry,
+ kHBargraph,
+ kVBargraph
+ };
+ enum Type { kAcc = 0, kGyr = 1, kNoType };
+
+ protected:
+ enum Mapping { kLin = 0, kLog = 1, kExp = 2 };
+
+ struct Item {
+ std::string fLabel;
+ std::string fShortname;
+ std::string fPath;
+ ValueConverter* fConversion;
+ FAUSTFLOAT* fZone;
+ FAUSTFLOAT fInit;
+ FAUSTFLOAT fMin;
+ FAUSTFLOAT fMax;
+ FAUSTFLOAT fStep;
+ ItemType fItemType;
+
+ Item(const std::string& label, const std::string& short_name,
+ const std::string& path, ValueConverter* conversion, FAUSTFLOAT* zone,
+ FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step,
+ ItemType item_type)
+ : fLabel(label)
+ , fShortname(short_name)
+ , fPath(path)
+ , fConversion(conversion)
+ , fZone(zone)
+ , fInit(init)
+ , fMin(min)
+ , fMax(max)
+ , fStep(step)
+ , fItemType(item_type)
{
- std::string path = buildPath(label);
- fFullPaths.push_back(path);
-
- // handle scale metadata
- ValueConverter* converter = nullptr;
- switch (fCurrentScale) {
- case kLin:
- converter = new LinearValueConverter(0, 1, min, max);
- break;
- case kLog:
- converter = new LogValueConverter(0, 1, min, max);
- break;
- case kExp:
- converter = new ExpValueConverter(0, 1, min, max);
- break;
- }
- fCurrentScale = kLin;
-
- fItems.push_back(Item(label, "", path, converter, zone, init, min, max, step, type));
-
- if (fCurrentAcc.size() > 0 && fCurrentGyr.size() > 0) {
- fprintf(stderr, "warning : 'acc' and 'gyr' metadata used for the same %s parameter !!\n", label);
- }
+ }
+ };
+ std::vector<Item> fItems;
+
+ std::vector<std::map<std::string, std::string> > fMetaData;
+ std::vector<ZoneControl*> fAcc[3];
+ std::vector<ZoneControl*> fGyr[3];
+
+ // Screen color control
+ // "...[screencolor:red]..." etc.
+ bool fHasScreenControl; // true if control screen color metadata
+ ZoneReader* fRedReader;
+ ZoneReader* fGreenReader;
+ ZoneReader* fBlueReader;
+
+ // Current values controlled by metadata
+ std::string fCurrentUnit;
+ int fCurrentScale;
+ std::string fCurrentAcc;
+ std::string fCurrentGyr;
+ std::string fCurrentColor;
+ std::string fCurrentTooltip;
+ std::map<std::string, std::string> fCurrentMetadata;
+
+ // Add a generic parameter
+ virtual void addParameter(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init,
+ FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step,
+ ItemType type)
+ {
+ std::string path = buildPath(label);
+ fFullPaths.push_back(path);
+
+ // handle scale metadata
+ ValueConverter* converter = nullptr;
+ switch (fCurrentScale) {
+ case kLin:
+ converter = new LinearValueConverter(0, 1, min, max);
+ break;
+ case kLog:
+ converter = new LogValueConverter(0, 1, min, max);
+ break;
+ case kExp:
+ converter = new ExpValueConverter(0, 1, min, max);
+ break;
+ }
+ fCurrentScale = kLin;
- // handle acc metadata "...[acc : <axe> <curve> <amin> <amid> <amax>]..."
- if (fCurrentAcc.size() > 0) {
- std::istringstream iss(fCurrentAcc);
- int axe, curve;
- double amin, amid, amax;
- iss >> axe >> curve >> amin >> amid >> amax;
-
- if ((0 <= axe) && (axe < 3) &&
- (0 <= curve) && (curve < 4) &&
- (amin < amax) && (amin <= amid) && (amid <= amax))
- {
- fAcc[axe].push_back(new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
- } else {
- fprintf(stderr, "incorrect acc metadata : %s \n", fCurrentAcc.c_str());
- }
- fCurrentAcc = "";
- }
+ fItems.push_back(
+ Item(label, "", path, converter, zone, init, min, max, step, type));
- // handle gyr metadata "...[gyr : <axe> <curve> <amin> <amid> <amax>]..."
- if (fCurrentGyr.size() > 0) {
- std::istringstream iss(fCurrentGyr);
- int axe, curve;
- double amin, amid, amax;
- iss >> axe >> curve >> amin >> amid >> amax;
-
- if ((0 <= axe) && (axe < 3) &&
- (0 <= curve) && (curve < 4) &&
- (amin < amax) && (amin <= amid) && (amid <= amax))
- {
- fGyr[axe].push_back(new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
- } else {
- fprintf(stderr, "incorrect gyr metadata : %s \n", fCurrentGyr.c_str());
- }
- fCurrentGyr = "";
- }
+ if (fCurrentAcc.size() > 0 && fCurrentGyr.size() > 0) {
+ fprintf(
+ stderr,
+ "warning : 'acc' and 'gyr' metadata used for the same %s parameter !!\n",
+ label);
+ }
- // handle screencolor metadata "...[screencolor:red|green|blue|white]..."
- if (fCurrentColor.size() > 0) {
- if ((fCurrentColor == "red") && (fRedReader == nullptr)) {
- fRedReader = new ZoneReader(zone, min, max);
- fHasScreenControl = true;
- } else if ((fCurrentColor == "green") && (fGreenReader == nullptr)) {
- fGreenReader = new ZoneReader(zone, min, max);
- fHasScreenControl = true;
- } else if ((fCurrentColor == "blue") && (fBlueReader == nullptr)) {
- fBlueReader = new ZoneReader(zone, min, max);
- fHasScreenControl = true;
- } else if ((fCurrentColor == "white") && (fRedReader == nullptr) && (fGreenReader == nullptr) && (fBlueReader == nullptr)) {
- fRedReader = new ZoneReader(zone, min, max);
- fGreenReader = new ZoneReader(zone, min, max);
- fBlueReader = new ZoneReader(zone, min, max);
- fHasScreenControl = true;
- } else {
- fprintf(stderr, "incorrect screencolor metadata : %s \n", fCurrentColor.c_str());
- }
+ // handle acc metadata "...[acc : <axe> <curve> <amin> <amid> <amax>]..."
+ if (fCurrentAcc.size() > 0) {
+ std::istringstream iss(fCurrentAcc);
+ int axe, curve;
+ double amin, amid, amax;
+ iss >> axe >> curve >> amin >> amid >> amax;
+
+ if ((0 <= axe) && (axe < 3) && (0 <= curve) && (curve < 4) && (amin < amax)
+ && (amin <= amid) && (amid <= amax)) {
+ fAcc[axe].push_back(
+ new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
+ } else {
+ fprintf(stderr, "incorrect acc metadata : %s \n", fCurrentAcc.c_str());
}
- fCurrentColor = "";
-
- fMetaData.push_back(fCurrentMetadata);
- fCurrentMetadata.clear();
+ fCurrentAcc = "";
}
- int getZoneIndex(std::vector<ZoneControl*>* table, int p, int val)
- {
- FAUSTFLOAT* zone = fItems[uint(p)].fZone;
- for (size_t i = 0; i < table[val].size(); i++) {
- if (zone == table[val][i]->getZone()) return int(i);
+ // handle gyr metadata "...[gyr : <axe> <curve> <amin> <amid> <amax>]..."
+ if (fCurrentGyr.size() > 0) {
+ std::istringstream iss(fCurrentGyr);
+ int axe, curve;
+ double amin, amid, amax;
+ iss >> axe >> curve >> amin >> amid >> amax;
+
+ if ((0 <= axe) && (axe < 3) && (0 <= curve) && (curve < 4) && (amin < amax)
+ && (amin <= amid) && (amid <= amax)) {
+ fGyr[axe].push_back(
+ new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
+ } else {
+ fprintf(stderr, "incorrect gyr metadata : %s \n", fCurrentGyr.c_str());
}
- return -1;
+ fCurrentGyr = "";
}
- void setConverter(std::vector<ZoneControl*>* table, int p, int val, int curve, double amin, double amid, double amax)
- {
- int id1 = getZoneIndex(table, p, 0);
- int id2 = getZoneIndex(table, p, 1);
- int id3 = getZoneIndex(table, p, 2);
-
- // Deactivates everywhere..
- if (id1 != -1) table[0][uint(id1)]->setActive(false);
- if (id2 != -1) table[1][uint(id2)]->setActive(false);
- if (id3 != -1) table[2][uint(id3)]->setActive(false);
-
- if (val == -1) { // Means: no more mapping...
- // So stay all deactivated...
+ // handle screencolor metadata "...[screencolor:red|green|blue|white]..."
+ if (fCurrentColor.size() > 0) {
+ if ((fCurrentColor == "red") && (fRedReader == nullptr)) {
+ fRedReader = new ZoneReader(zone, min, max);
+ fHasScreenControl = true;
+ } else if ((fCurrentColor == "green") && (fGreenReader == nullptr)) {
+ fGreenReader = new ZoneReader(zone, min, max);
+ fHasScreenControl = true;
+ } else if ((fCurrentColor == "blue") && (fBlueReader == nullptr)) {
+ fBlueReader = new ZoneReader(zone, min, max);
+ fHasScreenControl = true;
+ } else if ((fCurrentColor == "white") && (fRedReader == nullptr)
+ && (fGreenReader == nullptr) && (fBlueReader == nullptr)) {
+ fRedReader = new ZoneReader(zone, min, max);
+ fGreenReader = new ZoneReader(zone, min, max);
+ fBlueReader = new ZoneReader(zone, min, max);
+ fHasScreenControl = true;
} else {
- int id4 = getZoneIndex(table, p, val);
- if (id4 != -1) {
- // Reactivate the one we edit...
- table[val][uint(id4)]->setMappingValues(curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit, fItems[uint(p)].fMax);
- table[val][uint(id4)]->setActive(true);
- } else {
- // Allocate a new CurveZoneControl which is 'active' by default
- FAUSTFLOAT* zone = fItems[uint(p)].fZone;
- table[val].push_back(new CurveZoneControl(zone, curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit, fItems[uint(p)].fMax));
- }
+ fprintf(stderr, "incorrect screencolor metadata : %s \n",
+ fCurrentColor.c_str());
}
}
-
- void getConverter(std::vector<ZoneControl*>* table, int p, int& val, int& curve, double& amin, double& amid, double& amax)
- {
- int id1 = getZoneIndex(table, p, 0);
- int id2 = getZoneIndex(table, p, 1);
- int id3 = getZoneIndex(table, p, 2);
-
- if (id1 != -1) {
- val = 0;
- curve = table[val][uint(id1)]->getCurve();
- table[val][uint(id1)]->getMappingValues(amin, amid, amax);
- } else if (id2 != -1) {
- val = 1;
- curve = table[val][uint(id2)]->getCurve();
- table[val][uint(id2)]->getMappingValues(amin, amid, amax);
- } else if (id3 != -1) {
- val = 2;
- curve = table[val][uint(id3)]->getCurve();
- table[val][uint(id3)]->getMappingValues(amin, amid, amax);
+ fCurrentColor = "";
+
+ fMetaData.push_back(fCurrentMetadata);
+ fCurrentMetadata.clear();
+ }
+
+ int getZoneIndex(std::vector<ZoneControl*>* table, int p, int val)
+ {
+ FAUSTFLOAT* zone = fItems[uint(p)].fZone;
+ for (size_t i = 0; i < table[val].size(); i++) {
+ if (zone == table[val][i]->getZone())
+ return int(i);
+ }
+ return -1;
+ }
+
+ void setConverter(std::vector<ZoneControl*>* table, int p, int val, int curve,
+ double amin, double amid, double amax)
+ {
+ int id1 = getZoneIndex(table, p, 0);
+ int id2 = getZoneIndex(table, p, 1);
+ int id3 = getZoneIndex(table, p, 2);
+
+ // Deactivates everywhere..
+ if (id1 != -1)
+ table[0][uint(id1)]->setActive(false);
+ if (id2 != -1)
+ table[1][uint(id2)]->setActive(false);
+ if (id3 != -1)
+ table[2][uint(id3)]->setActive(false);
+
+ if (val == -1) { // Means: no more mapping...
+ // So stay all deactivated...
+ } else {
+ int id4 = getZoneIndex(table, p, val);
+ if (id4 != -1) {
+ // Reactivate the one we edit...
+ table[val][uint(id4)]->setMappingValues(
+ curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit,
+ fItems[uint(p)].fMax);
+ table[val][uint(id4)]->setActive(true);
} else {
- val = -1; // No mapping
- curve = 0;
- amin = -100.;
- amid = 0.;
- amax = 100.;
+ // Allocate a new CurveZoneControl which is 'active' by default
+ FAUSTFLOAT* zone = fItems[uint(p)].fZone;
+ table[val].push_back(new CurveZoneControl(
+ zone, curve, amin, amid, amax, fItems[uint(p)].fMin,
+ fItems[uint(p)].fInit, fItems[uint(p)].fMax));
}
}
+ }
+
+ void getConverter(std::vector<ZoneControl*>* table, int p, int& val, int& curve,
+ double& amin, double& amid, double& amax)
+ {
+ int id1 = getZoneIndex(table, p, 0);
+ int id2 = getZoneIndex(table, p, 1);
+ int id3 = getZoneIndex(table, p, 2);
+
+ if (id1 != -1) {
+ val = 0;
+ curve = table[val][uint(id1)]->getCurve();
+ table[val][uint(id1)]->getMappingValues(amin, amid, amax);
+ } else if (id2 != -1) {
+ val = 1;
+ curve = table[val][uint(id2)]->getCurve();
+ table[val][uint(id2)]->getMappingValues(amin, amid, amax);
+ } else if (id3 != -1) {
+ val = 2;
+ curve = table[val][uint(id3)]->getCurve();
+ table[val][uint(id3)]->getMappingValues(amin, amid, amax);
+ } else {
+ val = -1; // No mapping
+ curve = 0;
+ amin = -100.;
+ amid = 0.;
+ amax = 100.;
+ }
+ }
+
+ public:
+ APIUI()
+ : fHasScreenControl(false)
+ , fRedReader(nullptr)
+ , fGreenReader(nullptr)
+ , fBlueReader(nullptr)
+ , fCurrentScale(kLin)
+ {
+ }
+
+ virtual ~APIUI()
+ {
+ for (const auto& it : fItems)
+ delete it.fConversion;
+ for (int i = 0; i < 3; i++) {
+ for (const auto& it : fAcc[i])
+ delete it;
+ for (const auto& it : fGyr[i])
+ delete it;
+ }
+ delete fRedReader;
+ delete fGreenReader;
+ delete fBlueReader;
+ }
- public:
-
- APIUI() : fHasScreenControl(false), fRedReader(nullptr), fGreenReader(nullptr), fBlueReader(nullptr), fCurrentScale(kLin)
- {}
+ // -- widget's layouts
- virtual ~APIUI()
- {
- for (const auto& it : fItems) delete it.fConversion;
- for (int i = 0; i < 3; i++) {
- for (const auto& it : fAcc[i]) delete it;
- for (const auto& it : fGyr[i]) delete it;
+ virtual void openTabBox(const char* label) { pushLabel(label); }
+ virtual void openHorizontalBox(const char* label) { pushLabel(label); }
+ virtual void openVerticalBox(const char* label) { pushLabel(label); }
+ virtual void closeBox()
+ {
+ if (popLabel()) {
+ // Shortnames can be computed when all fullnames are known
+ computeShortNames();
+ // Fill 'shortname' field for each item
+ for (const auto& it : fFull2Short) {
+ int index = getParamIndex(it.first.c_str());
+ fItems[index].fShortname = it.second;
}
- delete fRedReader;
- delete fGreenReader;
- delete fBlueReader;
}
+ }
- // -- widget's layouts
+ // -- active widgets
- virtual void openTabBox(const char* label) { pushLabel(label); }
- virtual void openHorizontalBox(const char* label) { pushLabel(label); }
- virtual void openVerticalBox(const char* label) { pushLabel(label); }
- virtual void closeBox()
- {
- if (popLabel()) {
- // Shortnames can be computed when all fullnames are known
- computeShortNames();
- // Fill 'shortname' field for each item
- for (const auto& it : fFull2Short) {
- int index = getParamIndex(it.first.c_str());
- fItems[index].fShortname = it.second;
- }
- }
- }
+ virtual void addButton(const char* label, FAUSTFLOAT* zone)
+ {
+ addParameter(label, zone, 0, 0, 1, 1, kButton);
+ }
+
+ virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)
+ {
+ addParameter(label, zone, 0, 0, 1, 1, kCheckButton);
+ }
+
+ virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init,
+ FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+ {
+ addParameter(label, zone, init, min, max, step, kVSlider);
+ }
+
+ virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init,
+ FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+ {
+ addParameter(label, zone, init, min, max, step, kHSlider);
+ }
+
+ virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init,
+ FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+ {
+ addParameter(label, zone, init, min, max, step, kNumEntry);
+ }
- // -- active widgets
+ // -- passive widgets
- virtual void addButton(const char* label, FAUSTFLOAT* zone)
- {
- addParameter(label, zone, 0, 0, 1, 1, kButton);
- }
+ virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone,
+ FAUSTFLOAT min, FAUSTFLOAT max)
+ {
+ addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kHBargraph);
+ }
- virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)
- {
- addParameter(label, zone, 0, 0, 1, 1, kCheckButton);
- }
+ virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min,
+ FAUSTFLOAT max)
+ {
+ addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kVBargraph);
+ }
- virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
- {
- addParameter(label, zone, init, min, max, step, kVSlider);
- }
+ // -- soundfiles
- virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
- {
- addParameter(label, zone, init, min, max, step, kHSlider);
- }
+ virtual void addSoundfile(const char* /*label*/, const char* /*filename*/,
+ Soundfile** /*sf_zone*/)
+ {
+ }
- virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
- {
- addParameter(label, zone, init, min, max, step, kNumEntry);
- }
+ // -- metadata declarations
- // -- passive widgets
+ virtual void declare(FAUSTFLOAT* /*zone*/, const char* key, const char* val)
+ {
+ // Keep metadata
+ fCurrentMetadata[key] = val;
- virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
- {
- addParameter(label, zone, min, min, max, (max-min)/1000.0f, kHBargraph);
+ if (strcmp(key, "scale") == 0) {
+ if (strcmp(val, "log") == 0) {
+ fCurrentScale = kLog;
+ } else if (strcmp(val, "exp") == 0) {
+ fCurrentScale = kExp;
+ } else {
+ fCurrentScale = kLin;
+ }
+ } else if (strcmp(key, "unit") == 0) {
+ fCurrentUnit = val;
+ } else if (strcmp(key, "acc") == 0) {
+ fCurrentAcc = val;
+ } else if (strcmp(key, "gyr") == 0) {
+ fCurrentGyr = val;
+ } else if (strcmp(key, "screencolor") == 0) {
+ fCurrentColor = val; // val = "red", "green", "blue" or "white"
+ } else if (strcmp(key, "tooltip") == 0) {
+ fCurrentTooltip = val;
}
+ }
- virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
- {
- addParameter(label, zone, min, min, max, (max-min)/1000.0f, kVBargraph);
- }
+ virtual void declare(const char* /*key*/, const char* /*val*/) {}
- // -- soundfiles
+ //-------------------------------------------------------------------------------
+ // Simple API part
+ //-------------------------------------------------------------------------------
- virtual void addSoundfile(const char* /*label*/, const char* /*filename*/, Soundfile** /*sf_zone*/) {}
+ /**
+ * Return the number of parameters in the UI.
+ *
+ * @return the number of parameters
+ */
+ int getParamsCount() { return int(fItems.size()); }
- // -- metadata declarations
+ /**
+ * Return the param index.
+ *
+ * @param str - the UI parameter label/shortname/path
+ *
+ * @return the param index
+ */
+ int getParamIndex(const char* str)
+ {
+ std::string path = std::string(str);
+ auto it = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
+ return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path);
+ });
+ return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
+ }
- virtual void declare(FAUSTFLOAT* /*zone*/, const char* key, const char* val)
- {
- // Keep metadata
- fCurrentMetadata[key] = val;
-
- if (strcmp(key, "scale") == 0) {
- if (strcmp(val, "log") == 0) {
- fCurrentScale = kLog;
- } else if (strcmp(val, "exp") == 0) {
- fCurrentScale = kExp;
- } else {
- fCurrentScale = kLin;
- }
- } else if (strcmp(key, "unit") == 0) {
- fCurrentUnit = val;
- } else if (strcmp(key, "acc") == 0) {
- fCurrentAcc = val;
- } else if (strcmp(key, "gyr") == 0) {
- fCurrentGyr = val;
- } else if (strcmp(key, "screencolor") == 0) {
- fCurrentColor = val; // val = "red", "green", "blue" or "white"
- } else if (strcmp(key, "tooltip") == 0) {
- fCurrentTooltip = val;
- }
- }
+ /**
+ * Return the param label.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param label
+ */
+ const char* getParamLabel(int p) { return fItems[uint(p)].fLabel.c_str(); }
- virtual void declare(const char* /*key*/, const char* /*val*/)
- {}
-
- //-------------------------------------------------------------------------------
- // Simple API part
- //-------------------------------------------------------------------------------
-
- /**
- * Return the number of parameters in the UI.
- *
- * @return the number of parameters
- */
- int getParamsCount() { return int(fItems.size()); }
-
- /**
- * Return the param index.
- *
- * @param str - the UI parameter label/shortname/path
- *
- * @return the param index
- */
- int getParamIndex(const char* str)
- {
- std::string path = std::string(str);
- auto it = find_if(fItems.begin(), fItems.end(),
- [=](const Item& it) { return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path); });
- return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
- }
-
- /**
- * Return the param label.
- *
- * @param p - the UI parameter index
- *
- * @return the param label
- */
- const char* getParamLabel(int p) { return fItems[uint(p)].fLabel.c_str(); }
-
- /**
- * Return the param shortname.
- *
- * @param p - the UI parameter index
- *
- * @return the param shortname
- */
- const char* getParamShortname(int p) { return fItems[uint(p)].fShortname.c_str(); }
-
- /**
- * Return the param path.
- *
- * @param p - the UI parameter index
- *
- * @return the param path
- */
- const char* getParamAddress(int p) { return fItems[uint(p)].fPath.c_str(); }
-
- /**
- * Return the param metadata.
- *
- * @param p - the UI parameter index
- *
- * @return the param metadata as a map<key, value>
- */
- std::map<const char*, const char*> getMetadata(int p)
- {
- std::map<const char*, const char*> res;
- std::map<std::string, std::string> metadata = fMetaData[uint(p)];
- for (const auto& it : metadata) {
- res[it.first.c_str()] = it.second.c_str();
- }
- return res;
- }
+ /**
+ * Return the param shortname.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param shortname
+ */
+ const char* getParamShortname(int p) { return fItems[uint(p)].fShortname.c_str(); }
- /**
- * Return the param metadata value.
- *
- * @param p - the UI parameter index
- * @param key - the UI parameter index
- *
- * @return the param metadata value associate to the key
- */
- const char* getMetadata(int p, const char* key)
- {
- return (fMetaData[uint(p)].find(key) != fMetaData[uint(p)].end()) ? fMetaData[uint(p)][key].c_str() : "";
- }
-
- /**
- * Return the param minimum value.
- *
- * @param p - the UI parameter index
- *
- * @return the param minimum value
- */
- FAUSTFLOAT getParamMin(int p) { return fItems[uint(p)].fMin; }
-
- /**
- * Return the param maximum value.
- *
- * @param p - the UI parameter index
- *
- * @return the param maximum value
- */
- FAUSTFLOAT getParamMax(int p) { return fItems[uint(p)].fMax; }
-
- /**
- * Return the param step value.
- *
- * @param p - the UI parameter index
- *
- * @return the param step value
- */
- FAUSTFLOAT getParamStep(int p) { return fItems[uint(p)].fStep; }
-
- /**
- * Return the param init value.
- *
- * @param p - the UI parameter index
- *
- * @return the param init value
- */
- FAUSTFLOAT getParamInit(int p) { return fItems[uint(p)].fInit; }
-
- /**
- * Return the param memory zone.
- *
- * @param p - the UI parameter index
- *
- * @return the param memory zone.
- */
- FAUSTFLOAT* getParamZone(int p) { return fItems[uint(p)].fZone; }
-
- /**
- * Return the param value.
- *
- * @param p - the UI parameter index
- *
- * @return the param value.
- */
- FAUSTFLOAT getParamValue(int p) { return *fItems[uint(p)].fZone; }
-
- /**
- * Return the param value.
- *
- * @param str - the UI parameter label/shortname/path
- *
- * @return the param value.
- */
- FAUSTFLOAT getParamValue(const char* str)
- {
- int index = getParamIndex(str);
- if (index >= 0) {
- return getParamValue(index);
- } else {
- fprintf(stderr, "getParamValue : '%s' not found\n", (str == nullptr ? "NULL" : str));
- return FAUSTFLOAT(0);
- }
- }
+ /**
+ * Return the param path.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param path
+ */
+ const char* getParamAddress(int p) { return fItems[uint(p)].fPath.c_str(); }
- /**
- * Set the param value.
- *
- * @param p - the UI parameter index
- * @param v - the UI parameter value
- *
- */
- void setParamValue(int p, FAUSTFLOAT v) { *fItems[uint(p)].fZone = v; }
-
- /**
- * Set the param value.
- *
- * @param p - the UI parameter label/shortname/path
- * @param v - the UI parameter value
- *
- */
- void setParamValue(const char* path, FAUSTFLOAT v)
- {
- int index = getParamIndex(path);
- if (index >= 0) {
- setParamValue(index, v);
- } else {
- fprintf(stderr, "setParamValue : '%s' not found\n", (path == nullptr ? "NULL" : path));
- }
+ /**
+ * Return the param metadata.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param metadata as a map<key, value>
+ */
+ std::map<const char*, const char*> getMetadata(int p)
+ {
+ std::map<const char*, const char*> res;
+ std::map<std::string, std::string> metadata = fMetaData[uint(p)];
+ for (const auto& it : metadata) {
+ res[it.first.c_str()] = it.second.c_str();
}
+ return res;
+ }
- double getParamRatio(int p) { return fItems[uint(p)].fConversion->faust2ui(*fItems[uint(p)].fZone); }
- void setParamRatio(int p, double r) { *fItems[uint(p)].fZone = FAUSTFLOAT(fItems[uint(p)].fConversion->ui2faust(r)); }
+ /**
+ * Return the param metadata value.
+ *
+ * @param p - the UI parameter index
+ * @param key - the UI parameter index
+ *
+ * @return the param metadata value associate to the key
+ */
+ const char* getMetadata(int p, const char* key)
+ {
+ return (fMetaData[uint(p)].find(key) != fMetaData[uint(p)].end())
+ ? fMetaData[uint(p)][key].c_str()
+ : "";
+ }
- double value2ratio(int p, double r) { return fItems[uint(p)].fConversion->faust2ui(r); }
- double ratio2value(int p, double r) { return fItems[uint(p)].fConversion->ui2faust(r); }
+ /**
+ * Return the param minimum value.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param minimum value
+ */
+ FAUSTFLOAT getParamMin(int p) { return fItems[uint(p)].fMin; }
- /**
- * Return the control type (kAcc, kGyr, or -1) for a given parameter.
- *
- * @param p - the UI parameter index
- *
- * @return the type
- */
- Type getParamType(int p)
- {
- if (p >= 0) {
- if (getZoneIndex(fAcc, p, 0) != -1
- || getZoneIndex(fAcc, p, 1) != -1
- || getZoneIndex(fAcc, p, 2) != -1) {
- return kAcc;
- } else if (getZoneIndex(fGyr, p, 0) != -1
- || getZoneIndex(fGyr, p, 1) != -1
- || getZoneIndex(fGyr, p, 2) != -1) {
- return kGyr;
- }
- }
- return kNoType;
- }
+ /**
+ * Return the param maximum value.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param maximum value
+ */
+ FAUSTFLOAT getParamMax(int p) { return fItems[uint(p)].fMax; }
- /**
- * Return the Item type (kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry, kHBargraph, kVBargraph) for a given parameter.
- *
- * @param p - the UI parameter index
- *
- * @return the Item type
- */
- ItemType getParamItemType(int p)
- {
- return fItems[uint(p)].fItemType;
- }
+ /**
+ * Return the param step value.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param step value
+ */
+ FAUSTFLOAT getParamStep(int p) { return fItems[uint(p)].fStep; }
- /**
- * Set a new value coming from an accelerometer, propagate it to all relevant FAUSTFLOAT* zones.
- *
- * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
- * @param value - the new value
- *
- */
- void propagateAcc(int acc, double value)
- {
- for (size_t i = 0; i < fAcc[acc].size(); i++) {
- fAcc[acc][i]->update(value);
- }
- }
+ /**
+ * Return the param init value.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param init value
+ */
+ FAUSTFLOAT getParamInit(int p) { return fItems[uint(p)].fInit; }
- /**
- * Used to edit accelerometer curves and mapping. Set curve and related mapping for a given UI parameter.
- *
- * @param p - the UI parameter index
- * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer (-1 means "no mapping")
- * @param curve - between 0 and 3 (0: up, 1: down, 2: up and down, 2: down and up)
- * @param amin - mapping 'min' point
- * @param amid - mapping 'middle' point
- * @param amax - mapping 'max' point
- *
- */
- void setAccConverter(int p, int acc, int curve, double amin, double amid, double amax)
- {
- setConverter(fAcc, p, acc, curve, amin, amid, amax);
- }
+ /**
+ * Return the param memory zone.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param memory zone.
+ */
+ FAUSTFLOAT* getParamZone(int p) { return fItems[uint(p)].fZone; }
- /**
- * Used to edit gyroscope curves and mapping. Set curve and related mapping for a given UI parameter.
- *
- * @param p - the UI parameter index
- * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no mapping")
- * @param curve - between 0 and 3 (0: up, 1: down, 2: up and down, 2: down and up)
- * @param amin - mapping 'min' point
- * @param amid - mapping 'middle' point
- * @param amax - mapping 'max' point
- *
- */
- void setGyrConverter(int p, int gyr, int curve, double amin, double amid, double amax)
- {
- setConverter(fGyr, p, gyr, curve, amin, amid, amax);
- }
+ /**
+ * Return the param value.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param value.
+ */
+ FAUSTFLOAT getParamValue(int p) { return *fItems[uint(p)].fZone; }
- /**
- * Used to edit accelerometer curves and mapping. Get curve and related mapping for a given UI parameter.
- *
- * @param p - the UI parameter index
- * @param acc - the acc value to be retrieved (-1 means "no mapping")
- * @param curve - the curve value to be retrieved (between 0 and 3)
- * @param amin - the amin value to be retrieved
- * @param amid - the amid value to be retrieved
- * @param amax - the amax value to be retrieved
- *
- */
- void getAccConverter(int p, int& acc, int& curve, double& amin, double& amid, double& amax)
- {
- getConverter(fAcc, p, acc, curve, amin, amid, amax);
+ /**
+ * Return the param value.
+ *
+ * @param str - the UI parameter label/shortname/path
+ *
+ * @return the param value.
+ */
+ FAUSTFLOAT getParamValue(const char* str)
+ {
+ int index = getParamIndex(str);
+ if (index >= 0) {
+ return getParamValue(index);
+ } else {
+ fprintf(stderr, "getParamValue : '%s' not found\n",
+ (str == nullptr ? "NULL" : str));
+ return FAUSTFLOAT(0);
}
+ }
- /**
- * Used to edit gyroscope curves and mapping. Get curve and related mapping for a given UI parameter.
- *
- * @param p - the UI parameter index
- * @param gyr - the gyr value to be retrieved (-1 means "no mapping")
- * @param curve - the curve value to be retrieved (between 0 and 3)
- * @param amin - the amin value to be retrieved
- * @param amid - the amid value to be retrieved
- * @param amax - the amax value to be retrieved
- *
- */
- void getGyrConverter(int p, int& gyr, int& curve, double& amin, double& amid, double& amax)
- {
- getConverter(fGyr, p, gyr, curve, amin, amid, amax);
+ /**
+ * Set the param value.
+ *
+ * @param p - the UI parameter index
+ * @param v - the UI parameter value
+ *
+ */
+ void setParamValue(int p, FAUSTFLOAT v) { *fItems[uint(p)].fZone = v; }
+
+ /**
+ * Set the param value.
+ *
+ * @param p - the UI parameter label/shortname/path
+ * @param v - the UI parameter value
+ *
+ */
+ void setParamValue(const char* path, FAUSTFLOAT v)
+ {
+ int index = getParamIndex(path);
+ if (index >= 0) {
+ setParamValue(index, v);
+ } else {
+ fprintf(stderr, "setParamValue : '%s' not found\n",
+ (path == nullptr ? "NULL" : path));
}
+ }
+
+ double getParamRatio(int p)
+ {
+ return fItems[uint(p)].fConversion->faust2ui(*fItems[uint(p)].fZone);
+ }
+ void setParamRatio(int p, double r)
+ {
+ *fItems[uint(p)].fZone = FAUSTFLOAT(fItems[uint(p)].fConversion->ui2faust(r));
+ }
+
+ double value2ratio(int p, double r)
+ {
+ return fItems[uint(p)].fConversion->faust2ui(r);
+ }
+ double ratio2value(int p, double r)
+ {
+ return fItems[uint(p)].fConversion->ui2faust(r);
+ }
- /**
- * Set a new value coming from an gyroscope, propagate it to all relevant FAUSTFLOAT* zones.
- *
- * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
- * @param value - the new value
- *
- */
- void propagateGyr(int gyr, double value)
- {
- for (size_t i = 0; i < fGyr[gyr].size(); i++) {
- fGyr[gyr][i]->update(value);
+ /**
+ * Return the control type (kAcc, kGyr, or -1) for a given parameter.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the type
+ */
+ Type getParamType(int p)
+ {
+ if (p >= 0) {
+ if (getZoneIndex(fAcc, p, 0) != -1 || getZoneIndex(fAcc, p, 1) != -1
+ || getZoneIndex(fAcc, p, 2) != -1) {
+ return kAcc;
+ } else if (getZoneIndex(fGyr, p, 0) != -1 || getZoneIndex(fGyr, p, 1) != -1
+ || getZoneIndex(fGyr, p, 2) != -1) {
+ return kGyr;
}
}
+ return kNoType;
+ }
- /**
- * Get the number of FAUSTFLOAT* zones controlled with the accelerometer.
- *
- * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
- * @return the number of zones
- *
- */
- int getAccCount(int acc)
- {
- return (acc >= 0 && acc < 3) ? int(fAcc[acc].size()) : 0;
- }
+ /**
+ * Return the Item type (kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry,
+ * kHBargraph, kVBargraph) for a given parameter.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the Item type
+ */
+ ItemType getParamItemType(int p) { return fItems[uint(p)].fItemType; }
- /**
- * Get the number of FAUSTFLOAT* zones controlled with the gyroscope.
- *
- * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
- * @param the number of zones
- *
- */
- int getGyrCount(int gyr)
- {
- return (gyr >= 0 && gyr < 3) ? int(fGyr[gyr].size()) : 0;
+ /**
+ * Set a new value coming from an accelerometer, propagate it to all relevant
+ * FAUSTFLOAT* zones.
+ *
+ * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
+ * @param value - the new value
+ *
+ */
+ void propagateAcc(int acc, double value)
+ {
+ for (size_t i = 0; i < fAcc[acc].size(); i++) {
+ fAcc[acc][i]->update(value);
}
+ }
- /**
- * Get the requested screen color.
- *
- * -1 means no screen color control (no screencolor metadata found)
- * otherwise return 0x00RRGGBB a ready to use color
- *
- */
- int getScreenColor()
- {
- if (fHasScreenControl) {
- int r = (fRedReader) ? fRedReader->getValue() : 0;
- int g = (fGreenReader) ? fGreenReader->getValue() : 0;
- int b = (fBlueReader) ? fBlueReader->getValue() : 0;
- return (r<<16) | (g<<8) | b;
- } else {
- return -1;
- }
+ /**
+ * Used to edit accelerometer curves and mapping. Set curve and related mapping for a
+ * given UI parameter.
+ *
+ * @param p - the UI parameter index
+ * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
+ * (-1 means "no mapping")
+ * @param curve - between 0 and 3 (0: up, 1: down, 2: up and down, 2: down and up)
+ * @param amin - mapping 'min' point
+ * @param amid - mapping 'middle' point
+ * @param amax - mapping 'max' point
+ *
+ */
+ void setAccConverter(int p, int acc, int curve, double amin, double amid, double amax)
+ {
+ setConverter(fAcc, p, acc, curve, amin, amid, amax);
+ }
+
+ /**
+ * Used to edit gyroscope curves and mapping. Set curve and related mapping for a
+ * given UI parameter.
+ *
+ * @param p - the UI parameter index
+ * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no
+ * mapping")
+ * @param curve - between 0 and 3 (0: up, 1: down, 2: up and down, 2: down and up)
+ * @param amin - mapping 'min' point
+ * @param amid - mapping 'middle' point
+ * @param amax - mapping 'max' point
+ *
+ */
+ void setGyrConverter(int p, int gyr, int curve, double amin, double amid, double amax)
+ {
+ setConverter(fGyr, p, gyr, curve, amin, amid, amax);
+ }
+
+ /**
+ * Used to edit accelerometer curves and mapping. Get curve and related mapping for a
+ * given UI parameter.
+ *
+ * @param p - the UI parameter index
+ * @param acc - the acc value to be retrieved (-1 means "no mapping")
+ * @param curve - the curve value to be retrieved (between 0 and 3)
+ * @param amin - the amin value to be retrieved
+ * @param amid - the amid value to be retrieved
+ * @param amax - the amax value to be retrieved
+ *
+ */
+ void getAccConverter(int p, int& acc, int& curve, double& amin, double& amid,
+ double& amax)
+ {
+ getConverter(fAcc, p, acc, curve, amin, amid, amax);
+ }
+
+ /**
+ * Used to edit gyroscope curves and mapping. Get curve and related mapping for a
+ * given UI parameter.
+ *
+ * @param p - the UI parameter index
+ * @param gyr - the gyr value to be retrieved (-1 means "no mapping")
+ * @param curve - the curve value to be retrieved (between 0 and 3)
+ * @param amin - the amin value to be retrieved
+ * @param amid - the amid value to be retrieved
+ * @param amax - the amax value to be retrieved
+ *
+ */
+ void getGyrConverter(int p, int& gyr, int& curve, double& amin, double& amid,
+ double& amax)
+ {
+ getConverter(fGyr, p, gyr, curve, amin, amid, amax);
+ }
+
+ /**
+ * Set a new value coming from an gyroscope, propagate it to all relevant FAUSTFLOAT*
+ * zones.
+ *
+ * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
+ * @param value - the new value
+ *
+ */
+ void propagateGyr(int gyr, double value)
+ {
+ for (size_t i = 0; i < fGyr[gyr].size(); i++) {
+ fGyr[gyr][i]->update(value);
}
+ }
+ /**
+ * Get the number of FAUSTFLOAT* zones controlled with the accelerometer.
+ *
+ * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
+ * @return the number of zones
+ *
+ */
+ int getAccCount(int acc) { return (acc >= 0 && acc < 3) ? int(fAcc[acc].size()) : 0; }
+
+ /**
+ * Get the number of FAUSTFLOAT* zones controlled with the gyroscope.
+ *
+ * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
+ * @param the number of zones
+ *
+ */
+ int getGyrCount(int gyr) { return (gyr >= 0 && gyr < 3) ? int(fGyr[gyr].size()) : 0; }
+
+ /**
+ * Get the requested screen color.
+ *
+ * -1 means no screen color control (no screencolor metadata found)
+ * otherwise return 0x00RRGGBB a ready to use color
+ *
+ */
+ int getScreenColor()
+ {
+ if (fHasScreenControl) {
+ int r = (fRedReader) ? fRedReader->getValue() : 0;
+ int g = (fGreenReader) ? fGreenReader->getValue() : 0;
+ int b = (fBlueReader) ? fBlueReader->getValue() : 0;
+ return (r << 16) | (g << 8) | b;
+ } else {
+ return -1;
+ }
+ }
};
#endif
// FAUST Generated Code
//----------------------------------------------------------------------------
-
#ifndef FAUSTFLOAT
#define FAUSTFLOAT float
-#endif
+#endif
+
+#include <math.h>
#include <algorithm>
#include <cmath>
#include <cstdint>
-#include <math.h>
-#ifndef FAUSTCLASS
+#ifndef FAUSTCLASS
#define FAUSTCLASS monitordsp
#endif
-#ifdef __APPLE__
+#ifdef __APPLE__
#define exp10f __exp10f
-#define exp10 __exp10
+#define exp10 __exp10
#endif
#if defined(_WIN32)
#define RESTRICT __restrict__
#endif
-
-class monitordsp : public dsp {
-
- private:
-
- FAUSTFLOAT fHslider0;
- FAUSTFLOAT fCheckbox0;
- int fSampleRate;
- float fConst0;
- float fConst1;
- float fRec0[2];
-
- public:
-
- void metadata(Meta* m) {
- m->declare("author", "Dominick Hing, adapted from 'Volume Control' by Matt Horton");
- m->declare("basics.lib/name", "Faust Basic Element Library");
- m->declare("basics.lib/version", "0.9");
- m->declare("compile_options", "-a faust2header.cpp -lang cpp -i -inpl -cn monitordsp -es 1 -mcd 16 -single -ftz 0");
- m->declare("description", "Volume Control Faust Plugin for JackTrip, based on Faust examples");
- m->declare("filename", "monitordsp.dsp");
- m->declare("license", "MIT Style STK-4.2");
- m->declare("maths.lib/author", "GRAME");
- m->declare("maths.lib/copyright", "GRAME");
- m->declare("maths.lib/license", "LGPL with exception");
- m->declare("maths.lib/name", "Faust Math Library");
- m->declare("maths.lib/version", "2.5");
- m->declare("name", "monitor");
- m->declare("platform.lib/name", "Generic Platform Library");
- m->declare("platform.lib/version", "0.3");
- m->declare("signals.lib/name", "Faust Signal Routing Library");
- m->declare("signals.lib/version", "0.3");
- m->declare("version", "1.0");
- }
-
- virtual int getNumInputs() {
- return 2;
- }
- virtual int getNumOutputs() {
- return 1;
- }
-
- static void classInit(int /*sample_rate*/) {
- }
-
- virtual void instanceConstants(int sample_rate) {
- fSampleRate = sample_rate;
- fConst0 = 44.1f / std::min<float>(1.92e+05f, std::max<float>(1.0f, float(fSampleRate)));
- fConst1 = 1.0f - fConst0;
- }
-
- virtual void instanceResetUserInterface() {
- fHslider0 = FAUSTFLOAT(0.0f);
- fCheckbox0 = FAUSTFLOAT(0.0f);
- }
-
- virtual void instanceClear() {
- for (int l0 = 0; l0 < 2; l0 = l0 + 1) {
- fRec0[l0] = 0.0f;
- }
- }
-
- virtual void init(int sample_rate) {
- classInit(sample_rate);
- instanceInit(sample_rate);
- }
- virtual void instanceInit(int sample_rate) {
- instanceConstants(sample_rate);
- instanceResetUserInterface();
- instanceClear();
- }
-
- virtual monitordsp* clone() {
- return new monitordsp();
- }
-
- virtual int getSampleRate() {
- return fSampleRate;
- }
-
- virtual void buildUserInterface(UI* ui_interface) {
- ui_interface->openVerticalBox("Monitor");
- ui_interface->declare(&fHslider0, "0", "");
- ui_interface->addHorizontalSlider("Volume", &fHslider0, FAUSTFLOAT(0.0f), FAUSTFLOAT(-4e+01f), FAUSTFLOAT(0.0f), FAUSTFLOAT(0.1f));
- ui_interface->declare(&fCheckbox0, "1", "");
- ui_interface->addCheckButton("Mute", &fCheckbox0);
- ui_interface->closeBox();
- }
-
- virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {
- FAUSTFLOAT* input0 = inputs[0];
- FAUSTFLOAT* input1 = inputs[1];
- FAUSTFLOAT* output0 = outputs[0];
- float fSlow0 = float(fHslider0);
- int iSlow1 = fSlow0 == -4e+01f;
- int iSlow2 = int(float(fCheckbox0));
- float fSlow3 = fConst0 * std::pow(1e+01f, 0.05f * fSlow0);
- for (int i0 = 0; i0 < count; i0 = i0 + 1) {
- float fTemp0 = float(input1[i0]);
- float fTemp1 = float(input0[i0]);
- fRec0[0] = fSlow3 + fConst1 * fRec0[1];
- output0[i0] = FAUSTFLOAT(fTemp0 + ((iSlow1) ? 0.0f : ((iSlow2) ? 0.0f : fTemp1 * fRec0[0])));
- fRec0[1] = fRec0[0];
- }
- }
-
+class monitordsp : public dsp
+{
+ private:
+ FAUSTFLOAT fHslider0;
+ FAUSTFLOAT fCheckbox0;
+ int fSampleRate;
+ float fConst0;
+ float fConst1;
+ float fRec0[2];
+
+ public:
+ void metadata(Meta* m)
+ {
+ m->declare("author",
+ "Dominick Hing, adapted from 'Volume Control' by Matt Horton");
+ m->declare("basics.lib/name", "Faust Basic Element Library");
+ m->declare("basics.lib/version", "0.9");
+ m->declare("compile_options",
+ "-a faust2header.cpp -lang cpp -i -inpl -cn monitordsp -es 1 -mcd 16 "
+ "-single -ftz 0");
+ m->declare("description",
+ "Volume Control Faust Plugin for JackTrip, based on Faust examples");
+ m->declare("filename", "monitordsp.dsp");
+ m->declare("license", "MIT Style STK-4.2");
+ m->declare("maths.lib/author", "GRAME");
+ m->declare("maths.lib/copyright", "GRAME");
+ m->declare("maths.lib/license", "LGPL with exception");
+ m->declare("maths.lib/name", "Faust Math Library");
+ m->declare("maths.lib/version", "2.5");
+ m->declare("name", "monitor");
+ m->declare("platform.lib/name", "Generic Platform Library");
+ m->declare("platform.lib/version", "0.3");
+ m->declare("signals.lib/name", "Faust Signal Routing Library");
+ m->declare("signals.lib/version", "0.3");
+ m->declare("version", "1.0");
+ }
+
+ virtual int getNumInputs() { return 2; }
+ virtual int getNumOutputs() { return 1; }
+
+ static void classInit(int /*sample_rate*/) {}
+
+ virtual void instanceConstants(int sample_rate)
+ {
+ fSampleRate = sample_rate;
+ fConst0 =
+ 44.1f / std::min<float>(1.92e+05f, std::max<float>(1.0f, float(fSampleRate)));
+ fConst1 = 1.0f - fConst0;
+ }
+
+ virtual void instanceResetUserInterface()
+ {
+ fHslider0 = FAUSTFLOAT(0.0f);
+ fCheckbox0 = FAUSTFLOAT(0.0f);
+ }
+
+ virtual void instanceClear()
+ {
+ for (int l0 = 0; l0 < 2; l0 = l0 + 1) {
+ fRec0[l0] = 0.0f;
+ }
+ }
+
+ virtual void init(int sample_rate)
+ {
+ classInit(sample_rate);
+ instanceInit(sample_rate);
+ }
+ virtual void instanceInit(int sample_rate)
+ {
+ instanceConstants(sample_rate);
+ instanceResetUserInterface();
+ instanceClear();
+ }
+
+ virtual monitordsp* clone() { return new monitordsp(); }
+
+ virtual int getSampleRate() { return fSampleRate; }
+
+ virtual void buildUserInterface(UI* ui_interface)
+ {
+ ui_interface->openVerticalBox("Monitor");
+ ui_interface->declare(&fHslider0, "0", "");
+ ui_interface->addHorizontalSlider("Volume", &fHslider0, FAUSTFLOAT(0.0f),
+ FAUSTFLOAT(-4e+01f), FAUSTFLOAT(0.0f),
+ FAUSTFLOAT(0.1f));
+ ui_interface->declare(&fCheckbox0, "1", "");
+ ui_interface->addCheckButton("Mute", &fCheckbox0);
+ ui_interface->closeBox();
+ }
+
+ virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs)
+ {
+ FAUSTFLOAT* input0 = inputs[0];
+ FAUSTFLOAT* input1 = inputs[1];
+ FAUSTFLOAT* output0 = outputs[0];
+ float fSlow0 = float(fHslider0);
+ int iSlow1 = fSlow0 == -4e+01f;
+ int iSlow2 = int(float(fCheckbox0));
+ float fSlow3 = fConst0 * std::pow(1e+01f, 0.05f * fSlow0);
+ for (int i0 = 0; i0 < count; i0 = i0 + 1) {
+ float fTemp0 = float(input1[i0]);
+ float fTemp1 = float(input0[i0]);
+ fRec0[0] = fSlow3 + fConst1 * fRec0[1];
+ output0[i0] = FAUSTFLOAT(
+ fTemp0 + ((iSlow1) ? 0.0f : ((iSlow2) ? 0.0f : fTemp1 * fRec0[0])));
+ fRec0[1] = fRec0[0];
+ }
+ }
};
-
#endif
name: "stereo-to-mono"
version: "1.0"
Code generated with Faust 2.50.6 (https://faust.grame.fr)
-Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn stereotomonodsp -es 1 -mcd 16 -single -ftz 0
+Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn stereotomonodsp -es 1 -mcd
+16 -single -ftz 0
------------------------------------------------------------ */
-#ifndef __stereotomonodsp_H__
-#define __stereotomonodsp_H__
+#ifndef __stereotomonodsp_H__
+#define __stereotomonodsp_H__
// NOTE: ANY INCLUDE-GUARD HERE MUST BE DERIVED FROM THE CLASS NAME
//
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
#define FAUSTVERSION "2.50.6"
-// Use FAUST_API for code that is part of the external API but is also compiled in faust and libfaust
-// Use LIBFAUST_API for code that is compiled in faust and libfaust
+// Use FAUST_API for code that is part of the external API but is also compiled in faust
+// and libfaust Use LIBFAUST_API for code that is compiled in faust and libfaust
#ifdef _WIN32
- #pragma warning (disable: 4251)
- #ifdef FAUST_EXE
- #define FAUST_API
- #define LIBFAUST_API
- #elif FAUST_LIB
- #define FAUST_API __declspec(dllexport)
- #define LIBFAUST_API __declspec(dllexport)
- #else
- #define FAUST_API
- #define LIBFAUST_API
- #endif
+#pragma warning(disable : 4251)
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#elif FAUST_LIB
+#define FAUST_API __declspec(dllexport)
+#define LIBFAUST_API __declspec(dllexport)
+#else
+#define FAUST_API
+#define LIBFAUST_API
+#endif
+#else
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
#else
- #ifdef FAUST_EXE
- #define FAUST_API
- #define LIBFAUST_API
- #else
- #define FAUST_API __attribute__((visibility("default")))
- #define LIBFAUST_API __attribute__((visibility("default")))
- #endif
+#define FAUST_API __attribute__((visibility("default")))
+#define LIBFAUST_API __attribute__((visibility("default")))
+#endif
#endif
#endif
*/
struct FAUST_API dsp_memory_manager {
-
virtual ~dsp_memory_manager() {}
-
+
/**
* Inform the Memory Manager with the number of expected memory zones.
* @param count - the number of expected memory zones
*/
virtual void begin(size_t /* count */) {}
-
+
/**
* Give the Memory Manager information on a given memory zone.
* @param size - the size in bytes of the memory zone
* @param writes - the number of Write access to the zone used to compute one frame
*/
virtual void info(size_t /* size */, size_t /* reads */, size_t /* writes */) {}
-
+
/**
* Inform the Memory Manager that all memory zones have been described,
* to possibly start a 'compute the best allocation strategy' step.
*/
virtual void end() {}
-
+
/**
* Allocate a memory zone.
* @param size - the memory zone size in bytes
*/
virtual void* allocate(size_t size) = 0;
-
+
/**
* Destroy a memory zone.
* @param ptr - the memory zone pointer to be deallocated
*/
virtual void destroy(void* ptr) = 0;
-
-};
-
-/**
-* Signal processor definition.
-*/
-
-class FAUST_API dsp {
-
- public:
-
- dsp() {}
- virtual ~dsp() {}
-
- /* Return instance number of audio inputs */
- virtual int getNumInputs() = 0;
-
- /* Return instance number of audio outputs */
- virtual int getNumOutputs() = 0;
-
- /**
- * Trigger the ui_interface parameter with instance specific calls
- * to 'openTabBox', 'addButton', 'addVerticalSlider'... in order to build the UI.
- *
- * @param ui_interface - the user interface builder
- */
- virtual void buildUserInterface(UI* ui_interface) = 0;
-
- /* Return the sample rate currently used by the instance */
- virtual int getSampleRate() = 0;
-
- /**
- * Global init, calls the following methods:
- * - static class 'classInit': static tables initialization
- * - 'instanceInit': constants and instance state initialization
- *
- * @param sample_rate - the sampling rate in Hz
- */
- virtual void init(int sample_rate) = 0;
-
- /**
- * Init instance state
- *
- * @param sample_rate - the sampling rate in Hz
- */
- virtual void instanceInit(int sample_rate) = 0;
-
- /**
- * Init instance constant state
- *
- * @param sample_rate - the sampling rate in Hz
- */
- virtual void instanceConstants(int sample_rate) = 0;
-
- /* Init default control parameters values */
- virtual void instanceResetUserInterface() = 0;
-
- /* Init instance state (like delay lines...) but keep the control parameter values */
- virtual void instanceClear() = 0;
-
- /**
- * Return a clone of the instance.
- *
- * @return a copy of the instance on success, otherwise a null pointer.
- */
- virtual dsp* clone() = 0;
-
- /**
- * Trigger the Meta* parameter with instance specific calls to 'declare' (key, value) metadata.
- *
- * @param m - the Meta* meta user
- */
- virtual void metadata(Meta* m) = 0;
-
- /**
- * DSP instance computation, to be called with successive in/out audio buffers.
- *
- * @param count - the number of frames to compute
- * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT samples (eiher float, double or quad)
- * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT samples (eiher float, double or quad)
- *
- */
- virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) = 0;
-
- /**
- * DSP instance computation: alternative method to be used by subclasses.
- *
- * @param date_usec - the timestamp in microsec given by audio driver.
- * @param count - the number of frames to compute
- * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT samples (either float, double or quad)
- * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT samples (either float, double or quad)
- *
- */
- virtual void compute(double /*date_usec*/, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { compute(count, inputs, outputs); }
-
};
/**
- * Generic DSP decorator.
+ * Signal processor definition.
*/
-class FAUST_API decorator_dsp : public dsp {
+class FAUST_API dsp
+{
+ public:
+ dsp() {}
+ virtual ~dsp() {}
+
+ /* Return instance number of audio inputs */
+ virtual int getNumInputs() = 0;
+
+ /* Return instance number of audio outputs */
+ virtual int getNumOutputs() = 0;
+
+ /**
+ * Trigger the ui_interface parameter with instance specific calls
+ * to 'openTabBox', 'addButton', 'addVerticalSlider'... in order to build the UI.
+ *
+ * @param ui_interface - the user interface builder
+ */
+ virtual void buildUserInterface(UI* ui_interface) = 0;
+
+ /* Return the sample rate currently used by the instance */
+ virtual int getSampleRate() = 0;
+
+ /**
+ * Global init, calls the following methods:
+ * - static class 'classInit': static tables initialization
+ * - 'instanceInit': constants and instance state initialization
+ *
+ * @param sample_rate - the sampling rate in Hz
+ */
+ virtual void init(int sample_rate) = 0;
+
+ /**
+ * Init instance state
+ *
+ * @param sample_rate - the sampling rate in Hz
+ */
+ virtual void instanceInit(int sample_rate) = 0;
+
+ /**
+ * Init instance constant state
+ *
+ * @param sample_rate - the sampling rate in Hz
+ */
+ virtual void instanceConstants(int sample_rate) = 0;
- protected:
+ /* Init default control parameters values */
+ virtual void instanceResetUserInterface() = 0;
- dsp* fDSP;
+ /* Init instance state (like delay lines...) but keep the control parameter values */
+ virtual void instanceClear() = 0;
- public:
+ /**
+ * Return a clone of the instance.
+ *
+ * @return a copy of the instance on success, otherwise a null pointer.
+ */
+ virtual dsp* clone() = 0;
- decorator_dsp(dsp* dsp = nullptr):fDSP(dsp) {}
- virtual ~decorator_dsp() { delete fDSP; }
+ /**
+ * Trigger the Meta* parameter with instance specific calls to 'declare' (key, value)
+ * metadata.
+ *
+ * @param m - the Meta* meta user
+ */
+ virtual void metadata(Meta* m) = 0;
- virtual int getNumInputs() { return fDSP->getNumInputs(); }
- virtual int getNumOutputs() { return fDSP->getNumOutputs(); }
- virtual void buildUserInterface(UI* ui_interface) { fDSP->buildUserInterface(ui_interface); }
- virtual int getSampleRate() { return fDSP->getSampleRate(); }
- virtual void init(int sample_rate) { fDSP->init(sample_rate); }
- virtual void instanceInit(int sample_rate) { fDSP->instanceInit(sample_rate); }
- virtual void instanceConstants(int sample_rate) { fDSP->instanceConstants(sample_rate); }
- virtual void instanceResetUserInterface() { fDSP->instanceResetUserInterface(); }
- virtual void instanceClear() { fDSP->instanceClear(); }
- virtual decorator_dsp* clone() { return new decorator_dsp(fDSP->clone()); }
- virtual void metadata(Meta* m) { fDSP->metadata(m); }
- // Beware: subclasses usually have to overload the two 'compute' methods
- virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { fDSP->compute(count, inputs, outputs); }
- virtual void compute(double date_usec, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { fDSP->compute(date_usec, count, inputs, outputs); }
-
+ /**
+ * DSP instance computation, to be called with successive in/out audio buffers.
+ *
+ * @param count - the number of frames to compute
+ * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT
+ * samples (eiher float, double or quad)
+ * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT
+ * samples (eiher float, double or quad)
+ *
+ */
+ virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) = 0;
+
+ /**
+ * DSP instance computation: alternative method to be used by subclasses.
+ *
+ * @param date_usec - the timestamp in microsec given by audio driver.
+ * @param count - the number of frames to compute
+ * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT
+ * samples (either float, double or quad)
+ * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT
+ * samples (either float, double or quad)
+ *
+ */
+ virtual void compute(double /*date_usec*/, int count, FAUSTFLOAT** inputs,
+ FAUSTFLOAT** outputs)
+ {
+ compute(count, inputs, outputs);
+ }
+};
+
+/**
+ * Generic DSP decorator.
+ */
+
+class FAUST_API decorator_dsp : public dsp
+{
+ protected:
+ dsp* fDSP;
+
+ public:
+ decorator_dsp(dsp* dsp = nullptr) : fDSP(dsp) {}
+ virtual ~decorator_dsp() { delete fDSP; }
+
+ virtual int getNumInputs() { return fDSP->getNumInputs(); }
+ virtual int getNumOutputs() { return fDSP->getNumOutputs(); }
+ virtual void buildUserInterface(UI* ui_interface)
+ {
+ fDSP->buildUserInterface(ui_interface);
+ }
+ virtual int getSampleRate() { return fDSP->getSampleRate(); }
+ virtual void init(int sample_rate) { fDSP->init(sample_rate); }
+ virtual void instanceInit(int sample_rate) { fDSP->instanceInit(sample_rate); }
+ virtual void instanceConstants(int sample_rate)
+ {
+ fDSP->instanceConstants(sample_rate);
+ }
+ virtual void instanceResetUserInterface() { fDSP->instanceResetUserInterface(); }
+ virtual void instanceClear() { fDSP->instanceClear(); }
+ virtual decorator_dsp* clone() { return new decorator_dsp(fDSP->clone()); }
+ virtual void metadata(Meta* m) { fDSP->metadata(m); }
+ // Beware: subclasses usually have to overload the two 'compute' methods
+ virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs)
+ {
+ fDSP->compute(count, inputs, outputs);
+ }
+ virtual void compute(double date_usec, int count, FAUSTFLOAT** inputs,
+ FAUSTFLOAT** outputs)
+ {
+ fDSP->compute(date_usec, count, inputs, outputs);
+ }
};
/**
* to create DSP instances from a compiled DSP program.
*/
-class FAUST_API dsp_factory {
-
- protected:
-
- // So that to force sub-classes to use deleteDSPFactory(dsp_factory* factory);
- virtual ~dsp_factory() {}
-
- public:
-
- virtual std::string getName() = 0;
- virtual std::string getSHAKey() = 0;
- virtual std::string getDSPCode() = 0;
- virtual std::string getCompileOptions() = 0;
- virtual std::vector<std::string> getLibraryList() = 0;
- virtual std::vector<std::string> getIncludePathnames() = 0;
-
- virtual dsp* createDSPInstance() = 0;
-
- virtual void setMemoryManager(dsp_memory_manager* manager) = 0;
- virtual dsp_memory_manager* getMemoryManager() = 0;
-
+class FAUST_API dsp_factory
+{
+ protected:
+ // So that to force sub-classes to use deleteDSPFactory(dsp_factory* factory);
+ virtual ~dsp_factory() {}
+
+ public:
+ virtual std::string getName() = 0;
+ virtual std::string getSHAKey() = 0;
+ virtual std::string getDSPCode() = 0;
+ virtual std::string getCompileOptions() = 0;
+ virtual std::vector<std::string> getLibraryList() = 0;
+ virtual std::vector<std::string> getIncludePathnames() = 0;
+
+ virtual dsp* createDSPInstance() = 0;
+
+ virtual void setMemoryManager(dsp_memory_manager* manager) = 0;
+ virtual dsp_memory_manager* getMemoryManager() = 0;
};
// Denormal handling
-#if defined (__SSE__)
+#if defined(__SSE__)
#include <xmmintrin.h>
#endif
-class FAUST_API ScopedNoDenormals {
-
- private:
-
- intptr_t fpsr = 0;
-
- void setFpStatusRegister(intptr_t fpsr_aux) noexcept
- {
- #if defined (__arm64__) || defined (__aarch64__)
- asm volatile("msr fpcr, %0" : : "ri" (fpsr_aux));
- #elif defined (__SSE__)
- // The volatile keyword here is needed to workaround a bug in AppleClang 13.0
- // which aggressively optimises away the variable otherwise
- volatile uint32_t fpsr_w = static_cast<uint32_t>(fpsr_aux);
- _mm_setcsr(fpsr_w);
- #endif
- }
-
- void getFpStatusRegister() noexcept
- {
- #if defined (__arm64__) || defined (__aarch64__)
- asm volatile("mrs %0, fpcr" : "=r" (fpsr));
- #elif defined (__SSE__)
- fpsr = static_cast<intptr_t>(_mm_getcsr());
- #endif
- }
-
- public:
-
- ScopedNoDenormals() noexcept
- {
- #if defined (__arm64__) || defined (__aarch64__)
- intptr_t mask = (1 << 24 /* FZ */);
- #elif defined (__SSE__)
- #if defined (__SSE2__)
- intptr_t mask = 0x8040;
- #else
- intptr_t mask = 0x8000;
- #endif
- #else
- intptr_t mask = 0x0000;
- #endif
- getFpStatusRegister();
- setFpStatusRegister(fpsr | mask);
- }
-
- ~ScopedNoDenormals() noexcept
- {
- setFpStatusRegister(fpsr);
- }
+class FAUST_API ScopedNoDenormals
+{
+ private:
+ intptr_t fpsr = 0;
+
+ void setFpStatusRegister(intptr_t fpsr_aux) noexcept
+ {
+#if defined(__arm64__) || defined(__aarch64__)
+ asm volatile("msr fpcr, %0" : : "ri"(fpsr_aux));
+#elif defined(__SSE__)
+ // The volatile keyword here is needed to workaround a bug in AppleClang 13.0
+ // which aggressively optimises away the variable otherwise
+ volatile uint32_t fpsr_w = static_cast<uint32_t>(fpsr_aux);
+ _mm_setcsr(fpsr_w);
+#endif
+ }
+
+ void getFpStatusRegister() noexcept
+ {
+#if defined(__arm64__) || defined(__aarch64__)
+ asm volatile("mrs %0, fpcr" : "=r"(fpsr));
+#elif defined(__SSE__)
+ fpsr = static_cast<intptr_t>(_mm_getcsr());
+#endif
+ }
+
+ public:
+ ScopedNoDenormals() noexcept
+ {
+#if defined(__arm64__) || defined(__aarch64__)
+ intptr_t mask = (1 << 24 /* FZ */);
+#elif defined(__SSE__)
+#if defined(__SSE2__)
+ intptr_t mask = 0x8040;
+#else
+ intptr_t mask = 0x8000;
+#endif
+#else
+ intptr_t mask = 0x0000;
+#endif
+ getFpStatusRegister();
+ setFpStatusRegister(fpsr | mask);
+ }
+ ~ScopedNoDenormals() noexcept { setFpStatusRegister(fpsr); }
};
#define AVOIDDENORMALS ScopedNoDenormals ftz_scope;
#ifndef API_UI_H
#define API_UI_H
+#include <stdio.h>
+
+#include <map>
#include <sstream>
#include <string>
#include <vector>
-#include <stdio.h>
-#include <map>
/************************** BEGIN meta.h *******************************
FAUST Architecture File
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
#ifndef __meta__
#define __meta__
-
/**
- The base class of Meta handler to be used in dsp::metadata(Meta* m) method to retrieve (key, value) metadata.
+ The base class of Meta handler to be used in dsp::metadata(Meta* m) method to retrieve
+ (key, value) metadata.
*/
struct FAUST_API Meta {
virtual ~Meta() {}
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
#ifndef __UI_H__
#define __UI_H__
-
#ifndef FAUSTFLOAT
#define FAUSTFLOAT float
#endif
struct Soundfile;
-template <typename REAL>
+template<typename REAL>
struct FAUST_API UIReal {
-
UIReal() {}
virtual ~UIReal() {}
-
+
// -- widget's layouts
-
- virtual void openTabBox(const char* label) = 0;
+
+ virtual void openTabBox(const char* label) = 0;
virtual void openHorizontalBox(const char* label) = 0;
- virtual void openVerticalBox(const char* label) = 0;
- virtual void closeBox() = 0;
-
+ virtual void openVerticalBox(const char* label) = 0;
+ virtual void closeBox() = 0;
+
// -- active widgets
-
- virtual void addButton(const char* label, REAL* zone) = 0;
+
+ virtual void addButton(const char* label, REAL* zone) = 0;
virtual void addCheckButton(const char* label, REAL* zone) = 0;
- virtual void addVerticalSlider(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0;
- virtual void addHorizontalSlider(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0;
- virtual void addNumEntry(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0;
-
+ virtual void addVerticalSlider(const char* label, REAL* zone, REAL init, REAL min,
+ REAL max, REAL step) = 0;
+ virtual void addHorizontalSlider(const char* label, REAL* zone, REAL init, REAL min,
+ REAL max, REAL step) = 0;
+ virtual void addNumEntry(const char* label, REAL* zone, REAL init, REAL min, REAL max,
+ REAL step) = 0;
+
// -- passive widgets
-
- virtual void addHorizontalBargraph(const char* label, REAL* zone, REAL min, REAL max) = 0;
- virtual void addVerticalBargraph(const char* label, REAL* zone, REAL min, REAL max) = 0;
-
+
+ virtual void addHorizontalBargraph(const char* label, REAL* zone, REAL min,
+ REAL max) = 0;
+ virtual void addVerticalBargraph(const char* label, REAL* zone, REAL min,
+ REAL max) = 0;
+
// -- soundfiles
-
- virtual void addSoundfile(const char* label, const char* filename, Soundfile** sf_zone) = 0;
-
+
+ virtual void addSoundfile(const char* label, const char* filename,
+ Soundfile** sf_zone) = 0;
+
// -- metadata declarations
-
- virtual void declare(REAL* /* zone */, const char* /* key */, const char* /* val */) {}
-
+
+ virtual void declare(REAL* /* zone */, const char* /* key */, const char* /* val */)
+ {
+ }
+
// To be used by LLVM client
virtual int sizeOfFAUSTFLOAT() { return sizeof(FAUSTFLOAT); }
};
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
#ifndef __PathBuilder__
#define __PathBuilder__
-#include <vector>
-#include <set>
-#include <map>
-#include <string>
#include <algorithm>
+#include <map>
#include <regex>
-
+#include <set>
+#include <string>
+#include <vector>
/*******************************************************************************
* PathBuilder : Faust User Interface
* Helper class to build complete hierarchical path for UI items.
******************************************************************************/
-class FAUST_API PathBuilder {
-
- protected:
-
- std::vector<std::string> fControlsLevel;
- std::vector<std::string> fFullPaths;
- std::map<std::string, std::string> fFull2Short; // filled by computeShortNames()
-
- /**
- * @brief check if a character is acceptable for an ID
- *
- * @param c
- * @return true is the character is acceptable for an ID
- */
- bool isIDChar(char c) const
- {
- return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9'));
- }
-
- /**
- * @brief remove all "/0x00" parts
- *
- * @param src
- * @return modified string
- */
- std::string remove0x00(const std::string& src) const
- {
- return std::regex_replace(src, std::regex("/0x00"), "");
- }
-
- /**
- * @brief replace all non ID char with '_' (one '_' may replace several non ID char)
- *
- * @param src
- * @return modified string
- */
- std::string str2ID(const std::string& src) const
- {
- std::string dst;
- bool need_underscore = false;
- for (char c : src) {
- if (isIDChar(c) || (c == '/')) {
- if (need_underscore) {
- dst.push_back('_');
- need_underscore = false;
- }
- dst.push_back(c);
- } else {
- need_underscore = true;
+class FAUST_API PathBuilder
+{
+ protected:
+ std::vector<std::string> fControlsLevel;
+ std::vector<std::string> fFullPaths;
+ std::map<std::string, std::string> fFull2Short; // filled by computeShortNames()
+
+ /**
+ * @brief check if a character is acceptable for an ID
+ *
+ * @param c
+ * @return true is the character is acceptable for an ID
+ */
+ bool isIDChar(char c) const
+ {
+ return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))
+ || ((c >= '0') && (c <= '9'));
+ }
+
+ /**
+ * @brief remove all "/0x00" parts
+ *
+ * @param src
+ * @return modified string
+ */
+ std::string remove0x00(const std::string& src) const
+ {
+ return std::regex_replace(src, std::regex("/0x00"), "");
+ }
+
+ /**
+ * @brief replace all non ID char with '_' (one '_' may replace several non ID char)
+ *
+ * @param src
+ * @return modified string
+ */
+ std::string str2ID(const std::string& src) const
+ {
+ std::string dst;
+ bool need_underscore = false;
+ for (char c : src) {
+ if (isIDChar(c) || (c == '/')) {
+ if (need_underscore) {
+ dst.push_back('_');
+ need_underscore = false;
}
+ dst.push_back(c);
+ } else {
+ need_underscore = true;
}
- return dst;
}
-
- /**
- * @brief Keep only the last n slash-parts
- *
- * @param src
- * @param n : 1 indicates the last slash-part
- * @return modified string
- */
- std::string cut(const std::string& src, int n) const
- {
- std::string rdst;
- for (int i = int(src.length())-1; i >= 0; i--) {
- char c = src[i];
- if (c != '/') {
- rdst.push_back(c);
- } else if (n == 1) {
- std::string dst;
- for (int j = int(rdst.length())-1; j >= 0; j--) {
- dst.push_back(rdst[j]);
- }
- return dst;
- } else {
- n--;
- rdst.push_back(c);
+ return dst;
+ }
+
+ /**
+ * @brief Keep only the last n slash-parts
+ *
+ * @param src
+ * @param n : 1 indicates the last slash-part
+ * @return modified string
+ */
+ std::string cut(const std::string& src, int n) const
+ {
+ std::string rdst;
+ for (int i = int(src.length()) - 1; i >= 0; i--) {
+ char c = src[i];
+ if (c != '/') {
+ rdst.push_back(c);
+ } else if (n == 1) {
+ std::string dst;
+ for (int j = int(rdst.length()) - 1; j >= 0; j--) {
+ dst.push_back(rdst[j]);
}
+ return dst;
+ } else {
+ n--;
+ rdst.push_back(c);
}
- return src;
}
-
- void addFullPath(const std::string& label) { fFullPaths.push_back(buildPath(label)); }
-
- /**
- * @brief Compute the mapping between full path and short names
- */
- void computeShortNames()
- {
- std::vector<std::string> uniquePaths; // all full paths transformed but made unique with a prefix
- std::map<std::string, std::string> unique2full; // all full paths transformed but made unique with a prefix
- char num_buffer[16];
- int pnum = 0;
-
- for (const auto& s : fFullPaths) {
- sprintf(num_buffer, "%d", pnum++);
- std::string u = "/P" + std::string(num_buffer) + str2ID(remove0x00(s));
- uniquePaths.push_back(u);
- unique2full[u] = s; // remember the full path associated to a unique path
- }
-
- std::map<std::string, int> uniquePath2level; // map path to level
- for (const auto& s : uniquePaths) uniquePath2level[s] = 1; // we init all levels to 1
- bool have_collisions = true;
-
- while (have_collisions) {
- // compute collision list
- std::set<std::string> collisionSet;
- std::map<std::string, std::string> short2full;
- have_collisions = false;
- for (const auto& it : uniquePath2level) {
- std::string u = it.first;
- int n = it.second;
- std::string shortName = cut(u, n);
- auto p = short2full.find(shortName);
- if (p == short2full.end()) {
- // no collision
- short2full[shortName] = u;
- } else {
- // we have a collision, add the two paths to the collision set
- have_collisions = true;
- collisionSet.insert(u);
- collisionSet.insert(p->second);
- }
- }
- for (const auto& s : collisionSet) uniquePath2level[s]++; // increase level of colliding path
- }
-
+ return src;
+ }
+
+ void addFullPath(const std::string& label) { fFullPaths.push_back(buildPath(label)); }
+
+ /**
+ * @brief Compute the mapping between full path and short names
+ */
+ void computeShortNames()
+ {
+ std::vector<std::string>
+ uniquePaths; // all full paths transformed but made unique with a prefix
+ std::map<std::string, std::string>
+ unique2full; // all full paths transformed but made unique with a prefix
+ char num_buffer[16];
+ int pnum = 0;
+
+ for (const auto& s : fFullPaths) {
+ sprintf(num_buffer, "%d", pnum++);
+ std::string u = "/P" + std::string(num_buffer) + str2ID(remove0x00(s));
+ uniquePaths.push_back(u);
+ unique2full[u] = s; // remember the full path associated to a unique path
+ }
+
+ std::map<std::string, int> uniquePath2level; // map path to level
+ for (const auto& s : uniquePaths)
+ uniquePath2level[s] = 1; // we init all levels to 1
+ bool have_collisions = true;
+
+ while (have_collisions) {
+ // compute collision list
+ std::set<std::string> collisionSet;
+ std::map<std::string, std::string> short2full;
+ have_collisions = false;
for (const auto& it : uniquePath2level) {
- std::string u = it.first;
- int n = it.second;
- std::string shortName = replaceCharList(cut(u, n), {'/'}, '_');
- fFull2Short[unique2full[u]] = shortName;
+ std::string u = it.first;
+ int n = it.second;
+ std::string shortName = cut(u, n);
+ auto p = short2full.find(shortName);
+ if (p == short2full.end()) {
+ // no collision
+ short2full[shortName] = u;
+ } else {
+ // we have a collision, add the two paths to the collision set
+ have_collisions = true;
+ collisionSet.insert(u);
+ collisionSet.insert(p->second);
+ }
}
+ for (const auto& s : collisionSet)
+ uniquePath2level[s]++; // increase level of colliding path
}
-
- std::string replaceCharList(const std::string& str, const std::vector<char>& ch1, char ch2)
- {
- auto beg = ch1.begin();
- auto end = ch1.end();
- std::string res = str;
- for (size_t i = 0; i < str.length(); ++i) {
- if (std::find(beg, end, str[i]) != end) res[i] = ch2;
- }
- return res;
+
+ for (const auto& it : uniquePath2level) {
+ std::string u = it.first;
+ int n = it.second;
+ std::string shortName = replaceCharList(cut(u, n), {'/'}, '_');
+ fFull2Short[unique2full[u]] = shortName;
}
-
- public:
-
- PathBuilder() {}
- virtual ~PathBuilder() {}
-
- // Return true for the first level of groups
- bool pushLabel(const std::string& label) { fControlsLevel.push_back(label); return fControlsLevel.size() == 1;}
-
- // Return true for the last level of groups
- bool popLabel() { fControlsLevel.pop_back(); return fControlsLevel.size() == 0; }
-
- std::string buildPath(const std::string& label)
- {
- std::string res = "/";
- for (size_t i = 0; i < fControlsLevel.size(); i++) {
- res = res + fControlsLevel[i] + "/";
- }
- res += label;
- return replaceCharList(res, {' ', '#', '*', ',', '?', '[', ']', '{', '}', '(', ')'}, '_');
+ }
+
+ std::string replaceCharList(const std::string& str, const std::vector<char>& ch1,
+ char ch2)
+ {
+ auto beg = ch1.begin();
+ auto end = ch1.end();
+ std::string res = str;
+ for (size_t i = 0; i < str.length(); ++i) {
+ if (std::find(beg, end, str[i]) != end)
+ res[i] = ch2;
}
-
+ return res;
+ }
+
+ public:
+ PathBuilder() {}
+ virtual ~PathBuilder() {}
+
+ // Return true for the first level of groups
+ bool pushLabel(const std::string& label)
+ {
+ fControlsLevel.push_back(label);
+ return fControlsLevel.size() == 1;
+ }
+
+ // Return true for the last level of groups
+ bool popLabel()
+ {
+ fControlsLevel.pop_back();
+ return fControlsLevel.size() == 0;
+ }
+
+ std::string buildPath(const std::string& label)
+ {
+ std::string res = "/";
+ for (size_t i = 0; i < fControlsLevel.size(); i++) {
+ res = res + fControlsLevel[i] + "/";
+ }
+ res += label;
+ return replaceCharList(
+ res, {' ', '#', '*', ',', '?', '[', ']', '{', '}', '(', ')'}, '_');
+ }
};
#endif // __PathBuilder__
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
/***************************************************************************************
ValueConverter.h
(GRAME, Copyright 2015-2019)
-
+
Set of conversion objects used to map user interface values (for example a gui slider
delivering values between 0 and 1) to faust values (for example a vslider between
20 and 20000) using a log scale.
-
+
-- Utilities
-
+
Range(lo,hi) : clip a value x between lo and hi
- Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and v2
- Interpolator3pt(lo,mi,hi,v1,vm,v2) : Map values between lo mid hi to values between v1 vm v2
-
+ Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and
+v2 Interpolator3pt(lo,mi,hi,v1,vm,v2) : Map values between lo mid hi to values between v1
+vm v2
+
-- Value Converters
-
+
ValueConverter::ui2faust(x)
ValueConverter::faust2ui(x)
-
+
-- ValueConverters used for sliders depending of the scale
-
+
LinearValueConverter(umin, umax, fmin, fmax)
LinearValueConverter2(lo, mi, hi, v1, vm, v2) using 2 segments
LogValueConverter(umin, umax, fmin, fmax)
ExpValueConverter(umin, umax, fmin, fmax)
-
+
-- ValueConverters used for accelerometers based on 3 points
-
+
AccUpConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 0
AccDownConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 1
AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 2
AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 3
-
+
-- lists of ZoneControl are used to implement accelerometers metadata for each axes
-
+
ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter
-
+
-- ZoneReader are used to implement screencolor metadata
-
+
ZoneReader(zone, valueConverter) : a zone with a data converter
****************************************************************************************/
+#include <assert.h>
#include <float.h>
-#include <algorithm> // std::max
+
+#include <algorithm> // std::max
#include <cmath>
#include <vector>
-#include <assert.h>
-
//--------------------------------------------------------------------------------------
// Interpolator(lo,hi,v1,v2)
// y = v1 - lo*coef + x*coef
// y = offset + x*coef with offset = v1 - lo*coef
//--------------------------------------------------------------------------------------
-class FAUST_API Interpolator {
-
- private:
-
- //--------------------------------------------------------------------------------------
- // Range(lo,hi) clip a value between lo and hi
- //--------------------------------------------------------------------------------------
- struct Range
- {
- double fLo;
- double fHi;
-
- Range(double x, double y) : fLo(std::min<double>(x,y)), fHi(std::max<double>(x,y)) {}
- double operator()(double x) { return (x<fLo) ? fLo : (x>fHi) ? fHi : x; }
- };
-
-
- Range fRange;
- double fCoef;
- double fOffset;
-
- public:
-
- Interpolator(double lo, double hi, double v1, double v2) : fRange(lo,hi)
+class FAUST_API Interpolator
+{
+ private:
+ //--------------------------------------------------------------------------------------
+ // Range(lo,hi) clip a value between lo and hi
+ //--------------------------------------------------------------------------------------
+ struct Range {
+ double fLo;
+ double fHi;
+
+ Range(double x, double y)
+ : fLo(std::min<double>(x, y)), fHi(std::max<double>(x, y))
{
- if (hi != lo) {
- // regular case
- fCoef = (v2-v1)/(hi-lo);
- fOffset = v1 - lo*fCoef;
- } else {
- // degenerate case, avoids division by zero
- fCoef = 0;
- fOffset = (v1+v2)/2;
- }
}
- double operator()(double v)
- {
- double x = fRange(v);
- return fOffset + x*fCoef;
- }
-
- void getLowHigh(double& amin, double& amax)
- {
- amin = fRange.fLo;
- amax = fRange.fHi;
+ double operator()(double x) { return (x < fLo) ? fLo : (x > fHi) ? fHi : x; }
+ };
+
+ Range fRange;
+ double fCoef;
+ double fOffset;
+
+ public:
+ Interpolator(double lo, double hi, double v1, double v2) : fRange(lo, hi)
+ {
+ if (hi != lo) {
+ // regular case
+ fCoef = (v2 - v1) / (hi - lo);
+ fOffset = v1 - lo * fCoef;
+ } else {
+ // degenerate case, avoids division by zero
+ fCoef = 0;
+ fOffset = (v1 + v2) / 2;
}
+ }
+ double operator()(double v)
+ {
+ double x = fRange(v);
+ return fOffset + x * fCoef;
+ }
+
+ void getLowHigh(double& amin, double& amax)
+ {
+ amin = fRange.fLo;
+ amax = fRange.fHi;
+ }
};
//--------------------------------------------------------------------------------------
// Interpolator3pt(lo,mi,hi,v1,vm,v2)
// Map values between lo mid hi to values between v1 vm v2
//--------------------------------------------------------------------------------------
-class FAUST_API Interpolator3pt {
-
- private:
-
- Interpolator fSegment1;
- Interpolator fSegment2;
- double fMid;
-
- public:
-
- Interpolator3pt(double lo, double mi, double hi, double v1, double vm, double v2) :
- fSegment1(lo, mi, v1, vm),
- fSegment2(mi, hi, vm, v2),
- fMid(mi) {}
- double operator()(double x) { return (x < fMid) ? fSegment1(x) : fSegment2(x); }
-
- void getMappingValues(double& amin, double& amid, double& amax)
- {
- fSegment1.getLowHigh(amin, amid);
- fSegment2.getLowHigh(amid, amax);
- }
+class FAUST_API Interpolator3pt
+{
+ private:
+ Interpolator fSegment1;
+ Interpolator fSegment2;
+ double fMid;
+
+ public:
+ Interpolator3pt(double lo, double mi, double hi, double v1, double vm, double v2)
+ : fSegment1(lo, mi, v1, vm), fSegment2(mi, hi, vm, v2), fMid(mi)
+ {
+ }
+ double operator()(double x) { return (x < fMid) ? fSegment1(x) : fSegment2(x); }
+
+ void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fSegment1.getLowHigh(amin, amid);
+ fSegment2.getLowHigh(amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Abstract ValueConverter class. Converts values between UI and Faust representations
//--------------------------------------------------------------------------------------
-class FAUST_API ValueConverter {
-
- public:
-
- virtual ~ValueConverter() {}
- virtual double ui2faust(double x) { return x; };
- virtual double faust2ui(double x) { return x; };
+class FAUST_API ValueConverter
+{
+ public:
+ virtual ~ValueConverter() {}
+ virtual double ui2faust(double x) { return x; };
+ virtual double faust2ui(double x) { return x; };
};
//--------------------------------------------------------------------------------------
// A converter than can be updated
//--------------------------------------------------------------------------------------
-class FAUST_API UpdatableValueConverter : public ValueConverter {
-
- protected:
-
- bool fActive;
-
- public:
-
- UpdatableValueConverter():fActive(true)
- {}
- virtual ~UpdatableValueConverter()
- {}
-
- virtual void setMappingValues(double amin, double amid, double amax, double min, double init, double max) = 0;
- virtual void getMappingValues(double& amin, double& amid, double& amax) = 0;
-
- void setActive(bool on_off) { fActive = on_off; }
- bool getActive() { return fActive; }
-
+class FAUST_API UpdatableValueConverter : public ValueConverter
+{
+ protected:
+ bool fActive;
+
+ public:
+ UpdatableValueConverter() : fActive(true) {}
+ virtual ~UpdatableValueConverter() {}
+
+ virtual void setMappingValues(double amin, double amid, double amax, double min,
+ double init, double max) = 0;
+ virtual void getMappingValues(double& amin, double& amid, double& amax) = 0;
+
+ void setActive(bool on_off) { fActive = on_off; }
+ bool getActive() { return fActive; }
};
//--------------------------------------------------------------------------------------
// Linear conversion between ui and Faust values
//--------------------------------------------------------------------------------------
-class FAUST_API LinearValueConverter : public ValueConverter {
-
- private:
-
- Interpolator fUI2F;
- Interpolator fF2UI;
-
- public:
-
- LinearValueConverter(double umin, double umax, double fmin, double fmax) :
- fUI2F(umin,umax,fmin,fmax), fF2UI(fmin,fmax,umin,umax)
- {}
-
- LinearValueConverter() : fUI2F(0.,0.,0.,0.), fF2UI(0.,0.,0.,0.)
- {}
- virtual double ui2faust(double x) { return fUI2F(x); }
- virtual double faust2ui(double x) { return fF2UI(x); }
-
+class FAUST_API LinearValueConverter : public ValueConverter
+{
+ private:
+ Interpolator fUI2F;
+ Interpolator fF2UI;
+
+ public:
+ LinearValueConverter(double umin, double umax, double fmin, double fmax)
+ : fUI2F(umin, umax, fmin, fmax), fF2UI(fmin, fmax, umin, umax)
+ {
+ }
+
+ LinearValueConverter() : fUI2F(0., 0., 0., 0.), fF2UI(0., 0., 0., 0.) {}
+ virtual double ui2faust(double x) { return fUI2F(x); }
+ virtual double faust2ui(double x) { return fF2UI(x); }
};
//--------------------------------------------------------------------------------------
// Two segments linear conversion between ui and Faust values
//--------------------------------------------------------------------------------------
-class FAUST_API LinearValueConverter2 : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fUI2F;
- Interpolator3pt fF2UI;
-
- public:
-
- LinearValueConverter2(double amin, double amid, double amax, double min, double init, double max) :
- fUI2F(amin, amid, amax, min, init, max), fF2UI(min, init, max, amin, amid, amax)
- {}
-
- LinearValueConverter2() : fUI2F(0.,0.,0.,0.,0.,0.), fF2UI(0.,0.,0.,0.,0.,0.)
- {}
-
- virtual double ui2faust(double x) { return fUI2F(x); }
- virtual double faust2ui(double x) { return fF2UI(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double min, double init, double max)
- {
- fUI2F = Interpolator3pt(amin, amid, amax, min, init, max);
- fF2UI = Interpolator3pt(min, init, max, amin, amid, amax);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fUI2F.getMappingValues(amin, amid, amax);
- }
-
+class FAUST_API LinearValueConverter2 : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fUI2F;
+ Interpolator3pt fF2UI;
+
+ public:
+ LinearValueConverter2(double amin, double amid, double amax, double min, double init,
+ double max)
+ : fUI2F(amin, amid, amax, min, init, max), fF2UI(min, init, max, amin, amid, amax)
+ {
+ }
+
+ LinearValueConverter2() : fUI2F(0., 0., 0., 0., 0., 0.), fF2UI(0., 0., 0., 0., 0., 0.)
+ {
+ }
+
+ virtual double ui2faust(double x) { return fUI2F(x); }
+ virtual double faust2ui(double x) { return fF2UI(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double min,
+ double init, double max)
+ {
+ fUI2F = Interpolator3pt(amin, amid, amax, min, init, max);
+ fF2UI = Interpolator3pt(min, init, max, amin, amid, amax);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fUI2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Logarithmic conversion between ui and Faust values
//--------------------------------------------------------------------------------------
-class FAUST_API LogValueConverter : public LinearValueConverter {
-
- public:
-
- LogValueConverter(double umin, double umax, double fmin, double fmax) :
- LinearValueConverter(umin, umax, std::log(std::max<double>(DBL_MIN, fmin)), std::log(std::max<double>(DBL_MIN, fmax)))
- {}
-
- virtual double ui2faust(double x) { return std::exp(LinearValueConverter::ui2faust(x)); }
- virtual double faust2ui(double x) { return LinearValueConverter::faust2ui(std::log(std::max<double>(x, DBL_MIN))); }
-
+class FAUST_API LogValueConverter : public LinearValueConverter
+{
+ public:
+ LogValueConverter(double umin, double umax, double fmin, double fmax)
+ : LinearValueConverter(umin, umax, std::log(std::max<double>(DBL_MIN, fmin)),
+ std::log(std::max<double>(DBL_MIN, fmax)))
+ {
+ }
+
+ virtual double ui2faust(double x)
+ {
+ return std::exp(LinearValueConverter::ui2faust(x));
+ }
+ virtual double faust2ui(double x)
+ {
+ return LinearValueConverter::faust2ui(std::log(std::max<double>(x, DBL_MIN)));
+ }
};
//--------------------------------------------------------------------------------------
// Exponential conversion between ui and Faust values
//--------------------------------------------------------------------------------------
-class FAUST_API ExpValueConverter : public LinearValueConverter {
-
- public:
-
- ExpValueConverter(double umin, double umax, double fmin, double fmax) :
- LinearValueConverter(umin, umax, std::min<double>(DBL_MAX, std::exp(fmin)), std::min<double>(DBL_MAX, std::exp(fmax)))
- {}
-
- virtual double ui2faust(double x) { return std::log(LinearValueConverter::ui2faust(x)); }
- virtual double faust2ui(double x) { return LinearValueConverter::faust2ui(std::min<double>(DBL_MAX, std::exp(x))); }
-
+class FAUST_API ExpValueConverter : public LinearValueConverter
+{
+ public:
+ ExpValueConverter(double umin, double umax, double fmin, double fmax)
+ : LinearValueConverter(umin, umax, std::min<double>(DBL_MAX, std::exp(fmin)),
+ std::min<double>(DBL_MAX, std::exp(fmax)))
+ {
+ }
+
+ virtual double ui2faust(double x)
+ {
+ return std::log(LinearValueConverter::ui2faust(x));
+ }
+ virtual double faust2ui(double x)
+ {
+ return LinearValueConverter::faust2ui(std::min<double>(DBL_MAX, std::exp(x)));
+ }
};
//--------------------------------------------------------------------------------------
// Convert accelerometer or gyroscope values to Faust values
// Using an Up curve (curve 0)
//--------------------------------------------------------------------------------------
-class FAUST_API AccUpConverter : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fA2F;
- Interpolator3pt fF2A;
-
- public:
-
- AccUpConverter(double amin, double amid, double amax, double fmin, double fmid, double fmax) :
- fA2F(amin,amid,amax,fmin,fmid,fmax),
- fF2A(fmin,fmid,fmax,amin,amid,amax)
- {}
-
- virtual double ui2faust(double x) { return fA2F(x); }
- virtual double faust2ui(double x) { return fF2A(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double fmin, double fmid, double fmax)
- {
- //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
- fA2F = Interpolator3pt(amin, amid, amax, fmin, fmid, fmax);
- fF2A = Interpolator3pt(fmin, fmid, fmax, amin, amid, amax);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fA2F.getMappingValues(amin, amid, amax);
- }
-
+class FAUST_API AccUpConverter : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fA2F;
+ Interpolator3pt fF2A;
+
+ public:
+ AccUpConverter(double amin, double amid, double amax, double fmin, double fmid,
+ double fmax)
+ : fA2F(amin, amid, amax, fmin, fmid, fmax)
+ , fF2A(fmin, fmid, fmax, amin, amid, amax)
+ {
+ }
+
+ virtual double ui2faust(double x) { return fA2F(x); }
+ virtual double faust2ui(double x) { return fF2A(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double fmin,
+ double fmid, double fmax)
+ {
+ //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpConverter update %f %f %f
+ //%f %f %f", amin,amid,amax,fmin,fmid,fmax);
+ fA2F = Interpolator3pt(amin, amid, amax, fmin, fmid, fmax);
+ fF2A = Interpolator3pt(fmin, fmid, fmax, amin, amid, amax);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fA2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Convert accelerometer or gyroscope values to Faust values
// Using a Down curve (curve 1)
//--------------------------------------------------------------------------------------
-class FAUST_API AccDownConverter : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fA2F;
- Interpolator3pt fF2A;
-
- public:
-
- AccDownConverter(double amin, double amid, double amax, double fmin, double fmid, double fmax) :
- fA2F(amin,amid,amax,fmax,fmid,fmin),
- fF2A(fmin,fmid,fmax,amax,amid,amin)
- {}
-
- virtual double ui2faust(double x) { return fA2F(x); }
- virtual double faust2ui(double x) { return fF2A(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double fmin, double fmid, double fmax)
- {
- //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
- fA2F = Interpolator3pt(amin, amid, amax, fmax, fmid, fmin);
- fF2A = Interpolator3pt(fmin, fmid, fmax, amax, amid, amin);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fA2F.getMappingValues(amin, amid, amax);
- }
+class FAUST_API AccDownConverter : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fA2F;
+ Interpolator3pt fF2A;
+
+ public:
+ AccDownConverter(double amin, double amid, double amax, double fmin, double fmid,
+ double fmax)
+ : fA2F(amin, amid, amax, fmax, fmid, fmin)
+ , fF2A(fmin, fmid, fmax, amax, amid, amin)
+ {
+ }
+
+ virtual double ui2faust(double x) { return fA2F(x); }
+ virtual double faust2ui(double x) { return fF2A(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double fmin,
+ double fmid, double fmax)
+ {
+ //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownConverter update %f %f
+ //%f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+ fA2F = Interpolator3pt(amin, amid, amax, fmax, fmid, fmin);
+ fF2A = Interpolator3pt(fmin, fmid, fmax, amax, amid, amin);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fA2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Convert accelerometer or gyroscope values to Faust values
// Using an Up-Down curve (curve 2)
//--------------------------------------------------------------------------------------
-class FAUST_API AccUpDownConverter : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fA2F;
- Interpolator fF2A;
-
- public:
-
- AccUpDownConverter(double amin, double amid, double amax, double fmin, double /* fmid */, double fmax) :
- fA2F(amin,amid,amax,fmin,fmax,fmin),
- fF2A(fmin,fmax,amin,amax) // Special, pseudo inverse of a non monotonic function
- {}
-
- virtual double ui2faust(double x) { return fA2F(x); }
- virtual double faust2ui(double x) { return fF2A(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double fmin, double /* fmid */, double fmax)
- {
- //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpDownConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
- fA2F = Interpolator3pt(amin, amid, amax, fmin, fmax, fmin);
- fF2A = Interpolator(fmin, fmax, amin, amax);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fA2F.getMappingValues(amin, amid, amax);
- }
+class FAUST_API AccUpDownConverter : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fA2F;
+ Interpolator fF2A;
+
+ public:
+ AccUpDownConverter(double amin, double amid, double amax, double fmin,
+ double /* fmid */, double fmax)
+ : fA2F(amin, amid, amax, fmin, fmax, fmin)
+ , fF2A(fmin, fmax, amin,
+ amax) // Special, pseudo inverse of a non monotonic function
+ {
+ }
+
+ virtual double ui2faust(double x) { return fA2F(x); }
+ virtual double faust2ui(double x) { return fF2A(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double fmin,
+ double /* fmid */, double fmax)
+ {
+ //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpDownConverter update %f %f
+ //%f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+ fA2F = Interpolator3pt(amin, amid, amax, fmin, fmax, fmin);
+ fF2A = Interpolator(fmin, fmax, amin, amax);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fA2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Convert accelerometer or gyroscope values to Faust values
// Using a Down-Up curve (curve 3)
//--------------------------------------------------------------------------------------
-class FAUST_API AccDownUpConverter : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fA2F;
- Interpolator fF2A;
-
- public:
-
- AccDownUpConverter(double amin, double amid, double amax, double fmin, double /* fmid */, double fmax) :
- fA2F(amin,amid,amax,fmax,fmin,fmax),
- fF2A(fmin,fmax,amin,amax) // Special, pseudo inverse of a non monotonic function
- {}
-
- virtual double ui2faust(double x) { return fA2F(x); }
- virtual double faust2ui(double x) { return fF2A(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double fmin, double /* fmid */, double fmax)
- {
- //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownUpConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
- fA2F = Interpolator3pt(amin, amid, amax, fmax, fmin, fmax);
- fF2A = Interpolator(fmin, fmax, amin, amax);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fA2F.getMappingValues(amin, amid, amax);
- }
+class FAUST_API AccDownUpConverter : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fA2F;
+ Interpolator fF2A;
+
+ public:
+ AccDownUpConverter(double amin, double amid, double amax, double fmin,
+ double /* fmid */, double fmax)
+ : fA2F(amin, amid, amax, fmax, fmin, fmax)
+ , fF2A(fmin, fmax, amin,
+ amax) // Special, pseudo inverse of a non monotonic function
+ {
+ }
+
+ virtual double ui2faust(double x) { return fA2F(x); }
+ virtual double faust2ui(double x) { return fF2A(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double fmin,
+ double /* fmid */, double fmax)
+ {
+ //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownUpConverter update %f %f
+ //%f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+ fA2F = Interpolator3pt(amin, amid, amax, fmax, fmin, fmax);
+ fF2A = Interpolator(fmin, fmax, amin, amax);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fA2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Base class for ZoneControl
//--------------------------------------------------------------------------------------
-class FAUST_API ZoneControl {
-
- protected:
-
- FAUSTFLOAT* fZone;
-
- public:
-
- ZoneControl(FAUSTFLOAT* zone) : fZone(zone) {}
- virtual ~ZoneControl() {}
+class FAUST_API ZoneControl
+{
+ protected:
+ FAUSTFLOAT* fZone;
- virtual void update(double /* v */) const {}
+ public:
+ ZoneControl(FAUSTFLOAT* zone) : fZone(zone) {}
+ virtual ~ZoneControl() {}
- virtual void setMappingValues(int /* curve */, double /* amin */, double /* amid */, double /* amax */, double /* min */, double /* init */, double /* max */) {}
- virtual void getMappingValues(double& /* amin */, double& /* amid */, double& /* amax */) {}
+ virtual void update(double /* v */) const {}
- FAUSTFLOAT* getZone() { return fZone; }
+ virtual void setMappingValues(int /* curve */, double /* amin */, double /* amid */,
+ double /* amax */, double /* min */, double /* init */,
+ double /* max */)
+ {
+ }
+ virtual void getMappingValues(double& /* amin */, double& /* amid */,
+ double& /* amax */)
+ {
+ }
- virtual void setActive(bool /* on_off */) {}
- virtual bool getActive() { return false; }
+ FAUSTFLOAT* getZone() { return fZone; }
- virtual int getCurve() { return -1; }
+ virtual void setActive(bool /* on_off */) {}
+ virtual bool getActive() { return false; }
+ virtual int getCurve() { return -1; }
};
//--------------------------------------------------------------------------------------
// Useful to implement accelerometers metadata as a list of ZoneControl for each axes
//--------------------------------------------------------------------------------------
-class FAUST_API ConverterZoneControl : public ZoneControl {
-
- protected:
-
- ValueConverter* fValueConverter;
-
- public:
-
- ConverterZoneControl(FAUSTFLOAT* zone, ValueConverter* converter) : ZoneControl(zone), fValueConverter(converter) {}
- virtual ~ConverterZoneControl() { delete fValueConverter; } // Assuming fValueConverter is not kept elsewhere...
-
- virtual void update(double v) const { *fZone = FAUSTFLOAT(fValueConverter->ui2faust(v)); }
-
- ValueConverter* getConverter() { return fValueConverter; }
-
+class FAUST_API ConverterZoneControl : public ZoneControl
+{
+ protected:
+ ValueConverter* fValueConverter;
+
+ public:
+ ConverterZoneControl(FAUSTFLOAT* zone, ValueConverter* converter)
+ : ZoneControl(zone), fValueConverter(converter)
+ {
+ }
+ virtual ~ConverterZoneControl()
+ {
+ delete fValueConverter;
+ } // Assuming fValueConverter is not kept elsewhere...
+
+ virtual void update(double v) const
+ {
+ *fZone = FAUSTFLOAT(fValueConverter->ui2faust(v));
+ }
+
+ ValueConverter* getConverter() { return fValueConverter; }
};
//--------------------------------------------------------------------------------------
// Association of a zone and a four value converter, each one for each possible curve.
// Useful to implement accelerometers metadata as a list of ZoneControl for each axes
//--------------------------------------------------------------------------------------
-class FAUST_API CurveZoneControl : public ZoneControl {
-
- private:
-
- std::vector<UpdatableValueConverter*> fValueConverters;
- int fCurve;
-
- public:
-
- CurveZoneControl(FAUSTFLOAT* zone, int curve, double amin, double amid, double amax, double min, double init, double max) : ZoneControl(zone), fCurve(0)
- {
- assert(curve >= 0 && curve <= 3);
- fValueConverters.push_back(new AccUpConverter(amin, amid, amax, min, init, max));
- fValueConverters.push_back(new AccDownConverter(amin, amid, amax, min, init, max));
- fValueConverters.push_back(new AccUpDownConverter(amin, amid, amax, min, init, max));
- fValueConverters.push_back(new AccDownUpConverter(amin, amid, amax, min, init, max));
- fCurve = curve;
- }
- virtual ~CurveZoneControl()
- {
- for (const auto& it : fValueConverters) { delete it; }
- }
- void update(double v) const { if (fValueConverters[fCurve]->getActive()) *fZone = FAUSTFLOAT(fValueConverters[fCurve]->ui2faust(v)); }
-
- void setMappingValues(int curve, double amin, double amid, double amax, double min, double init, double max)
- {
- fValueConverters[curve]->setMappingValues(amin, amid, amax, min, init, max);
- fCurve = curve;
- }
-
- void getMappingValues(double& amin, double& amid, double& amax)
- {
- fValueConverters[fCurve]->getMappingValues(amin, amid, amax);
+class FAUST_API CurveZoneControl : public ZoneControl
+{
+ private:
+ std::vector<UpdatableValueConverter*> fValueConverters;
+ int fCurve;
+
+ public:
+ CurveZoneControl(FAUSTFLOAT* zone, int curve, double amin, double amid, double amax,
+ double min, double init, double max)
+ : ZoneControl(zone), fCurve(0)
+ {
+ assert(curve >= 0 && curve <= 3);
+ fValueConverters.push_back(new AccUpConverter(amin, amid, amax, min, init, max));
+ fValueConverters.push_back(
+ new AccDownConverter(amin, amid, amax, min, init, max));
+ fValueConverters.push_back(
+ new AccUpDownConverter(amin, amid, amax, min, init, max));
+ fValueConverters.push_back(
+ new AccDownUpConverter(amin, amid, amax, min, init, max));
+ fCurve = curve;
+ }
+ virtual ~CurveZoneControl()
+ {
+ for (const auto& it : fValueConverters) {
+ delete it;
}
-
- void setActive(bool on_off)
- {
- for (const auto& it : fValueConverters) { it->setActive(on_off); }
+ }
+ void update(double v) const
+ {
+ if (fValueConverters[fCurve]->getActive())
+ *fZone = FAUSTFLOAT(fValueConverters[fCurve]->ui2faust(v));
+ }
+
+ void setMappingValues(int curve, double amin, double amid, double amax, double min,
+ double init, double max)
+ {
+ fValueConverters[curve]->setMappingValues(amin, amid, amax, min, init, max);
+ fCurve = curve;
+ }
+
+ void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fValueConverters[fCurve]->getMappingValues(amin, amid, amax);
+ }
+
+ void setActive(bool on_off)
+ {
+ for (const auto& it : fValueConverters) {
+ it->setActive(on_off);
}
+ }
- int getCurve() { return fCurve; }
+ int getCurve() { return fCurve; }
};
-class FAUST_API ZoneReader {
-
- private:
-
- FAUSTFLOAT* fZone;
- Interpolator fInterpolator;
-
- public:
-
- ZoneReader(FAUSTFLOAT* zone, double lo, double hi) : fZone(zone), fInterpolator(lo, hi, 0, 255) {}
+class FAUST_API ZoneReader
+{
+ private:
+ FAUSTFLOAT* fZone;
+ Interpolator fInterpolator;
- virtual ~ZoneReader() {}
+ public:
+ ZoneReader(FAUSTFLOAT* zone, double lo, double hi)
+ : fZone(zone), fInterpolator(lo, hi, 0, 255)
+ {
+ }
- int getValue()
- {
- return (fZone != nullptr) ? int(fInterpolator(*fZone)) : 127;
- }
+ virtual ~ZoneReader() {}
+ int getValue() { return (fZone != nullptr) ? int(fInterpolator(*fZone)) : 127; }
};
#endif
typedef unsigned int uint;
-class APIUI : public PathBuilder, public Meta, public UI
+class APIUI
+ : public PathBuilder
+ , public Meta
+ , public UI
{
- public:
- enum ItemType { kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry, kHBargraph, kVBargraph };
- enum Type { kAcc = 0, kGyr = 1, kNoType };
-
- protected:
-
- enum Mapping { kLin = 0, kLog = 1, kExp = 2 };
-
- struct Item {
- std::string fLabel;
- std::string fShortname;
- std::string fPath;
- ValueConverter* fConversion;
- FAUSTFLOAT* fZone;
- FAUSTFLOAT fInit;
- FAUSTFLOAT fMin;
- FAUSTFLOAT fMax;
- FAUSTFLOAT fStep;
- ItemType fItemType;
-
- Item(const std::string& label,
- const std::string& short_name,
- const std::string& path,
- ValueConverter* conversion,
- FAUSTFLOAT* zone,
- FAUSTFLOAT init,
- FAUSTFLOAT min,
- FAUSTFLOAT max,
- FAUSTFLOAT step,
- ItemType item_type)
- :fLabel(label), fShortname(short_name), fPath(path), fConversion(conversion),
- fZone(zone), fInit(init), fMin(min), fMax(max), fStep(step), fItemType(item_type)
- {}
- };
- std::vector<Item> fItems;
-
- std::vector<std::map<std::string, std::string> > fMetaData;
- std::vector<ZoneControl*> fAcc[3];
- std::vector<ZoneControl*> fGyr[3];
-
- // Screen color control
- // "...[screencolor:red]..." etc.
- bool fHasScreenControl; // true if control screen color metadata
- ZoneReader* fRedReader;
- ZoneReader* fGreenReader;
- ZoneReader* fBlueReader;
-
- // Current values controlled by metadata
- std::string fCurrentUnit;
- int fCurrentScale;
- std::string fCurrentAcc;
- std::string fCurrentGyr;
- std::string fCurrentColor;
- std::string fCurrentTooltip;
- std::map<std::string, std::string> fCurrentMetadata;
-
- // Add a generic parameter
- virtual void addParameter(const char* label,
- FAUSTFLOAT* zone,
- FAUSTFLOAT init,
- FAUSTFLOAT min,
- FAUSTFLOAT max,
- FAUSTFLOAT step,
- ItemType type)
+ public:
+ enum ItemType {
+ kButton = 0,
+ kCheckButton,
+ kVSlider,
+ kHSlider,
+ kNumEntry,
+ kHBargraph,
+ kVBargraph
+ };
+ enum Type { kAcc = 0, kGyr = 1, kNoType };
+
+ protected:
+ enum Mapping { kLin = 0, kLog = 1, kExp = 2 };
+
+ struct Item {
+ std::string fLabel;
+ std::string fShortname;
+ std::string fPath;
+ ValueConverter* fConversion;
+ FAUSTFLOAT* fZone;
+ FAUSTFLOAT fInit;
+ FAUSTFLOAT fMin;
+ FAUSTFLOAT fMax;
+ FAUSTFLOAT fStep;
+ ItemType fItemType;
+
+ Item(const std::string& label, const std::string& short_name,
+ const std::string& path, ValueConverter* conversion, FAUSTFLOAT* zone,
+ FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step,
+ ItemType item_type)
+ : fLabel(label)
+ , fShortname(short_name)
+ , fPath(path)
+ , fConversion(conversion)
+ , fZone(zone)
+ , fInit(init)
+ , fMin(min)
+ , fMax(max)
+ , fStep(step)
+ , fItemType(item_type)
{
- std::string path = buildPath(label);
- fFullPaths.push_back(path);
-
- // handle scale metadata
- ValueConverter* converter = nullptr;
- switch (fCurrentScale) {
- case kLin:
- converter = new LinearValueConverter(0, 1, min, max);
- break;
- case kLog:
- converter = new LogValueConverter(0, 1, min, max);
- break;
- case kExp:
- converter = new ExpValueConverter(0, 1, min, max);
- break;
- }
- fCurrentScale = kLin;
-
- fItems.push_back(Item(label, "", path, converter, zone, init, min, max, step, type));
-
- if (fCurrentAcc.size() > 0 && fCurrentGyr.size() > 0) {
- fprintf(stderr, "warning : 'acc' and 'gyr' metadata used for the same %s parameter !!\n", label);
- }
+ }
+ };
+ std::vector<Item> fItems;
+
+ std::vector<std::map<std::string, std::string> > fMetaData;
+ std::vector<ZoneControl*> fAcc[3];
+ std::vector<ZoneControl*> fGyr[3];
+
+ // Screen color control
+ // "...[screencolor:red]..." etc.
+ bool fHasScreenControl; // true if control screen color metadata
+ ZoneReader* fRedReader;
+ ZoneReader* fGreenReader;
+ ZoneReader* fBlueReader;
+
+ // Current values controlled by metadata
+ std::string fCurrentUnit;
+ int fCurrentScale;
+ std::string fCurrentAcc;
+ std::string fCurrentGyr;
+ std::string fCurrentColor;
+ std::string fCurrentTooltip;
+ std::map<std::string, std::string> fCurrentMetadata;
+
+ // Add a generic parameter
+ virtual void addParameter(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init,
+ FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step,
+ ItemType type)
+ {
+ std::string path = buildPath(label);
+ fFullPaths.push_back(path);
+
+ // handle scale metadata
+ ValueConverter* converter = nullptr;
+ switch (fCurrentScale) {
+ case kLin:
+ converter = new LinearValueConverter(0, 1, min, max);
+ break;
+ case kLog:
+ converter = new LogValueConverter(0, 1, min, max);
+ break;
+ case kExp:
+ converter = new ExpValueConverter(0, 1, min, max);
+ break;
+ }
+ fCurrentScale = kLin;
- // handle acc metadata "...[acc : <axe> <curve> <amin> <amid> <amax>]..."
- if (fCurrentAcc.size() > 0) {
- std::istringstream iss(fCurrentAcc);
- int axe, curve;
- double amin, amid, amax;
- iss >> axe >> curve >> amin >> amid >> amax;
-
- if ((0 <= axe) && (axe < 3) &&
- (0 <= curve) && (curve < 4) &&
- (amin < amax) && (amin <= amid) && (amid <= amax))
- {
- fAcc[axe].push_back(new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
- } else {
- fprintf(stderr, "incorrect acc metadata : %s \n", fCurrentAcc.c_str());
- }
- fCurrentAcc = "";
- }
+ fItems.push_back(
+ Item(label, "", path, converter, zone, init, min, max, step, type));
- // handle gyr metadata "...[gyr : <axe> <curve> <amin> <amid> <amax>]..."
- if (fCurrentGyr.size() > 0) {
- std::istringstream iss(fCurrentGyr);
- int axe, curve;
- double amin, amid, amax;
- iss >> axe >> curve >> amin >> amid >> amax;
-
- if ((0 <= axe) && (axe < 3) &&
- (0 <= curve) && (curve < 4) &&
- (amin < amax) && (amin <= amid) && (amid <= amax))
- {
- fGyr[axe].push_back(new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
- } else {
- fprintf(stderr, "incorrect gyr metadata : %s \n", fCurrentGyr.c_str());
- }
- fCurrentGyr = "";
- }
+ if (fCurrentAcc.size() > 0 && fCurrentGyr.size() > 0) {
+ fprintf(
+ stderr,
+ "warning : 'acc' and 'gyr' metadata used for the same %s parameter !!\n",
+ label);
+ }
- // handle screencolor metadata "...[screencolor:red|green|blue|white]..."
- if (fCurrentColor.size() > 0) {
- if ((fCurrentColor == "red") && (fRedReader == nullptr)) {
- fRedReader = new ZoneReader(zone, min, max);
- fHasScreenControl = true;
- } else if ((fCurrentColor == "green") && (fGreenReader == nullptr)) {
- fGreenReader = new ZoneReader(zone, min, max);
- fHasScreenControl = true;
- } else if ((fCurrentColor == "blue") && (fBlueReader == nullptr)) {
- fBlueReader = new ZoneReader(zone, min, max);
- fHasScreenControl = true;
- } else if ((fCurrentColor == "white") && (fRedReader == nullptr) && (fGreenReader == nullptr) && (fBlueReader == nullptr)) {
- fRedReader = new ZoneReader(zone, min, max);
- fGreenReader = new ZoneReader(zone, min, max);
- fBlueReader = new ZoneReader(zone, min, max);
- fHasScreenControl = true;
- } else {
- fprintf(stderr, "incorrect screencolor metadata : %s \n", fCurrentColor.c_str());
- }
+ // handle acc metadata "...[acc : <axe> <curve> <amin> <amid> <amax>]..."
+ if (fCurrentAcc.size() > 0) {
+ std::istringstream iss(fCurrentAcc);
+ int axe, curve;
+ double amin, amid, amax;
+ iss >> axe >> curve >> amin >> amid >> amax;
+
+ if ((0 <= axe) && (axe < 3) && (0 <= curve) && (curve < 4) && (amin < amax)
+ && (amin <= amid) && (amid <= amax)) {
+ fAcc[axe].push_back(
+ new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
+ } else {
+ fprintf(stderr, "incorrect acc metadata : %s \n", fCurrentAcc.c_str());
}
- fCurrentColor = "";
-
- fMetaData.push_back(fCurrentMetadata);
- fCurrentMetadata.clear();
+ fCurrentAcc = "";
}
- int getZoneIndex(std::vector<ZoneControl*>* table, int p, int val)
- {
- FAUSTFLOAT* zone = fItems[uint(p)].fZone;
- for (size_t i = 0; i < table[val].size(); i++) {
- if (zone == table[val][i]->getZone()) return int(i);
+ // handle gyr metadata "...[gyr : <axe> <curve> <amin> <amid> <amax>]..."
+ if (fCurrentGyr.size() > 0) {
+ std::istringstream iss(fCurrentGyr);
+ int axe, curve;
+ double amin, amid, amax;
+ iss >> axe >> curve >> amin >> amid >> amax;
+
+ if ((0 <= axe) && (axe < 3) && (0 <= curve) && (curve < 4) && (amin < amax)
+ && (amin <= amid) && (amid <= amax)) {
+ fGyr[axe].push_back(
+ new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
+ } else {
+ fprintf(stderr, "incorrect gyr metadata : %s \n", fCurrentGyr.c_str());
}
- return -1;
+ fCurrentGyr = "";
}
- void setConverter(std::vector<ZoneControl*>* table, int p, int val, int curve, double amin, double amid, double amax)
- {
- int id1 = getZoneIndex(table, p, 0);
- int id2 = getZoneIndex(table, p, 1);
- int id3 = getZoneIndex(table, p, 2);
-
- // Deactivates everywhere..
- if (id1 != -1) table[0][uint(id1)]->setActive(false);
- if (id2 != -1) table[1][uint(id2)]->setActive(false);
- if (id3 != -1) table[2][uint(id3)]->setActive(false);
-
- if (val == -1) { // Means: no more mapping...
- // So stay all deactivated...
+ // handle screencolor metadata "...[screencolor:red|green|blue|white]..."
+ if (fCurrentColor.size() > 0) {
+ if ((fCurrentColor == "red") && (fRedReader == nullptr)) {
+ fRedReader = new ZoneReader(zone, min, max);
+ fHasScreenControl = true;
+ } else if ((fCurrentColor == "green") && (fGreenReader == nullptr)) {
+ fGreenReader = new ZoneReader(zone, min, max);
+ fHasScreenControl = true;
+ } else if ((fCurrentColor == "blue") && (fBlueReader == nullptr)) {
+ fBlueReader = new ZoneReader(zone, min, max);
+ fHasScreenControl = true;
+ } else if ((fCurrentColor == "white") && (fRedReader == nullptr)
+ && (fGreenReader == nullptr) && (fBlueReader == nullptr)) {
+ fRedReader = new ZoneReader(zone, min, max);
+ fGreenReader = new ZoneReader(zone, min, max);
+ fBlueReader = new ZoneReader(zone, min, max);
+ fHasScreenControl = true;
} else {
- int id4 = getZoneIndex(table, p, val);
- if (id4 != -1) {
- // Reactivate the one we edit...
- table[val][uint(id4)]->setMappingValues(curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit, fItems[uint(p)].fMax);
- table[val][uint(id4)]->setActive(true);
- } else {
- // Allocate a new CurveZoneControl which is 'active' by default
- FAUSTFLOAT* zone = fItems[uint(p)].fZone;
- table[val].push_back(new CurveZoneControl(zone, curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit, fItems[uint(p)].fMax));
- }
+ fprintf(stderr, "incorrect screencolor metadata : %s \n",
+ fCurrentColor.c_str());
}
}
-
- void getConverter(std::vector<ZoneControl*>* table, int p, int& val, int& curve, double& amin, double& amid, double& amax)
- {
- int id1 = getZoneIndex(table, p, 0);
- int id2 = getZoneIndex(table, p, 1);
- int id3 = getZoneIndex(table, p, 2);
-
- if (id1 != -1) {
- val = 0;
- curve = table[val][uint(id1)]->getCurve();
- table[val][uint(id1)]->getMappingValues(amin, amid, amax);
- } else if (id2 != -1) {
- val = 1;
- curve = table[val][uint(id2)]->getCurve();
- table[val][uint(id2)]->getMappingValues(amin, amid, amax);
- } else if (id3 != -1) {
- val = 2;
- curve = table[val][uint(id3)]->getCurve();
- table[val][uint(id3)]->getMappingValues(amin, amid, amax);
+ fCurrentColor = "";
+
+ fMetaData.push_back(fCurrentMetadata);
+ fCurrentMetadata.clear();
+ }
+
+ int getZoneIndex(std::vector<ZoneControl*>* table, int p, int val)
+ {
+ FAUSTFLOAT* zone = fItems[uint(p)].fZone;
+ for (size_t i = 0; i < table[val].size(); i++) {
+ if (zone == table[val][i]->getZone())
+ return int(i);
+ }
+ return -1;
+ }
+
+ void setConverter(std::vector<ZoneControl*>* table, int p, int val, int curve,
+ double amin, double amid, double amax)
+ {
+ int id1 = getZoneIndex(table, p, 0);
+ int id2 = getZoneIndex(table, p, 1);
+ int id3 = getZoneIndex(table, p, 2);
+
+ // Deactivates everywhere..
+ if (id1 != -1)
+ table[0][uint(id1)]->setActive(false);
+ if (id2 != -1)
+ table[1][uint(id2)]->setActive(false);
+ if (id3 != -1)
+ table[2][uint(id3)]->setActive(false);
+
+ if (val == -1) { // Means: no more mapping...
+ // So stay all deactivated...
+ } else {
+ int id4 = getZoneIndex(table, p, val);
+ if (id4 != -1) {
+ // Reactivate the one we edit...
+ table[val][uint(id4)]->setMappingValues(
+ curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit,
+ fItems[uint(p)].fMax);
+ table[val][uint(id4)]->setActive(true);
} else {
- val = -1; // No mapping
- curve = 0;
- amin = -100.;
- amid = 0.;
- amax = 100.;
+ // Allocate a new CurveZoneControl which is 'active' by default
+ FAUSTFLOAT* zone = fItems[uint(p)].fZone;
+ table[val].push_back(new CurveZoneControl(
+ zone, curve, amin, amid, amax, fItems[uint(p)].fMin,
+ fItems[uint(p)].fInit, fItems[uint(p)].fMax));
}
}
+ }
+
+ void getConverter(std::vector<ZoneControl*>* table, int p, int& val, int& curve,
+ double& amin, double& amid, double& amax)
+ {
+ int id1 = getZoneIndex(table, p, 0);
+ int id2 = getZoneIndex(table, p, 1);
+ int id3 = getZoneIndex(table, p, 2);
+
+ if (id1 != -1) {
+ val = 0;
+ curve = table[val][uint(id1)]->getCurve();
+ table[val][uint(id1)]->getMappingValues(amin, amid, amax);
+ } else if (id2 != -1) {
+ val = 1;
+ curve = table[val][uint(id2)]->getCurve();
+ table[val][uint(id2)]->getMappingValues(amin, amid, amax);
+ } else if (id3 != -1) {
+ val = 2;
+ curve = table[val][uint(id3)]->getCurve();
+ table[val][uint(id3)]->getMappingValues(amin, amid, amax);
+ } else {
+ val = -1; // No mapping
+ curve = 0;
+ amin = -100.;
+ amid = 0.;
+ amax = 100.;
+ }
+ }
+
+ public:
+ APIUI()
+ : fHasScreenControl(false)
+ , fRedReader(nullptr)
+ , fGreenReader(nullptr)
+ , fBlueReader(nullptr)
+ , fCurrentScale(kLin)
+ {
+ }
+
+ virtual ~APIUI()
+ {
+ for (const auto& it : fItems)
+ delete it.fConversion;
+ for (int i = 0; i < 3; i++) {
+ for (const auto& it : fAcc[i])
+ delete it;
+ for (const auto& it : fGyr[i])
+ delete it;
+ }
+ delete fRedReader;
+ delete fGreenReader;
+ delete fBlueReader;
+ }
- public:
-
- APIUI() : fHasScreenControl(false), fRedReader(nullptr), fGreenReader(nullptr), fBlueReader(nullptr), fCurrentScale(kLin)
- {}
+ // -- widget's layouts
- virtual ~APIUI()
- {
- for (const auto& it : fItems) delete it.fConversion;
- for (int i = 0; i < 3; i++) {
- for (const auto& it : fAcc[i]) delete it;
- for (const auto& it : fGyr[i]) delete it;
+ virtual void openTabBox(const char* label) { pushLabel(label); }
+ virtual void openHorizontalBox(const char* label) { pushLabel(label); }
+ virtual void openVerticalBox(const char* label) { pushLabel(label); }
+ virtual void closeBox()
+ {
+ if (popLabel()) {
+ // Shortnames can be computed when all fullnames are known
+ computeShortNames();
+ // Fill 'shortname' field for each item
+ for (const auto& it : fFull2Short) {
+ int index = getParamIndex(it.first.c_str());
+ fItems[index].fShortname = it.second;
}
- delete fRedReader;
- delete fGreenReader;
- delete fBlueReader;
}
+ }
- // -- widget's layouts
+ // -- active widgets
- virtual void openTabBox(const char* label) { pushLabel(label); }
- virtual void openHorizontalBox(const char* label) { pushLabel(label); }
- virtual void openVerticalBox(const char* label) { pushLabel(label); }
- virtual void closeBox()
- {
- if (popLabel()) {
- // Shortnames can be computed when all fullnames are known
- computeShortNames();
- // Fill 'shortname' field for each item
- for (const auto& it : fFull2Short) {
- int index = getParamIndex(it.first.c_str());
- fItems[index].fShortname = it.second;
- }
- }
- }
+ virtual void addButton(const char* label, FAUSTFLOAT* zone)
+ {
+ addParameter(label, zone, 0, 0, 1, 1, kButton);
+ }
+
+ virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)
+ {
+ addParameter(label, zone, 0, 0, 1, 1, kCheckButton);
+ }
+
+ virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init,
+ FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+ {
+ addParameter(label, zone, init, min, max, step, kVSlider);
+ }
+
+ virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init,
+ FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+ {
+ addParameter(label, zone, init, min, max, step, kHSlider);
+ }
+
+ virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init,
+ FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+ {
+ addParameter(label, zone, init, min, max, step, kNumEntry);
+ }
- // -- active widgets
+ // -- passive widgets
- virtual void addButton(const char* label, FAUSTFLOAT* zone)
- {
- addParameter(label, zone, 0, 0, 1, 1, kButton);
- }
+ virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone,
+ FAUSTFLOAT min, FAUSTFLOAT max)
+ {
+ addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kHBargraph);
+ }
- virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)
- {
- addParameter(label, zone, 0, 0, 1, 1, kCheckButton);
- }
+ virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min,
+ FAUSTFLOAT max)
+ {
+ addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kVBargraph);
+ }
- virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
- {
- addParameter(label, zone, init, min, max, step, kVSlider);
- }
+ // -- soundfiles
- virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
- {
- addParameter(label, zone, init, min, max, step, kHSlider);
- }
+ virtual void addSoundfile(const char* /* label */, const char* /* filename */,
+ Soundfile** /* sf_zone */)
+ {
+ }
- virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
- {
- addParameter(label, zone, init, min, max, step, kNumEntry);
- }
+ // -- metadata declarations
- // -- passive widgets
+ virtual void declare(FAUSTFLOAT* /* zone */, const char* key, const char* val)
+ {
+ // Keep metadata
+ fCurrentMetadata[key] = val;
- virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
- {
- addParameter(label, zone, min, min, max, (max-min)/1000.0f, kHBargraph);
+ if (strcmp(key, "scale") == 0) {
+ if (strcmp(val, "log") == 0) {
+ fCurrentScale = kLog;
+ } else if (strcmp(val, "exp") == 0) {
+ fCurrentScale = kExp;
+ } else {
+ fCurrentScale = kLin;
+ }
+ } else if (strcmp(key, "unit") == 0) {
+ fCurrentUnit = val;
+ } else if (strcmp(key, "acc") == 0) {
+ fCurrentAcc = val;
+ } else if (strcmp(key, "gyr") == 0) {
+ fCurrentGyr = val;
+ } else if (strcmp(key, "screencolor") == 0) {
+ fCurrentColor = val; // val = "red", "green", "blue" or "white"
+ } else if (strcmp(key, "tooltip") == 0) {
+ fCurrentTooltip = val;
}
+ }
- virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
- {
- addParameter(label, zone, min, min, max, (max-min)/1000.0f, kVBargraph);
- }
+ virtual void declare(const char* /* key */, const char* /* val */) {}
- // -- soundfiles
+ //-------------------------------------------------------------------------------
+ // Simple API part
+ //-------------------------------------------------------------------------------
- virtual void addSoundfile(const char* /* label */, const char* /* filename */, Soundfile** /* sf_zone */) {}
+ /**
+ * Return the number of parameters in the UI.
+ *
+ * @return the number of parameters
+ */
+ int getParamsCount() { return int(fItems.size()); }
- // -- metadata declarations
+ /**
+ * Return the param index.
+ *
+ * @param str - the UI parameter label/shortname/path
+ *
+ * @return the param index
+ */
+ int getParamIndex(const char* str)
+ {
+ std::string path = std::string(str);
+ auto it = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
+ return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path);
+ });
+ return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
+ }
- virtual void declare(FAUSTFLOAT* /* zone */, const char* key, const char* val)
- {
- // Keep metadata
- fCurrentMetadata[key] = val;
-
- if (strcmp(key, "scale") == 0) {
- if (strcmp(val, "log") == 0) {
- fCurrentScale = kLog;
- } else if (strcmp(val, "exp") == 0) {
- fCurrentScale = kExp;
- } else {
- fCurrentScale = kLin;
- }
- } else if (strcmp(key, "unit") == 0) {
- fCurrentUnit = val;
- } else if (strcmp(key, "acc") == 0) {
- fCurrentAcc = val;
- } else if (strcmp(key, "gyr") == 0) {
- fCurrentGyr = val;
- } else if (strcmp(key, "screencolor") == 0) {
- fCurrentColor = val; // val = "red", "green", "blue" or "white"
- } else if (strcmp(key, "tooltip") == 0) {
- fCurrentTooltip = val;
- }
- }
+ /**
+ * Return the param label.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param label
+ */
+ const char* getParamLabel(int p) { return fItems[uint(p)].fLabel.c_str(); }
- virtual void declare(const char* /* key */, const char* /* val */)
- {}
-
- //-------------------------------------------------------------------------------
- // Simple API part
- //-------------------------------------------------------------------------------
-
- /**
- * Return the number of parameters in the UI.
- *
- * @return the number of parameters
- */
- int getParamsCount() { return int(fItems.size()); }
-
- /**
- * Return the param index.
- *
- * @param str - the UI parameter label/shortname/path
- *
- * @return the param index
- */
- int getParamIndex(const char* str)
- {
- std::string path = std::string(str);
- auto it = find_if(fItems.begin(), fItems.end(),
- [=](const Item& it) { return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path); });
- return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
- }
-
- /**
- * Return the param label.
- *
- * @param p - the UI parameter index
- *
- * @return the param label
- */
- const char* getParamLabel(int p) { return fItems[uint(p)].fLabel.c_str(); }
-
- /**
- * Return the param shortname.
- *
- * @param p - the UI parameter index
- *
- * @return the param shortname
- */
- const char* getParamShortname(int p) { return fItems[uint(p)].fShortname.c_str(); }
-
- /**
- * Return the param path.
- *
- * @param p - the UI parameter index
- *
- * @return the param path
- */
- const char* getParamAddress(int p) { return fItems[uint(p)].fPath.c_str(); }
-
- /**
- * Return the param metadata.
- *
- * @param p - the UI parameter index
- *
- * @return the param metadata as a map<key, value>
- */
- std::map<const char*, const char*> getMetadata(int p)
- {
- std::map<const char*, const char*> res;
- std::map<std::string, std::string> metadata = fMetaData[uint(p)];
- for (const auto& it : metadata) {
- res[it.first.c_str()] = it.second.c_str();
- }
- return res;
- }
+ /**
+ * Return the param shortname.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param shortname
+ */
+ const char* getParamShortname(int p) { return fItems[uint(p)].fShortname.c_str(); }
- /**
- * Return the param metadata value.
- *
- * @param p - the UI parameter index
- * @param key - the UI parameter index
- *
- * @return the param metadata value associate to the key
- */
- const char* getMetadata(int p, const char* key)
- {
- return (fMetaData[uint(p)].find(key) != fMetaData[uint(p)].end()) ? fMetaData[uint(p)][key].c_str() : "";
- }
-
- /**
- * Return the param minimum value.
- *
- * @param p - the UI parameter index
- *
- * @return the param minimum value
- */
- FAUSTFLOAT getParamMin(int p) { return fItems[uint(p)].fMin; }
-
- /**
- * Return the param maximum value.
- *
- * @param p - the UI parameter index
- *
- * @return the param maximum value
- */
- FAUSTFLOAT getParamMax(int p) { return fItems[uint(p)].fMax; }
-
- /**
- * Return the param step value.
- *
- * @param p - the UI parameter index
- *
- * @return the param step value
- */
- FAUSTFLOAT getParamStep(int p) { return fItems[uint(p)].fStep; }
-
- /**
- * Return the param init value.
- *
- * @param p - the UI parameter index
- *
- * @return the param init value
- */
- FAUSTFLOAT getParamInit(int p) { return fItems[uint(p)].fInit; }
-
- /**
- * Return the param memory zone.
- *
- * @param p - the UI parameter index
- *
- * @return the param memory zone.
- */
- FAUSTFLOAT* getParamZone(int p) { return fItems[uint(p)].fZone; }
-
- /**
- * Return the param value.
- *
- * @param p - the UI parameter index
- *
- * @return the param value.
- */
- FAUSTFLOAT getParamValue(int p) { return *fItems[uint(p)].fZone; }
-
- /**
- * Return the param value.
- *
- * @param str - the UI parameter label/shortname/path
- *
- * @return the param value.
- */
- FAUSTFLOAT getParamValue(const char* str)
- {
- int index = getParamIndex(str);
- if (index >= 0) {
- return getParamValue(index);
- } else {
- fprintf(stderr, "getParamValue : '%s' not found\n", (str == nullptr ? "NULL" : str));
- return FAUSTFLOAT(0);
- }
- }
+ /**
+ * Return the param path.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param path
+ */
+ const char* getParamAddress(int p) { return fItems[uint(p)].fPath.c_str(); }
- /**
- * Set the param value.
- *
- * @param p - the UI parameter index
- * @param v - the UI parameter value
- *
- */
- void setParamValue(int p, FAUSTFLOAT v) { *fItems[uint(p)].fZone = v; }
-
- /**
- * Set the param value.
- *
- * @param p - the UI parameter label/shortname/path
- * @param v - the UI parameter value
- *
- */
- void setParamValue(const char* path, FAUSTFLOAT v)
- {
- int index = getParamIndex(path);
- if (index >= 0) {
- setParamValue(index, v);
- } else {
- fprintf(stderr, "setParamValue : '%s' not found\n", (path == nullptr ? "NULL" : path));
- }
+ /**
+ * Return the param metadata.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param metadata as a map<key, value>
+ */
+ std::map<const char*, const char*> getMetadata(int p)
+ {
+ std::map<const char*, const char*> res;
+ std::map<std::string, std::string> metadata = fMetaData[uint(p)];
+ for (const auto& it : metadata) {
+ res[it.first.c_str()] = it.second.c_str();
}
+ return res;
+ }
- double getParamRatio(int p) { return fItems[uint(p)].fConversion->faust2ui(*fItems[uint(p)].fZone); }
- void setParamRatio(int p, double r) { *fItems[uint(p)].fZone = FAUSTFLOAT(fItems[uint(p)].fConversion->ui2faust(r)); }
+ /**
+ * Return the param metadata value.
+ *
+ * @param p - the UI parameter index
+ * @param key - the UI parameter index
+ *
+ * @return the param metadata value associate to the key
+ */
+ const char* getMetadata(int p, const char* key)
+ {
+ return (fMetaData[uint(p)].find(key) != fMetaData[uint(p)].end())
+ ? fMetaData[uint(p)][key].c_str()
+ : "";
+ }
- double value2ratio(int p, double r) { return fItems[uint(p)].fConversion->faust2ui(r); }
- double ratio2value(int p, double r) { return fItems[uint(p)].fConversion->ui2faust(r); }
+ /**
+ * Return the param minimum value.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param minimum value
+ */
+ FAUSTFLOAT getParamMin(int p) { return fItems[uint(p)].fMin; }
- /**
- * Return the control type (kAcc, kGyr, or -1) for a given parameter.
- *
- * @param p - the UI parameter index
- *
- * @return the type
- */
- Type getParamType(int p)
- {
- if (p >= 0) {
- if (getZoneIndex(fAcc, p, 0) != -1
- || getZoneIndex(fAcc, p, 1) != -1
- || getZoneIndex(fAcc, p, 2) != -1) {
- return kAcc;
- } else if (getZoneIndex(fGyr, p, 0) != -1
- || getZoneIndex(fGyr, p, 1) != -1
- || getZoneIndex(fGyr, p, 2) != -1) {
- return kGyr;
- }
- }
- return kNoType;
- }
+ /**
+ * Return the param maximum value.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param maximum value
+ */
+ FAUSTFLOAT getParamMax(int p) { return fItems[uint(p)].fMax; }
- /**
- * Return the Item type (kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry, kHBargraph, kVBargraph) for a given parameter.
- *
- * @param p - the UI parameter index
- *
- * @return the Item type
- */
- ItemType getParamItemType(int p)
- {
- return fItems[uint(p)].fItemType;
- }
+ /**
+ * Return the param step value.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param step value
+ */
+ FAUSTFLOAT getParamStep(int p) { return fItems[uint(p)].fStep; }
- /**
- * Set a new value coming from an accelerometer, propagate it to all relevant FAUSTFLOAT* zones.
- *
- * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
- * @param value - the new value
- *
- */
- void propagateAcc(int acc, double value)
- {
- for (size_t i = 0; i < fAcc[acc].size(); i++) {
- fAcc[acc][i]->update(value);
- }
- }
+ /**
+ * Return the param init value.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param init value
+ */
+ FAUSTFLOAT getParamInit(int p) { return fItems[uint(p)].fInit; }
- /**
- * Used to edit accelerometer curves and mapping. Set curve and related mapping for a given UI parameter.
- *
- * @param p - the UI parameter index
- * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer (-1 means "no mapping")
- * @param curve - between 0 and 3 (0: up, 1: down, 2: up and down, 2: down and up)
- * @param amin - mapping 'min' point
- * @param amid - mapping 'middle' point
- * @param amax - mapping 'max' point
- *
- */
- void setAccConverter(int p, int acc, int curve, double amin, double amid, double amax)
- {
- setConverter(fAcc, p, acc, curve, amin, amid, amax);
- }
+ /**
+ * Return the param memory zone.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param memory zone.
+ */
+ FAUSTFLOAT* getParamZone(int p) { return fItems[uint(p)].fZone; }
- /**
- * Used to edit gyroscope curves and mapping. Set curve and related mapping for a given UI parameter.
- *
- * @param p - the UI parameter index
- * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no mapping")
- * @param curve - between 0 and 3 (0: up, 1: down, 2: up and down, 2: down and up)
- * @param amin - mapping 'min' point
- * @param amid - mapping 'middle' point
- * @param amax - mapping 'max' point
- *
- */
- void setGyrConverter(int p, int gyr, int curve, double amin, double amid, double amax)
- {
- setConverter(fGyr, p, gyr, curve, amin, amid, amax);
- }
+ /**
+ * Return the param value.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param value.
+ */
+ FAUSTFLOAT getParamValue(int p) { return *fItems[uint(p)].fZone; }
- /**
- * Used to edit accelerometer curves and mapping. Get curve and related mapping for a given UI parameter.
- *
- * @param p - the UI parameter index
- * @param acc - the acc value to be retrieved (-1 means "no mapping")
- * @param curve - the curve value to be retrieved (between 0 and 3)
- * @param amin - the amin value to be retrieved
- * @param amid - the amid value to be retrieved
- * @param amax - the amax value to be retrieved
- *
- */
- void getAccConverter(int p, int& acc, int& curve, double& amin, double& amid, double& amax)
- {
- getConverter(fAcc, p, acc, curve, amin, amid, amax);
+ /**
+ * Return the param value.
+ *
+ * @param str - the UI parameter label/shortname/path
+ *
+ * @return the param value.
+ */
+ FAUSTFLOAT getParamValue(const char* str)
+ {
+ int index = getParamIndex(str);
+ if (index >= 0) {
+ return getParamValue(index);
+ } else {
+ fprintf(stderr, "getParamValue : '%s' not found\n",
+ (str == nullptr ? "NULL" : str));
+ return FAUSTFLOAT(0);
}
+ }
- /**
- * Used to edit gyroscope curves and mapping. Get curve and related mapping for a given UI parameter.
- *
- * @param p - the UI parameter index
- * @param gyr - the gyr value to be retrieved (-1 means "no mapping")
- * @param curve - the curve value to be retrieved (between 0 and 3)
- * @param amin - the amin value to be retrieved
- * @param amid - the amid value to be retrieved
- * @param amax - the amax value to be retrieved
- *
- */
- void getGyrConverter(int p, int& gyr, int& curve, double& amin, double& amid, double& amax)
- {
- getConverter(fGyr, p, gyr, curve, amin, amid, amax);
+ /**
+ * Set the param value.
+ *
+ * @param p - the UI parameter index
+ * @param v - the UI parameter value
+ *
+ */
+ void setParamValue(int p, FAUSTFLOAT v) { *fItems[uint(p)].fZone = v; }
+
+ /**
+ * Set the param value.
+ *
+ * @param p - the UI parameter label/shortname/path
+ * @param v - the UI parameter value
+ *
+ */
+ void setParamValue(const char* path, FAUSTFLOAT v)
+ {
+ int index = getParamIndex(path);
+ if (index >= 0) {
+ setParamValue(index, v);
+ } else {
+ fprintf(stderr, "setParamValue : '%s' not found\n",
+ (path == nullptr ? "NULL" : path));
}
+ }
+
+ double getParamRatio(int p)
+ {
+ return fItems[uint(p)].fConversion->faust2ui(*fItems[uint(p)].fZone);
+ }
+ void setParamRatio(int p, double r)
+ {
+ *fItems[uint(p)].fZone = FAUSTFLOAT(fItems[uint(p)].fConversion->ui2faust(r));
+ }
+
+ double value2ratio(int p, double r)
+ {
+ return fItems[uint(p)].fConversion->faust2ui(r);
+ }
+ double ratio2value(int p, double r)
+ {
+ return fItems[uint(p)].fConversion->ui2faust(r);
+ }
- /**
- * Set a new value coming from an gyroscope, propagate it to all relevant FAUSTFLOAT* zones.
- *
- * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
- * @param value - the new value
- *
- */
- void propagateGyr(int gyr, double value)
- {
- for (size_t i = 0; i < fGyr[gyr].size(); i++) {
- fGyr[gyr][i]->update(value);
+ /**
+ * Return the control type (kAcc, kGyr, or -1) for a given parameter.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the type
+ */
+ Type getParamType(int p)
+ {
+ if (p >= 0) {
+ if (getZoneIndex(fAcc, p, 0) != -1 || getZoneIndex(fAcc, p, 1) != -1
+ || getZoneIndex(fAcc, p, 2) != -1) {
+ return kAcc;
+ } else if (getZoneIndex(fGyr, p, 0) != -1 || getZoneIndex(fGyr, p, 1) != -1
+ || getZoneIndex(fGyr, p, 2) != -1) {
+ return kGyr;
}
}
+ return kNoType;
+ }
- /**
- * Get the number of FAUSTFLOAT* zones controlled with the accelerometer.
- *
- * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
- * @return the number of zones
- *
- */
- int getAccCount(int acc)
- {
- return (acc >= 0 && acc < 3) ? int(fAcc[acc].size()) : 0;
- }
+ /**
+ * Return the Item type (kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry,
+ * kHBargraph, kVBargraph) for a given parameter.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the Item type
+ */
+ ItemType getParamItemType(int p) { return fItems[uint(p)].fItemType; }
- /**
- * Get the number of FAUSTFLOAT* zones controlled with the gyroscope.
- *
- * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
- * @param the number of zones
- *
- */
- int getGyrCount(int gyr)
- {
- return (gyr >= 0 && gyr < 3) ? int(fGyr[gyr].size()) : 0;
+ /**
+ * Set a new value coming from an accelerometer, propagate it to all relevant
+ * FAUSTFLOAT* zones.
+ *
+ * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
+ * @param value - the new value
+ *
+ */
+ void propagateAcc(int acc, double value)
+ {
+ for (size_t i = 0; i < fAcc[acc].size(); i++) {
+ fAcc[acc][i]->update(value);
}
+ }
- /**
- * Get the requested screen color.
- *
- * -1 means no screen color control (no screencolor metadata found)
- * otherwise return 0x00RRGGBB a ready to use color
- *
- */
- int getScreenColor()
- {
- if (fHasScreenControl) {
- int r = (fRedReader) ? fRedReader->getValue() : 0;
- int g = (fGreenReader) ? fGreenReader->getValue() : 0;
- int b = (fBlueReader) ? fBlueReader->getValue() : 0;
- return (r<<16) | (g<<8) | b;
- } else {
- return -1;
- }
+ /**
+ * Used to edit accelerometer curves and mapping. Set curve and related mapping for a
+ * given UI parameter.
+ *
+ * @param p - the UI parameter index
+ * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
+ * (-1 means "no mapping")
+ * @param curve - between 0 and 3 (0: up, 1: down, 2: up and down, 2: down and up)
+ * @param amin - mapping 'min' point
+ * @param amid - mapping 'middle' point
+ * @param amax - mapping 'max' point
+ *
+ */
+ void setAccConverter(int p, int acc, int curve, double amin, double amid, double amax)
+ {
+ setConverter(fAcc, p, acc, curve, amin, amid, amax);
+ }
+
+ /**
+ * Used to edit gyroscope curves and mapping. Set curve and related mapping for a
+ * given UI parameter.
+ *
+ * @param p - the UI parameter index
+ * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no
+ * mapping")
+ * @param curve - between 0 and 3 (0: up, 1: down, 2: up and down, 2: down and up)
+ * @param amin - mapping 'min' point
+ * @param amid - mapping 'middle' point
+ * @param amax - mapping 'max' point
+ *
+ */
+ void setGyrConverter(int p, int gyr, int curve, double amin, double amid, double amax)
+ {
+ setConverter(fGyr, p, gyr, curve, amin, amid, amax);
+ }
+
+ /**
+ * Used to edit accelerometer curves and mapping. Get curve and related mapping for a
+ * given UI parameter.
+ *
+ * @param p - the UI parameter index
+ * @param acc - the acc value to be retrieved (-1 means "no mapping")
+ * @param curve - the curve value to be retrieved (between 0 and 3)
+ * @param amin - the amin value to be retrieved
+ * @param amid - the amid value to be retrieved
+ * @param amax - the amax value to be retrieved
+ *
+ */
+ void getAccConverter(int p, int& acc, int& curve, double& amin, double& amid,
+ double& amax)
+ {
+ getConverter(fAcc, p, acc, curve, amin, amid, amax);
+ }
+
+ /**
+ * Used to edit gyroscope curves and mapping. Get curve and related mapping for a
+ * given UI parameter.
+ *
+ * @param p - the UI parameter index
+ * @param gyr - the gyr value to be retrieved (-1 means "no mapping")
+ * @param curve - the curve value to be retrieved (between 0 and 3)
+ * @param amin - the amin value to be retrieved
+ * @param amid - the amid value to be retrieved
+ * @param amax - the amax value to be retrieved
+ *
+ */
+ void getGyrConverter(int p, int& gyr, int& curve, double& amin, double& amid,
+ double& amax)
+ {
+ getConverter(fGyr, p, gyr, curve, amin, amid, amax);
+ }
+
+ /**
+ * Set a new value coming from an gyroscope, propagate it to all relevant FAUSTFLOAT*
+ * zones.
+ *
+ * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
+ * @param value - the new value
+ *
+ */
+ void propagateGyr(int gyr, double value)
+ {
+ for (size_t i = 0; i < fGyr[gyr].size(); i++) {
+ fGyr[gyr][i]->update(value);
}
+ }
+
+ /**
+ * Get the number of FAUSTFLOAT* zones controlled with the accelerometer.
+ *
+ * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
+ * @return the number of zones
+ *
+ */
+ int getAccCount(int acc) { return (acc >= 0 && acc < 3) ? int(fAcc[acc].size()) : 0; }
+ /**
+ * Get the number of FAUSTFLOAT* zones controlled with the gyroscope.
+ *
+ * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
+ * @param the number of zones
+ *
+ */
+ int getGyrCount(int gyr) { return (gyr >= 0 && gyr < 3) ? int(fGyr[gyr].size()) : 0; }
+
+ /**
+ * Get the requested screen color.
+ *
+ * -1 means no screen color control (no screencolor metadata found)
+ * otherwise return 0x00RRGGBB a ready to use color
+ *
+ */
+ int getScreenColor()
+ {
+ if (fHasScreenControl) {
+ int r = (fRedReader) ? fRedReader->getValue() : 0;
+ int g = (fGreenReader) ? fGreenReader->getValue() : 0;
+ int b = (fBlueReader) ? fBlueReader->getValue() : 0;
+ return (r << 16) | (g << 8) | b;
+ } else {
+ return -1;
+ }
+ }
};
#endif
// FAUST Generated Code
//----------------------------------------------------------------------------
-
#ifndef FAUSTFLOAT
#define FAUSTFLOAT float
-#endif
+#endif
#include <algorithm>
#include <cmath>
#include <cstdint>
-#ifndef FAUSTCLASS
+#ifndef FAUSTCLASS
#define FAUSTCLASS stereotomonodsp
#endif
-#ifdef __APPLE__
+#ifdef __APPLE__
#define exp10f __exp10f
-#define exp10 __exp10
+#define exp10 __exp10
#endif
#if defined(_WIN32)
#define RESTRICT __restrict__
#endif
-
-class stereotomonodsp : public dsp {
-
- private:
-
- int fSampleRate;
-
- public:
-
- void metadata(Meta* m) {
- m->declare("author", "Dominick Hing");
- m->declare("compile_options", "-a faust2header.cpp -lang cpp -i -inpl -cn stereotomonodsp -es 1 -mcd 16 -single -ftz 0");
- m->declare("description", "Stereo-to-Mono Faust Plugin for JackTrip");
- m->declare("filename", "stereotomonodsp.dsp");
- m->declare("license", "MIT Style STK-4.2");
- m->declare("name", "stereo-to-mono");
- m->declare("version", "1.0");
- }
-
- virtual int getNumInputs() {
- return 2;
- }
- virtual int getNumOutputs() {
- return 1;
- }
-
- static void classInit(int /* sample_rate */) {
- }
-
- virtual void instanceConstants(int sample_rate) {
- fSampleRate = sample_rate;
- }
-
- virtual void instanceResetUserInterface() {
- }
-
- virtual void instanceClear() {
- }
-
- virtual void init(int sample_rate) {
- classInit(sample_rate);
- instanceInit(sample_rate);
- }
- virtual void instanceInit(int sample_rate) {
- instanceConstants(sample_rate);
- instanceResetUserInterface();
- instanceClear();
- }
-
- virtual stereotomonodsp* clone() {
- return new stereotomonodsp();
- }
-
- virtual int getSampleRate() {
- return fSampleRate;
- }
-
- virtual void buildUserInterface(UI* ui_interface) {
- ui_interface->openVerticalBox("stereo-to-mono");
- ui_interface->closeBox();
- }
-
- virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {
- FAUSTFLOAT* input0 = inputs[0];
- FAUSTFLOAT* input1 = inputs[1];
- FAUSTFLOAT* output0 = outputs[0];
- for (int i0 = 0; i0 < count; i0 = i0 + 1) {
- float fTemp0 = float(input0[i0]);
- float fTemp1 = float(input1[i0]);
- output0[i0] = FAUSTFLOAT(0.5f * (fTemp0 + fTemp1));
- }
- }
-
+class stereotomonodsp : public dsp
+{
+ private:
+ int fSampleRate;
+
+ public:
+ void metadata(Meta* m)
+ {
+ m->declare("author", "Dominick Hing");
+ m->declare("compile_options",
+ "-a faust2header.cpp -lang cpp -i -inpl -cn stereotomonodsp -es 1 "
+ "-mcd 16 -single -ftz 0");
+ m->declare("description", "Stereo-to-Mono Faust Plugin for JackTrip");
+ m->declare("filename", "stereotomonodsp.dsp");
+ m->declare("license", "MIT Style STK-4.2");
+ m->declare("name", "stereo-to-mono");
+ m->declare("version", "1.0");
+ }
+
+ virtual int getNumInputs() { return 2; }
+ virtual int getNumOutputs() { return 1; }
+
+ static void classInit(int /* sample_rate */) {}
+
+ virtual void instanceConstants(int sample_rate) { fSampleRate = sample_rate; }
+
+ virtual void instanceResetUserInterface() {}
+
+ virtual void instanceClear() {}
+
+ virtual void init(int sample_rate)
+ {
+ classInit(sample_rate);
+ instanceInit(sample_rate);
+ }
+ virtual void instanceInit(int sample_rate)
+ {
+ instanceConstants(sample_rate);
+ instanceResetUserInterface();
+ instanceClear();
+ }
+
+ virtual stereotomonodsp* clone() { return new stereotomonodsp(); }
+
+ virtual int getSampleRate() { return fSampleRate; }
+
+ virtual void buildUserInterface(UI* ui_interface)
+ {
+ ui_interface->openVerticalBox("stereo-to-mono");
+ ui_interface->closeBox();
+ }
+
+ virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs)
+ {
+ FAUSTFLOAT* input0 = inputs[0];
+ FAUSTFLOAT* input1 = inputs[1];
+ FAUSTFLOAT* output0 = outputs[0];
+ for (int i0 = 0; i0 < count; i0 = i0 + 1) {
+ float fTemp0 = float(input0[i0]);
+ float fTemp1 = float(input1[i0]);
+ output0[i0] = FAUSTFLOAT(0.5f * (fTemp0 + fTemp1));
+ }
+ }
};
-
#endif
/* ------------------------------------------------------------
name: "tonedsp"
Code generated with Faust 2.50.6 (https://faust.grame.fr)
-Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn tonedsp -es 1 -mcd 16 -single -ftz 0
+Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn tonedsp -es 1 -mcd 16
+-single -ftz 0
------------------------------------------------------------ */
-#ifndef __tonedsp_H__
-#define __tonedsp_H__
+#ifndef __tonedsp_H__
+#define __tonedsp_H__
// NOTE: ANY INCLUDE-GUARD HERE MUST BE DERIVED FROM THE CLASS NAME
//
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
#define FAUSTVERSION "2.50.6"
-// Use FAUST_API for code that is part of the external API but is also compiled in faust and libfaust
-// Use LIBFAUST_API for code that is compiled in faust and libfaust
+// Use FAUST_API for code that is part of the external API but is also compiled in faust
+// and libfaust Use LIBFAUST_API for code that is compiled in faust and libfaust
#ifdef _WIN32
- #pragma warning (disable: 4251)
- #ifdef FAUST_EXE
- #define FAUST_API
- #define LIBFAUST_API
- #elif FAUST_LIB
- #define FAUST_API __declspec(dllexport)
- #define LIBFAUST_API __declspec(dllexport)
- #else
- #define FAUST_API
- #define LIBFAUST_API
- #endif
+#pragma warning(disable : 4251)
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#elif FAUST_LIB
+#define FAUST_API __declspec(dllexport)
+#define LIBFAUST_API __declspec(dllexport)
+#else
+#define FAUST_API
+#define LIBFAUST_API
+#endif
+#else
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
#else
- #ifdef FAUST_EXE
- #define FAUST_API
- #define LIBFAUST_API
- #else
- #define FAUST_API __attribute__((visibility("default")))
- #define LIBFAUST_API __attribute__((visibility("default")))
- #endif
+#define FAUST_API __attribute__((visibility("default")))
+#define LIBFAUST_API __attribute__((visibility("default")))
+#endif
#endif
#endif
*/
struct FAUST_API dsp_memory_manager {
-
virtual ~dsp_memory_manager() {}
-
+
/**
* Inform the Memory Manager with the number of expected memory zones.
* @param count - the number of expected memory zones
*/
virtual void begin(size_t /*count*/) {}
-
+
/**
* Give the Memory Manager information on a given memory zone.
* @param size - the size in bytes of the memory zone
* @param writes - the number of Write access to the zone used to compute one frame
*/
virtual void info(size_t /*size*/, size_t /*reads*/, size_t /*writes*/) {}
-
+
/**
* Inform the Memory Manager that all memory zones have been described,
* to possibly start a 'compute the best allocation strategy' step.
*/
virtual void end() {}
-
+
/**
* Allocate a memory zone.
* @param size - the memory zone size in bytes
*/
virtual void* allocate(size_t size) = 0;
-
+
/**
* Destroy a memory zone.
* @param ptr - the memory zone pointer to be deallocated
*/
virtual void destroy(void* ptr) = 0;
-
-};
-
-/**
-* Signal processor definition.
-*/
-
-class FAUST_API dsp {
-
- public:
-
- dsp() {}
- virtual ~dsp() {}
-
- /* Return instance number of audio inputs */
- virtual int getNumInputs() = 0;
-
- /* Return instance number of audio outputs */
- virtual int getNumOutputs() = 0;
-
- /**
- * Trigger the ui_interface parameter with instance specific calls
- * to 'openTabBox', 'addButton', 'addVerticalSlider'... in order to build the UI.
- *
- * @param ui_interface - the user interface builder
- */
- virtual void buildUserInterface(UI* ui_interface) = 0;
-
- /* Return the sample rate currently used by the instance */
- virtual int getSampleRate() = 0;
-
- /**
- * Global init, calls the following methods:
- * - static class 'classInit': static tables initialization
- * - 'instanceInit': constants and instance state initialization
- *
- * @param sample_rate - the sampling rate in Hz
- */
- virtual void init(int sample_rate) = 0;
-
- /**
- * Init instance state
- *
- * @param sample_rate - the sampling rate in Hz
- */
- virtual void instanceInit(int sample_rate) = 0;
-
- /**
- * Init instance constant state
- *
- * @param sample_rate - the sampling rate in Hz
- */
- virtual void instanceConstants(int sample_rate) = 0;
-
- /* Init default control parameters values */
- virtual void instanceResetUserInterface() = 0;
-
- /* Init instance state (like delay lines...) but keep the control parameter values */
- virtual void instanceClear() = 0;
-
- /**
- * Return a clone of the instance.
- *
- * @return a copy of the instance on success, otherwise a null pointer.
- */
- virtual dsp* clone() = 0;
-
- /**
- * Trigger the Meta* parameter with instance specific calls to 'declare' (key, value) metadata.
- *
- * @param m - the Meta* meta user
- */
- virtual void metadata(Meta* m) = 0;
-
- /**
- * DSP instance computation, to be called with successive in/out audio buffers.
- *
- * @param count - the number of frames to compute
- * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT samples (eiher float, double or quad)
- * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT samples (eiher float, double or quad)
- *
- */
- virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) = 0;
-
- /**
- * DSP instance computation: alternative method to be used by subclasses.
- *
- * @param date_usec - the timestamp in microsec given by audio driver.
- * @param count - the number of frames to compute
- * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT samples (either float, double or quad)
- * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT samples (either float, double or quad)
- *
- */
- virtual void compute(double /*date_usec*/, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { compute(count, inputs, outputs); }
-
};
/**
- * Generic DSP decorator.
+ * Signal processor definition.
*/
-class FAUST_API decorator_dsp : public dsp {
+class FAUST_API dsp
+{
+ public:
+ dsp() {}
+ virtual ~dsp() {}
+
+ /* Return instance number of audio inputs */
+ virtual int getNumInputs() = 0;
+
+ /* Return instance number of audio outputs */
+ virtual int getNumOutputs() = 0;
+
+ /**
+ * Trigger the ui_interface parameter with instance specific calls
+ * to 'openTabBox', 'addButton', 'addVerticalSlider'... in order to build the UI.
+ *
+ * @param ui_interface - the user interface builder
+ */
+ virtual void buildUserInterface(UI* ui_interface) = 0;
+
+ /* Return the sample rate currently used by the instance */
+ virtual int getSampleRate() = 0;
+
+ /**
+ * Global init, calls the following methods:
+ * - static class 'classInit': static tables initialization
+ * - 'instanceInit': constants and instance state initialization
+ *
+ * @param sample_rate - the sampling rate in Hz
+ */
+ virtual void init(int sample_rate) = 0;
+
+ /**
+ * Init instance state
+ *
+ * @param sample_rate - the sampling rate in Hz
+ */
+ virtual void instanceInit(int sample_rate) = 0;
+
+ /**
+ * Init instance constant state
+ *
+ * @param sample_rate - the sampling rate in Hz
+ */
+ virtual void instanceConstants(int sample_rate) = 0;
- protected:
+ /* Init default control parameters values */
+ virtual void instanceResetUserInterface() = 0;
- dsp* fDSP;
+ /* Init instance state (like delay lines...) but keep the control parameter values */
+ virtual void instanceClear() = 0;
+
+ /**
+ * Return a clone of the instance.
+ *
+ * @return a copy of the instance on success, otherwise a null pointer.
+ */
+ virtual dsp* clone() = 0;
- public:
+ /**
+ * Trigger the Meta* parameter with instance specific calls to 'declare' (key, value)
+ * metadata.
+ *
+ * @param m - the Meta* meta user
+ */
+ virtual void metadata(Meta* m) = 0;
- decorator_dsp(dsp* dsp = nullptr):fDSP(dsp) {}
- virtual ~decorator_dsp() { delete fDSP; }
+ /**
+ * DSP instance computation, to be called with successive in/out audio buffers.
+ *
+ * @param count - the number of frames to compute
+ * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT
+ * samples (eiher float, double or quad)
+ * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT
+ * samples (eiher float, double or quad)
+ *
+ */
+ virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) = 0;
+
+ /**
+ * DSP instance computation: alternative method to be used by subclasses.
+ *
+ * @param date_usec - the timestamp in microsec given by audio driver.
+ * @param count - the number of frames to compute
+ * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT
+ * samples (either float, double or quad)
+ * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT
+ * samples (either float, double or quad)
+ *
+ */
+ virtual void compute(double /*date_usec*/, int count, FAUSTFLOAT** inputs,
+ FAUSTFLOAT** outputs)
+ {
+ compute(count, inputs, outputs);
+ }
+};
+
+/**
+ * Generic DSP decorator.
+ */
- virtual int getNumInputs() { return fDSP->getNumInputs(); }
- virtual int getNumOutputs() { return fDSP->getNumOutputs(); }
- virtual void buildUserInterface(UI* ui_interface) { fDSP->buildUserInterface(ui_interface); }
- virtual int getSampleRate() { return fDSP->getSampleRate(); }
- virtual void init(int sample_rate) { fDSP->init(sample_rate); }
- virtual void instanceInit(int sample_rate) { fDSP->instanceInit(sample_rate); }
- virtual void instanceConstants(int sample_rate) { fDSP->instanceConstants(sample_rate); }
- virtual void instanceResetUserInterface() { fDSP->instanceResetUserInterface(); }
- virtual void instanceClear() { fDSP->instanceClear(); }
- virtual decorator_dsp* clone() { return new decorator_dsp(fDSP->clone()); }
- virtual void metadata(Meta* m) { fDSP->metadata(m); }
- // Beware: subclasses usually have to overload the two 'compute' methods
- virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { fDSP->compute(count, inputs, outputs); }
- virtual void compute(double date_usec, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { fDSP->compute(date_usec, count, inputs, outputs); }
-
+class FAUST_API decorator_dsp : public dsp
+{
+ protected:
+ dsp* fDSP;
+
+ public:
+ decorator_dsp(dsp* dsp = nullptr) : fDSP(dsp) {}
+ virtual ~decorator_dsp() { delete fDSP; }
+
+ virtual int getNumInputs() { return fDSP->getNumInputs(); }
+ virtual int getNumOutputs() { return fDSP->getNumOutputs(); }
+ virtual void buildUserInterface(UI* ui_interface)
+ {
+ fDSP->buildUserInterface(ui_interface);
+ }
+ virtual int getSampleRate() { return fDSP->getSampleRate(); }
+ virtual void init(int sample_rate) { fDSP->init(sample_rate); }
+ virtual void instanceInit(int sample_rate) { fDSP->instanceInit(sample_rate); }
+ virtual void instanceConstants(int sample_rate)
+ {
+ fDSP->instanceConstants(sample_rate);
+ }
+ virtual void instanceResetUserInterface() { fDSP->instanceResetUserInterface(); }
+ virtual void instanceClear() { fDSP->instanceClear(); }
+ virtual decorator_dsp* clone() { return new decorator_dsp(fDSP->clone()); }
+ virtual void metadata(Meta* m) { fDSP->metadata(m); }
+ // Beware: subclasses usually have to overload the two 'compute' methods
+ virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs)
+ {
+ fDSP->compute(count, inputs, outputs);
+ }
+ virtual void compute(double date_usec, int count, FAUSTFLOAT** inputs,
+ FAUSTFLOAT** outputs)
+ {
+ fDSP->compute(date_usec, count, inputs, outputs);
+ }
};
/**
* to create DSP instances from a compiled DSP program.
*/
-class FAUST_API dsp_factory {
-
- protected:
-
- // So that to force sub-classes to use deleteDSPFactory(dsp_factory* factory);
- virtual ~dsp_factory() {}
-
- public:
-
- virtual std::string getName() = 0;
- virtual std::string getSHAKey() = 0;
- virtual std::string getDSPCode() = 0;
- virtual std::string getCompileOptions() = 0;
- virtual std::vector<std::string> getLibraryList() = 0;
- virtual std::vector<std::string> getIncludePathnames() = 0;
-
- virtual dsp* createDSPInstance() = 0;
-
- virtual void setMemoryManager(dsp_memory_manager* manager) = 0;
- virtual dsp_memory_manager* getMemoryManager() = 0;
-
+class FAUST_API dsp_factory
+{
+ protected:
+ // So that to force sub-classes to use deleteDSPFactory(dsp_factory* factory);
+ virtual ~dsp_factory() {}
+
+ public:
+ virtual std::string getName() = 0;
+ virtual std::string getSHAKey() = 0;
+ virtual std::string getDSPCode() = 0;
+ virtual std::string getCompileOptions() = 0;
+ virtual std::vector<std::string> getLibraryList() = 0;
+ virtual std::vector<std::string> getIncludePathnames() = 0;
+
+ virtual dsp* createDSPInstance() = 0;
+
+ virtual void setMemoryManager(dsp_memory_manager* manager) = 0;
+ virtual dsp_memory_manager* getMemoryManager() = 0;
};
// Denormal handling
-#if defined (__SSE__)
+#if defined(__SSE__)
#include <xmmintrin.h>
#endif
-class FAUST_API ScopedNoDenormals {
-
- private:
-
- intptr_t fpsr = 0;
-
- void setFpStatusRegister(intptr_t fpsr_aux) noexcept
- {
- #if defined (__arm64__) || defined (__aarch64__)
- asm volatile("msr fpcr, %0" : : "ri" (fpsr_aux));
- #elif defined (__SSE__)
- // The volatile keyword here is needed to workaround a bug in AppleClang 13.0
- // which aggressively optimises away the variable otherwise
- volatile uint32_t fpsr_w = static_cast<uint32_t>(fpsr_aux);
- _mm_setcsr(fpsr_w);
- #endif
- }
-
- void getFpStatusRegister() noexcept
- {
- #if defined (__arm64__) || defined (__aarch64__)
- asm volatile("mrs %0, fpcr" : "=r" (fpsr));
- #elif defined (__SSE__)
- fpsr = static_cast<intptr_t>(_mm_getcsr());
- #endif
- }
-
- public:
-
- ScopedNoDenormals() noexcept
- {
- #if defined (__arm64__) || defined (__aarch64__)
- intptr_t mask = (1 << 24 /* FZ */);
- #elif defined (__SSE__)
- #if defined (__SSE2__)
- intptr_t mask = 0x8040;
- #else
- intptr_t mask = 0x8000;
- #endif
- #else
- intptr_t mask = 0x0000;
- #endif
- getFpStatusRegister();
- setFpStatusRegister(fpsr | mask);
- }
-
- ~ScopedNoDenormals() noexcept
- {
- setFpStatusRegister(fpsr);
- }
+class FAUST_API ScopedNoDenormals
+{
+ private:
+ intptr_t fpsr = 0;
+
+ void setFpStatusRegister(intptr_t fpsr_aux) noexcept
+ {
+#if defined(__arm64__) || defined(__aarch64__)
+ asm volatile("msr fpcr, %0" : : "ri"(fpsr_aux));
+#elif defined(__SSE__)
+ // The volatile keyword here is needed to workaround a bug in AppleClang 13.0
+ // which aggressively optimises away the variable otherwise
+ volatile uint32_t fpsr_w = static_cast<uint32_t>(fpsr_aux);
+ _mm_setcsr(fpsr_w);
+#endif
+ }
+
+ void getFpStatusRegister() noexcept
+ {
+#if defined(__arm64__) || defined(__aarch64__)
+ asm volatile("mrs %0, fpcr" : "=r"(fpsr));
+#elif defined(__SSE__)
+ fpsr = static_cast<intptr_t>(_mm_getcsr());
+#endif
+ }
+
+ public:
+ ScopedNoDenormals() noexcept
+ {
+#if defined(__arm64__) || defined(__aarch64__)
+ intptr_t mask = (1 << 24 /* FZ */);
+#elif defined(__SSE__)
+#if defined(__SSE2__)
+ intptr_t mask = 0x8040;
+#else
+ intptr_t mask = 0x8000;
+#endif
+#else
+ intptr_t mask = 0x0000;
+#endif
+ getFpStatusRegister();
+ setFpStatusRegister(fpsr | mask);
+ }
+ ~ScopedNoDenormals() noexcept { setFpStatusRegister(fpsr); }
};
#define AVOIDDENORMALS ScopedNoDenormals ftz_scope;
#ifndef API_UI_H
#define API_UI_H
+#include <stdio.h>
+
+#include <map>
#include <sstream>
#include <string>
#include <vector>
-#include <stdio.h>
-#include <map>
/************************** BEGIN meta.h *******************************
FAUST Architecture File
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
#ifndef __meta__
#define __meta__
-
/**
- The base class of Meta handler to be used in dsp::metadata(Meta* m) method to retrieve (key, value) metadata.
+ The base class of Meta handler to be used in dsp::metadata(Meta* m) method to retrieve
+ (key, value) metadata.
*/
struct FAUST_API Meta {
virtual ~Meta() {}
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
#ifndef __UI_H__
#define __UI_H__
-
#ifndef FAUSTFLOAT
#define FAUSTFLOAT float
#endif
struct Soundfile;
-template <typename REAL>
+template<typename REAL>
struct FAUST_API UIReal {
-
UIReal() {}
virtual ~UIReal() {}
-
+
// -- widget's layouts
-
- virtual void openTabBox(const char* label) = 0;
+
+ virtual void openTabBox(const char* label) = 0;
virtual void openHorizontalBox(const char* label) = 0;
- virtual void openVerticalBox(const char* label) = 0;
- virtual void closeBox() = 0;
-
+ virtual void openVerticalBox(const char* label) = 0;
+ virtual void closeBox() = 0;
+
// -- active widgets
-
- virtual void addButton(const char* label, REAL* zone) = 0;
+
+ virtual void addButton(const char* label, REAL* zone) = 0;
virtual void addCheckButton(const char* label, REAL* zone) = 0;
- virtual void addVerticalSlider(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0;
- virtual void addHorizontalSlider(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0;
- virtual void addNumEntry(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0;
-
+ virtual void addVerticalSlider(const char* label, REAL* zone, REAL init, REAL min,
+ REAL max, REAL step) = 0;
+ virtual void addHorizontalSlider(const char* label, REAL* zone, REAL init, REAL min,
+ REAL max, REAL step) = 0;
+ virtual void addNumEntry(const char* label, REAL* zone, REAL init, REAL min, REAL max,
+ REAL step) = 0;
+
// -- passive widgets
-
- virtual void addHorizontalBargraph(const char* label, REAL* zone, REAL min, REAL max) = 0;
- virtual void addVerticalBargraph(const char* label, REAL* zone, REAL min, REAL max) = 0;
-
+
+ virtual void addHorizontalBargraph(const char* label, REAL* zone, REAL min,
+ REAL max) = 0;
+ virtual void addVerticalBargraph(const char* label, REAL* zone, REAL min,
+ REAL max) = 0;
+
// -- soundfiles
-
- virtual void addSoundfile(const char* label, const char* filename, Soundfile** sf_zone) = 0;
-
+
+ virtual void addSoundfile(const char* label, const char* filename,
+ Soundfile** sf_zone) = 0;
+
// -- metadata declarations
-
+
virtual void declare(REAL* /*zone*/, const char* /*key*/, const char* /*val*/) {}
-
+
// To be used by LLVM client
virtual int sizeOfFAUSTFLOAT() { return sizeof(FAUSTFLOAT); }
};
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
#ifndef __PathBuilder__
#define __PathBuilder__
-#include <vector>
-#include <set>
-#include <map>
-#include <string>
#include <algorithm>
+#include <map>
#include <regex>
-
+#include <set>
+#include <string>
+#include <vector>
/*******************************************************************************
* PathBuilder : Faust User Interface
* Helper class to build complete hierarchical path for UI items.
******************************************************************************/
-class FAUST_API PathBuilder {
-
- protected:
-
- std::vector<std::string> fControlsLevel;
- std::vector<std::string> fFullPaths;
- std::map<std::string, std::string> fFull2Short; // filled by computeShortNames()
-
- /**
- * @brief check if a character is acceptable for an ID
- *
- * @param c
- * @return true is the character is acceptable for an ID
- */
- bool isIDChar(char c) const
- {
- return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9'));
- }
-
- /**
- * @brief remove all "/0x00" parts
- *
- * @param src
- * @return modified string
- */
- std::string remove0x00(const std::string& src) const
- {
- return std::regex_replace(src, std::regex("/0x00"), "");
- }
-
- /**
- * @brief replace all non ID char with '_' (one '_' may replace several non ID char)
- *
- * @param src
- * @return modified string
- */
- std::string str2ID(const std::string& src) const
- {
- std::string dst;
- bool need_underscore = false;
- for (char c : src) {
- if (isIDChar(c) || (c == '/')) {
- if (need_underscore) {
- dst.push_back('_');
- need_underscore = false;
- }
- dst.push_back(c);
- } else {
- need_underscore = true;
+class FAUST_API PathBuilder
+{
+ protected:
+ std::vector<std::string> fControlsLevel;
+ std::vector<std::string> fFullPaths;
+ std::map<std::string, std::string> fFull2Short; // filled by computeShortNames()
+
+ /**
+ * @brief check if a character is acceptable for an ID
+ *
+ * @param c
+ * @return true is the character is acceptable for an ID
+ */
+ bool isIDChar(char c) const
+ {
+ return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))
+ || ((c >= '0') && (c <= '9'));
+ }
+
+ /**
+ * @brief remove all "/0x00" parts
+ *
+ * @param src
+ * @return modified string
+ */
+ std::string remove0x00(const std::string& src) const
+ {
+ return std::regex_replace(src, std::regex("/0x00"), "");
+ }
+
+ /**
+ * @brief replace all non ID char with '_' (one '_' may replace several non ID char)
+ *
+ * @param src
+ * @return modified string
+ */
+ std::string str2ID(const std::string& src) const
+ {
+ std::string dst;
+ bool need_underscore = false;
+ for (char c : src) {
+ if (isIDChar(c) || (c == '/')) {
+ if (need_underscore) {
+ dst.push_back('_');
+ need_underscore = false;
}
+ dst.push_back(c);
+ } else {
+ need_underscore = true;
}
- return dst;
}
-
- /**
- * @brief Keep only the last n slash-parts
- *
- * @param src
- * @param n : 1 indicates the last slash-part
- * @return modified string
- */
- std::string cut(const std::string& src, int n) const
- {
- std::string rdst;
- for (int i = int(src.length())-1; i >= 0; i--) {
- char c = src[i];
- if (c != '/') {
- rdst.push_back(c);
- } else if (n == 1) {
- std::string dst;
- for (int j = int(rdst.length())-1; j >= 0; j--) {
- dst.push_back(rdst[j]);
- }
- return dst;
- } else {
- n--;
- rdst.push_back(c);
+ return dst;
+ }
+
+ /**
+ * @brief Keep only the last n slash-parts
+ *
+ * @param src
+ * @param n : 1 indicates the last slash-part
+ * @return modified string
+ */
+ std::string cut(const std::string& src, int n) const
+ {
+ std::string rdst;
+ for (int i = int(src.length()) - 1; i >= 0; i--) {
+ char c = src[i];
+ if (c != '/') {
+ rdst.push_back(c);
+ } else if (n == 1) {
+ std::string dst;
+ for (int j = int(rdst.length()) - 1; j >= 0; j--) {
+ dst.push_back(rdst[j]);
}
+ return dst;
+ } else {
+ n--;
+ rdst.push_back(c);
}
- return src;
}
-
- void addFullPath(const std::string& label) { fFullPaths.push_back(buildPath(label)); }
-
- /**
- * @brief Compute the mapping between full path and short names
- */
- void computeShortNames()
- {
- std::vector<std::string> uniquePaths; // all full paths transformed but made unique with a prefix
- std::map<std::string, std::string> unique2full; // all full paths transformed but made unique with a prefix
- char num_buffer[16];
- int pnum = 0;
-
- for (const auto& s : fFullPaths) {
- sprintf(num_buffer, "%d", pnum++);
- std::string u = "/P" + std::string(num_buffer) + str2ID(remove0x00(s));
- uniquePaths.push_back(u);
- unique2full[u] = s; // remember the full path associated to a unique path
- }
-
- std::map<std::string, int> uniquePath2level; // map path to level
- for (const auto& s : uniquePaths) uniquePath2level[s] = 1; // we init all levels to 1
- bool have_collisions = true;
-
- while (have_collisions) {
- // compute collision list
- std::set<std::string> collisionSet;
- std::map<std::string, std::string> short2full;
- have_collisions = false;
- for (const auto& it : uniquePath2level) {
- std::string u = it.first;
- int n = it.second;
- std::string shortName = cut(u, n);
- auto p = short2full.find(shortName);
- if (p == short2full.end()) {
- // no collision
- short2full[shortName] = u;
- } else {
- // we have a collision, add the two paths to the collision set
- have_collisions = true;
- collisionSet.insert(u);
- collisionSet.insert(p->second);
- }
- }
- for (const auto& s : collisionSet) uniquePath2level[s]++; // increase level of colliding path
- }
-
+ return src;
+ }
+
+ void addFullPath(const std::string& label) { fFullPaths.push_back(buildPath(label)); }
+
+ /**
+ * @brief Compute the mapping between full path and short names
+ */
+ void computeShortNames()
+ {
+ std::vector<std::string>
+ uniquePaths; // all full paths transformed but made unique with a prefix
+ std::map<std::string, std::string>
+ unique2full; // all full paths transformed but made unique with a prefix
+ char num_buffer[16];
+ int pnum = 0;
+
+ for (const auto& s : fFullPaths) {
+ sprintf(num_buffer, "%d", pnum++);
+ std::string u = "/P" + std::string(num_buffer) + str2ID(remove0x00(s));
+ uniquePaths.push_back(u);
+ unique2full[u] = s; // remember the full path associated to a unique path
+ }
+
+ std::map<std::string, int> uniquePath2level; // map path to level
+ for (const auto& s : uniquePaths)
+ uniquePath2level[s] = 1; // we init all levels to 1
+ bool have_collisions = true;
+
+ while (have_collisions) {
+ // compute collision list
+ std::set<std::string> collisionSet;
+ std::map<std::string, std::string> short2full;
+ have_collisions = false;
for (const auto& it : uniquePath2level) {
- std::string u = it.first;
- int n = it.second;
- std::string shortName = replaceCharList(cut(u, n), {'/'}, '_');
- fFull2Short[unique2full[u]] = shortName;
+ std::string u = it.first;
+ int n = it.second;
+ std::string shortName = cut(u, n);
+ auto p = short2full.find(shortName);
+ if (p == short2full.end()) {
+ // no collision
+ short2full[shortName] = u;
+ } else {
+ // we have a collision, add the two paths to the collision set
+ have_collisions = true;
+ collisionSet.insert(u);
+ collisionSet.insert(p->second);
+ }
}
+ for (const auto& s : collisionSet)
+ uniquePath2level[s]++; // increase level of colliding path
}
-
- std::string replaceCharList(const std::string& str, const std::vector<char>& ch1, char ch2)
- {
- auto beg = ch1.begin();
- auto end = ch1.end();
- std::string res = str;
- for (size_t i = 0; i < str.length(); ++i) {
- if (std::find(beg, end, str[i]) != end) res[i] = ch2;
- }
- return res;
+
+ for (const auto& it : uniquePath2level) {
+ std::string u = it.first;
+ int n = it.second;
+ std::string shortName = replaceCharList(cut(u, n), {'/'}, '_');
+ fFull2Short[unique2full[u]] = shortName;
}
-
- public:
-
- PathBuilder() {}
- virtual ~PathBuilder() {}
-
- // Return true for the first level of groups
- bool pushLabel(const std::string& label) { fControlsLevel.push_back(label); return fControlsLevel.size() == 1;}
-
- // Return true for the last level of groups
- bool popLabel() { fControlsLevel.pop_back(); return fControlsLevel.size() == 0; }
-
- std::string buildPath(const std::string& label)
- {
- std::string res = "/";
- for (size_t i = 0; i < fControlsLevel.size(); i++) {
- res = res + fControlsLevel[i] + "/";
- }
- res += label;
- return replaceCharList(res, {' ', '#', '*', ',', '?', '[', ']', '{', '}', '(', ')'}, '_');
+ }
+
+ std::string replaceCharList(const std::string& str, const std::vector<char>& ch1,
+ char ch2)
+ {
+ auto beg = ch1.begin();
+ auto end = ch1.end();
+ std::string res = str;
+ for (size_t i = 0; i < str.length(); ++i) {
+ if (std::find(beg, end, str[i]) != end)
+ res[i] = ch2;
}
-
+ return res;
+ }
+
+ public:
+ PathBuilder() {}
+ virtual ~PathBuilder() {}
+
+ // Return true for the first level of groups
+ bool pushLabel(const std::string& label)
+ {
+ fControlsLevel.push_back(label);
+ return fControlsLevel.size() == 1;
+ }
+
+ // Return true for the last level of groups
+ bool popLabel()
+ {
+ fControlsLevel.pop_back();
+ return fControlsLevel.size() == 0;
+ }
+
+ std::string buildPath(const std::string& label)
+ {
+ std::string res = "/";
+ for (size_t i = 0; i < fControlsLevel.size(); i++) {
+ res = res + fControlsLevel[i] + "/";
+ }
+ res += label;
+ return replaceCharList(
+ res, {' ', '#', '*', ',', '?', '[', ']', '{', '}', '(', ')'}, '_');
+ }
};
#endif // __PathBuilder__
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
/***************************************************************************************
ValueConverter.h
(GRAME, Copyright 2015-2019)
-
+
Set of conversion objects used to map user interface values (for example a gui slider
delivering values between 0 and 1) to faust values (for example a vslider between
20 and 20000) using a log scale.
-
+
-- Utilities
-
+
Range(lo,hi) : clip a value x between lo and hi
- Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and v2
- Interpolator3pt(lo,mi,hi,v1,vm,v2) : Map values between lo mid hi to values between v1 vm v2
-
+ Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and
+v2 Interpolator3pt(lo,mi,hi,v1,vm,v2) : Map values between lo mid hi to values between v1
+vm v2
+
-- Value Converters
-
+
ValueConverter::ui2faust(x)
ValueConverter::faust2ui(x)
-
+
-- ValueConverters used for sliders depending of the scale
-
+
LinearValueConverter(umin, umax, fmin, fmax)
LinearValueConverter2(lo, mi, hi, v1, vm, v2) using 2 segments
LogValueConverter(umin, umax, fmin, fmax)
ExpValueConverter(umin, umax, fmin, fmax)
-
+
-- ValueConverters used for accelerometers based on 3 points
-
+
AccUpConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 0
AccDownConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 1
AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 2
AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 3
-
+
-- lists of ZoneControl are used to implement accelerometers metadata for each axes
-
+
ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter
-
+
-- ZoneReader are used to implement screencolor metadata
-
+
ZoneReader(zone, valueConverter) : a zone with a data converter
****************************************************************************************/
+#include <assert.h>
#include <float.h>
-#include <algorithm> // std::max
+
+#include <algorithm> // std::max
#include <cmath>
#include <vector>
-#include <assert.h>
-
//--------------------------------------------------------------------------------------
// Interpolator(lo,hi,v1,v2)
// y = v1 - lo*coef + x*coef
// y = offset + x*coef with offset = v1 - lo*coef
//--------------------------------------------------------------------------------------
-class FAUST_API Interpolator {
-
- private:
-
- //--------------------------------------------------------------------------------------
- // Range(lo,hi) clip a value between lo and hi
- //--------------------------------------------------------------------------------------
- struct Range
- {
- double fLo;
- double fHi;
-
- Range(double x, double y) : fLo(std::min<double>(x,y)), fHi(std::max<double>(x,y)) {}
- double operator()(double x) { return (x<fLo) ? fLo : (x>fHi) ? fHi : x; }
- };
-
-
- Range fRange;
- double fCoef;
- double fOffset;
-
- public:
-
- Interpolator(double lo, double hi, double v1, double v2) : fRange(lo,hi)
+class FAUST_API Interpolator
+{
+ private:
+ //--------------------------------------------------------------------------------------
+ // Range(lo,hi) clip a value between lo and hi
+ //--------------------------------------------------------------------------------------
+ struct Range {
+ double fLo;
+ double fHi;
+
+ Range(double x, double y)
+ : fLo(std::min<double>(x, y)), fHi(std::max<double>(x, y))
{
- if (hi != lo) {
- // regular case
- fCoef = (v2-v1)/(hi-lo);
- fOffset = v1 - lo*fCoef;
- } else {
- // degenerate case, avoids division by zero
- fCoef = 0;
- fOffset = (v1+v2)/2;
- }
}
- double operator()(double v)
- {
- double x = fRange(v);
- return fOffset + x*fCoef;
- }
-
- void getLowHigh(double& amin, double& amax)
- {
- amin = fRange.fLo;
- amax = fRange.fHi;
+ double operator()(double x) { return (x < fLo) ? fLo : (x > fHi) ? fHi : x; }
+ };
+
+ Range fRange;
+ double fCoef;
+ double fOffset;
+
+ public:
+ Interpolator(double lo, double hi, double v1, double v2) : fRange(lo, hi)
+ {
+ if (hi != lo) {
+ // regular case
+ fCoef = (v2 - v1) / (hi - lo);
+ fOffset = v1 - lo * fCoef;
+ } else {
+ // degenerate case, avoids division by zero
+ fCoef = 0;
+ fOffset = (v1 + v2) / 2;
}
+ }
+ double operator()(double v)
+ {
+ double x = fRange(v);
+ return fOffset + x * fCoef;
+ }
+
+ void getLowHigh(double& amin, double& amax)
+ {
+ amin = fRange.fLo;
+ amax = fRange.fHi;
+ }
};
//--------------------------------------------------------------------------------------
// Interpolator3pt(lo,mi,hi,v1,vm,v2)
// Map values between lo mid hi to values between v1 vm v2
//--------------------------------------------------------------------------------------
-class FAUST_API Interpolator3pt {
-
- private:
-
- Interpolator fSegment1;
- Interpolator fSegment2;
- double fMid;
-
- public:
-
- Interpolator3pt(double lo, double mi, double hi, double v1, double vm, double v2) :
- fSegment1(lo, mi, v1, vm),
- fSegment2(mi, hi, vm, v2),
- fMid(mi) {}
- double operator()(double x) { return (x < fMid) ? fSegment1(x) : fSegment2(x); }
-
- void getMappingValues(double& amin, double& amid, double& amax)
- {
- fSegment1.getLowHigh(amin, amid);
- fSegment2.getLowHigh(amid, amax);
- }
+class FAUST_API Interpolator3pt
+{
+ private:
+ Interpolator fSegment1;
+ Interpolator fSegment2;
+ double fMid;
+
+ public:
+ Interpolator3pt(double lo, double mi, double hi, double v1, double vm, double v2)
+ : fSegment1(lo, mi, v1, vm), fSegment2(mi, hi, vm, v2), fMid(mi)
+ {
+ }
+ double operator()(double x) { return (x < fMid) ? fSegment1(x) : fSegment2(x); }
+
+ void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fSegment1.getLowHigh(amin, amid);
+ fSegment2.getLowHigh(amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Abstract ValueConverter class. Converts values between UI and Faust representations
//--------------------------------------------------------------------------------------
-class FAUST_API ValueConverter {
-
- public:
-
- virtual ~ValueConverter() {}
- virtual double ui2faust(double x) { return x; };
- virtual double faust2ui(double x) { return x; };
+class FAUST_API ValueConverter
+{
+ public:
+ virtual ~ValueConverter() {}
+ virtual double ui2faust(double x) { return x; };
+ virtual double faust2ui(double x) { return x; };
};
//--------------------------------------------------------------------------------------
// A converter than can be updated
//--------------------------------------------------------------------------------------
-class FAUST_API UpdatableValueConverter : public ValueConverter {
-
- protected:
-
- bool fActive;
-
- public:
-
- UpdatableValueConverter():fActive(true)
- {}
- virtual ~UpdatableValueConverter()
- {}
-
- virtual void setMappingValues(double amin, double amid, double amax, double min, double init, double max) = 0;
- virtual void getMappingValues(double& amin, double& amid, double& amax) = 0;
-
- void setActive(bool on_off) { fActive = on_off; }
- bool getActive() { return fActive; }
-
+class FAUST_API UpdatableValueConverter : public ValueConverter
+{
+ protected:
+ bool fActive;
+
+ public:
+ UpdatableValueConverter() : fActive(true) {}
+ virtual ~UpdatableValueConverter() {}
+
+ virtual void setMappingValues(double amin, double amid, double amax, double min,
+ double init, double max) = 0;
+ virtual void getMappingValues(double& amin, double& amid, double& amax) = 0;
+
+ void setActive(bool on_off) { fActive = on_off; }
+ bool getActive() { return fActive; }
};
//--------------------------------------------------------------------------------------
// Linear conversion between ui and Faust values
//--------------------------------------------------------------------------------------
-class FAUST_API LinearValueConverter : public ValueConverter {
-
- private:
-
- Interpolator fUI2F;
- Interpolator fF2UI;
-
- public:
-
- LinearValueConverter(double umin, double umax, double fmin, double fmax) :
- fUI2F(umin,umax,fmin,fmax), fF2UI(fmin,fmax,umin,umax)
- {}
-
- LinearValueConverter() : fUI2F(0.,0.,0.,0.), fF2UI(0.,0.,0.,0.)
- {}
- virtual double ui2faust(double x) { return fUI2F(x); }
- virtual double faust2ui(double x) { return fF2UI(x); }
-
+class FAUST_API LinearValueConverter : public ValueConverter
+{
+ private:
+ Interpolator fUI2F;
+ Interpolator fF2UI;
+
+ public:
+ LinearValueConverter(double umin, double umax, double fmin, double fmax)
+ : fUI2F(umin, umax, fmin, fmax), fF2UI(fmin, fmax, umin, umax)
+ {
+ }
+
+ LinearValueConverter() : fUI2F(0., 0., 0., 0.), fF2UI(0., 0., 0., 0.) {}
+ virtual double ui2faust(double x) { return fUI2F(x); }
+ virtual double faust2ui(double x) { return fF2UI(x); }
};
//--------------------------------------------------------------------------------------
// Two segments linear conversion between ui and Faust values
//--------------------------------------------------------------------------------------
-class FAUST_API LinearValueConverter2 : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fUI2F;
- Interpolator3pt fF2UI;
-
- public:
-
- LinearValueConverter2(double amin, double amid, double amax, double min, double init, double max) :
- fUI2F(amin, amid, amax, min, init, max), fF2UI(min, init, max, amin, amid, amax)
- {}
-
- LinearValueConverter2() : fUI2F(0.,0.,0.,0.,0.,0.), fF2UI(0.,0.,0.,0.,0.,0.)
- {}
-
- virtual double ui2faust(double x) { return fUI2F(x); }
- virtual double faust2ui(double x) { return fF2UI(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double min, double init, double max)
- {
- fUI2F = Interpolator3pt(amin, amid, amax, min, init, max);
- fF2UI = Interpolator3pt(min, init, max, amin, amid, amax);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fUI2F.getMappingValues(amin, amid, amax);
- }
-
+class FAUST_API LinearValueConverter2 : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fUI2F;
+ Interpolator3pt fF2UI;
+
+ public:
+ LinearValueConverter2(double amin, double amid, double amax, double min, double init,
+ double max)
+ : fUI2F(amin, amid, amax, min, init, max), fF2UI(min, init, max, amin, amid, amax)
+ {
+ }
+
+ LinearValueConverter2() : fUI2F(0., 0., 0., 0., 0., 0.), fF2UI(0., 0., 0., 0., 0., 0.)
+ {
+ }
+
+ virtual double ui2faust(double x) { return fUI2F(x); }
+ virtual double faust2ui(double x) { return fF2UI(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double min,
+ double init, double max)
+ {
+ fUI2F = Interpolator3pt(amin, amid, amax, min, init, max);
+ fF2UI = Interpolator3pt(min, init, max, amin, amid, amax);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fUI2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Logarithmic conversion between ui and Faust values
//--------------------------------------------------------------------------------------
-class FAUST_API LogValueConverter : public LinearValueConverter {
-
- public:
-
- LogValueConverter(double umin, double umax, double fmin, double fmax) :
- LinearValueConverter(umin, umax, std::log(std::max<double>(DBL_MIN, fmin)), std::log(std::max<double>(DBL_MIN, fmax)))
- {}
-
- virtual double ui2faust(double x) { return std::exp(LinearValueConverter::ui2faust(x)); }
- virtual double faust2ui(double x) { return LinearValueConverter::faust2ui(std::log(std::max<double>(x, DBL_MIN))); }
-
+class FAUST_API LogValueConverter : public LinearValueConverter
+{
+ public:
+ LogValueConverter(double umin, double umax, double fmin, double fmax)
+ : LinearValueConverter(umin, umax, std::log(std::max<double>(DBL_MIN, fmin)),
+ std::log(std::max<double>(DBL_MIN, fmax)))
+ {
+ }
+
+ virtual double ui2faust(double x)
+ {
+ return std::exp(LinearValueConverter::ui2faust(x));
+ }
+ virtual double faust2ui(double x)
+ {
+ return LinearValueConverter::faust2ui(std::log(std::max<double>(x, DBL_MIN)));
+ }
};
//--------------------------------------------------------------------------------------
// Exponential conversion between ui and Faust values
//--------------------------------------------------------------------------------------
-class FAUST_API ExpValueConverter : public LinearValueConverter {
-
- public:
-
- ExpValueConverter(double umin, double umax, double fmin, double fmax) :
- LinearValueConverter(umin, umax, std::min<double>(DBL_MAX, std::exp(fmin)), std::min<double>(DBL_MAX, std::exp(fmax)))
- {}
-
- virtual double ui2faust(double x) { return std::log(LinearValueConverter::ui2faust(x)); }
- virtual double faust2ui(double x) { return LinearValueConverter::faust2ui(std::min<double>(DBL_MAX, std::exp(x))); }
-
+class FAUST_API ExpValueConverter : public LinearValueConverter
+{
+ public:
+ ExpValueConverter(double umin, double umax, double fmin, double fmax)
+ : LinearValueConverter(umin, umax, std::min<double>(DBL_MAX, std::exp(fmin)),
+ std::min<double>(DBL_MAX, std::exp(fmax)))
+ {
+ }
+
+ virtual double ui2faust(double x)
+ {
+ return std::log(LinearValueConverter::ui2faust(x));
+ }
+ virtual double faust2ui(double x)
+ {
+ return LinearValueConverter::faust2ui(std::min<double>(DBL_MAX, std::exp(x)));
+ }
};
//--------------------------------------------------------------------------------------
// Convert accelerometer or gyroscope values to Faust values
// Using an Up curve (curve 0)
//--------------------------------------------------------------------------------------
-class FAUST_API AccUpConverter : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fA2F;
- Interpolator3pt fF2A;
-
- public:
-
- AccUpConverter(double amin, double amid, double amax, double fmin, double fmid, double fmax) :
- fA2F(amin,amid,amax,fmin,fmid,fmax),
- fF2A(fmin,fmid,fmax,amin,amid,amax)
- {}
-
- virtual double ui2faust(double x) { return fA2F(x); }
- virtual double faust2ui(double x) { return fF2A(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double fmin, double fmid, double fmax)
- {
- //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
- fA2F = Interpolator3pt(amin, amid, amax, fmin, fmid, fmax);
- fF2A = Interpolator3pt(fmin, fmid, fmax, amin, amid, amax);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fA2F.getMappingValues(amin, amid, amax);
- }
-
+class FAUST_API AccUpConverter : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fA2F;
+ Interpolator3pt fF2A;
+
+ public:
+ AccUpConverter(double amin, double amid, double amax, double fmin, double fmid,
+ double fmax)
+ : fA2F(amin, amid, amax, fmin, fmid, fmax)
+ , fF2A(fmin, fmid, fmax, amin, amid, amax)
+ {
+ }
+
+ virtual double ui2faust(double x) { return fA2F(x); }
+ virtual double faust2ui(double x) { return fF2A(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double fmin,
+ double fmid, double fmax)
+ {
+ //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpConverter update %f %f %f
+ //%f %f %f", amin,amid,amax,fmin,fmid,fmax);
+ fA2F = Interpolator3pt(amin, amid, amax, fmin, fmid, fmax);
+ fF2A = Interpolator3pt(fmin, fmid, fmax, amin, amid, amax);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fA2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Convert accelerometer or gyroscope values to Faust values
// Using a Down curve (curve 1)
//--------------------------------------------------------------------------------------
-class FAUST_API AccDownConverter : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fA2F;
- Interpolator3pt fF2A;
-
- public:
-
- AccDownConverter(double amin, double amid, double amax, double fmin, double fmid, double fmax) :
- fA2F(amin,amid,amax,fmax,fmid,fmin),
- fF2A(fmin,fmid,fmax,amax,amid,amin)
- {}
-
- virtual double ui2faust(double x) { return fA2F(x); }
- virtual double faust2ui(double x) { return fF2A(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double fmin, double fmid, double fmax)
- {
- //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
- fA2F = Interpolator3pt(amin, amid, amax, fmax, fmid, fmin);
- fF2A = Interpolator3pt(fmin, fmid, fmax, amax, amid, amin);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fA2F.getMappingValues(amin, amid, amax);
- }
+class FAUST_API AccDownConverter : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fA2F;
+ Interpolator3pt fF2A;
+
+ public:
+ AccDownConverter(double amin, double amid, double amax, double fmin, double fmid,
+ double fmax)
+ : fA2F(amin, amid, amax, fmax, fmid, fmin)
+ , fF2A(fmin, fmid, fmax, amax, amid, amin)
+ {
+ }
+
+ virtual double ui2faust(double x) { return fA2F(x); }
+ virtual double faust2ui(double x) { return fF2A(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double fmin,
+ double fmid, double fmax)
+ {
+ //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownConverter update %f %f
+ //%f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+ fA2F = Interpolator3pt(amin, amid, amax, fmax, fmid, fmin);
+ fF2A = Interpolator3pt(fmin, fmid, fmax, amax, amid, amin);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fA2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Convert accelerometer or gyroscope values to Faust values
// Using an Up-Down curve (curve 2)
//--------------------------------------------------------------------------------------
-class FAUST_API AccUpDownConverter : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fA2F;
- Interpolator fF2A;
-
- public:
-
- AccUpDownConverter(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax) :
- fA2F(amin,amid,amax,fmin,fmax,fmin),
- fF2A(fmin,fmax,amin,amax) // Special, pseudo inverse of a non monotonic function
- {}
-
- virtual double ui2faust(double x) { return fA2F(x); }
- virtual double faust2ui(double x) { return fF2A(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax)
- {
- //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpDownConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
- fA2F = Interpolator3pt(amin, amid, amax, fmin, fmax, fmin);
- fF2A = Interpolator(fmin, fmax, amin, amax);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fA2F.getMappingValues(amin, amid, amax);
- }
+class FAUST_API AccUpDownConverter : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fA2F;
+ Interpolator fF2A;
+
+ public:
+ AccUpDownConverter(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
+ : fA2F(amin, amid, amax, fmin, fmax, fmin)
+ , fF2A(fmin, fmax, amin,
+ amax) // Special, pseudo inverse of a non monotonic function
+ {
+ }
+
+ virtual double ui2faust(double x) { return fA2F(x); }
+ virtual double faust2ui(double x) { return fF2A(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
+ {
+ //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpDownConverter update %f %f
+ //%f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+ fA2F = Interpolator3pt(amin, amid, amax, fmin, fmax, fmin);
+ fF2A = Interpolator(fmin, fmax, amin, amax);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fA2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Convert accelerometer or gyroscope values to Faust values
// Using a Down-Up curve (curve 3)
//--------------------------------------------------------------------------------------
-class FAUST_API AccDownUpConverter : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fA2F;
- Interpolator fF2A;
-
- public:
-
- AccDownUpConverter(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax) :
- fA2F(amin,amid,amax,fmax,fmin,fmax),
- fF2A(fmin,fmax,amin,amax) // Special, pseudo inverse of a non monotonic function
- {}
-
- virtual double ui2faust(double x) { return fA2F(x); }
- virtual double faust2ui(double x) { return fF2A(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax)
- {
- //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownUpConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
- fA2F = Interpolator3pt(amin, amid, amax, fmax, fmin, fmax);
- fF2A = Interpolator(fmin, fmax, amin, amax);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fA2F.getMappingValues(amin, amid, amax);
- }
+class FAUST_API AccDownUpConverter : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fA2F;
+ Interpolator fF2A;
+
+ public:
+ AccDownUpConverter(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
+ : fA2F(amin, amid, amax, fmax, fmin, fmax)
+ , fF2A(fmin, fmax, amin,
+ amax) // Special, pseudo inverse of a non monotonic function
+ {
+ }
+
+ virtual double ui2faust(double x) { return fA2F(x); }
+ virtual double faust2ui(double x) { return fF2A(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
+ {
+ //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownUpConverter update %f %f
+ //%f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+ fA2F = Interpolator3pt(amin, amid, amax, fmax, fmin, fmax);
+ fF2A = Interpolator(fmin, fmax, amin, amax);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fA2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Base class for ZoneControl
//--------------------------------------------------------------------------------------
-class FAUST_API ZoneControl {
-
- protected:
-
- FAUSTFLOAT* fZone;
-
- public:
-
- ZoneControl(FAUSTFLOAT* zone) : fZone(zone) {}
- virtual ~ZoneControl() {}
+class FAUST_API ZoneControl
+{
+ protected:
+ FAUSTFLOAT* fZone;
- virtual void update(double /*v*/) const {}
+ public:
+ ZoneControl(FAUSTFLOAT* zone) : fZone(zone) {}
+ virtual ~ZoneControl() {}
- virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/, double /*amax*/, double /*min*/, double /*init*/, double /*max*/) {}
- virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
+ virtual void update(double /*v*/) const {}
- FAUSTFLOAT* getZone() { return fZone; }
+ virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/,
+ double /*amax*/, double /*min*/, double /*init*/,
+ double /*max*/)
+ {
+ }
+ virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
- virtual void setActive(bool /*on_off*/) {}
- virtual bool getActive() { return false; }
+ FAUSTFLOAT* getZone() { return fZone; }
- virtual int getCurve() { return -1; }
+ virtual void setActive(bool /*on_off*/) {}
+ virtual bool getActive() { return false; }
+ virtual int getCurve() { return -1; }
};
//--------------------------------------------------------------------------------------
// Useful to implement accelerometers metadata as a list of ZoneControl for each axes
//--------------------------------------------------------------------------------------
-class FAUST_API ConverterZoneControl : public ZoneControl {
-
- protected:
-
- ValueConverter* fValueConverter;
-
- public:
-
- ConverterZoneControl(FAUSTFLOAT* zone, ValueConverter* converter) : ZoneControl(zone), fValueConverter(converter) {}
- virtual ~ConverterZoneControl() { delete fValueConverter; } // Assuming fValueConverter is not kept elsewhere...
-
- virtual void update(double v) const { *fZone = FAUSTFLOAT(fValueConverter->ui2faust(v)); }
-
- ValueConverter* getConverter() { return fValueConverter; }
-
+class FAUST_API ConverterZoneControl : public ZoneControl
+{
+ protected:
+ ValueConverter* fValueConverter;
+
+ public:
+ ConverterZoneControl(FAUSTFLOAT* zone, ValueConverter* converter)
+ : ZoneControl(zone), fValueConverter(converter)
+ {
+ }
+ virtual ~ConverterZoneControl()
+ {
+ delete fValueConverter;
+ } // Assuming fValueConverter is not kept elsewhere...
+
+ virtual void update(double v) const
+ {
+ *fZone = FAUSTFLOAT(fValueConverter->ui2faust(v));
+ }
+
+ ValueConverter* getConverter() { return fValueConverter; }
};
//--------------------------------------------------------------------------------------
// Association of a zone and a four value converter, each one for each possible curve.
// Useful to implement accelerometers metadata as a list of ZoneControl for each axes
//--------------------------------------------------------------------------------------
-class FAUST_API CurveZoneControl : public ZoneControl {
-
- private:
-
- std::vector<UpdatableValueConverter*> fValueConverters;
- int fCurve;
-
- public:
-
- CurveZoneControl(FAUSTFLOAT* zone, int curve, double amin, double amid, double amax, double min, double init, double max) : ZoneControl(zone), fCurve(0)
- {
- assert(curve >= 0 && curve <= 3);
- fValueConverters.push_back(new AccUpConverter(amin, amid, amax, min, init, max));
- fValueConverters.push_back(new AccDownConverter(amin, amid, amax, min, init, max));
- fValueConverters.push_back(new AccUpDownConverter(amin, amid, amax, min, init, max));
- fValueConverters.push_back(new AccDownUpConverter(amin, amid, amax, min, init, max));
- fCurve = curve;
- }
- virtual ~CurveZoneControl()
- {
- for (const auto& it : fValueConverters) { delete it; }
- }
- void update(double v) const { if (fValueConverters[fCurve]->getActive()) *fZone = FAUSTFLOAT(fValueConverters[fCurve]->ui2faust(v)); }
-
- void setMappingValues(int curve, double amin, double amid, double amax, double min, double init, double max)
- {
- fValueConverters[curve]->setMappingValues(amin, amid, amax, min, init, max);
- fCurve = curve;
- }
-
- void getMappingValues(double& amin, double& amid, double& amax)
- {
- fValueConverters[fCurve]->getMappingValues(amin, amid, amax);
+class FAUST_API CurveZoneControl : public ZoneControl
+{
+ private:
+ std::vector<UpdatableValueConverter*> fValueConverters;
+ int fCurve;
+
+ public:
+ CurveZoneControl(FAUSTFLOAT* zone, int curve, double amin, double amid, double amax,
+ double min, double init, double max)
+ : ZoneControl(zone), fCurve(0)
+ {
+ assert(curve >= 0 && curve <= 3);
+ fValueConverters.push_back(new AccUpConverter(amin, amid, amax, min, init, max));
+ fValueConverters.push_back(
+ new AccDownConverter(amin, amid, amax, min, init, max));
+ fValueConverters.push_back(
+ new AccUpDownConverter(amin, amid, amax, min, init, max));
+ fValueConverters.push_back(
+ new AccDownUpConverter(amin, amid, amax, min, init, max));
+ fCurve = curve;
+ }
+ virtual ~CurveZoneControl()
+ {
+ for (const auto& it : fValueConverters) {
+ delete it;
}
-
- void setActive(bool on_off)
- {
- for (const auto& it : fValueConverters) { it->setActive(on_off); }
+ }
+ void update(double v) const
+ {
+ if (fValueConverters[fCurve]->getActive())
+ *fZone = FAUSTFLOAT(fValueConverters[fCurve]->ui2faust(v));
+ }
+
+ void setMappingValues(int curve, double amin, double amid, double amax, double min,
+ double init, double max)
+ {
+ fValueConverters[curve]->setMappingValues(amin, amid, amax, min, init, max);
+ fCurve = curve;
+ }
+
+ void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fValueConverters[fCurve]->getMappingValues(amin, amid, amax);
+ }
+
+ void setActive(bool on_off)
+ {
+ for (const auto& it : fValueConverters) {
+ it->setActive(on_off);
}
+ }
- int getCurve() { return fCurve; }
+ int getCurve() { return fCurve; }
};
-class FAUST_API ZoneReader {
-
- private:
-
- FAUSTFLOAT* fZone;
- Interpolator fInterpolator;
-
- public:
+class FAUST_API ZoneReader
+{
+ private:
+ FAUSTFLOAT* fZone;
+ Interpolator fInterpolator;
- ZoneReader(FAUSTFLOAT* zone, double lo, double hi) : fZone(zone), fInterpolator(lo, hi, 0, 255) {}
+ public:
+ ZoneReader(FAUSTFLOAT* zone, double lo, double hi)
+ : fZone(zone), fInterpolator(lo, hi, 0, 255)
+ {
+ }
- virtual ~ZoneReader() {}
-
- int getValue()
- {
- return (fZone != nullptr) ? int(fInterpolator(*fZone)) : 127;
- }
+ virtual ~ZoneReader() {}
+ int getValue() { return (fZone != nullptr) ? int(fInterpolator(*fZone)) : 127; }
};
#endif
typedef unsigned int uint;
-class APIUI : public PathBuilder, public Meta, public UI
+class APIUI
+ : public PathBuilder
+ , public Meta
+ , public UI
{
- public:
- enum ItemType { kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry, kHBargraph, kVBargraph };
- enum Type { kAcc = 0, kGyr = 1, kNoType };
-
- protected:
-
- enum Mapping { kLin = 0, kLog = 1, kExp = 2 };
-
- struct Item {
- std::string fLabel;
- std::string fShortname;
- std::string fPath;
- ValueConverter* fConversion;
- FAUSTFLOAT* fZone;
- FAUSTFLOAT fInit;
- FAUSTFLOAT fMin;
- FAUSTFLOAT fMax;
- FAUSTFLOAT fStep;
- ItemType fItemType;
-
- Item(const std::string& label,
- const std::string& short_name,
- const std::string& path,
- ValueConverter* conversion,
- FAUSTFLOAT* zone,
- FAUSTFLOAT init,
- FAUSTFLOAT min,
- FAUSTFLOAT max,
- FAUSTFLOAT step,
- ItemType item_type)
- :fLabel(label), fShortname(short_name), fPath(path), fConversion(conversion),
- fZone(zone), fInit(init), fMin(min), fMax(max), fStep(step), fItemType(item_type)
- {}
- };
- std::vector<Item> fItems;
-
- std::vector<std::map<std::string, std::string> > fMetaData;
- std::vector<ZoneControl*> fAcc[3];
- std::vector<ZoneControl*> fGyr[3];
-
- // Screen color control
- // "...[screencolor:red]..." etc.
- bool fHasScreenControl; // true if control screen color metadata
- ZoneReader* fRedReader;
- ZoneReader* fGreenReader;
- ZoneReader* fBlueReader;
-
- // Current values controlled by metadata
- std::string fCurrentUnit;
- int fCurrentScale;
- std::string fCurrentAcc;
- std::string fCurrentGyr;
- std::string fCurrentColor;
- std::string fCurrentTooltip;
- std::map<std::string, std::string> fCurrentMetadata;
-
- // Add a generic parameter
- virtual void addParameter(const char* label,
- FAUSTFLOAT* zone,
- FAUSTFLOAT init,
- FAUSTFLOAT min,
- FAUSTFLOAT max,
- FAUSTFLOAT step,
- ItemType type)
+ public:
+ enum ItemType {
+ kButton = 0,
+ kCheckButton,
+ kVSlider,
+ kHSlider,
+ kNumEntry,
+ kHBargraph,
+ kVBargraph
+ };
+ enum Type { kAcc = 0, kGyr = 1, kNoType };
+
+ protected:
+ enum Mapping { kLin = 0, kLog = 1, kExp = 2 };
+
+ struct Item {
+ std::string fLabel;
+ std::string fShortname;
+ std::string fPath;
+ ValueConverter* fConversion;
+ FAUSTFLOAT* fZone;
+ FAUSTFLOAT fInit;
+ FAUSTFLOAT fMin;
+ FAUSTFLOAT fMax;
+ FAUSTFLOAT fStep;
+ ItemType fItemType;
+
+ Item(const std::string& label, const std::string& short_name,
+ const std::string& path, ValueConverter* conversion, FAUSTFLOAT* zone,
+ FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step,
+ ItemType item_type)
+ : fLabel(label)
+ , fShortname(short_name)
+ , fPath(path)
+ , fConversion(conversion)
+ , fZone(zone)
+ , fInit(init)
+ , fMin(min)
+ , fMax(max)
+ , fStep(step)
+ , fItemType(item_type)
{
- std::string path = buildPath(label);
- fFullPaths.push_back(path);
-
- // handle scale metadata
- ValueConverter* converter = nullptr;
- switch (fCurrentScale) {
- case kLin:
- converter = new LinearValueConverter(0, 1, min, max);
- break;
- case kLog:
- converter = new LogValueConverter(0, 1, min, max);
- break;
- case kExp:
- converter = new ExpValueConverter(0, 1, min, max);
- break;
- }
- fCurrentScale = kLin;
-
- fItems.push_back(Item(label, "", path, converter, zone, init, min, max, step, type));
-
- if (fCurrentAcc.size() > 0 && fCurrentGyr.size() > 0) {
- fprintf(stderr, "warning : 'acc' and 'gyr' metadata used for the same %s parameter !!\n", label);
- }
+ }
+ };
+ std::vector<Item> fItems;
+
+ std::vector<std::map<std::string, std::string> > fMetaData;
+ std::vector<ZoneControl*> fAcc[3];
+ std::vector<ZoneControl*> fGyr[3];
+
+ // Screen color control
+ // "...[screencolor:red]..." etc.
+ bool fHasScreenControl; // true if control screen color metadata
+ ZoneReader* fRedReader;
+ ZoneReader* fGreenReader;
+ ZoneReader* fBlueReader;
+
+ // Current values controlled by metadata
+ std::string fCurrentUnit;
+ int fCurrentScale;
+ std::string fCurrentAcc;
+ std::string fCurrentGyr;
+ std::string fCurrentColor;
+ std::string fCurrentTooltip;
+ std::map<std::string, std::string> fCurrentMetadata;
+
+ // Add a generic parameter
+ virtual void addParameter(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init,
+ FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step,
+ ItemType type)
+ {
+ std::string path = buildPath(label);
+ fFullPaths.push_back(path);
+
+ // handle scale metadata
+ ValueConverter* converter = nullptr;
+ switch (fCurrentScale) {
+ case kLin:
+ converter = new LinearValueConverter(0, 1, min, max);
+ break;
+ case kLog:
+ converter = new LogValueConverter(0, 1, min, max);
+ break;
+ case kExp:
+ converter = new ExpValueConverter(0, 1, min, max);
+ break;
+ }
+ fCurrentScale = kLin;
- // handle acc metadata "...[acc : <axe> <curve> <amin> <amid> <amax>]..."
- if (fCurrentAcc.size() > 0) {
- std::istringstream iss(fCurrentAcc);
- int axe, curve;
- double amin, amid, amax;
- iss >> axe >> curve >> amin >> amid >> amax;
-
- if ((0 <= axe) && (axe < 3) &&
- (0 <= curve) && (curve < 4) &&
- (amin < amax) && (amin <= amid) && (amid <= amax))
- {
- fAcc[axe].push_back(new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
- } else {
- fprintf(stderr, "incorrect acc metadata : %s \n", fCurrentAcc.c_str());
- }
- fCurrentAcc = "";
- }
+ fItems.push_back(
+ Item(label, "", path, converter, zone, init, min, max, step, type));
- // handle gyr metadata "...[gyr : <axe> <curve> <amin> <amid> <amax>]..."
- if (fCurrentGyr.size() > 0) {
- std::istringstream iss(fCurrentGyr);
- int axe, curve;
- double amin, amid, amax;
- iss >> axe >> curve >> amin >> amid >> amax;
-
- if ((0 <= axe) && (axe < 3) &&
- (0 <= curve) && (curve < 4) &&
- (amin < amax) && (amin <= amid) && (amid <= amax))
- {
- fGyr[axe].push_back(new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
- } else {
- fprintf(stderr, "incorrect gyr metadata : %s \n", fCurrentGyr.c_str());
- }
- fCurrentGyr = "";
- }
+ if (fCurrentAcc.size() > 0 && fCurrentGyr.size() > 0) {
+ fprintf(
+ stderr,
+ "warning : 'acc' and 'gyr' metadata used for the same %s parameter !!\n",
+ label);
+ }
- // handle screencolor metadata "...[screencolor:red|green|blue|white]..."
- if (fCurrentColor.size() > 0) {
- if ((fCurrentColor == "red") && (fRedReader == nullptr)) {
- fRedReader = new ZoneReader(zone, min, max);
- fHasScreenControl = true;
- } else if ((fCurrentColor == "green") && (fGreenReader == nullptr)) {
- fGreenReader = new ZoneReader(zone, min, max);
- fHasScreenControl = true;
- } else if ((fCurrentColor == "blue") && (fBlueReader == nullptr)) {
- fBlueReader = new ZoneReader(zone, min, max);
- fHasScreenControl = true;
- } else if ((fCurrentColor == "white") && (fRedReader == nullptr) && (fGreenReader == nullptr) && (fBlueReader == nullptr)) {
- fRedReader = new ZoneReader(zone, min, max);
- fGreenReader = new ZoneReader(zone, min, max);
- fBlueReader = new ZoneReader(zone, min, max);
- fHasScreenControl = true;
- } else {
- fprintf(stderr, "incorrect screencolor metadata : %s \n", fCurrentColor.c_str());
- }
+ // handle acc metadata "...[acc : <axe> <curve> <amin> <amid> <amax>]..."
+ if (fCurrentAcc.size() > 0) {
+ std::istringstream iss(fCurrentAcc);
+ int axe, curve;
+ double amin, amid, amax;
+ iss >> axe >> curve >> amin >> amid >> amax;
+
+ if ((0 <= axe) && (axe < 3) && (0 <= curve) && (curve < 4) && (amin < amax)
+ && (amin <= amid) && (amid <= amax)) {
+ fAcc[axe].push_back(
+ new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
+ } else {
+ fprintf(stderr, "incorrect acc metadata : %s \n", fCurrentAcc.c_str());
}
- fCurrentColor = "";
-
- fMetaData.push_back(fCurrentMetadata);
- fCurrentMetadata.clear();
+ fCurrentAcc = "";
}
- int getZoneIndex(std::vector<ZoneControl*>* table, int p, int val)
- {
- FAUSTFLOAT* zone = fItems[uint(p)].fZone;
- for (size_t i = 0; i < table[val].size(); i++) {
- if (zone == table[val][i]->getZone()) return int(i);
+ // handle gyr metadata "...[gyr : <axe> <curve> <amin> <amid> <amax>]..."
+ if (fCurrentGyr.size() > 0) {
+ std::istringstream iss(fCurrentGyr);
+ int axe, curve;
+ double amin, amid, amax;
+ iss >> axe >> curve >> amin >> amid >> amax;
+
+ if ((0 <= axe) && (axe < 3) && (0 <= curve) && (curve < 4) && (amin < amax)
+ && (amin <= amid) && (amid <= amax)) {
+ fGyr[axe].push_back(
+ new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
+ } else {
+ fprintf(stderr, "incorrect gyr metadata : %s \n", fCurrentGyr.c_str());
}
- return -1;
+ fCurrentGyr = "";
}
- void setConverter(std::vector<ZoneControl*>* table, int p, int val, int curve, double amin, double amid, double amax)
- {
- int id1 = getZoneIndex(table, p, 0);
- int id2 = getZoneIndex(table, p, 1);
- int id3 = getZoneIndex(table, p, 2);
-
- // Deactivates everywhere..
- if (id1 != -1) table[0][uint(id1)]->setActive(false);
- if (id2 != -1) table[1][uint(id2)]->setActive(false);
- if (id3 != -1) table[2][uint(id3)]->setActive(false);
-
- if (val == -1) { // Means: no more mapping...
- // So stay all deactivated...
+ // handle screencolor metadata "...[screencolor:red|green|blue|white]..."
+ if (fCurrentColor.size() > 0) {
+ if ((fCurrentColor == "red") && (fRedReader == nullptr)) {
+ fRedReader = new ZoneReader(zone, min, max);
+ fHasScreenControl = true;
+ } else if ((fCurrentColor == "green") && (fGreenReader == nullptr)) {
+ fGreenReader = new ZoneReader(zone, min, max);
+ fHasScreenControl = true;
+ } else if ((fCurrentColor == "blue") && (fBlueReader == nullptr)) {
+ fBlueReader = new ZoneReader(zone, min, max);
+ fHasScreenControl = true;
+ } else if ((fCurrentColor == "white") && (fRedReader == nullptr)
+ && (fGreenReader == nullptr) && (fBlueReader == nullptr)) {
+ fRedReader = new ZoneReader(zone, min, max);
+ fGreenReader = new ZoneReader(zone, min, max);
+ fBlueReader = new ZoneReader(zone, min, max);
+ fHasScreenControl = true;
} else {
- int id4 = getZoneIndex(table, p, val);
- if (id4 != -1) {
- // Reactivate the one we edit...
- table[val][uint(id4)]->setMappingValues(curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit, fItems[uint(p)].fMax);
- table[val][uint(id4)]->setActive(true);
- } else {
- // Allocate a new CurveZoneControl which is 'active' by default
- FAUSTFLOAT* zone = fItems[uint(p)].fZone;
- table[val].push_back(new CurveZoneControl(zone, curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit, fItems[uint(p)].fMax));
- }
+ fprintf(stderr, "incorrect screencolor metadata : %s \n",
+ fCurrentColor.c_str());
}
}
-
- void getConverter(std::vector<ZoneControl*>* table, int p, int& val, int& curve, double& amin, double& amid, double& amax)
- {
- int id1 = getZoneIndex(table, p, 0);
- int id2 = getZoneIndex(table, p, 1);
- int id3 = getZoneIndex(table, p, 2);
-
- if (id1 != -1) {
- val = 0;
- curve = table[val][uint(id1)]->getCurve();
- table[val][uint(id1)]->getMappingValues(amin, amid, amax);
- } else if (id2 != -1) {
- val = 1;
- curve = table[val][uint(id2)]->getCurve();
- table[val][uint(id2)]->getMappingValues(amin, amid, amax);
- } else if (id3 != -1) {
- val = 2;
- curve = table[val][uint(id3)]->getCurve();
- table[val][uint(id3)]->getMappingValues(amin, amid, amax);
+ fCurrentColor = "";
+
+ fMetaData.push_back(fCurrentMetadata);
+ fCurrentMetadata.clear();
+ }
+
+ int getZoneIndex(std::vector<ZoneControl*>* table, int p, int val)
+ {
+ FAUSTFLOAT* zone = fItems[uint(p)].fZone;
+ for (size_t i = 0; i < table[val].size(); i++) {
+ if (zone == table[val][i]->getZone())
+ return int(i);
+ }
+ return -1;
+ }
+
+ void setConverter(std::vector<ZoneControl*>* table, int p, int val, int curve,
+ double amin, double amid, double amax)
+ {
+ int id1 = getZoneIndex(table, p, 0);
+ int id2 = getZoneIndex(table, p, 1);
+ int id3 = getZoneIndex(table, p, 2);
+
+ // Deactivates everywhere..
+ if (id1 != -1)
+ table[0][uint(id1)]->setActive(false);
+ if (id2 != -1)
+ table[1][uint(id2)]->setActive(false);
+ if (id3 != -1)
+ table[2][uint(id3)]->setActive(false);
+
+ if (val == -1) { // Means: no more mapping...
+ // So stay all deactivated...
+ } else {
+ int id4 = getZoneIndex(table, p, val);
+ if (id4 != -1) {
+ // Reactivate the one we edit...
+ table[val][uint(id4)]->setMappingValues(
+ curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit,
+ fItems[uint(p)].fMax);
+ table[val][uint(id4)]->setActive(true);
} else {
- val = -1; // No mapping
- curve = 0;
- amin = -100.;
- amid = 0.;
- amax = 100.;
+ // Allocate a new CurveZoneControl which is 'active' by default
+ FAUSTFLOAT* zone = fItems[uint(p)].fZone;
+ table[val].push_back(new CurveZoneControl(
+ zone, curve, amin, amid, amax, fItems[uint(p)].fMin,
+ fItems[uint(p)].fInit, fItems[uint(p)].fMax));
}
}
+ }
+
+ void getConverter(std::vector<ZoneControl*>* table, int p, int& val, int& curve,
+ double& amin, double& amid, double& amax)
+ {
+ int id1 = getZoneIndex(table, p, 0);
+ int id2 = getZoneIndex(table, p, 1);
+ int id3 = getZoneIndex(table, p, 2);
+
+ if (id1 != -1) {
+ val = 0;
+ curve = table[val][uint(id1)]->getCurve();
+ table[val][uint(id1)]->getMappingValues(amin, amid, amax);
+ } else if (id2 != -1) {
+ val = 1;
+ curve = table[val][uint(id2)]->getCurve();
+ table[val][uint(id2)]->getMappingValues(amin, amid, amax);
+ } else if (id3 != -1) {
+ val = 2;
+ curve = table[val][uint(id3)]->getCurve();
+ table[val][uint(id3)]->getMappingValues(amin, amid, amax);
+ } else {
+ val = -1; // No mapping
+ curve = 0;
+ amin = -100.;
+ amid = 0.;
+ amax = 100.;
+ }
+ }
+
+ public:
+ APIUI()
+ : fHasScreenControl(false)
+ , fRedReader(nullptr)
+ , fGreenReader(nullptr)
+ , fBlueReader(nullptr)
+ , fCurrentScale(kLin)
+ {
+ }
+
+ virtual ~APIUI()
+ {
+ for (const auto& it : fItems)
+ delete it.fConversion;
+ for (int i = 0; i < 3; i++) {
+ for (const auto& it : fAcc[i])
+ delete it;
+ for (const auto& it : fGyr[i])
+ delete it;
+ }
+ delete fRedReader;
+ delete fGreenReader;
+ delete fBlueReader;
+ }
- public:
-
- APIUI() : fHasScreenControl(false), fRedReader(nullptr), fGreenReader(nullptr), fBlueReader(nullptr), fCurrentScale(kLin)
- {}
+ // -- widget's layouts
- virtual ~APIUI()
- {
- for (const auto& it : fItems) delete it.fConversion;
- for (int i = 0; i < 3; i++) {
- for (const auto& it : fAcc[i]) delete it;
- for (const auto& it : fGyr[i]) delete it;
+ virtual void openTabBox(const char* label) { pushLabel(label); }
+ virtual void openHorizontalBox(const char* label) { pushLabel(label); }
+ virtual void openVerticalBox(const char* label) { pushLabel(label); }
+ virtual void closeBox()
+ {
+ if (popLabel()) {
+ // Shortnames can be computed when all fullnames are known
+ computeShortNames();
+ // Fill 'shortname' field for each item
+ for (const auto& it : fFull2Short) {
+ int index = getParamIndex(it.first.c_str());
+ fItems[index].fShortname = it.second;
}
- delete fRedReader;
- delete fGreenReader;
- delete fBlueReader;
}
+ }
- // -- widget's layouts
+ // -- active widgets
- virtual void openTabBox(const char* label) { pushLabel(label); }
- virtual void openHorizontalBox(const char* label) { pushLabel(label); }
- virtual void openVerticalBox(const char* label) { pushLabel(label); }
- virtual void closeBox()
- {
- if (popLabel()) {
- // Shortnames can be computed when all fullnames are known
- computeShortNames();
- // Fill 'shortname' field for each item
- for (const auto& it : fFull2Short) {
- int index = getParamIndex(it.first.c_str());
- fItems[index].fShortname = it.second;
- }
- }
- }
+ virtual void addButton(const char* label, FAUSTFLOAT* zone)
+ {
+ addParameter(label, zone, 0, 0, 1, 1, kButton);
+ }
+
+ virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)
+ {
+ addParameter(label, zone, 0, 0, 1, 1, kCheckButton);
+ }
+
+ virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init,
+ FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+ {
+ addParameter(label, zone, init, min, max, step, kVSlider);
+ }
+
+ virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init,
+ FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+ {
+ addParameter(label, zone, init, min, max, step, kHSlider);
+ }
+
+ virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init,
+ FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+ {
+ addParameter(label, zone, init, min, max, step, kNumEntry);
+ }
- // -- active widgets
+ // -- passive widgets
- virtual void addButton(const char* label, FAUSTFLOAT* zone)
- {
- addParameter(label, zone, 0, 0, 1, 1, kButton);
- }
+ virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone,
+ FAUSTFLOAT min, FAUSTFLOAT max)
+ {
+ addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kHBargraph);
+ }
- virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)
- {
- addParameter(label, zone, 0, 0, 1, 1, kCheckButton);
- }
+ virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min,
+ FAUSTFLOAT max)
+ {
+ addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kVBargraph);
+ }
- virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
- {
- addParameter(label, zone, init, min, max, step, kVSlider);
- }
+ // -- soundfiles
- virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
- {
- addParameter(label, zone, init, min, max, step, kHSlider);
- }
+ virtual void addSoundfile(const char* /*label*/, const char* /*filename*/,
+ Soundfile** /*sf_zone*/)
+ {
+ }
- virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
- {
- addParameter(label, zone, init, min, max, step, kNumEntry);
- }
+ // -- metadata declarations
- // -- passive widgets
+ virtual void declare(FAUSTFLOAT* /*zone*/, const char* key, const char* val)
+ {
+ // Keep metadata
+ fCurrentMetadata[key] = val;
- virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
- {
- addParameter(label, zone, min, min, max, (max-min)/1000.0f, kHBargraph);
+ if (strcmp(key, "scale") == 0) {
+ if (strcmp(val, "log") == 0) {
+ fCurrentScale = kLog;
+ } else if (strcmp(val, "exp") == 0) {
+ fCurrentScale = kExp;
+ } else {
+ fCurrentScale = kLin;
+ }
+ } else if (strcmp(key, "unit") == 0) {
+ fCurrentUnit = val;
+ } else if (strcmp(key, "acc") == 0) {
+ fCurrentAcc = val;
+ } else if (strcmp(key, "gyr") == 0) {
+ fCurrentGyr = val;
+ } else if (strcmp(key, "screencolor") == 0) {
+ fCurrentColor = val; // val = "red", "green", "blue" or "white"
+ } else if (strcmp(key, "tooltip") == 0) {
+ fCurrentTooltip = val;
}
+ }
- virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
- {
- addParameter(label, zone, min, min, max, (max-min)/1000.0f, kVBargraph);
- }
+ virtual void declare(const char* /*key*/, const char* /*val*/) {}
- // -- soundfiles
+ //-------------------------------------------------------------------------------
+ // Simple API part
+ //-------------------------------------------------------------------------------
- virtual void addSoundfile(const char* /*label*/, const char* /*filename*/, Soundfile** /*sf_zone*/) {}
+ /**
+ * Return the number of parameters in the UI.
+ *
+ * @return the number of parameters
+ */
+ int getParamsCount() { return int(fItems.size()); }
- // -- metadata declarations
+ /**
+ * Return the param index.
+ *
+ * @param str - the UI parameter label/shortname/path
+ *
+ * @return the param index
+ */
+ int getParamIndex(const char* str)
+ {
+ std::string path = std::string(str);
+ auto it = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
+ return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path);
+ });
+ return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
+ }
- virtual void declare(FAUSTFLOAT* /*zone*/, const char* key, const char* val)
- {
- // Keep metadata
- fCurrentMetadata[key] = val;
-
- if (strcmp(key, "scale") == 0) {
- if (strcmp(val, "log") == 0) {
- fCurrentScale = kLog;
- } else if (strcmp(val, "exp") == 0) {
- fCurrentScale = kExp;
- } else {
- fCurrentScale = kLin;
- }
- } else if (strcmp(key, "unit") == 0) {
- fCurrentUnit = val;
- } else if (strcmp(key, "acc") == 0) {
- fCurrentAcc = val;
- } else if (strcmp(key, "gyr") == 0) {
- fCurrentGyr = val;
- } else if (strcmp(key, "screencolor") == 0) {
- fCurrentColor = val; // val = "red", "green", "blue" or "white"
- } else if (strcmp(key, "tooltip") == 0) {
- fCurrentTooltip = val;
- }
- }
+ /**
+ * Return the param label.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param label
+ */
+ const char* getParamLabel(int p) { return fItems[uint(p)].fLabel.c_str(); }
- virtual void declare(const char* /*key*/, const char* /*val*/)
- {}
-
- //-------------------------------------------------------------------------------
- // Simple API part
- //-------------------------------------------------------------------------------
-
- /**
- * Return the number of parameters in the UI.
- *
- * @return the number of parameters
- */
- int getParamsCount() { return int(fItems.size()); }
-
- /**
- * Return the param index.
- *
- * @param str - the UI parameter label/shortname/path
- *
- * @return the param index
- */
- int getParamIndex(const char* str)
- {
- std::string path = std::string(str);
- auto it = find_if(fItems.begin(), fItems.end(),
- [=](const Item& it) { return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path); });
- return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
- }
-
- /**
- * Return the param label.
- *
- * @param p - the UI parameter index
- *
- * @return the param label
- */
- const char* getParamLabel(int p) { return fItems[uint(p)].fLabel.c_str(); }
-
- /**
- * Return the param shortname.
- *
- * @param p - the UI parameter index
- *
- * @return the param shortname
- */
- const char* getParamShortname(int p) { return fItems[uint(p)].fShortname.c_str(); }
-
- /**
- * Return the param path.
- *
- * @param p - the UI parameter index
- *
- * @return the param path
- */
- const char* getParamAddress(int p) { return fItems[uint(p)].fPath.c_str(); }
-
- /**
- * Return the param metadata.
- *
- * @param p - the UI parameter index
- *
- * @return the param metadata as a map<key, value>
- */
- std::map<const char*, const char*> getMetadata(int p)
- {
- std::map<const char*, const char*> res;
- std::map<std::string, std::string> metadata = fMetaData[uint(p)];
- for (const auto& it : metadata) {
- res[it.first.c_str()] = it.second.c_str();
- }
- return res;
- }
+ /**
+ * Return the param shortname.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param shortname
+ */
+ const char* getParamShortname(int p) { return fItems[uint(p)].fShortname.c_str(); }
- /**
- * Return the param metadata value.
- *
- * @param p - the UI parameter index
- * @param key - the UI parameter index
- *
- * @return the param metadata value associate to the key
- */
- const char* getMetadata(int p, const char* key)
- {
- return (fMetaData[uint(p)].find(key) != fMetaData[uint(p)].end()) ? fMetaData[uint(p)][key].c_str() : "";
- }
-
- /**
- * Return the param minimum value.
- *
- * @param p - the UI parameter index
- *
- * @return the param minimum value
- */
- FAUSTFLOAT getParamMin(int p) { return fItems[uint(p)].fMin; }
-
- /**
- * Return the param maximum value.
- *
- * @param p - the UI parameter index
- *
- * @return the param maximum value
- */
- FAUSTFLOAT getParamMax(int p) { return fItems[uint(p)].fMax; }
-
- /**
- * Return the param step value.
- *
- * @param p - the UI parameter index
- *
- * @return the param step value
- */
- FAUSTFLOAT getParamStep(int p) { return fItems[uint(p)].fStep; }
-
- /**
- * Return the param init value.
- *
- * @param p - the UI parameter index
- *
- * @return the param init value
- */
- FAUSTFLOAT getParamInit(int p) { return fItems[uint(p)].fInit; }
-
- /**
- * Return the param memory zone.
- *
- * @param p - the UI parameter index
- *
- * @return the param memory zone.
- */
- FAUSTFLOAT* getParamZone(int p) { return fItems[uint(p)].fZone; }
-
- /**
- * Return the param value.
- *
- * @param p - the UI parameter index
- *
- * @return the param value.
- */
- FAUSTFLOAT getParamValue(int p) { return *fItems[uint(p)].fZone; }
-
- /**
- * Return the param value.
- *
- * @param str - the UI parameter label/shortname/path
- *
- * @return the param value.
- */
- FAUSTFLOAT getParamValue(const char* str)
- {
- int index = getParamIndex(str);
- if (index >= 0) {
- return getParamValue(index);
- } else {
- fprintf(stderr, "getParamValue : '%s' not found\n", (str == nullptr ? "NULL" : str));
- return FAUSTFLOAT(0);
- }
- }
+ /**
+ * Return the param path.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param path
+ */
+ const char* getParamAddress(int p) { return fItems[uint(p)].fPath.c_str(); }
- /**
- * Set the param value.
- *
- * @param p - the UI parameter index
- * @param v - the UI parameter value
- *
- */
- void setParamValue(int p, FAUSTFLOAT v) { *fItems[uint(p)].fZone = v; }
-
- /**
- * Set the param value.
- *
- * @param p - the UI parameter label/shortname/path
- * @param v - the UI parameter value
- *
- */
- void setParamValue(const char* path, FAUSTFLOAT v)
- {
- int index = getParamIndex(path);
- if (index >= 0) {
- setParamValue(index, v);
- } else {
- fprintf(stderr, "setParamValue : '%s' not found\n", (path == nullptr ? "NULL" : path));
- }
+ /**
+ * Return the param metadata.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param metadata as a map<key, value>
+ */
+ std::map<const char*, const char*> getMetadata(int p)
+ {
+ std::map<const char*, const char*> res;
+ std::map<std::string, std::string> metadata = fMetaData[uint(p)];
+ for (const auto& it : metadata) {
+ res[it.first.c_str()] = it.second.c_str();
}
+ return res;
+ }
- double getParamRatio(int p) { return fItems[uint(p)].fConversion->faust2ui(*fItems[uint(p)].fZone); }
- void setParamRatio(int p, double r) { *fItems[uint(p)].fZone = FAUSTFLOAT(fItems[uint(p)].fConversion->ui2faust(r)); }
+ /**
+ * Return the param metadata value.
+ *
+ * @param p - the UI parameter index
+ * @param key - the UI parameter index
+ *
+ * @return the param metadata value associate to the key
+ */
+ const char* getMetadata(int p, const char* key)
+ {
+ return (fMetaData[uint(p)].find(key) != fMetaData[uint(p)].end())
+ ? fMetaData[uint(p)][key].c_str()
+ : "";
+ }
- double value2ratio(int p, double r) { return fItems[uint(p)].fConversion->faust2ui(r); }
- double ratio2value(int p, double r) { return fItems[uint(p)].fConversion->ui2faust(r); }
+ /**
+ * Return the param minimum value.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param minimum value
+ */
+ FAUSTFLOAT getParamMin(int p) { return fItems[uint(p)].fMin; }
- /**
- * Return the control type (kAcc, kGyr, or -1) for a given parameter.
- *
- * @param p - the UI parameter index
- *
- * @return the type
- */
- Type getParamType(int p)
- {
- if (p >= 0) {
- if (getZoneIndex(fAcc, p, 0) != -1
- || getZoneIndex(fAcc, p, 1) != -1
- || getZoneIndex(fAcc, p, 2) != -1) {
- return kAcc;
- } else if (getZoneIndex(fGyr, p, 0) != -1
- || getZoneIndex(fGyr, p, 1) != -1
- || getZoneIndex(fGyr, p, 2) != -1) {
- return kGyr;
- }
- }
- return kNoType;
- }
+ /**
+ * Return the param maximum value.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param maximum value
+ */
+ FAUSTFLOAT getParamMax(int p) { return fItems[uint(p)].fMax; }
- /**
- * Return the Item type (kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry, kHBargraph, kVBargraph) for a given parameter.
- *
- * @param p - the UI parameter index
- *
- * @return the Item type
- */
- ItemType getParamItemType(int p)
- {
- return fItems[uint(p)].fItemType;
- }
+ /**
+ * Return the param step value.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param step value
+ */
+ FAUSTFLOAT getParamStep(int p) { return fItems[uint(p)].fStep; }
- /**
- * Set a new value coming from an accelerometer, propagate it to all relevant FAUSTFLOAT* zones.
- *
- * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
- * @param value - the new value
- *
- */
- void propagateAcc(int acc, double value)
- {
- for (size_t i = 0; i < fAcc[acc].size(); i++) {
- fAcc[acc][i]->update(value);
- }
- }
+ /**
+ * Return the param init value.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param init value
+ */
+ FAUSTFLOAT getParamInit(int p) { return fItems[uint(p)].fInit; }
- /**
- * Used to edit accelerometer curves and mapping. Set curve and related mapping for a given UI parameter.
- *
- * @param p - the UI parameter index
- * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer (-1 means "no mapping")
- * @param curve - between 0 and 3 (0: up, 1: down, 2: up and down, 2: down and up)
- * @param amin - mapping 'min' point
- * @param amid - mapping 'middle' point
- * @param amax - mapping 'max' point
- *
- */
- void setAccConverter(int p, int acc, int curve, double amin, double amid, double amax)
- {
- setConverter(fAcc, p, acc, curve, amin, amid, amax);
- }
+ /**
+ * Return the param memory zone.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param memory zone.
+ */
+ FAUSTFLOAT* getParamZone(int p) { return fItems[uint(p)].fZone; }
- /**
- * Used to edit gyroscope curves and mapping. Set curve and related mapping for a given UI parameter.
- *
- * @param p - the UI parameter index
- * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no mapping")
- * @param curve - between 0 and 3 (0: up, 1: down, 2: up and down, 2: down and up)
- * @param amin - mapping 'min' point
- * @param amid - mapping 'middle' point
- * @param amax - mapping 'max' point
- *
- */
- void setGyrConverter(int p, int gyr, int curve, double amin, double amid, double amax)
- {
- setConverter(fGyr, p, gyr, curve, amin, amid, amax);
- }
+ /**
+ * Return the param value.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the param value.
+ */
+ FAUSTFLOAT getParamValue(int p) { return *fItems[uint(p)].fZone; }
- /**
- * Used to edit accelerometer curves and mapping. Get curve and related mapping for a given UI parameter.
- *
- * @param p - the UI parameter index
- * @param acc - the acc value to be retrieved (-1 means "no mapping")
- * @param curve - the curve value to be retrieved (between 0 and 3)
- * @param amin - the amin value to be retrieved
- * @param amid - the amid value to be retrieved
- * @param amax - the amax value to be retrieved
- *
- */
- void getAccConverter(int p, int& acc, int& curve, double& amin, double& amid, double& amax)
- {
- getConverter(fAcc, p, acc, curve, amin, amid, amax);
+ /**
+ * Return the param value.
+ *
+ * @param str - the UI parameter label/shortname/path
+ *
+ * @return the param value.
+ */
+ FAUSTFLOAT getParamValue(const char* str)
+ {
+ int index = getParamIndex(str);
+ if (index >= 0) {
+ return getParamValue(index);
+ } else {
+ fprintf(stderr, "getParamValue : '%s' not found\n",
+ (str == nullptr ? "NULL" : str));
+ return FAUSTFLOAT(0);
}
+ }
- /**
- * Used to edit gyroscope curves and mapping. Get curve and related mapping for a given UI parameter.
- *
- * @param p - the UI parameter index
- * @param gyr - the gyr value to be retrieved (-1 means "no mapping")
- * @param curve - the curve value to be retrieved (between 0 and 3)
- * @param amin - the amin value to be retrieved
- * @param amid - the amid value to be retrieved
- * @param amax - the amax value to be retrieved
- *
- */
- void getGyrConverter(int p, int& gyr, int& curve, double& amin, double& amid, double& amax)
- {
- getConverter(fGyr, p, gyr, curve, amin, amid, amax);
+ /**
+ * Set the param value.
+ *
+ * @param p - the UI parameter index
+ * @param v - the UI parameter value
+ *
+ */
+ void setParamValue(int p, FAUSTFLOAT v) { *fItems[uint(p)].fZone = v; }
+
+ /**
+ * Set the param value.
+ *
+ * @param p - the UI parameter label/shortname/path
+ * @param v - the UI parameter value
+ *
+ */
+ void setParamValue(const char* path, FAUSTFLOAT v)
+ {
+ int index = getParamIndex(path);
+ if (index >= 0) {
+ setParamValue(index, v);
+ } else {
+ fprintf(stderr, "setParamValue : '%s' not found\n",
+ (path == nullptr ? "NULL" : path));
}
+ }
+
+ double getParamRatio(int p)
+ {
+ return fItems[uint(p)].fConversion->faust2ui(*fItems[uint(p)].fZone);
+ }
+ void setParamRatio(int p, double r)
+ {
+ *fItems[uint(p)].fZone = FAUSTFLOAT(fItems[uint(p)].fConversion->ui2faust(r));
+ }
+
+ double value2ratio(int p, double r)
+ {
+ return fItems[uint(p)].fConversion->faust2ui(r);
+ }
+ double ratio2value(int p, double r)
+ {
+ return fItems[uint(p)].fConversion->ui2faust(r);
+ }
- /**
- * Set a new value coming from an gyroscope, propagate it to all relevant FAUSTFLOAT* zones.
- *
- * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
- * @param value - the new value
- *
- */
- void propagateGyr(int gyr, double value)
- {
- for (size_t i = 0; i < fGyr[gyr].size(); i++) {
- fGyr[gyr][i]->update(value);
+ /**
+ * Return the control type (kAcc, kGyr, or -1) for a given parameter.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the type
+ */
+ Type getParamType(int p)
+ {
+ if (p >= 0) {
+ if (getZoneIndex(fAcc, p, 0) != -1 || getZoneIndex(fAcc, p, 1) != -1
+ || getZoneIndex(fAcc, p, 2) != -1) {
+ return kAcc;
+ } else if (getZoneIndex(fGyr, p, 0) != -1 || getZoneIndex(fGyr, p, 1) != -1
+ || getZoneIndex(fGyr, p, 2) != -1) {
+ return kGyr;
}
}
+ return kNoType;
+ }
- /**
- * Get the number of FAUSTFLOAT* zones controlled with the accelerometer.
- *
- * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
- * @return the number of zones
- *
- */
- int getAccCount(int acc)
- {
- return (acc >= 0 && acc < 3) ? int(fAcc[acc].size()) : 0;
- }
+ /**
+ * Return the Item type (kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry,
+ * kHBargraph, kVBargraph) for a given parameter.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the Item type
+ */
+ ItemType getParamItemType(int p) { return fItems[uint(p)].fItemType; }
- /**
- * Get the number of FAUSTFLOAT* zones controlled with the gyroscope.
- *
- * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
- * @param the number of zones
- *
- */
- int getGyrCount(int gyr)
- {
- return (gyr >= 0 && gyr < 3) ? int(fGyr[gyr].size()) : 0;
+ /**
+ * Set a new value coming from an accelerometer, propagate it to all relevant
+ * FAUSTFLOAT* zones.
+ *
+ * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
+ * @param value - the new value
+ *
+ */
+ void propagateAcc(int acc, double value)
+ {
+ for (size_t i = 0; i < fAcc[acc].size(); i++) {
+ fAcc[acc][i]->update(value);
}
+ }
- /**
- * Get the requested screen color.
- *
- * -1 means no screen color control (no screencolor metadata found)
- * otherwise return 0x00RRGGBB a ready to use color
- *
- */
- int getScreenColor()
- {
- if (fHasScreenControl) {
- int r = (fRedReader) ? fRedReader->getValue() : 0;
- int g = (fGreenReader) ? fGreenReader->getValue() : 0;
- int b = (fBlueReader) ? fBlueReader->getValue() : 0;
- return (r<<16) | (g<<8) | b;
- } else {
- return -1;
- }
+ /**
+ * Used to edit accelerometer curves and mapping. Set curve and related mapping for a
+ * given UI parameter.
+ *
+ * @param p - the UI parameter index
+ * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
+ * (-1 means "no mapping")
+ * @param curve - between 0 and 3 (0: up, 1: down, 2: up and down, 2: down and up)
+ * @param amin - mapping 'min' point
+ * @param amid - mapping 'middle' point
+ * @param amax - mapping 'max' point
+ *
+ */
+ void setAccConverter(int p, int acc, int curve, double amin, double amid, double amax)
+ {
+ setConverter(fAcc, p, acc, curve, amin, amid, amax);
+ }
+
+ /**
+ * Used to edit gyroscope curves and mapping. Set curve and related mapping for a
+ * given UI parameter.
+ *
+ * @param p - the UI parameter index
+ * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no
+ * mapping")
+ * @param curve - between 0 and 3 (0: up, 1: down, 2: up and down, 2: down and up)
+ * @param amin - mapping 'min' point
+ * @param amid - mapping 'middle' point
+ * @param amax - mapping 'max' point
+ *
+ */
+ void setGyrConverter(int p, int gyr, int curve, double amin, double amid, double amax)
+ {
+ setConverter(fGyr, p, gyr, curve, amin, amid, amax);
+ }
+
+ /**
+ * Used to edit accelerometer curves and mapping. Get curve and related mapping for a
+ * given UI parameter.
+ *
+ * @param p - the UI parameter index
+ * @param acc - the acc value to be retrieved (-1 means "no mapping")
+ * @param curve - the curve value to be retrieved (between 0 and 3)
+ * @param amin - the amin value to be retrieved
+ * @param amid - the amid value to be retrieved
+ * @param amax - the amax value to be retrieved
+ *
+ */
+ void getAccConverter(int p, int& acc, int& curve, double& amin, double& amid,
+ double& amax)
+ {
+ getConverter(fAcc, p, acc, curve, amin, amid, amax);
+ }
+
+ /**
+ * Used to edit gyroscope curves and mapping. Get curve and related mapping for a
+ * given UI parameter.
+ *
+ * @param p - the UI parameter index
+ * @param gyr - the gyr value to be retrieved (-1 means "no mapping")
+ * @param curve - the curve value to be retrieved (between 0 and 3)
+ * @param amin - the amin value to be retrieved
+ * @param amid - the amid value to be retrieved
+ * @param amax - the amax value to be retrieved
+ *
+ */
+ void getGyrConverter(int p, int& gyr, int& curve, double& amin, double& amid,
+ double& amax)
+ {
+ getConverter(fGyr, p, gyr, curve, amin, amid, amax);
+ }
+
+ /**
+ * Set a new value coming from an gyroscope, propagate it to all relevant FAUSTFLOAT*
+ * zones.
+ *
+ * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
+ * @param value - the new value
+ *
+ */
+ void propagateGyr(int gyr, double value)
+ {
+ for (size_t i = 0; i < fGyr[gyr].size(); i++) {
+ fGyr[gyr][i]->update(value);
}
+ }
+
+ /**
+ * Get the number of FAUSTFLOAT* zones controlled with the accelerometer.
+ *
+ * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
+ * @return the number of zones
+ *
+ */
+ int getAccCount(int acc) { return (acc >= 0 && acc < 3) ? int(fAcc[acc].size()) : 0; }
+
+ /**
+ * Get the number of FAUSTFLOAT* zones controlled with the gyroscope.
+ *
+ * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
+ * @param the number of zones
+ *
+ */
+ int getGyrCount(int gyr) { return (gyr >= 0 && gyr < 3) ? int(fGyr[gyr].size()) : 0; }
+ /**
+ * Get the requested screen color.
+ *
+ * -1 means no screen color control (no screencolor metadata found)
+ * otherwise return 0x00RRGGBB a ready to use color
+ *
+ */
+ int getScreenColor()
+ {
+ if (fHasScreenControl) {
+ int r = (fRedReader) ? fRedReader->getValue() : 0;
+ int g = (fGreenReader) ? fGreenReader->getValue() : 0;
+ int b = (fBlueReader) ? fBlueReader->getValue() : 0;
+ return (r << 16) | (g << 8) | b;
+ } else {
+ return -1;
+ }
+ }
};
#endif
// FAUST Generated Code
//----------------------------------------------------------------------------
-
#ifndef FAUSTFLOAT
#define FAUSTFLOAT float
-#endif
+#endif
+
+#include <math.h>
#include <algorithm>
#include <cmath>
#include <cstdint>
-#include <math.h>
-#ifndef FAUSTCLASS
+#ifndef FAUSTCLASS
#define FAUSTCLASS tonedsp
#endif
-#ifdef __APPLE__
+#ifdef __APPLE__
#define exp10f __exp10f
-#define exp10 __exp10
+#define exp10 __exp10
#endif
#if defined(_WIN32)
#define RESTRICT __restrict__
#endif
-class tonedspSIG0 {
-
- private:
-
- int iVec0[2];
- int iRec0[2];
-
- public:
-
- int getNumInputstonedspSIG0() {
- return 0;
- }
- int getNumOutputstonedspSIG0() {
- return 1;
- }
-
- void instanceInittonedspSIG0(int /*sample_rate*/) {
- for (int l0 = 0; l0 < 2; l0 = l0 + 1) {
- iVec0[l0] = 0;
- }
- for (int l1 = 0; l1 < 2; l1 = l1 + 1) {
- iRec0[l1] = 0;
- }
- }
-
- void filltonedspSIG0(int count, float* table) {
- for (int i1 = 0; i1 < count; i1 = i1 + 1) {
- iVec0[0] = 1;
- iRec0[0] = (iVec0[1] + iRec0[1]) % 65536;
- table[i1] = std::sin(9.58738e-05f * float(iRec0[0]));
- iVec0[1] = iVec0[0];
- iRec0[1] = iRec0[0];
- }
- }
-
+class tonedspSIG0
+{
+ private:
+ int iVec0[2];
+ int iRec0[2];
+
+ public:
+ int getNumInputstonedspSIG0() { return 0; }
+ int getNumOutputstonedspSIG0() { return 1; }
+
+ void instanceInittonedspSIG0(int /*sample_rate*/)
+ {
+ for (int l0 = 0; l0 < 2; l0 = l0 + 1) {
+ iVec0[l0] = 0;
+ }
+ for (int l1 = 0; l1 < 2; l1 = l1 + 1) {
+ iRec0[l1] = 0;
+ }
+ }
+
+ void filltonedspSIG0(int count, float* table)
+ {
+ for (int i1 = 0; i1 < count; i1 = i1 + 1) {
+ iVec0[0] = 1;
+ iRec0[0] = (iVec0[1] + iRec0[1]) % 65536;
+ table[i1] = std::sin(9.58738e-05f * float(iRec0[0]));
+ iVec0[1] = iVec0[0];
+ iRec0[1] = iRec0[0];
+ }
+ }
};
-static tonedspSIG0* newtonedspSIG0() { return (tonedspSIG0*)new tonedspSIG0(); }
-static void deletetonedspSIG0(tonedspSIG0* dsp) { delete dsp; }
+static tonedspSIG0* newtonedspSIG0()
+{
+ return (tonedspSIG0*)new tonedspSIG0();
+}
+static void deletetonedspSIG0(tonedspSIG0* dsp)
+{
+ delete dsp;
+}
static float ftbl0tonedspSIG0[65536];
-class tonedsp : public dsp {
-
- private:
-
- int fSampleRate;
- float fConst0;
- float fConst1;
- FAUSTFLOAT fHslider0;
- FAUSTFLOAT fHslider1;
- float fRec1[2];
- float fConst2;
- float fConst3;
- FAUSTFLOAT fButton0;
- float fVec1[2];
- int iRec2[2];
- float fConst4;
- FAUSTFLOAT fHslider2;
- float fConst5;
- float fRec3[2];
- float fRec4[2];
- float fConst6;
- float fRec5[2];
- float fConst7;
- float fRec6[2];
- float fConst8;
- float fRec7[2];
- float fConst9;
- float fRec8[2];
- float fConst10;
-
- public:
-
- void metadata(Meta* m) {
- m->declare("basics.lib/name", "Faust Basic Element Library");
- m->declare("basics.lib/version", "0.8");
- m->declare("compile_options", "-a faust2header.cpp -lang cpp -i -inpl -cn tonedsp -es 1 -mcd 16 -single -ftz 0");
- m->declare("envelopes.lib/ar:author", "Yann Orlarey, Stéphane Letz");
- m->declare("envelopes.lib/author", "GRAME");
- m->declare("envelopes.lib/copyright", "GRAME");
- m->declare("envelopes.lib/license", "LGPL with exception");
- m->declare("envelopes.lib/name", "Faust Envelope Library");
- m->declare("envelopes.lib/version", "0.2");
- m->declare("filename", "tonedsp.dsp");
- m->declare("maths.lib/author", "GRAME");
- m->declare("maths.lib/copyright", "GRAME");
- m->declare("maths.lib/license", "LGPL with exception");
- m->declare("maths.lib/name", "Faust Math Library");
- m->declare("maths.lib/version", "2.5");
- m->declare("name", "tonedsp");
- m->declare("oscillators.lib/name", "Faust Oscillator Library");
- m->declare("oscillators.lib/version", "0.3");
- m->declare("platform.lib/name", "Generic Platform Library");
- m->declare("platform.lib/version", "0.2");
- m->declare("signals.lib/name", "Faust Signal Routing Library");
- m->declare("signals.lib/version", "0.3");
- m->declare("synths.lib/additiveDrum:author", "Romain Michon");
- m->declare("synths.lib/name", "Faust Synthesizer Library");
- m->declare("synths.lib/version", "0.1");
- }
-
- virtual int getNumInputs() {
- return 0;
- }
- virtual int getNumOutputs() {
- return 1;
- }
-
- static void classInit(int sample_rate) {
- tonedspSIG0* sig0 = newtonedspSIG0();
- sig0->instanceInittonedspSIG0(sample_rate);
- sig0->filltonedspSIG0(65536, ftbl0tonedspSIG0);
- deletetonedspSIG0(sig0);
- }
-
- virtual void instanceConstants(int sample_rate) {
- fSampleRate = sample_rate;
- fConst0 = std::min<float>(1.92e+05f, std::max<float>(1.0f, float(fSampleRate)));
- fConst1 = 1.0f / fConst0;
- fConst2 = std::max<float>(1.0f, 0.001f * fConst0);
- fConst3 = 1.0f / fConst2;
- fConst4 = 44.1f / fConst0;
- fConst5 = 1.0f - fConst4;
- fConst6 = 0.8666667f * fConst0;
- fConst7 = 0.73333335f * fConst0;
- fConst8 = 0.6f * fConst0;
- fConst9 = 0.46666667f * fConst0;
- fConst10 = 0.33333334f * fConst0;
- }
-
- virtual void instanceResetUserInterface() {
- fHslider0 = FAUSTFLOAT(4e+02f);
- fHslider1 = FAUSTFLOAT(0.0f);
- fButton0 = FAUSTFLOAT(0.0f);
- fHslider2 = FAUSTFLOAT(2.5f);
- }
-
- virtual void instanceClear() {
- for (int l2 = 0; l2 < 2; l2 = l2 + 1) {
- fRec1[l2] = 0.0f;
- }
- for (int l3 = 0; l3 < 2; l3 = l3 + 1) {
- fVec1[l3] = 0.0f;
- }
- for (int l4 = 0; l4 < 2; l4 = l4 + 1) {
- iRec2[l4] = 0;
- }
- for (int l5 = 0; l5 < 2; l5 = l5 + 1) {
- fRec3[l5] = 0.0f;
- }
- for (int l6 = 0; l6 < 2; l6 = l6 + 1) {
- fRec4[l6] = 0.0f;
- }
- for (int l7 = 0; l7 < 2; l7 = l7 + 1) {
- fRec5[l7] = 0.0f;
- }
- for (int l8 = 0; l8 < 2; l8 = l8 + 1) {
- fRec6[l8] = 0.0f;
- }
- for (int l9 = 0; l9 < 2; l9 = l9 + 1) {
- fRec7[l9] = 0.0f;
- }
- for (int l10 = 0; l10 < 2; l10 = l10 + 1) {
- fRec8[l10] = 0.0f;
- }
- }
-
- virtual void init(int sample_rate) {
- classInit(sample_rate);
- instanceInit(sample_rate);
- }
- virtual void instanceInit(int sample_rate) {
- instanceConstants(sample_rate);
- instanceResetUserInterface();
- instanceClear();
- }
-
- virtual tonedsp* clone() {
- return new tonedsp();
- }
-
- virtual int getSampleRate() {
- return fSampleRate;
- }
-
- virtual void buildUserInterface(UI* ui_interface) {
- ui_interface->openVerticalBox("tonedsp");
- ui_interface->addHorizontalSlider("freq", &fHslider0, FAUSTFLOAT(4e+02f), FAUSTFLOAT(5e+01f), FAUSTFLOAT(2e+03f), FAUSTFLOAT(0.01f));
- ui_interface->addButton("gate", &fButton0);
- ui_interface->declare(&fHslider2, "acc", "0 0 -10 0 10");
- ui_interface->addHorizontalSlider("res", &fHslider2, FAUSTFLOAT(2.5f), FAUSTFLOAT(0.01f), FAUSTFLOAT(5.0f), FAUSTFLOAT(0.01f));
- ui_interface->addHorizontalSlider("y", &fHslider1, FAUSTFLOAT(0.0f), FAUSTFLOAT(0.0f), FAUSTFLOAT(1.0f), FAUSTFLOAT(0.01f));
- ui_interface->closeBox();
- }
-
- virtual void compute(int count, FAUSTFLOAT** /*inputs*/, FAUSTFLOAT** outputs) {
- FAUSTFLOAT* output0 = outputs[0];
- float fSlow0 = float(fHslider0);
- float fSlow1 = float(fHslider1);
- float fSlow2 = fConst1 * fSlow0 * (0.8333333f * fSlow1 + 1.0f);
- float fSlow3 = float(fButton0);
- float fSlow4 = fConst4 * float(fHslider2);
- float fSlow5 = fConst1 * fSlow0 * (1.6666666f * fSlow1 + 1.0f);
- float fSlow6 = fConst1 * fSlow0 * (2.5f * fSlow1 + 1.0f);
- float fSlow7 = fConst1 * fSlow0 * (3.3333333f * fSlow1 + 1.0f);
- float fSlow8 = fConst1 * fSlow0 * (4.1666665f * fSlow1 + 1.0f);
- float fSlow9 = fConst1 * fSlow0 * (5.0f * fSlow1 + 1.0f);
- for (int i0 = 0; i0 < count; i0 = i0 + 1) {
- fRec1[0] = fSlow2 + (fRec1[1] - std::floor(fSlow2 + fRec1[1]));
- fVec1[0] = fSlow3;
- iRec2[0] = (iRec2[1] + (iRec2[1] > 0)) * (fSlow3 <= fVec1[1]) + (fSlow3 > fVec1[1]);
- float fTemp0 = float(iRec2[0]);
- float fTemp1 = fConst3 * fTemp0;
- float fTemp2 = fConst2 - fTemp0;
- fRec3[0] = fSlow4 + fConst5 * fRec3[1];
- fRec4[0] = fSlow5 + (fRec4[1] - std::floor(fSlow5 + fRec4[1]));
- fRec5[0] = fSlow6 + (fRec5[1] - std::floor(fSlow6 + fRec5[1]));
- fRec6[0] = fSlow7 + (fRec6[1] - std::floor(fSlow7 + fRec6[1]));
- fRec7[0] = fSlow8 + (fRec7[1] - std::floor(fSlow8 + fRec7[1]));
- fRec8[0] = fSlow9 + (fRec8[1] - std::floor(fSlow9 + fRec8[1]));
- output0[i0] = FAUSTFLOAT(0.05f * (0.44444445f * ftbl0tonedspSIG0[int(65536.0f * fRec1[0])] * std::max<float>(0.0f, std::min<float>(fTemp1, fTemp2 / std::max<float>(1.0f, fConst0 * fRec3[0]) + 1.0f)) + ftbl0tonedspSIG0[int(65536.0f * fRec4[0])] * (0.0f - 0.11111111f * std::max<float>(0.0f, std::min<float>(fTemp1, fTemp2 / std::max<float>(1.0f, fConst6 * fRec3[0]) + 1.0f))) + ftbl0tonedspSIG0[int(65536.0f * fRec5[0])] * (0.0f - 0.6666667f * std::max<float>(0.0f, std::min<float>(fTemp1, fTemp2 / std::max<float>(1.0f, fConst7 * fRec3[0]) + 1.0f))) + ftbl0tonedspSIG0[int(65536.0f * fRec6[0])] * (0.0f - 1.2222222f * std::max<float>(0.0f, std::min<float>(fTemp1, fTemp2 / std::max<float>(1.0f, fConst8 * fRec3[0]) + 1.0f))) + ftbl0tonedspSIG0[int(65536.0f * fRec7[0])] * (0.0f - 1.7777778f * std::max<float>(0.0f, std::min<float>(fTemp1, fTemp2 / std::max<float>(1.0f, fConst9 * fRec3[0]) + 1.0f))) + ftbl0tonedspSIG0[int(65536.0f * fRec8[0])] * (0.0f - 2.3333333f * std::max<float>(0.0f, std::min<float>(fTemp1, fTemp2 / std::max<float>(1.0f, fConst10 * fRec3[0]) + 1.0f)))));
- fRec1[1] = fRec1[0];
- fVec1[1] = fVec1[0];
- iRec2[1] = iRec2[0];
- fRec3[1] = fRec3[0];
- fRec4[1] = fRec4[0];
- fRec5[1] = fRec5[0];
- fRec6[1] = fRec6[0];
- fRec7[1] = fRec7[0];
- fRec8[1] = fRec8[0];
- }
- }
-
+class tonedsp : public dsp
+{
+ private:
+ int fSampleRate;
+ float fConst0;
+ float fConst1;
+ FAUSTFLOAT fHslider0;
+ FAUSTFLOAT fHslider1;
+ float fRec1[2];
+ float fConst2;
+ float fConst3;
+ FAUSTFLOAT fButton0;
+ float fVec1[2];
+ int iRec2[2];
+ float fConst4;
+ FAUSTFLOAT fHslider2;
+ float fConst5;
+ float fRec3[2];
+ float fRec4[2];
+ float fConst6;
+ float fRec5[2];
+ float fConst7;
+ float fRec6[2];
+ float fConst8;
+ float fRec7[2];
+ float fConst9;
+ float fRec8[2];
+ float fConst10;
+
+ public:
+ void metadata(Meta* m)
+ {
+ m->declare("basics.lib/name", "Faust Basic Element Library");
+ m->declare("basics.lib/version", "0.8");
+ m->declare("compile_options",
+ "-a faust2header.cpp -lang cpp -i -inpl -cn tonedsp -es 1 -mcd 16 "
+ "-single -ftz 0");
+ m->declare("envelopes.lib/ar:author", "Yann Orlarey, Stéphane Letz");
+ m->declare("envelopes.lib/author", "GRAME");
+ m->declare("envelopes.lib/copyright", "GRAME");
+ m->declare("envelopes.lib/license", "LGPL with exception");
+ m->declare("envelopes.lib/name", "Faust Envelope Library");
+ m->declare("envelopes.lib/version", "0.2");
+ m->declare("filename", "tonedsp.dsp");
+ m->declare("maths.lib/author", "GRAME");
+ m->declare("maths.lib/copyright", "GRAME");
+ m->declare("maths.lib/license", "LGPL with exception");
+ m->declare("maths.lib/name", "Faust Math Library");
+ m->declare("maths.lib/version", "2.5");
+ m->declare("name", "tonedsp");
+ m->declare("oscillators.lib/name", "Faust Oscillator Library");
+ m->declare("oscillators.lib/version", "0.3");
+ m->declare("platform.lib/name", "Generic Platform Library");
+ m->declare("platform.lib/version", "0.2");
+ m->declare("signals.lib/name", "Faust Signal Routing Library");
+ m->declare("signals.lib/version", "0.3");
+ m->declare("synths.lib/additiveDrum:author", "Romain Michon");
+ m->declare("synths.lib/name", "Faust Synthesizer Library");
+ m->declare("synths.lib/version", "0.1");
+ }
+
+ virtual int getNumInputs() { return 0; }
+ virtual int getNumOutputs() { return 1; }
+
+ static void classInit(int sample_rate)
+ {
+ tonedspSIG0* sig0 = newtonedspSIG0();
+ sig0->instanceInittonedspSIG0(sample_rate);
+ sig0->filltonedspSIG0(65536, ftbl0tonedspSIG0);
+ deletetonedspSIG0(sig0);
+ }
+
+ virtual void instanceConstants(int sample_rate)
+ {
+ fSampleRate = sample_rate;
+ fConst0 = std::min<float>(1.92e+05f, std::max<float>(1.0f, float(fSampleRate)));
+ fConst1 = 1.0f / fConst0;
+ fConst2 = std::max<float>(1.0f, 0.001f * fConst0);
+ fConst3 = 1.0f / fConst2;
+ fConst4 = 44.1f / fConst0;
+ fConst5 = 1.0f - fConst4;
+ fConst6 = 0.8666667f * fConst0;
+ fConst7 = 0.73333335f * fConst0;
+ fConst8 = 0.6f * fConst0;
+ fConst9 = 0.46666667f * fConst0;
+ fConst10 = 0.33333334f * fConst0;
+ }
+
+ virtual void instanceResetUserInterface()
+ {
+ fHslider0 = FAUSTFLOAT(4e+02f);
+ fHslider1 = FAUSTFLOAT(0.0f);
+ fButton0 = FAUSTFLOAT(0.0f);
+ fHslider2 = FAUSTFLOAT(2.5f);
+ }
+
+ virtual void instanceClear()
+ {
+ for (int l2 = 0; l2 < 2; l2 = l2 + 1) {
+ fRec1[l2] = 0.0f;
+ }
+ for (int l3 = 0; l3 < 2; l3 = l3 + 1) {
+ fVec1[l3] = 0.0f;
+ }
+ for (int l4 = 0; l4 < 2; l4 = l4 + 1) {
+ iRec2[l4] = 0;
+ }
+ for (int l5 = 0; l5 < 2; l5 = l5 + 1) {
+ fRec3[l5] = 0.0f;
+ }
+ for (int l6 = 0; l6 < 2; l6 = l6 + 1) {
+ fRec4[l6] = 0.0f;
+ }
+ for (int l7 = 0; l7 < 2; l7 = l7 + 1) {
+ fRec5[l7] = 0.0f;
+ }
+ for (int l8 = 0; l8 < 2; l8 = l8 + 1) {
+ fRec6[l8] = 0.0f;
+ }
+ for (int l9 = 0; l9 < 2; l9 = l9 + 1) {
+ fRec7[l9] = 0.0f;
+ }
+ for (int l10 = 0; l10 < 2; l10 = l10 + 1) {
+ fRec8[l10] = 0.0f;
+ }
+ }
+
+ virtual void init(int sample_rate)
+ {
+ classInit(sample_rate);
+ instanceInit(sample_rate);
+ }
+ virtual void instanceInit(int sample_rate)
+ {
+ instanceConstants(sample_rate);
+ instanceResetUserInterface();
+ instanceClear();
+ }
+
+ virtual tonedsp* clone() { return new tonedsp(); }
+
+ virtual int getSampleRate() { return fSampleRate; }
+
+ virtual void buildUserInterface(UI* ui_interface)
+ {
+ ui_interface->openVerticalBox("tonedsp");
+ ui_interface->addHorizontalSlider("freq", &fHslider0, FAUSTFLOAT(4e+02f),
+ FAUSTFLOAT(5e+01f), FAUSTFLOAT(2e+03f),
+ FAUSTFLOAT(0.01f));
+ ui_interface->addButton("gate", &fButton0);
+ ui_interface->declare(&fHslider2, "acc", "0 0 -10 0 10");
+ ui_interface->addHorizontalSlider("res", &fHslider2, FAUSTFLOAT(2.5f),
+ FAUSTFLOAT(0.01f), FAUSTFLOAT(5.0f),
+ FAUSTFLOAT(0.01f));
+ ui_interface->addHorizontalSlider("y", &fHslider1, FAUSTFLOAT(0.0f),
+ FAUSTFLOAT(0.0f), FAUSTFLOAT(1.0f),
+ FAUSTFLOAT(0.01f));
+ ui_interface->closeBox();
+ }
+
+ virtual void compute(int count, FAUSTFLOAT** /*inputs*/, FAUSTFLOAT** outputs)
+ {
+ FAUSTFLOAT* output0 = outputs[0];
+ float fSlow0 = float(fHslider0);
+ float fSlow1 = float(fHslider1);
+ float fSlow2 = fConst1 * fSlow0 * (0.8333333f * fSlow1 + 1.0f);
+ float fSlow3 = float(fButton0);
+ float fSlow4 = fConst4 * float(fHslider2);
+ float fSlow5 = fConst1 * fSlow0 * (1.6666666f * fSlow1 + 1.0f);
+ float fSlow6 = fConst1 * fSlow0 * (2.5f * fSlow1 + 1.0f);
+ float fSlow7 = fConst1 * fSlow0 * (3.3333333f * fSlow1 + 1.0f);
+ float fSlow8 = fConst1 * fSlow0 * (4.1666665f * fSlow1 + 1.0f);
+ float fSlow9 = fConst1 * fSlow0 * (5.0f * fSlow1 + 1.0f);
+ for (int i0 = 0; i0 < count; i0 = i0 + 1) {
+ fRec1[0] = fSlow2 + (fRec1[1] - std::floor(fSlow2 + fRec1[1]));
+ fVec1[0] = fSlow3;
+ iRec2[0] =
+ (iRec2[1] + (iRec2[1] > 0)) * (fSlow3 <= fVec1[1]) + (fSlow3 > fVec1[1]);
+ float fTemp0 = float(iRec2[0]);
+ float fTemp1 = fConst3 * fTemp0;
+ float fTemp2 = fConst2 - fTemp0;
+ fRec3[0] = fSlow4 + fConst5 * fRec3[1];
+ fRec4[0] = fSlow5 + (fRec4[1] - std::floor(fSlow5 + fRec4[1]));
+ fRec5[0] = fSlow6 + (fRec5[1] - std::floor(fSlow6 + fRec5[1]));
+ fRec6[0] = fSlow7 + (fRec6[1] - std::floor(fSlow7 + fRec6[1]));
+ fRec7[0] = fSlow8 + (fRec7[1] - std::floor(fSlow8 + fRec7[1]));
+ fRec8[0] = fSlow9 + (fRec8[1] - std::floor(fSlow9 + fRec8[1]));
+ output0[i0] = FAUSTFLOAT(
+ 0.05f
+ * (0.44444445f * ftbl0tonedspSIG0[int(65536.0f * fRec1[0])]
+ * std::max<float>(
+ 0.0f,
+ std::min<float>(
+ fTemp1,
+ fTemp2 / std::max<float>(1.0f, fConst0 * fRec3[0]) + 1.0f))
+ + ftbl0tonedspSIG0[int(65536.0f * fRec4[0])]
+ * (0.0f
+ - 0.11111111f
+ * std::max<float>(
+ 0.0f,
+ std::min<float>(
+ fTemp1, fTemp2
+ / std::max<float>(
+ 1.0f, fConst6 * fRec3[0])
+ + 1.0f)))
+ + ftbl0tonedspSIG0[int(65536.0f * fRec5[0])]
+ * (0.0f
+ - 0.6666667f
+ * std::max<float>(
+ 0.0f,
+ std::min<float>(
+ fTemp1, fTemp2
+ / std::max<float>(
+ 1.0f, fConst7 * fRec3[0])
+ + 1.0f)))
+ + ftbl0tonedspSIG0[int(65536.0f * fRec6[0])]
+ * (0.0f
+ - 1.2222222f
+ * std::max<float>(
+ 0.0f,
+ std::min<float>(
+ fTemp1, fTemp2
+ / std::max<float>(
+ 1.0f, fConst8 * fRec3[0])
+ + 1.0f)))
+ + ftbl0tonedspSIG0[int(65536.0f * fRec7[0])]
+ * (0.0f
+ - 1.7777778f
+ * std::max<float>(
+ 0.0f,
+ std::min<float>(
+ fTemp1, fTemp2
+ / std::max<float>(
+ 1.0f, fConst9 * fRec3[0])
+ + 1.0f)))
+ + ftbl0tonedspSIG0[int(65536.0f * fRec8[0])]
+ * (0.0f
+ - 2.3333333f
+ * std::max<float>(
+ 0.0f,
+ std::min<float>(
+ fTemp1, fTemp2
+ / std::max<float>(
+ 1.0f, fConst10 * fRec3[0])
+ + 1.0f)))));
+ fRec1[1] = fRec1[0];
+ fVec1[1] = fVec1[0];
+ iRec2[1] = iRec2[0];
+ fRec3[1] = fRec3[0];
+ fRec4[1] = fRec4[0];
+ fRec5[1] = fRec5[0];
+ fRec6[1] = fRec6[0];
+ fRec7[1] = fRec7[0];
+ fRec8[1] = fRec8[0];
+ }
+ }
};
-
#endif
name: "volume"
version: "1.0"
Code generated with Faust 2.41.1 (https://faust.grame.fr)
-Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn volumedsp -es 1 -mcd 16 -single -ftz 0
+Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn volumedsp -es 1 -mcd 16
+-single -ftz 0
------------------------------------------------------------ */
-#ifndef __volumedsp_H__
-#define __volumedsp_H__
+#ifndef __volumedsp_H__
+#define __volumedsp_H__
// NOTE: ANY INCLUDE-GUARD HERE MUST BE DERIVED FROM THE CLASS NAME
//
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
#define FAUSTVERSION "2.41.1"
-// Use FAUST_API for code that is part of the external API but is also compiled in faust and libfaust
-// Use LIBFAUST_API for code that is compiled in faust and libfaust
+// Use FAUST_API for code that is part of the external API but is also compiled in faust
+// and libfaust Use LIBFAUST_API for code that is compiled in faust and libfaust
#ifdef _WIN32
- #pragma warning (disable: 4251)
- #ifdef FAUST_EXE
- #define FAUST_API
- #define LIBFAUST_API
- #elif FAUST_LIB
- #define FAUST_API __declspec(dllexport)
- #define LIBFAUST_API __declspec(dllexport)
- #else
- #define FAUST_API
- #define LIBFAUST_API
- #endif
+#pragma warning(disable : 4251)
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#elif FAUST_LIB
+#define FAUST_API __declspec(dllexport)
+#define LIBFAUST_API __declspec(dllexport)
#else
- #ifdef FAUST_EXE
- #define FAUST_API
- #define LIBFAUST_API
- #else
- #define FAUST_API __attribute__((visibility("default")))
- #define LIBFAUST_API __attribute__((visibility("default")))
- #endif
+#define FAUST_API
+#define LIBFAUST_API
+#endif
+#else
+#ifdef FAUST_EXE
+#define FAUST_API
+#define LIBFAUST_API
+#else
+#define FAUST_API __attribute__((visibility("default")))
+#define LIBFAUST_API __attribute__((visibility("default")))
+#endif
#endif
#endif
*/
struct FAUST_API dsp_memory_manager {
-
virtual ~dsp_memory_manager() {}
-
+
/**
* Inform the Memory Manager with the number of expected memory zones.
* @param count - the number of expected memory zones
*/
virtual void begin(size_t /*count*/) {}
-
+
/**
* Give the Memory Manager information on a given memory zone.
* @param size - the size in bytes of the memory zone
* @param writes - the number of Write access to the zone used to compute one frame
*/
virtual void info(size_t /*size*/, size_t /*reads*/, size_t /*writes*/) {}
-
+
/**
* Inform the Memory Manager that all memory zones have been described,
* to possibly start a 'compute the best allocation strategy' step.
*/
virtual void end() {}
-
+
/**
* Allocate a memory zone.
* @param size - the memory zone size in bytes
*/
virtual void* allocate(size_t size) = 0;
-
+
/**
* Destroy a memory zone.
* @param ptr - the memory zone pointer to be deallocated
*/
virtual void destroy(void* ptr) = 0;
-
};
/**
-* Signal processor definition.
-*/
-
-class FAUST_API dsp {
-
- public:
-
- dsp() {}
- virtual ~dsp() {}
-
- /* Return instance number of audio inputs */
- virtual int getNumInputs() = 0;
-
- /* Return instance number of audio outputs */
- virtual int getNumOutputs() = 0;
-
- /**
- * Trigger the ui_interface parameter with instance specific calls
- * to 'openTabBox', 'addButton', 'addVerticalSlider'... in order to build the UI.
- *
- * @param ui_interface - the user interface builder
- */
- virtual void buildUserInterface(UI* ui_interface) = 0;
-
- /* Return the sample rate currently used by the instance */
- virtual int getSampleRate() = 0;
-
- /**
- * Global init, calls the following methods:
- * - static class 'classInit': static tables initialization
- * - 'instanceInit': constants and instance state initialization
- *
- * @param sample_rate - the sampling rate in Hz
- */
- virtual void init(int sample_rate) = 0;
-
- /**
- * Init instance state
- *
- * @param sample_rate - the sampling rate in Hz
- */
- virtual void instanceInit(int sample_rate) = 0;
-
- /**
- * Init instance constant state
- *
- * @param sample_rate - the sampling rate in Hz
- */
- virtual void instanceConstants(int sample_rate) = 0;
-
- /* Init default control parameters values */
- virtual void instanceResetUserInterface() = 0;
-
- /* Init instance state (like delay lines...) but keep the control parameter values */
- virtual void instanceClear() = 0;
-
- /**
- * Return a clone of the instance.
- *
- * @return a copy of the instance on success, otherwise a null pointer.
- */
- virtual dsp* clone() = 0;
-
- /**
- * Trigger the Meta* parameter with instance specific calls to 'declare' (key, value) metadata.
- *
- * @param m - the Meta* meta user
- */
- virtual void metadata(Meta* m) = 0;
-
- /**
- * DSP instance computation, to be called with successive in/out audio buffers.
- *
- * @param count - the number of frames to compute
- * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT samples (eiher float, double or quad)
- * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT samples (eiher float, double or quad)
- *
- */
- virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) = 0;
-
- /**
- * DSP instance computation: alternative method to be used by subclasses.
- *
- * @param date_usec - the timestamp in microsec given by audio driver.
- * @param count - the number of frames to compute
- * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT samples (either float, double or quad)
- * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT samples (either float, double or quad)
- *
- */
- virtual void compute(double /*date_usec*/, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { compute(count, inputs, outputs); }
-
-};
-
-/**
- * Generic DSP decorator.
+ * Signal processor definition.
*/
-class FAUST_API decorator_dsp : public dsp {
+class FAUST_API dsp
+{
+ public:
+ dsp() {}
+ virtual ~dsp() {}
+
+ /* Return instance number of audio inputs */
+ virtual int getNumInputs() = 0;
+
+ /* Return instance number of audio outputs */
+ virtual int getNumOutputs() = 0;
+
+ /**
+ * Trigger the ui_interface parameter with instance specific calls
+ * to 'openTabBox', 'addButton', 'addVerticalSlider'... in order to build the UI.
+ *
+ * @param ui_interface - the user interface builder
+ */
+ virtual void buildUserInterface(UI* ui_interface) = 0;
+
+ /* Return the sample rate currently used by the instance */
+ virtual int getSampleRate() = 0;
+
+ /**
+ * Global init, calls the following methods:
+ * - static class 'classInit': static tables initialization
+ * - 'instanceInit': constants and instance state initialization
+ *
+ * @param sample_rate - the sampling rate in Hz
+ */
+ virtual void init(int sample_rate) = 0;
+
+ /**
+ * Init instance state
+ *
+ * @param sample_rate - the sampling rate in Hz
+ */
+ virtual void instanceInit(int sample_rate) = 0;
- protected:
+ /**
+ * Init instance constant state
+ *
+ * @param sample_rate - the sampling rate in Hz
+ */
+ virtual void instanceConstants(int sample_rate) = 0;
- dsp* fDSP;
+ /* Init default control parameters values */
+ virtual void instanceResetUserInterface() = 0;
+
+ /* Init instance state (like delay lines...) but keep the control parameter values */
+ virtual void instanceClear() = 0;
+
+ /**
+ * Return a clone of the instance.
+ *
+ * @return a copy of the instance on success, otherwise a null pointer.
+ */
+ virtual dsp* clone() = 0;
- public:
+ /**
+ * Trigger the Meta* parameter with instance specific calls to 'declare' (key, value)
+ * metadata.
+ *
+ * @param m - the Meta* meta user
+ */
+ virtual void metadata(Meta* m) = 0;
- decorator_dsp(dsp* dsp = nullptr):fDSP(dsp) {}
- virtual ~decorator_dsp() { delete fDSP; }
+ /**
+ * DSP instance computation, to be called with successive in/out audio buffers.
+ *
+ * @param count - the number of frames to compute
+ * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT
+ * samples (eiher float, double or quad)
+ * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT
+ * samples (eiher float, double or quad)
+ *
+ */
+ virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) = 0;
- virtual int getNumInputs() { return fDSP->getNumInputs(); }
- virtual int getNumOutputs() { return fDSP->getNumOutputs(); }
- virtual void buildUserInterface(UI* ui_interface) { fDSP->buildUserInterface(ui_interface); }
- virtual int getSampleRate() { return fDSP->getSampleRate(); }
- virtual void init(int sample_rate) { fDSP->init(sample_rate); }
- virtual void instanceInit(int sample_rate) { fDSP->instanceInit(sample_rate); }
- virtual void instanceConstants(int sample_rate) { fDSP->instanceConstants(sample_rate); }
- virtual void instanceResetUserInterface() { fDSP->instanceResetUserInterface(); }
- virtual void instanceClear() { fDSP->instanceClear(); }
- virtual decorator_dsp* clone() { return new decorator_dsp(fDSP->clone()); }
- virtual void metadata(Meta* m) { fDSP->metadata(m); }
- // Beware: subclasses usually have to overload the two 'compute' methods
- virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { fDSP->compute(count, inputs, outputs); }
- virtual void compute(double date_usec, int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) { fDSP->compute(date_usec, count, inputs, outputs); }
-
+ /**
+ * DSP instance computation: alternative method to be used by subclasses.
+ *
+ * @param date_usec - the timestamp in microsec given by audio driver.
+ * @param count - the number of frames to compute
+ * @param inputs - the input audio buffers as an array of non-interleaved FAUSTFLOAT
+ * samples (either float, double or quad)
+ * @param outputs - the output audio buffers as an array of non-interleaved FAUSTFLOAT
+ * samples (either float, double or quad)
+ *
+ */
+ virtual void compute(double /*date_usec*/, int count, FAUSTFLOAT** inputs,
+ FAUSTFLOAT** outputs)
+ {
+ compute(count, inputs, outputs);
+ }
+};
+
+/**
+ * Generic DSP decorator.
+ */
+
+class FAUST_API decorator_dsp : public dsp
+{
+ protected:
+ dsp* fDSP;
+
+ public:
+ decorator_dsp(dsp* dsp = nullptr) : fDSP(dsp) {}
+ virtual ~decorator_dsp() { delete fDSP; }
+
+ virtual int getNumInputs() { return fDSP->getNumInputs(); }
+ virtual int getNumOutputs() { return fDSP->getNumOutputs(); }
+ virtual void buildUserInterface(UI* ui_interface)
+ {
+ fDSP->buildUserInterface(ui_interface);
+ }
+ virtual int getSampleRate() { return fDSP->getSampleRate(); }
+ virtual void init(int sample_rate) { fDSP->init(sample_rate); }
+ virtual void instanceInit(int sample_rate) { fDSP->instanceInit(sample_rate); }
+ virtual void instanceConstants(int sample_rate)
+ {
+ fDSP->instanceConstants(sample_rate);
+ }
+ virtual void instanceResetUserInterface() { fDSP->instanceResetUserInterface(); }
+ virtual void instanceClear() { fDSP->instanceClear(); }
+ virtual decorator_dsp* clone() { return new decorator_dsp(fDSP->clone()); }
+ virtual void metadata(Meta* m) { fDSP->metadata(m); }
+ // Beware: subclasses usually have to overload the two 'compute' methods
+ virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs)
+ {
+ fDSP->compute(count, inputs, outputs);
+ }
+ virtual void compute(double date_usec, int count, FAUSTFLOAT** inputs,
+ FAUSTFLOAT** outputs)
+ {
+ fDSP->compute(date_usec, count, inputs, outputs);
+ }
};
/**
* to create DSP instances from a compiled DSP program.
*/
-class FAUST_API dsp_factory {
-
- protected:
-
- // So that to force sub-classes to use deleteDSPFactory(dsp_factory* factory);
- virtual ~dsp_factory() {}
-
- public:
-
- virtual std::string getName() = 0;
- virtual std::string getSHAKey() = 0;
- virtual std::string getDSPCode() = 0;
- virtual std::string getCompileOptions() = 0;
- virtual std::vector<std::string> getLibraryList() = 0;
- virtual std::vector<std::string> getIncludePathnames() = 0;
-
- virtual dsp* createDSPInstance() = 0;
-
- virtual void setMemoryManager(dsp_memory_manager* manager) = 0;
- virtual dsp_memory_manager* getMemoryManager() = 0;
-
+class FAUST_API dsp_factory
+{
+ protected:
+ // So that to force sub-classes to use deleteDSPFactory(dsp_factory* factory);
+ virtual ~dsp_factory() {}
+
+ public:
+ virtual std::string getName() = 0;
+ virtual std::string getSHAKey() = 0;
+ virtual std::string getDSPCode() = 0;
+ virtual std::string getCompileOptions() = 0;
+ virtual std::vector<std::string> getLibraryList() = 0;
+ virtual std::vector<std::string> getIncludePathnames() = 0;
+
+ virtual dsp* createDSPInstance() = 0;
+
+ virtual void setMemoryManager(dsp_memory_manager* manager) = 0;
+ virtual dsp_memory_manager* getMemoryManager() = 0;
};
// Denormal handling
-#if defined (__SSE__)
+#if defined(__SSE__)
#include <xmmintrin.h>
#endif
-class FAUST_API ScopedNoDenormals {
-
- private:
-
- intptr_t fpsr;
-
- void setFpStatusRegister(intptr_t fpsr_aux) noexcept
- {
- #if defined (__arm64__) || defined (__aarch64__)
- asm volatile("msr fpcr, %0" : : "ri" (fpsr_aux));
- #elif defined (__SSE__)
- _mm_setcsr(static_cast<uint32_t>(fpsr_aux));
- #endif
- }
-
- void getFpStatusRegister() noexcept
- {
- #if defined (__arm64__) || defined (__aarch64__)
- asm volatile("mrs %0, fpcr" : "=r" (fpsr));
- #elif defined ( __SSE__)
- fpsr = static_cast<intptr_t>(_mm_getcsr());
- #endif
- }
-
- public:
-
- ScopedNoDenormals() noexcept
- {
- #if defined (__arm64__) || defined (__aarch64__)
- intptr_t mask = (1 << 24 /* FZ */);
- #else
- #if defined(__SSE__)
- #if defined(__SSE2__)
- intptr_t mask = 0x8040;
- #else
- intptr_t mask = 0x8000;
- #endif
- #else
- intptr_t mask = 0x0000;
- #endif
- #endif
- getFpStatusRegister();
- setFpStatusRegister(fpsr | mask);
- }
-
- ~ScopedNoDenormals() noexcept
- {
- setFpStatusRegister(fpsr);
- }
+class FAUST_API ScopedNoDenormals
+{
+ private:
+ intptr_t fpsr;
+
+ void setFpStatusRegister(intptr_t fpsr_aux) noexcept
+ {
+#if defined(__arm64__) || defined(__aarch64__)
+ asm volatile("msr fpcr, %0" : : "ri"(fpsr_aux));
+#elif defined(__SSE__)
+ _mm_setcsr(static_cast<uint32_t>(fpsr_aux));
+#endif
+ }
+
+ void getFpStatusRegister() noexcept
+ {
+#if defined(__arm64__) || defined(__aarch64__)
+ asm volatile("mrs %0, fpcr" : "=r"(fpsr));
+#elif defined(__SSE__)
+ fpsr = static_cast<intptr_t>(_mm_getcsr());
+#endif
+ }
+
+ public:
+ ScopedNoDenormals() noexcept
+ {
+#if defined(__arm64__) || defined(__aarch64__)
+ intptr_t mask = (1 << 24 /* FZ */);
+#else
+#if defined(__SSE__)
+#if defined(__SSE2__)
+ intptr_t mask = 0x8040;
+#else
+ intptr_t mask = 0x8000;
+#endif
+#else
+ intptr_t mask = 0x0000;
+#endif
+#endif
+ getFpStatusRegister();
+ setFpStatusRegister(fpsr | mask);
+ }
+ ~ScopedNoDenormals() noexcept { setFpStatusRegister(fpsr); }
};
#define AVOIDDENORMALS ScopedNoDenormals();
#ifndef API_UI_H
#define API_UI_H
+#include <stdio.h>
+
+#include <map>
#include <sstream>
#include <string>
#include <vector>
-#include <stdio.h>
-#include <map>
/************************** BEGIN meta.h *******************************
FAUST Architecture File
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
#ifndef __meta__
#define __meta__
-
/**
- The base class of Meta handler to be used in dsp::metadata(Meta* m) method to retrieve (key, value) metadata.
+ The base class of Meta handler to be used in dsp::metadata(Meta* m) method to retrieve
+ (key, value) metadata.
*/
struct FAUST_API Meta {
virtual ~Meta() {}
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
#ifndef __UI_H__
#define __UI_H__
-
#ifndef FAUSTFLOAT
#define FAUSTFLOAT float
#endif
struct Soundfile;
-template <typename REAL>
+template<typename REAL>
struct FAUST_API UIReal {
-
UIReal() {}
virtual ~UIReal() {}
-
+
// -- widget's layouts
-
- virtual void openTabBox(const char* label) = 0;
+
+ virtual void openTabBox(const char* label) = 0;
virtual void openHorizontalBox(const char* label) = 0;
- virtual void openVerticalBox(const char* label) = 0;
- virtual void closeBox() = 0;
-
+ virtual void openVerticalBox(const char* label) = 0;
+ virtual void closeBox() = 0;
+
// -- active widgets
-
- virtual void addButton(const char* label, REAL* zone) = 0;
+
+ virtual void addButton(const char* label, REAL* zone) = 0;
virtual void addCheckButton(const char* label, REAL* zone) = 0;
- virtual void addVerticalSlider(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0;
- virtual void addHorizontalSlider(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0;
- virtual void addNumEntry(const char* label, REAL* zone, REAL init, REAL min, REAL max, REAL step) = 0;
-
+ virtual void addVerticalSlider(const char* label, REAL* zone, REAL init, REAL min,
+ REAL max, REAL step) = 0;
+ virtual void addHorizontalSlider(const char* label, REAL* zone, REAL init, REAL min,
+ REAL max, REAL step) = 0;
+ virtual void addNumEntry(const char* label, REAL* zone, REAL init, REAL min, REAL max,
+ REAL step) = 0;
+
// -- passive widgets
-
- virtual void addHorizontalBargraph(const char* label, REAL* zone, REAL min, REAL max) = 0;
- virtual void addVerticalBargraph(const char* label, REAL* zone, REAL min, REAL max) = 0;
-
+
+ virtual void addHorizontalBargraph(const char* label, REAL* zone, REAL min,
+ REAL max) = 0;
+ virtual void addVerticalBargraph(const char* label, REAL* zone, REAL min,
+ REAL max) = 0;
+
// -- soundfiles
-
- virtual void addSoundfile(const char* /*label*/, const char* /*filename*/, Soundfile** /*sf_zone*/) = 0;
-
+
+ virtual void addSoundfile(const char* /*label*/, const char* /*filename*/,
+ Soundfile** /*sf_zone*/) = 0;
+
// -- metadata declarations
-
+
virtual void declare(REAL* /*zone*/, const char* /*key*/, const char* /*val*/) {}
-
+
// To be used by LLVM client
virtual int sizeOfFAUSTFLOAT() { return sizeof(FAUSTFLOAT); }
};
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
#ifndef __PathBuilder__
#define __PathBuilder__
-#include <vector>
-#include <set>
-#include <map>
-#include <string>
#include <algorithm>
+#include <map>
#include <regex>
-
+#include <set>
+#include <string>
+#include <vector>
/*******************************************************************************
* PathBuilder : Faust User Interface
* Helper class to build complete hierarchical path for UI items.
******************************************************************************/
-class FAUST_API PathBuilder {
-
- protected:
-
- std::vector<std::string> fControlsLevel;
- std::vector<std::string> fFullPaths;
- std::map<std::string, std::string> fFull2Short; // filled by computeShortNames()
-
- /**
- * @brief check if a character is acceptable for an ID
- *
- * @param c
- * @return true is the character is acceptable for an ID
- */
- bool isIDChar(char c) const
- {
- return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) || ((c >= '0') && (c <= '9'));
- }
-
- /**
- * @brief remove all "/0x00" parts
- *
- * @param src
- * @return modified string
- */
- std::string remove0x00(const std::string& src) const
- {
- return std::regex_replace(src, std::regex("/0x00"), "");
- }
-
- /**
- * @brief replace all non ID char with '_' (one '_' may replace several non ID char)
- *
- * @param src
- * @return modified string
- */
- std::string str2ID(const std::string& src) const
- {
- std::string dst;
- bool need_underscore = false;
- for (char c : src) {
- if (isIDChar(c) || (c == '/')) {
- if (need_underscore) {
- dst.push_back('_');
- need_underscore = false;
- }
- dst.push_back(c);
- } else {
- need_underscore = true;
+class FAUST_API PathBuilder
+{
+ protected:
+ std::vector<std::string> fControlsLevel;
+ std::vector<std::string> fFullPaths;
+ std::map<std::string, std::string> fFull2Short; // filled by computeShortNames()
+
+ /**
+ * @brief check if a character is acceptable for an ID
+ *
+ * @param c
+ * @return true is the character is acceptable for an ID
+ */
+ bool isIDChar(char c) const
+ {
+ return ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))
+ || ((c >= '0') && (c <= '9'));
+ }
+
+ /**
+ * @brief remove all "/0x00" parts
+ *
+ * @param src
+ * @return modified string
+ */
+ std::string remove0x00(const std::string& src) const
+ {
+ return std::regex_replace(src, std::regex("/0x00"), "");
+ }
+
+ /**
+ * @brief replace all non ID char with '_' (one '_' may replace several non ID char)
+ *
+ * @param src
+ * @return modified string
+ */
+ std::string str2ID(const std::string& src) const
+ {
+ std::string dst;
+ bool need_underscore = false;
+ for (char c : src) {
+ if (isIDChar(c) || (c == '/')) {
+ if (need_underscore) {
+ dst.push_back('_');
+ need_underscore = false;
}
+ dst.push_back(c);
+ } else {
+ need_underscore = true;
}
- return dst;
}
-
- /**
- * @brief Keep only the last n slash-parts
- *
- * @param src
- * @param n : 1 indicates the last slash-part
- * @return modified string
- */
- std::string cut(const std::string& src, int n) const
- {
- std::string rdst;
- for (int i = int(src.length())-1; i >= 0; i--) {
- char c = src[i];
- if (c != '/') {
- rdst.push_back(c);
- } else if (n == 1) {
- std::string dst;
- for (int j = int(rdst.length())-1; j >= 0; j--) {
- dst.push_back(rdst[j]);
- }
- return dst;
- } else {
- n--;
- rdst.push_back(c);
+ return dst;
+ }
+
+ /**
+ * @brief Keep only the last n slash-parts
+ *
+ * @param src
+ * @param n : 1 indicates the last slash-part
+ * @return modified string
+ */
+ std::string cut(const std::string& src, int n) const
+ {
+ std::string rdst;
+ for (int i = int(src.length()) - 1; i >= 0; i--) {
+ char c = src[i];
+ if (c != '/') {
+ rdst.push_back(c);
+ } else if (n == 1) {
+ std::string dst;
+ for (int j = int(rdst.length()) - 1; j >= 0; j--) {
+ dst.push_back(rdst[j]);
}
+ return dst;
+ } else {
+ n--;
+ rdst.push_back(c);
}
- return src;
}
-
- void addFullPath(const std::string& label) { fFullPaths.push_back(buildPath(label)); }
-
- /**
- * @brief Compute the mapping between full path and short names
- */
- void computeShortNames()
- {
- std::vector<std::string> uniquePaths; // all full paths transformed but made unique with a prefix
- std::map<std::string, std::string> unique2full; // all full paths transformed but made unique with a prefix
- char num_buffer[16];
- int pnum = 0;
-
- for (const auto& s : fFullPaths) {
- sprintf(num_buffer, "%d", pnum++);
- std::string u = "/P" + std::string(num_buffer) + str2ID(remove0x00(s));
- uniquePaths.push_back(u);
- unique2full[u] = s; // remember the full path associated to a unique path
- }
-
- std::map<std::string, int> uniquePath2level; // map path to level
- for (const auto& s : uniquePaths) uniquePath2level[s] = 1; // we init all levels to 1
- bool have_collisions = true;
-
- while (have_collisions) {
- // compute collision list
- std::set<std::string> collisionSet;
- std::map<std::string, std::string> short2full;
- have_collisions = false;
- for (const auto& it : uniquePath2level) {
- std::string u = it.first;
- int n = it.second;
- std::string shortName = cut(u, n);
- auto p = short2full.find(shortName);
- if (p == short2full.end()) {
- // no collision
- short2full[shortName] = u;
- } else {
- // we have a collision, add the two paths to the collision set
- have_collisions = true;
- collisionSet.insert(u);
- collisionSet.insert(p->second);
- }
- }
- for (const auto& s : collisionSet) uniquePath2level[s]++; // increase level of colliding path
- }
-
+ return src;
+ }
+
+ void addFullPath(const std::string& label) { fFullPaths.push_back(buildPath(label)); }
+
+ /**
+ * @brief Compute the mapping between full path and short names
+ */
+ void computeShortNames()
+ {
+ std::vector<std::string>
+ uniquePaths; // all full paths transformed but made unique with a prefix
+ std::map<std::string, std::string>
+ unique2full; // all full paths transformed but made unique with a prefix
+ char num_buffer[16];
+ int pnum = 0;
+
+ for (const auto& s : fFullPaths) {
+ sprintf(num_buffer, "%d", pnum++);
+ std::string u = "/P" + std::string(num_buffer) + str2ID(remove0x00(s));
+ uniquePaths.push_back(u);
+ unique2full[u] = s; // remember the full path associated to a unique path
+ }
+
+ std::map<std::string, int> uniquePath2level; // map path to level
+ for (const auto& s : uniquePaths)
+ uniquePath2level[s] = 1; // we init all levels to 1
+ bool have_collisions = true;
+
+ while (have_collisions) {
+ // compute collision list
+ std::set<std::string> collisionSet;
+ std::map<std::string, std::string> short2full;
+ have_collisions = false;
for (const auto& it : uniquePath2level) {
- std::string u = it.first;
- int n = it.second;
- std::string shortName = replaceCharList(cut(u, n), {'/'}, '_');
- fFull2Short[unique2full[u]] = shortName;
+ std::string u = it.first;
+ int n = it.second;
+ std::string shortName = cut(u, n);
+ auto p = short2full.find(shortName);
+ if (p == short2full.end()) {
+ // no collision
+ short2full[shortName] = u;
+ } else {
+ // we have a collision, add the two paths to the collision set
+ have_collisions = true;
+ collisionSet.insert(u);
+ collisionSet.insert(p->second);
+ }
}
+ for (const auto& s : collisionSet)
+ uniquePath2level[s]++; // increase level of colliding path
}
-
- std::string replaceCharList(const std::string& str, const std::vector<char>& ch1, char ch2)
- {
- auto beg = ch1.begin();
- auto end = ch1.end();
- std::string res = str;
- for (size_t i = 0; i < str.length(); ++i) {
- if (std::find(beg, end, str[i]) != end) res[i] = ch2;
- }
- return res;
+
+ for (const auto& it : uniquePath2level) {
+ std::string u = it.first;
+ int n = it.second;
+ std::string shortName = replaceCharList(cut(u, n), {'/'}, '_');
+ fFull2Short[unique2full[u]] = shortName;
}
-
- public:
-
- PathBuilder() {}
- virtual ~PathBuilder() {}
-
- // Return true for the first level of groups
- bool pushLabel(const std::string& label) { fControlsLevel.push_back(label); return fControlsLevel.size() == 1;}
-
- // Return true for the last level of groups
- bool popLabel() { fControlsLevel.pop_back(); return fControlsLevel.size() == 0; }
-
- std::string buildPath(const std::string& label)
- {
- std::string res = "/";
- for (size_t i = 0; i < fControlsLevel.size(); i++) {
- res = res + fControlsLevel[i] + "/";
- }
- res += label;
- return replaceCharList(res, {' ', '#', '*', ',', '?', '[', ']', '{', '}', '(', ')'}, '_');
+ }
+
+ std::string replaceCharList(const std::string& str, const std::vector<char>& ch1,
+ char ch2)
+ {
+ auto beg = ch1.begin();
+ auto end = ch1.end();
+ std::string res = str;
+ for (size_t i = 0; i < str.length(); ++i) {
+ if (std::find(beg, end, str[i]) != end)
+ res[i] = ch2;
}
-
+ return res;
+ }
+
+ public:
+ PathBuilder() {}
+ virtual ~PathBuilder() {}
+
+ // Return true for the first level of groups
+ bool pushLabel(const std::string& label)
+ {
+ fControlsLevel.push_back(label);
+ return fControlsLevel.size() == 1;
+ }
+
+ // Return true for the last level of groups
+ bool popLabel()
+ {
+ fControlsLevel.pop_back();
+ return fControlsLevel.size() == 0;
+ }
+
+ std::string buildPath(const std::string& label)
+ {
+ std::string res = "/";
+ for (size_t i = 0; i < fControlsLevel.size(); i++) {
+ res = res + fControlsLevel[i] + "/";
+ }
+ res += label;
+ return replaceCharList(
+ res, {' ', '#', '*', ',', '?', '[', ']', '{', '}', '(', ')'}, '_');
+ }
};
#endif // __PathBuilder__
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
+
EXCEPTION : As a special exception, you may create a larger work
that contains this FAUST architecture section and distribute
that work under terms of your choice, so long as this FAUST
/***************************************************************************************
ValueConverter.h
(GRAME, Copyright 2015-2019)
-
+
Set of conversion objects used to map user interface values (for example a gui slider
delivering values between 0 and 1) to faust values (for example a vslider between
20 and 20000) using a log scale.
-
+
-- Utilities
-
+
Range(lo,hi) : clip a value x between lo and hi
- Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and v2
- Interpolator3pt(lo,mi,hi,v1,vm,v2) : Map values between lo mid hi to values between v1 vm v2
-
+ Interpolator(lo,hi,v1,v2) : Maps a value x between lo and hi to a value y between v1 and
+v2 Interpolator3pt(lo,mi,hi,v1,vm,v2) : Map values between lo mid hi to values between v1
+vm v2
+
-- Value Converters
-
+
ValueConverter::ui2faust(x)
ValueConverter::faust2ui(x)
-
+
-- ValueConverters used for sliders depending of the scale
-
+
LinearValueConverter(umin, umax, fmin, fmax)
LinearValueConverter2(lo, mi, hi, v1, vm, v2) using 2 segments
LogValueConverter(umin, umax, fmin, fmax)
ExpValueConverter(umin, umax, fmin, fmax)
-
+
-- ValueConverters used for accelerometers based on 3 points
-
+
AccUpConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 0
AccDownConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 1
AccUpDownConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 2
AccDownUpConverter(amin, amid, amax, fmin, fmid, fmax) -- curve 3
-
+
-- lists of ZoneControl are used to implement accelerometers metadata for each axes
-
+
ZoneControl(zone, valueConverter) : a zone with an accelerometer data converter
-
+
-- ZoneReader are used to implement screencolor metadata
-
+
ZoneReader(zone, valueConverter) : a zone with a data converter
****************************************************************************************/
+#include <assert.h>
#include <float.h>
-#include <algorithm> // std::max
+
+#include <algorithm> // std::max
#include <cmath>
#include <vector>
-#include <assert.h>
-
//--------------------------------------------------------------------------------------
// Interpolator(lo,hi,v1,v2)
// y = v1 - lo*coef + x*coef
// y = offset + x*coef with offset = v1 - lo*coef
//--------------------------------------------------------------------------------------
-class FAUST_API Interpolator {
-
- private:
-
- //--------------------------------------------------------------------------------------
- // Range(lo,hi) clip a value between lo and hi
- //--------------------------------------------------------------------------------------
- struct Range
- {
- double fLo;
- double fHi;
-
- Range(double x, double y) : fLo(std::min<double>(x,y)), fHi(std::max<double>(x,y)) {}
- double operator()(double x) { return (x<fLo) ? fLo : (x>fHi) ? fHi : x; }
- };
-
-
- Range fRange;
- double fCoef;
- double fOffset;
-
- public:
-
- Interpolator(double lo, double hi, double v1, double v2) : fRange(lo,hi)
+class FAUST_API Interpolator
+{
+ private:
+ //--------------------------------------------------------------------------------------
+ // Range(lo,hi) clip a value between lo and hi
+ //--------------------------------------------------------------------------------------
+ struct Range {
+ double fLo;
+ double fHi;
+
+ Range(double x, double y)
+ : fLo(std::min<double>(x, y)), fHi(std::max<double>(x, y))
{
- if (hi != lo) {
- // regular case
- fCoef = (v2-v1)/(hi-lo);
- fOffset = v1 - lo*fCoef;
- } else {
- // degenerate case, avoids division by zero
- fCoef = 0;
- fOffset = (v1+v2)/2;
- }
}
- double operator()(double v)
- {
- double x = fRange(v);
- return fOffset + x*fCoef;
- }
-
- void getLowHigh(double& amin, double& amax)
- {
- amin = fRange.fLo;
- amax = fRange.fHi;
+ double operator()(double x) { return (x < fLo) ? fLo : (x > fHi) ? fHi : x; }
+ };
+
+ Range fRange;
+ double fCoef;
+ double fOffset;
+
+ public:
+ Interpolator(double lo, double hi, double v1, double v2) : fRange(lo, hi)
+ {
+ if (hi != lo) {
+ // regular case
+ fCoef = (v2 - v1) / (hi - lo);
+ fOffset = v1 - lo * fCoef;
+ } else {
+ // degenerate case, avoids division by zero
+ fCoef = 0;
+ fOffset = (v1 + v2) / 2;
}
+ }
+ double operator()(double v)
+ {
+ double x = fRange(v);
+ return fOffset + x * fCoef;
+ }
+
+ void getLowHigh(double& amin, double& amax)
+ {
+ amin = fRange.fLo;
+ amax = fRange.fHi;
+ }
};
//--------------------------------------------------------------------------------------
// Interpolator3pt(lo,mi,hi,v1,vm,v2)
// Map values between lo mid hi to values between v1 vm v2
//--------------------------------------------------------------------------------------
-class FAUST_API Interpolator3pt {
-
- private:
-
- Interpolator fSegment1;
- Interpolator fSegment2;
- double fMid;
-
- public:
-
- Interpolator3pt(double lo, double mi, double hi, double v1, double vm, double v2) :
- fSegment1(lo, mi, v1, vm),
- fSegment2(mi, hi, vm, v2),
- fMid(mi) {}
- double operator()(double x) { return (x < fMid) ? fSegment1(x) : fSegment2(x); }
-
- void getMappingValues(double& amin, double& amid, double& amax)
- {
- fSegment1.getLowHigh(amin, amid);
- fSegment2.getLowHigh(amid, amax);
- }
+class FAUST_API Interpolator3pt
+{
+ private:
+ Interpolator fSegment1;
+ Interpolator fSegment2;
+ double fMid;
+
+ public:
+ Interpolator3pt(double lo, double mi, double hi, double v1, double vm, double v2)
+ : fSegment1(lo, mi, v1, vm), fSegment2(mi, hi, vm, v2), fMid(mi)
+ {
+ }
+ double operator()(double x) { return (x < fMid) ? fSegment1(x) : fSegment2(x); }
+
+ void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fSegment1.getLowHigh(amin, amid);
+ fSegment2.getLowHigh(amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Abstract ValueConverter class. Converts values between UI and Faust representations
//--------------------------------------------------------------------------------------
-class FAUST_API ValueConverter {
-
- public:
-
- virtual ~ValueConverter() {}
- virtual double ui2faust(double x) { return x; };
- virtual double faust2ui(double x) { return x; };
+class FAUST_API ValueConverter
+{
+ public:
+ virtual ~ValueConverter() {}
+ virtual double ui2faust(double x) { return x; };
+ virtual double faust2ui(double x) { return x; };
};
//--------------------------------------------------------------------------------------
// A converter than can be updated
//--------------------------------------------------------------------------------------
-class FAUST_API UpdatableValueConverter : public ValueConverter {
-
- protected:
-
- bool fActive;
-
- public:
-
- UpdatableValueConverter():fActive(true)
- {}
- virtual ~UpdatableValueConverter()
- {}
-
- virtual void setMappingValues(double amin, double amid, double amax, double min, double init, double max) = 0;
- virtual void getMappingValues(double& amin, double& amid, double& amax) = 0;
-
- void setActive(bool on_off) { fActive = on_off; }
- bool getActive() { return fActive; }
-
+class FAUST_API UpdatableValueConverter : public ValueConverter
+{
+ protected:
+ bool fActive;
+
+ public:
+ UpdatableValueConverter() : fActive(true) {}
+ virtual ~UpdatableValueConverter() {}
+
+ virtual void setMappingValues(double amin, double amid, double amax, double min,
+ double init, double max) = 0;
+ virtual void getMappingValues(double& amin, double& amid, double& amax) = 0;
+
+ void setActive(bool on_off) { fActive = on_off; }
+ bool getActive() { return fActive; }
};
//--------------------------------------------------------------------------------------
// Linear conversion between ui and Faust values
//--------------------------------------------------------------------------------------
-class FAUST_API LinearValueConverter : public ValueConverter {
-
- private:
-
- Interpolator fUI2F;
- Interpolator fF2UI;
-
- public:
-
- LinearValueConverter(double umin, double umax, double fmin, double fmax) :
- fUI2F(umin,umax,fmin,fmax), fF2UI(fmin,fmax,umin,umax)
- {}
-
- LinearValueConverter() : fUI2F(0.,0.,0.,0.), fF2UI(0.,0.,0.,0.)
- {}
- virtual double ui2faust(double x) { return fUI2F(x); }
- virtual double faust2ui(double x) { return fF2UI(x); }
-
+class FAUST_API LinearValueConverter : public ValueConverter
+{
+ private:
+ Interpolator fUI2F;
+ Interpolator fF2UI;
+
+ public:
+ LinearValueConverter(double umin, double umax, double fmin, double fmax)
+ : fUI2F(umin, umax, fmin, fmax), fF2UI(fmin, fmax, umin, umax)
+ {
+ }
+
+ LinearValueConverter() : fUI2F(0., 0., 0., 0.), fF2UI(0., 0., 0., 0.) {}
+ virtual double ui2faust(double x) { return fUI2F(x); }
+ virtual double faust2ui(double x) { return fF2UI(x); }
};
//--------------------------------------------------------------------------------------
// Two segments linear conversion between ui and Faust values
//--------------------------------------------------------------------------------------
-class FAUST_API LinearValueConverter2 : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fUI2F;
- Interpolator3pt fF2UI;
-
- public:
-
- LinearValueConverter2(double amin, double amid, double amax, double min, double init, double max) :
- fUI2F(amin, amid, amax, min, init, max), fF2UI(min, init, max, amin, amid, amax)
- {}
-
- LinearValueConverter2() : fUI2F(0.,0.,0.,0.,0.,0.), fF2UI(0.,0.,0.,0.,0.,0.)
- {}
-
- virtual double ui2faust(double x) { return fUI2F(x); }
- virtual double faust2ui(double x) { return fF2UI(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double min, double init, double max)
- {
- fUI2F = Interpolator3pt(amin, amid, amax, min, init, max);
- fF2UI = Interpolator3pt(min, init, max, amin, amid, amax);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fUI2F.getMappingValues(amin, amid, amax);
- }
-
+class FAUST_API LinearValueConverter2 : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fUI2F;
+ Interpolator3pt fF2UI;
+
+ public:
+ LinearValueConverter2(double amin, double amid, double amax, double min, double init,
+ double max)
+ : fUI2F(amin, amid, amax, min, init, max), fF2UI(min, init, max, amin, amid, amax)
+ {
+ }
+
+ LinearValueConverter2() : fUI2F(0., 0., 0., 0., 0., 0.), fF2UI(0., 0., 0., 0., 0., 0.)
+ {
+ }
+
+ virtual double ui2faust(double x) { return fUI2F(x); }
+ virtual double faust2ui(double x) { return fF2UI(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double min,
+ double init, double max)
+ {
+ fUI2F = Interpolator3pt(amin, amid, amax, min, init, max);
+ fF2UI = Interpolator3pt(min, init, max, amin, amid, amax);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fUI2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Logarithmic conversion between ui and Faust values
//--------------------------------------------------------------------------------------
-class FAUST_API LogValueConverter : public LinearValueConverter {
-
- public:
-
- LogValueConverter(double umin, double umax, double fmin, double fmax) :
- LinearValueConverter(umin, umax, std::log(std::max<double>(DBL_MIN, fmin)), std::log(std::max<double>(DBL_MIN, fmax)))
- {}
-
- virtual double ui2faust(double x) { return std::exp(LinearValueConverter::ui2faust(x)); }
- virtual double faust2ui(double x) { return LinearValueConverter::faust2ui(std::log(std::max<double>(x, DBL_MIN))); }
-
+class FAUST_API LogValueConverter : public LinearValueConverter
+{
+ public:
+ LogValueConverter(double umin, double umax, double fmin, double fmax)
+ : LinearValueConverter(umin, umax, std::log(std::max<double>(DBL_MIN, fmin)),
+ std::log(std::max<double>(DBL_MIN, fmax)))
+ {
+ }
+
+ virtual double ui2faust(double x)
+ {
+ return std::exp(LinearValueConverter::ui2faust(x));
+ }
+ virtual double faust2ui(double x)
+ {
+ return LinearValueConverter::faust2ui(std::log(std::max<double>(x, DBL_MIN)));
+ }
};
//--------------------------------------------------------------------------------------
// Exponential conversion between ui and Faust values
//--------------------------------------------------------------------------------------
-class FAUST_API ExpValueConverter : public LinearValueConverter {
-
- public:
-
- ExpValueConverter(double umin, double umax, double fmin, double fmax) :
- LinearValueConverter(umin, umax, std::min<double>(DBL_MAX, std::exp(fmin)), std::min<double>(DBL_MAX, std::exp(fmax)))
- {}
-
- virtual double ui2faust(double x) { return std::log(LinearValueConverter::ui2faust(x)); }
- virtual double faust2ui(double x) { return LinearValueConverter::faust2ui(std::min<double>(DBL_MAX, std::exp(x))); }
-
+class FAUST_API ExpValueConverter : public LinearValueConverter
+{
+ public:
+ ExpValueConverter(double umin, double umax, double fmin, double fmax)
+ : LinearValueConverter(umin, umax, std::min<double>(DBL_MAX, std::exp(fmin)),
+ std::min<double>(DBL_MAX, std::exp(fmax)))
+ {
+ }
+
+ virtual double ui2faust(double x)
+ {
+ return std::log(LinearValueConverter::ui2faust(x));
+ }
+ virtual double faust2ui(double x)
+ {
+ return LinearValueConverter::faust2ui(std::min<double>(DBL_MAX, std::exp(x)));
+ }
};
//--------------------------------------------------------------------------------------
// Convert accelerometer or gyroscope values to Faust values
// Using an Up curve (curve 0)
//--------------------------------------------------------------------------------------
-class FAUST_API AccUpConverter : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fA2F;
- Interpolator3pt fF2A;
-
- public:
-
- AccUpConverter(double amin, double amid, double amax, double fmin, double fmid, double fmax) :
- fA2F(amin,amid,amax,fmin,fmid,fmax),
- fF2A(fmin,fmid,fmax,amin,amid,amax)
- {}
-
- virtual double ui2faust(double x) { return fA2F(x); }
- virtual double faust2ui(double x) { return fF2A(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double fmin, double fmid, double fmax)
- {
- //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
- fA2F = Interpolator3pt(amin, amid, amax, fmin, fmid, fmax);
- fF2A = Interpolator3pt(fmin, fmid, fmax, amin, amid, amax);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fA2F.getMappingValues(amin, amid, amax);
- }
-
+class FAUST_API AccUpConverter : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fA2F;
+ Interpolator3pt fF2A;
+
+ public:
+ AccUpConverter(double amin, double amid, double amax, double fmin, double fmid,
+ double fmax)
+ : fA2F(amin, amid, amax, fmin, fmid, fmax)
+ , fF2A(fmin, fmid, fmax, amin, amid, amax)
+ {
+ }
+
+ virtual double ui2faust(double x) { return fA2F(x); }
+ virtual double faust2ui(double x) { return fF2A(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double fmin,
+ double fmid, double fmax)
+ {
+ //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpConverter update %f %f %f
+ //%f %f %f", amin,amid,amax,fmin,fmid,fmax);
+ fA2F = Interpolator3pt(amin, amid, amax, fmin, fmid, fmax);
+ fF2A = Interpolator3pt(fmin, fmid, fmax, amin, amid, amax);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fA2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Convert accelerometer or gyroscope values to Faust values
// Using a Down curve (curve 1)
//--------------------------------------------------------------------------------------
-class FAUST_API AccDownConverter : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fA2F;
- Interpolator3pt fF2A;
-
- public:
-
- AccDownConverter(double amin, double amid, double amax, double fmin, double fmid, double fmax) :
- fA2F(amin,amid,amax,fmax,fmid,fmin),
- fF2A(fmin,fmid,fmax,amax,amid,amin)
- {}
-
- virtual double ui2faust(double x) { return fA2F(x); }
- virtual double faust2ui(double x) { return fF2A(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double fmin, double fmid, double fmax)
- {
- //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
- fA2F = Interpolator3pt(amin, amid, amax, fmax, fmid, fmin);
- fF2A = Interpolator3pt(fmin, fmid, fmax, amax, amid, amin);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fA2F.getMappingValues(amin, amid, amax);
- }
+class FAUST_API AccDownConverter : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fA2F;
+ Interpolator3pt fF2A;
+
+ public:
+ AccDownConverter(double amin, double amid, double amax, double fmin, double fmid,
+ double fmax)
+ : fA2F(amin, amid, amax, fmax, fmid, fmin)
+ , fF2A(fmin, fmid, fmax, amax, amid, amin)
+ {
+ }
+
+ virtual double ui2faust(double x) { return fA2F(x); }
+ virtual double faust2ui(double x) { return fF2A(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double fmin,
+ double fmid, double fmax)
+ {
+ //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownConverter update %f %f
+ //%f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+ fA2F = Interpolator3pt(amin, amid, amax, fmax, fmid, fmin);
+ fF2A = Interpolator3pt(fmin, fmid, fmax, amax, amid, amin);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fA2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Convert accelerometer or gyroscope values to Faust values
// Using an Up-Down curve (curve 2)
//--------------------------------------------------------------------------------------
-class FAUST_API AccUpDownConverter : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fA2F;
- Interpolator fF2A;
-
- public:
-
- AccUpDownConverter(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax) :
- fA2F(amin,amid,amax,fmin,fmax,fmin),
- fF2A(fmin,fmax,amin,amax) // Special, pseudo inverse of a non monotonic function
- {}
-
- virtual double ui2faust(double x) { return fA2F(x); }
- virtual double faust2ui(double x) { return fF2A(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax)
- {
- //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpDownConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
- fA2F = Interpolator3pt(amin, amid, amax, fmin, fmax, fmin);
- fF2A = Interpolator(fmin, fmax, amin, amax);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fA2F.getMappingValues(amin, amid, amax);
- }
+class FAUST_API AccUpDownConverter : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fA2F;
+ Interpolator fF2A;
+
+ public:
+ AccUpDownConverter(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
+ : fA2F(amin, amid, amax, fmin, fmax, fmin)
+ , fF2A(fmin, fmax, amin,
+ amax) // Special, pseudo inverse of a non monotonic function
+ {
+ }
+
+ virtual double ui2faust(double x) { return fA2F(x); }
+ virtual double faust2ui(double x) { return fF2A(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
+ {
+ //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccUpDownConverter update %f %f
+ //%f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+ fA2F = Interpolator3pt(amin, amid, amax, fmin, fmax, fmin);
+ fF2A = Interpolator(fmin, fmax, amin, amax);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fA2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Convert accelerometer or gyroscope values to Faust values
// Using a Down-Up curve (curve 3)
//--------------------------------------------------------------------------------------
-class FAUST_API AccDownUpConverter : public UpdatableValueConverter {
-
- private:
-
- Interpolator3pt fA2F;
- Interpolator fF2A;
-
- public:
-
- AccDownUpConverter(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax) :
- fA2F(amin,amid,amax,fmax,fmin,fmax),
- fF2A(fmin,fmax,amin,amax) // Special, pseudo inverse of a non monotonic function
- {}
-
- virtual double ui2faust(double x) { return fA2F(x); }
- virtual double faust2ui(double x) { return fF2A(x); }
-
- virtual void setMappingValues(double amin, double amid, double amax, double fmin, double /*fmid*/, double fmax)
- {
- //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownUpConverter update %f %f %f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
- fA2F = Interpolator3pt(amin, amid, amax, fmax, fmin, fmax);
- fF2A = Interpolator(fmin, fmax, amin, amax);
- }
-
- virtual void getMappingValues(double& amin, double& amid, double& amax)
- {
- fA2F.getMappingValues(amin, amid, amax);
- }
+class FAUST_API AccDownUpConverter : public UpdatableValueConverter
+{
+ private:
+ Interpolator3pt fA2F;
+ Interpolator fF2A;
+
+ public:
+ AccDownUpConverter(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
+ : fA2F(amin, amid, amax, fmax, fmin, fmax)
+ , fF2A(fmin, fmax, amin,
+ amax) // Special, pseudo inverse of a non monotonic function
+ {
+ }
+
+ virtual double ui2faust(double x) { return fA2F(x); }
+ virtual double faust2ui(double x) { return fF2A(x); }
+
+ virtual void setMappingValues(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
+ {
+ //__android_log_print(ANDROID_LOG_ERROR, "Faust", "AccDownUpConverter update %f %f
+ //%f %f %f %f", amin,amid,amax,fmin,fmid,fmax);
+ fA2F = Interpolator3pt(amin, amid, amax, fmax, fmin, fmax);
+ fF2A = Interpolator(fmin, fmax, amin, amax);
+ }
+
+ virtual void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fA2F.getMappingValues(amin, amid, amax);
+ }
};
//--------------------------------------------------------------------------------------
// Base class for ZoneControl
//--------------------------------------------------------------------------------------
-class FAUST_API ZoneControl {
-
- protected:
-
- FAUSTFLOAT* fZone;
-
- public:
-
- ZoneControl(FAUSTFLOAT* zone) : fZone(zone) {}
- virtual ~ZoneControl() {}
+class FAUST_API ZoneControl
+{
+ protected:
+ FAUSTFLOAT* fZone;
- virtual void update(double /*v*/) const {}
+ public:
+ ZoneControl(FAUSTFLOAT* zone) : fZone(zone) {}
+ virtual ~ZoneControl() {}
- virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/, double /*amax*/, double /*min*/, double /*init*/, double /*max*/) {}
- virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
+ virtual void update(double /*v*/) const {}
- FAUSTFLOAT* getZone() { return fZone; }
+ virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/,
+ double /*amax*/, double /*min*/, double /*init*/,
+ double /*max*/)
+ {
+ }
+ virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
- virtual void setActive(bool /*on_off*/) {}
- virtual bool getActive() { return false; }
+ FAUSTFLOAT* getZone() { return fZone; }
- virtual int getCurve() { return -1; }
+ virtual void setActive(bool /*on_off*/) {}
+ virtual bool getActive() { return false; }
+ virtual int getCurve() { return -1; }
};
//--------------------------------------------------------------------------------------
// Useful to implement accelerometers metadata as a list of ZoneControl for each axes
//--------------------------------------------------------------------------------------
-class FAUST_API ConverterZoneControl : public ZoneControl {
-
- protected:
-
- ValueConverter* fValueConverter;
-
- public:
-
- ConverterZoneControl(FAUSTFLOAT* zone, ValueConverter* converter) : ZoneControl(zone), fValueConverter(converter) {}
- virtual ~ConverterZoneControl() { delete fValueConverter; } // Assuming fValueConverter is not kept elsewhere...
-
- virtual void update(double v) const { *fZone = FAUSTFLOAT(fValueConverter->ui2faust(v)); }
-
- ValueConverter* getConverter() { return fValueConverter; }
-
+class FAUST_API ConverterZoneControl : public ZoneControl
+{
+ protected:
+ ValueConverter* fValueConverter;
+
+ public:
+ ConverterZoneControl(FAUSTFLOAT* zone, ValueConverter* converter)
+ : ZoneControl(zone), fValueConverter(converter)
+ {
+ }
+ virtual ~ConverterZoneControl()
+ {
+ delete fValueConverter;
+ } // Assuming fValueConverter is not kept elsewhere...
+
+ virtual void update(double v) const
+ {
+ *fZone = FAUSTFLOAT(fValueConverter->ui2faust(v));
+ }
+
+ ValueConverter* getConverter() { return fValueConverter; }
};
//--------------------------------------------------------------------------------------
// Association of a zone and a four value converter, each one for each possible curve.
// Useful to implement accelerometers metadata as a list of ZoneControl for each axes
//--------------------------------------------------------------------------------------
-class FAUST_API CurveZoneControl : public ZoneControl {
-
- private:
-
- std::vector<UpdatableValueConverter*> fValueConverters;
- int fCurve;
-
- public:
-
- CurveZoneControl(FAUSTFLOAT* zone, int curve, double amin, double amid, double amax, double min, double init, double max) : ZoneControl(zone), fCurve(0)
- {
- assert(curve >= 0 && curve <= 3);
- fValueConverters.push_back(new AccUpConverter(amin, amid, amax, min, init, max));
- fValueConverters.push_back(new AccDownConverter(amin, amid, amax, min, init, max));
- fValueConverters.push_back(new AccUpDownConverter(amin, amid, amax, min, init, max));
- fValueConverters.push_back(new AccDownUpConverter(amin, amid, amax, min, init, max));
- fCurve = curve;
- }
- virtual ~CurveZoneControl()
- {
- for (const auto& it : fValueConverters) { delete it; }
- }
- void update(double v) const { if (fValueConverters[fCurve]->getActive()) *fZone = FAUSTFLOAT(fValueConverters[fCurve]->ui2faust(v)); }
-
- void setMappingValues(int curve, double amin, double amid, double amax, double min, double init, double max)
- {
- fValueConverters[curve]->setMappingValues(amin, amid, amax, min, init, max);
- fCurve = curve;
- }
-
- void getMappingValues(double& amin, double& amid, double& amax)
- {
- fValueConverters[fCurve]->getMappingValues(amin, amid, amax);
+class FAUST_API CurveZoneControl : public ZoneControl
+{
+ private:
+ std::vector<UpdatableValueConverter*> fValueConverters;
+ int fCurve;
+
+ public:
+ CurveZoneControl(FAUSTFLOAT* zone, int curve, double amin, double amid, double amax,
+ double min, double init, double max)
+ : ZoneControl(zone), fCurve(0)
+ {
+ assert(curve >= 0 && curve <= 3);
+ fValueConverters.push_back(new AccUpConverter(amin, amid, amax, min, init, max));
+ fValueConverters.push_back(
+ new AccDownConverter(amin, amid, amax, min, init, max));
+ fValueConverters.push_back(
+ new AccUpDownConverter(amin, amid, amax, min, init, max));
+ fValueConverters.push_back(
+ new AccDownUpConverter(amin, amid, amax, min, init, max));
+ fCurve = curve;
+ }
+ virtual ~CurveZoneControl()
+ {
+ for (const auto& it : fValueConverters) {
+ delete it;
}
-
- void setActive(bool on_off)
- {
- for (const auto& it : fValueConverters) { it->setActive(on_off); }
+ }
+ void update(double v) const
+ {
+ if (fValueConverters[fCurve]->getActive())
+ *fZone = FAUSTFLOAT(fValueConverters[fCurve]->ui2faust(v));
+ }
+
+ void setMappingValues(int curve, double amin, double amid, double amax, double min,
+ double init, double max)
+ {
+ fValueConverters[curve]->setMappingValues(amin, amid, amax, min, init, max);
+ fCurve = curve;
+ }
+
+ void getMappingValues(double& amin, double& amid, double& amax)
+ {
+ fValueConverters[fCurve]->getMappingValues(amin, amid, amax);
+ }
+
+ void setActive(bool on_off)
+ {
+ for (const auto& it : fValueConverters) {
+ it->setActive(on_off);
}
+ }
- int getCurve() { return fCurve; }
+ int getCurve() { return fCurve; }
};
-class FAUST_API ZoneReader {
-
- private:
-
- FAUSTFLOAT* fZone;
- Interpolator fInterpolator;
-
- public:
-
- ZoneReader(FAUSTFLOAT* zone, double lo, double hi) : fZone(zone), fInterpolator(lo, hi, 0, 255) {}
+class FAUST_API ZoneReader
+{
+ private:
+ FAUSTFLOAT* fZone;
+ Interpolator fInterpolator;
- virtual ~ZoneReader() {}
+ public:
+ ZoneReader(FAUSTFLOAT* zone, double lo, double hi)
+ : fZone(zone), fInterpolator(lo, hi, 0, 255)
+ {
+ }
- int getValue()
- {
- return (fZone != nullptr) ? int(fInterpolator(*fZone)) : 127;
- }
+ virtual ~ZoneReader() {}
+ int getValue() { return (fZone != nullptr) ? int(fInterpolator(*fZone)) : 127; }
};
#endif
typedef unsigned int uint;
-class APIUI : public PathBuilder, public Meta, public UI
+class APIUI
+ : public PathBuilder
+ , public Meta
+ , public UI
{
- public:
- enum ItemType { kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry, kHBargraph, kVBargraph };
- enum Type { kAcc = 0, kGyr = 1, kNoType };
-
- protected:
-
- enum Mapping { kLin = 0, kLog = 1, kExp = 2 };
-
- struct Item {
- std::string fLabel;
- std::string fShortname;
- std::string fPath;
- ValueConverter* fConversion;
- FAUSTFLOAT* fZone;
- FAUSTFLOAT fInit;
- FAUSTFLOAT fMin;
- FAUSTFLOAT fMax;
- FAUSTFLOAT fStep;
- ItemType fItemType;
-
- Item(const std::string& label,
- const std::string& short_name,
- const std::string& path,
- ValueConverter* conversion,
- FAUSTFLOAT* zone,
- FAUSTFLOAT init,
- FAUSTFLOAT min,
- FAUSTFLOAT max,
- FAUSTFLOAT step,
- ItemType item_type)
- :fLabel(label), fShortname(short_name), fPath(path), fConversion(conversion),
- fZone(zone), fInit(init), fMin(min), fMax(max), fStep(step), fItemType(item_type)
- {}
- };
- std::vector<Item> fItems;
-
- std::vector<std::map<std::string, std::string> > fMetaData;
- std::vector<ZoneControl*> fAcc[3];
- std::vector<ZoneControl*> fGyr[3];
-
- // Screen color control
- // "...[screencolor:red]..." etc.
- bool fHasScreenControl; // true if control screen color metadata
- ZoneReader* fRedReader;
- ZoneReader* fGreenReader;
- ZoneReader* fBlueReader;
-
- // Current values controlled by metadata
- std::string fCurrentUnit;
- int fCurrentScale;
- std::string fCurrentAcc;
- std::string fCurrentGyr;
- std::string fCurrentColor;
- std::string fCurrentTooltip;
- std::map<std::string, std::string> fCurrentMetadata;
-
- // Add a generic parameter
- virtual void addParameter(const char* label,
- FAUSTFLOAT* zone,
- FAUSTFLOAT init,
- FAUSTFLOAT min,
- FAUSTFLOAT max,
- FAUSTFLOAT step,
- ItemType type)
+ public:
+ enum ItemType {
+ kButton = 0,
+ kCheckButton,
+ kVSlider,
+ kHSlider,
+ kNumEntry,
+ kHBargraph,
+ kVBargraph
+ };
+ enum Type { kAcc = 0, kGyr = 1, kNoType };
+
+ protected:
+ enum Mapping { kLin = 0, kLog = 1, kExp = 2 };
+
+ struct Item {
+ std::string fLabel;
+ std::string fShortname;
+ std::string fPath;
+ ValueConverter* fConversion;
+ FAUSTFLOAT* fZone;
+ FAUSTFLOAT fInit;
+ FAUSTFLOAT fMin;
+ FAUSTFLOAT fMax;
+ FAUSTFLOAT fStep;
+ ItemType fItemType;
+
+ Item(const std::string& label, const std::string& short_name,
+ const std::string& path, ValueConverter* conversion, FAUSTFLOAT* zone,
+ FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step,
+ ItemType item_type)
+ : fLabel(label)
+ , fShortname(short_name)
+ , fPath(path)
+ , fConversion(conversion)
+ , fZone(zone)
+ , fInit(init)
+ , fMin(min)
+ , fMax(max)
+ , fStep(step)
+ , fItemType(item_type)
{
- std::string path = buildPath(label);
- fFullPaths.push_back(path);
-
- // handle scale metadata
- ValueConverter* converter = nullptr;
- switch (fCurrentScale) {
- case kLin:
- converter = new LinearValueConverter(0, 1, min, max);
- break;
- case kLog:
- converter = new LogValueConverter(0, 1, min, max);
- break;
- case kExp:
- converter = new ExpValueConverter(0, 1, min, max);
- break;
- }
- fCurrentScale = kLin;
-
- fItems.push_back(Item(label, "", path, converter, zone, init, min, max, step, type));
-
- if (fCurrentAcc.size() > 0 && fCurrentGyr.size() > 0) {
- fprintf(stderr, "warning : 'acc' and 'gyr' metadata used for the same %s parameter !!\n", label);
- }
-
- // handle acc metadata "...[acc : <axe> <curve> <amin> <amid> <amax>]..."
- if (fCurrentAcc.size() > 0) {
- std::istringstream iss(fCurrentAcc);
- int axe, curve;
- double amin, amid, amax;
- iss >> axe >> curve >> amin >> amid >> amax;
-
- if ((0 <= axe) && (axe < 3) &&
- (0 <= curve) && (curve < 4) &&
- (amin < amax) && (amin <= amid) && (amid <= amax))
- {
- fAcc[axe].push_back(new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
- } else {
- fprintf(stderr, "incorrect acc metadata : %s \n", fCurrentAcc.c_str());
- }
- fCurrentAcc = "";
- }
-
- // handle gyr metadata "...[gyr : <axe> <curve> <amin> <amid> <amax>]..."
- if (fCurrentGyr.size() > 0) {
- std::istringstream iss(fCurrentGyr);
- int axe, curve;
- double amin, amid, amax;
- iss >> axe >> curve >> amin >> amid >> amax;
-
- if ((0 <= axe) && (axe < 3) &&
- (0 <= curve) && (curve < 4) &&
- (amin < amax) && (amin <= amid) && (amid <= amax))
- {
- fGyr[axe].push_back(new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
- } else {
- fprintf(stderr, "incorrect gyr metadata : %s \n", fCurrentGyr.c_str());
- }
- fCurrentGyr = "";
- }
-
- // handle screencolor metadata "...[screencolor:red|green|blue|white]..."
- if (fCurrentColor.size() > 0) {
- if ((fCurrentColor == "red") && (fRedReader == nullptr)) {
- fRedReader = new ZoneReader(zone, min, max);
- fHasScreenControl = true;
- } else if ((fCurrentColor == "green") && (fGreenReader == nullptr)) {
- fGreenReader = new ZoneReader(zone, min, max);
- fHasScreenControl = true;
- } else if ((fCurrentColor == "blue") && (fBlueReader == nullptr)) {
- fBlueReader = new ZoneReader(zone, min, max);
- fHasScreenControl = true;
- } else if ((fCurrentColor == "white") && (fRedReader == nullptr) && (fGreenReader == nullptr) && (fBlueReader == nullptr)) {
- fRedReader = new ZoneReader(zone, min, max);
- fGreenReader = new ZoneReader(zone, min, max);
- fBlueReader = new ZoneReader(zone, min, max);
- fHasScreenControl = true;
- } else {
- fprintf(stderr, "incorrect screencolor metadata : %s \n", fCurrentColor.c_str());
- }
- }
- fCurrentColor = "";
-
- fMetaData.push_back(fCurrentMetadata);
- fCurrentMetadata.clear();
}
-
- int getZoneIndex(std::vector<ZoneControl*>* table, int p, int val)
- {
- FAUSTFLOAT* zone = fItems[uint(p)].fZone;
- for (size_t i = 0; i < table[val].size(); i++) {
- if (zone == table[val][i]->getZone()) return int(i);
- }
- return -1;
+ };
+ std::vector<Item> fItems;
+
+ std::vector<std::map<std::string, std::string> > fMetaData;
+ std::vector<ZoneControl*> fAcc[3];
+ std::vector<ZoneControl*> fGyr[3];
+
+ // Screen color control
+ // "...[screencolor:red]..." etc.
+ bool fHasScreenControl; // true if control screen color metadata
+ ZoneReader* fRedReader;
+ ZoneReader* fGreenReader;
+ ZoneReader* fBlueReader;
+
+ // Current values controlled by metadata
+ std::string fCurrentUnit;
+ int fCurrentScale;
+ std::string fCurrentAcc;
+ std::string fCurrentGyr;
+ std::string fCurrentColor;
+ std::string fCurrentTooltip;
+ std::map<std::string, std::string> fCurrentMetadata;
+
+ // Add a generic parameter
+ virtual void addParameter(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init,
+ FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step,
+ ItemType type)
+ {
+ std::string path = buildPath(label);
+ fFullPaths.push_back(path);
+
+ // handle scale metadata
+ ValueConverter* converter = nullptr;
+ switch (fCurrentScale) {
+ case kLin:
+ converter = new LinearValueConverter(0, 1, min, max);
+ break;
+ case kLog:
+ converter = new LogValueConverter(0, 1, min, max);
+ break;
+ case kExp:
+ converter = new ExpValueConverter(0, 1, min, max);
+ break;
}
+ fCurrentScale = kLin;
- void setConverter(std::vector<ZoneControl*>* table, int p, int val, int curve, double amin, double amid, double amax)
- {
- int id1 = getZoneIndex(table, p, 0);
- int id2 = getZoneIndex(table, p, 1);
- int id3 = getZoneIndex(table, p, 2);
+ fItems.push_back(
+ Item(label, "", path, converter, zone, init, min, max, step, type));
- // Deactivates everywhere..
- if (id1 != -1) table[0][uint(id1)]->setActive(false);
- if (id2 != -1) table[1][uint(id2)]->setActive(false);
- if (id3 != -1) table[2][uint(id3)]->setActive(false);
-
- if (val == -1) { // Means: no more mapping...
- // So stay all deactivated...
- } else {
- int id4 = getZoneIndex(table, p, val);
- if (id4 != -1) {
- // Reactivate the one we edit...
- table[val][uint(id4)]->setMappingValues(curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit, fItems[uint(p)].fMax);
- table[val][uint(id4)]->setActive(true);
- } else {
- // Allocate a new CurveZoneControl which is 'active' by default
- FAUSTFLOAT* zone = fItems[uint(p)].fZone;
- table[val].push_back(new CurveZoneControl(zone, curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit, fItems[uint(p)].fMax));
- }
- }
+ if (fCurrentAcc.size() > 0 && fCurrentGyr.size() > 0) {
+ fprintf(
+ stderr,
+ "warning : 'acc' and 'gyr' metadata used for the same %s parameter !!\n",
+ label);
}
- void getConverter(std::vector<ZoneControl*>* table, int p, int& val, int& curve, double& amin, double& amid, double& amax)
- {
- int id1 = getZoneIndex(table, p, 0);
- int id2 = getZoneIndex(table, p, 1);
- int id3 = getZoneIndex(table, p, 2);
-
- if (id1 != -1) {
- val = 0;
- curve = table[val][uint(id1)]->getCurve();
- table[val][uint(id1)]->getMappingValues(amin, amid, amax);
- } else if (id2 != -1) {
- val = 1;
- curve = table[val][uint(id2)]->getCurve();
- table[val][uint(id2)]->getMappingValues(amin, amid, amax);
- } else if (id3 != -1) {
- val = 2;
- curve = table[val][uint(id3)]->getCurve();
- table[val][uint(id3)]->getMappingValues(amin, amid, amax);
+ // handle acc metadata "...[acc : <axe> <curve> <amin> <amid> <amax>]..."
+ if (fCurrentAcc.size() > 0) {
+ std::istringstream iss(fCurrentAcc);
+ int axe, curve;
+ double amin, amid, amax;
+ iss >> axe >> curve >> amin >> amid >> amax;
+
+ if ((0 <= axe) && (axe < 3) && (0 <= curve) && (curve < 4) && (amin < amax)
+ && (amin <= amid) && (amid <= amax)) {
+ fAcc[axe].push_back(
+ new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
} else {
- val = -1; // No mapping
- curve = 0;
- amin = -100.;
- amid = 0.;
- amax = 100.;
+ fprintf(stderr, "incorrect acc metadata : %s \n", fCurrentAcc.c_str());
}
+ fCurrentAcc = "";
}
- public:
-
- APIUI() : fHasScreenControl(false), fRedReader(nullptr), fGreenReader(nullptr), fBlueReader(nullptr), fCurrentScale(kLin)
- {}
-
- virtual ~APIUI()
- {
- for (const auto& it : fItems) delete it.fConversion;
- for (int i = 0; i < 3; i++) {
- for (const auto& it : fAcc[i]) delete it;
- for (const auto& it : fGyr[i]) delete it;
+ // handle gyr metadata "...[gyr : <axe> <curve> <amin> <amid> <amax>]..."
+ if (fCurrentGyr.size() > 0) {
+ std::istringstream iss(fCurrentGyr);
+ int axe, curve;
+ double amin, amid, amax;
+ iss >> axe >> curve >> amin >> amid >> amax;
+
+ if ((0 <= axe) && (axe < 3) && (0 <= curve) && (curve < 4) && (amin < amax)
+ && (amin <= amid) && (amid <= amax)) {
+ fGyr[axe].push_back(
+ new CurveZoneControl(zone, curve, amin, amid, amax, min, init, max));
+ } else {
+ fprintf(stderr, "incorrect gyr metadata : %s \n", fCurrentGyr.c_str());
}
- delete fRedReader;
- delete fGreenReader;
- delete fBlueReader;
+ fCurrentGyr = "";
}
- // -- widget's layouts
-
- virtual void openTabBox(const char* label) { pushLabel(label); }
- virtual void openHorizontalBox(const char* label) { pushLabel(label); }
- virtual void openVerticalBox(const char* label) { pushLabel(label); }
- virtual void closeBox()
- {
- if (popLabel()) {
- // Shortnames can be computed when all fullnames are known
- computeShortNames();
- // Fill 'shortname' field for each item
- for (const auto& it : fFull2Short) {
- int index = getParamIndex(it.first.c_str());
- fItems[index].fShortname = it.second;
- }
+ // handle screencolor metadata "...[screencolor:red|green|blue|white]..."
+ if (fCurrentColor.size() > 0) {
+ if ((fCurrentColor == "red") && (fRedReader == nullptr)) {
+ fRedReader = new ZoneReader(zone, min, max);
+ fHasScreenControl = true;
+ } else if ((fCurrentColor == "green") && (fGreenReader == nullptr)) {
+ fGreenReader = new ZoneReader(zone, min, max);
+ fHasScreenControl = true;
+ } else if ((fCurrentColor == "blue") && (fBlueReader == nullptr)) {
+ fBlueReader = new ZoneReader(zone, min, max);
+ fHasScreenControl = true;
+ } else if ((fCurrentColor == "white") && (fRedReader == nullptr)
+ && (fGreenReader == nullptr) && (fBlueReader == nullptr)) {
+ fRedReader = new ZoneReader(zone, min, max);
+ fGreenReader = new ZoneReader(zone, min, max);
+ fBlueReader = new ZoneReader(zone, min, max);
+ fHasScreenControl = true;
+ } else {
+ fprintf(stderr, "incorrect screencolor metadata : %s \n",
+ fCurrentColor.c_str());
}
}
-
- // -- active widgets
-
- virtual void addButton(const char* label, FAUSTFLOAT* zone)
- {
- addParameter(label, zone, 0, 0, 1, 1, kButton);
- }
-
- virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)
- {
- addParameter(label, zone, 0, 0, 1, 1, kCheckButton);
+ fCurrentColor = "";
+
+ fMetaData.push_back(fCurrentMetadata);
+ fCurrentMetadata.clear();
+ }
+
+ int getZoneIndex(std::vector<ZoneControl*>* table, int p, int val)
+ {
+ FAUSTFLOAT* zone = fItems[uint(p)].fZone;
+ for (size_t i = 0; i < table[val].size(); i++) {
+ if (zone == table[val][i]->getZone())
+ return int(i);
}
-
- virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
- {
- addParameter(label, zone, init, min, max, step, kVSlider);
+ return -1;
+ }
+
+ void setConverter(std::vector<ZoneControl*>* table, int p, int val, int curve,
+ double amin, double amid, double amax)
+ {
+ int id1 = getZoneIndex(table, p, 0);
+ int id2 = getZoneIndex(table, p, 1);
+ int id3 = getZoneIndex(table, p, 2);
+
+ // Deactivates everywhere..
+ if (id1 != -1)
+ table[0][uint(id1)]->setActive(false);
+ if (id2 != -1)
+ table[1][uint(id2)]->setActive(false);
+ if (id3 != -1)
+ table[2][uint(id3)]->setActive(false);
+
+ if (val == -1) { // Means: no more mapping...
+ // So stay all deactivated...
+ } else {
+ int id4 = getZoneIndex(table, p, val);
+ if (id4 != -1) {
+ // Reactivate the one we edit...
+ table[val][uint(id4)]->setMappingValues(
+ curve, amin, amid, amax, fItems[uint(p)].fMin, fItems[uint(p)].fInit,
+ fItems[uint(p)].fMax);
+ table[val][uint(id4)]->setActive(true);
+ } else {
+ // Allocate a new CurveZoneControl which is 'active' by default
+ FAUSTFLOAT* zone = fItems[uint(p)].fZone;
+ table[val].push_back(new CurveZoneControl(
+ zone, curve, amin, amid, amax, fItems[uint(p)].fMin,
+ fItems[uint(p)].fInit, fItems[uint(p)].fMax));
+ }
}
-
- virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
- {
- addParameter(label, zone, init, min, max, step, kHSlider);
+ }
+
+ void getConverter(std::vector<ZoneControl*>* table, int p, int& val, int& curve,
+ double& amin, double& amid, double& amax)
+ {
+ int id1 = getZoneIndex(table, p, 0);
+ int id2 = getZoneIndex(table, p, 1);
+ int id3 = getZoneIndex(table, p, 2);
+
+ if (id1 != -1) {
+ val = 0;
+ curve = table[val][uint(id1)]->getCurve();
+ table[val][uint(id1)]->getMappingValues(amin, amid, amax);
+ } else if (id2 != -1) {
+ val = 1;
+ curve = table[val][uint(id2)]->getCurve();
+ table[val][uint(id2)]->getMappingValues(amin, amid, amax);
+ } else if (id3 != -1) {
+ val = 2;
+ curve = table[val][uint(id3)]->getCurve();
+ table[val][uint(id3)]->getMappingValues(amin, amid, amax);
+ } else {
+ val = -1; // No mapping
+ curve = 0;
+ amin = -100.;
+ amid = 0.;
+ amax = 100.;
}
-
- virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init, FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
- {
- addParameter(label, zone, init, min, max, step, kNumEntry);
+ }
+
+ public:
+ APIUI()
+ : fHasScreenControl(false)
+ , fRedReader(nullptr)
+ , fGreenReader(nullptr)
+ , fBlueReader(nullptr)
+ , fCurrentScale(kLin)
+ {
+ }
+
+ virtual ~APIUI()
+ {
+ for (const auto& it : fItems)
+ delete it.fConversion;
+ for (int i = 0; i < 3; i++) {
+ for (const auto& it : fAcc[i])
+ delete it;
+ for (const auto& it : fGyr[i])
+ delete it;
}
+ delete fRedReader;
+ delete fGreenReader;
+ delete fBlueReader;
+ }
- // -- passive widgets
-
- virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
- {
- addParameter(label, zone, min, min, max, (max-min)/1000.0f, kHBargraph);
- }
+ // -- widget's layouts
- virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min, FAUSTFLOAT max)
- {
- addParameter(label, zone, min, min, max, (max-min)/1000.0f, kVBargraph);
+ virtual void openTabBox(const char* label) { pushLabel(label); }
+ virtual void openHorizontalBox(const char* label) { pushLabel(label); }
+ virtual void openVerticalBox(const char* label) { pushLabel(label); }
+ virtual void closeBox()
+ {
+ if (popLabel()) {
+ // Shortnames can be computed when all fullnames are known
+ computeShortNames();
+ // Fill 'shortname' field for each item
+ for (const auto& it : fFull2Short) {
+ int index = getParamIndex(it.first.c_str());
+ fItems[index].fShortname = it.second;
+ }
}
+ }
- // -- soundfiles
+ // -- active widgets
- virtual void addSoundfile(const char* /*label*/, const char* /*filename*/, Soundfile** /*sf_zone*/) {}
+ virtual void addButton(const char* label, FAUSTFLOAT* zone)
+ {
+ addParameter(label, zone, 0, 0, 1, 1, kButton);
+ }
+
+ virtual void addCheckButton(const char* label, FAUSTFLOAT* zone)
+ {
+ addParameter(label, zone, 0, 0, 1, 1, kCheckButton);
+ }
+
+ virtual void addVerticalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init,
+ FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+ {
+ addParameter(label, zone, init, min, max, step, kVSlider);
+ }
+
+ virtual void addHorizontalSlider(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init,
+ FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+ {
+ addParameter(label, zone, init, min, max, step, kHSlider);
+ }
+
+ virtual void addNumEntry(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT init,
+ FAUSTFLOAT min, FAUSTFLOAT max, FAUSTFLOAT step)
+ {
+ addParameter(label, zone, init, min, max, step, kNumEntry);
+ }
- // -- metadata declarations
+ // -- passive widgets
- virtual void declare(FAUSTFLOAT* /*zone*/, const char* key, const char* val)
- {
- // Keep metadata
- fCurrentMetadata[key] = val;
-
- if (strcmp(key, "scale") == 0) {
- if (strcmp(val, "log") == 0) {
- fCurrentScale = kLog;
- } else if (strcmp(val, "exp") == 0) {
- fCurrentScale = kExp;
- } else {
- fCurrentScale = kLin;
- }
- } else if (strcmp(key, "unit") == 0) {
- fCurrentUnit = val;
- } else if (strcmp(key, "acc") == 0) {
- fCurrentAcc = val;
- } else if (strcmp(key, "gyr") == 0) {
- fCurrentGyr = val;
- } else if (strcmp(key, "screencolor") == 0) {
- fCurrentColor = val; // val = "red", "green", "blue" or "white"
- } else if (strcmp(key, "tooltip") == 0) {
- fCurrentTooltip = val;
- }
- }
+ virtual void addHorizontalBargraph(const char* label, FAUSTFLOAT* zone,
+ FAUSTFLOAT min, FAUSTFLOAT max)
+ {
+ addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kHBargraph);
+ }
- virtual void declare(const char* /*key*/, const char* /*val*/)
- {}
+ virtual void addVerticalBargraph(const char* label, FAUSTFLOAT* zone, FAUSTFLOAT min,
+ FAUSTFLOAT max)
+ {
+ addParameter(label, zone, min, min, max, (max - min) / 1000.0f, kVBargraph);
+ }
- //-------------------------------------------------------------------------------
- // Simple API part
- //-------------------------------------------------------------------------------
- int getParamsCount() { return int(fItems.size()); }
+ // -- soundfiles
- int getParamIndex(const char* path_aux)
- {
- std::string path = std::string(path_aux);
- auto it = find_if(fItems.begin(), fItems.end(),
- [=](const Item& it) { return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path); });
- return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
- }
-
- const char* getParamLabel(int p) { return fItems[uint(p)].fLabel.c_str(); }
- const char* getParamShortname(int p) { return fItems[uint(p)].fShortname.c_str(); }
- const char* getParamAddress(int p) { return fItems[uint(p)].fPath.c_str(); }
-
- std::map<const char*, const char*> getMetadata(int p)
- {
- std::map<const char*, const char*> res;
- std::map<std::string, std::string> metadata = fMetaData[uint(p)];
- for (const auto& it : metadata) {
- res[it.first.c_str()] = it.second.c_str();
- }
- return res;
- }
+ virtual void addSoundfile(const char* /*label*/, const char* /*filename*/,
+ Soundfile** /*sf_zone*/)
+ {
+ }
- const char* getMetadata(int p, const char* key)
- {
- return (fMetaData[uint(p)].find(key) != fMetaData[uint(p)].end()) ? fMetaData[uint(p)][key].c_str() : "";
- }
- FAUSTFLOAT getParamMin(int p) { return fItems[uint(p)].fMin; }
- FAUSTFLOAT getParamMax(int p) { return fItems[uint(p)].fMax; }
- FAUSTFLOAT getParamStep(int p) { return fItems[uint(p)].fStep; }
- FAUSTFLOAT getParamInit(int p) { return fItems[uint(p)].fInit; }
+ // -- metadata declarations
- FAUSTFLOAT* getParamZone(int p) { return fItems[uint(p)].fZone; }
+ virtual void declare(FAUSTFLOAT* /*zone*/, const char* key, const char* val)
+ {
+ // Keep metadata
+ fCurrentMetadata[key] = val;
- FAUSTFLOAT getParamValue(int p) { return *fItems[uint(p)].fZone; }
- FAUSTFLOAT getParamValue(const char* path)
- {
- int index = getParamIndex(path);
- if (index >= 0) {
- return getParamValue(index);
+ if (strcmp(key, "scale") == 0) {
+ if (strcmp(val, "log") == 0) {
+ fCurrentScale = kLog;
+ } else if (strcmp(val, "exp") == 0) {
+ fCurrentScale = kExp;
} else {
- fprintf(stderr, "getParamValue : '%s' not found\n", (path == nullptr ? "NULL" : path));
- return FAUSTFLOAT(0);
+ fCurrentScale = kLin;
}
+ } else if (strcmp(key, "unit") == 0) {
+ fCurrentUnit = val;
+ } else if (strcmp(key, "acc") == 0) {
+ fCurrentAcc = val;
+ } else if (strcmp(key, "gyr") == 0) {
+ fCurrentGyr = val;
+ } else if (strcmp(key, "screencolor") == 0) {
+ fCurrentColor = val; // val = "red", "green", "blue" or "white"
+ } else if (strcmp(key, "tooltip") == 0) {
+ fCurrentTooltip = val;
}
-
- void setParamValue(int p, FAUSTFLOAT v) { *fItems[uint(p)].fZone = v; }
- void setParamValue(const char* path, FAUSTFLOAT v)
- {
- int index = getParamIndex(path);
- if (index >= 0) {
- setParamValue(index, v);
- } else {
- fprintf(stderr, "setParamValue : '%s' not found\n", (path == nullptr ? "NULL" : path));
- }
+ }
+
+ virtual void declare(const char* /*key*/, const char* /*val*/) {}
+
+ //-------------------------------------------------------------------------------
+ // Simple API part
+ //-------------------------------------------------------------------------------
+ int getParamsCount() { return int(fItems.size()); }
+
+ int getParamIndex(const char* path_aux)
+ {
+ std::string path = std::string(path_aux);
+ auto it = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
+ return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path);
+ });
+ return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
+ }
+
+ const char* getParamLabel(int p) { return fItems[uint(p)].fLabel.c_str(); }
+ const char* getParamShortname(int p) { return fItems[uint(p)].fShortname.c_str(); }
+ const char* getParamAddress(int p) { return fItems[uint(p)].fPath.c_str(); }
+
+ std::map<const char*, const char*> getMetadata(int p)
+ {
+ std::map<const char*, const char*> res;
+ std::map<std::string, std::string> metadata = fMetaData[uint(p)];
+ for (const auto& it : metadata) {
+ res[it.first.c_str()] = it.second.c_str();
}
-
- double getParamRatio(int p) { return fItems[uint(p)].fConversion->faust2ui(*fItems[uint(p)].fZone); }
- void setParamRatio(int p, double r) { *fItems[uint(p)].fZone = FAUSTFLOAT(fItems[uint(p)].fConversion->ui2faust(r)); }
-
- double value2ratio(int p, double r) { return fItems[uint(p)].fConversion->faust2ui(r); }
- double ratio2value(int p, double r) { return fItems[uint(p)].fConversion->ui2faust(r); }
-
- /**
- * Return the control type (kAcc, kGyr, or -1) for a given parameter.
- *
- * @param p - the UI parameter index
- *
- * @return the type
- */
- Type getParamType(int p)
- {
- if (p >= 0) {
- if (getZoneIndex(fAcc, p, 0) != -1
- || getZoneIndex(fAcc, p, 1) != -1
- || getZoneIndex(fAcc, p, 2) != -1) {
- return kAcc;
- } else if (getZoneIndex(fGyr, p, 0) != -1
- || getZoneIndex(fGyr, p, 1) != -1
- || getZoneIndex(fGyr, p, 2) != -1) {
- return kGyr;
- }
- }
- return kNoType;
+ return res;
+ }
+
+ const char* getMetadata(int p, const char* key)
+ {
+ return (fMetaData[uint(p)].find(key) != fMetaData[uint(p)].end())
+ ? fMetaData[uint(p)][key].c_str()
+ : "";
+ }
+ FAUSTFLOAT getParamMin(int p) { return fItems[uint(p)].fMin; }
+ FAUSTFLOAT getParamMax(int p) { return fItems[uint(p)].fMax; }
+ FAUSTFLOAT getParamStep(int p) { return fItems[uint(p)].fStep; }
+ FAUSTFLOAT getParamInit(int p) { return fItems[uint(p)].fInit; }
+
+ FAUSTFLOAT* getParamZone(int p) { return fItems[uint(p)].fZone; }
+
+ FAUSTFLOAT getParamValue(int p) { return *fItems[uint(p)].fZone; }
+ FAUSTFLOAT getParamValue(const char* path)
+ {
+ int index = getParamIndex(path);
+ if (index >= 0) {
+ return getParamValue(index);
+ } else {
+ fprintf(stderr, "getParamValue : '%s' not found\n",
+ (path == nullptr ? "NULL" : path));
+ return FAUSTFLOAT(0);
}
-
- /**
- * Return the Item type (kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry, kHBargraph, kVBargraph) for a given parameter.
- *
- * @param p - the UI parameter index
- *
- * @return the Item type
- */
- ItemType getParamItemType(int p)
- {
- return fItems[uint(p)].fItemType;
+ }
+
+ void setParamValue(int p, FAUSTFLOAT v) { *fItems[uint(p)].fZone = v; }
+ void setParamValue(const char* path, FAUSTFLOAT v)
+ {
+ int index = getParamIndex(path);
+ if (index >= 0) {
+ setParamValue(index, v);
+ } else {
+ fprintf(stderr, "setParamValue : '%s' not found\n",
+ (path == nullptr ? "NULL" : path));
}
+ }
+
+ double getParamRatio(int p)
+ {
+ return fItems[uint(p)].fConversion->faust2ui(*fItems[uint(p)].fZone);
+ }
+ void setParamRatio(int p, double r)
+ {
+ *fItems[uint(p)].fZone = FAUSTFLOAT(fItems[uint(p)].fConversion->ui2faust(r));
+ }
+
+ double value2ratio(int p, double r)
+ {
+ return fItems[uint(p)].fConversion->faust2ui(r);
+ }
+ double ratio2value(int p, double r)
+ {
+ return fItems[uint(p)].fConversion->ui2faust(r);
+ }
- /**
- * Set a new value coming from an accelerometer, propagate it to all relevant FAUSTFLOAT* zones.
- *
- * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
- * @param value - the new value
- *
- */
- void propagateAcc(int acc, double value)
- {
- for (size_t i = 0; i < fAcc[acc].size(); i++) {
- fAcc[acc][i]->update(value);
+ /**
+ * Return the control type (kAcc, kGyr, or -1) for a given parameter.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the type
+ */
+ Type getParamType(int p)
+ {
+ if (p >= 0) {
+ if (getZoneIndex(fAcc, p, 0) != -1 || getZoneIndex(fAcc, p, 1) != -1
+ || getZoneIndex(fAcc, p, 2) != -1) {
+ return kAcc;
+ } else if (getZoneIndex(fGyr, p, 0) != -1 || getZoneIndex(fGyr, p, 1) != -1
+ || getZoneIndex(fGyr, p, 2) != -1) {
+ return kGyr;
}
}
+ return kNoType;
+ }
- /**
- * Used to edit accelerometer curves and mapping. Set curve and related mapping for a given UI parameter.
- *
- * @param p - the UI parameter index
- * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer (-1 means "no mapping")
- * @param curve - between 0 and 3
- * @param amin - mapping 'min' point
- * @param amid - mapping 'middle' point
- * @param amax - mapping 'max' point
- *
- */
- void setAccConverter(int p, int acc, int curve, double amin, double amid, double amax)
- {
- setConverter(fAcc, p, acc, curve, amin, amid, amax);
- }
+ /**
+ * Return the Item type (kButton = 0, kCheckButton, kVSlider, kHSlider, kNumEntry,
+ * kHBargraph, kVBargraph) for a given parameter.
+ *
+ * @param p - the UI parameter index
+ *
+ * @return the Item type
+ */
+ ItemType getParamItemType(int p) { return fItems[uint(p)].fItemType; }
- /**
- * Used to edit gyroscope curves and mapping. Set curve and related mapping for a given UI parameter.
- *
- * @param p - the UI parameter index
- * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no mapping")
- * @param curve - between 0 and 3
- * @param amin - mapping 'min' point
- * @param amid - mapping 'middle' point
- * @param amax - mapping 'max' point
- *
- */
- void setGyrConverter(int p, int gyr, int curve, double amin, double amid, double amax)
- {
- setConverter(fGyr, p, gyr, curve, amin, amid, amax);
+ /**
+ * Set a new value coming from an accelerometer, propagate it to all relevant
+ * FAUSTFLOAT* zones.
+ *
+ * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
+ * @param value - the new value
+ *
+ */
+ void propagateAcc(int acc, double value)
+ {
+ for (size_t i = 0; i < fAcc[acc].size(); i++) {
+ fAcc[acc][i]->update(value);
}
+ }
- /**
- * Used to edit accelerometer curves and mapping. Get curve and related mapping for a given UI parameter.
- *
- * @param p - the UI parameter index
- * @param acc - the acc value to be retrieved (-1 means "no mapping")
- * @param curve - the curve value to be retrieved
- * @param amin - the amin value to be retrieved
- * @param amid - the amid value to be retrieved
- * @param amax - the amax value to be retrieved
- *
- */
- void getAccConverter(int p, int& acc, int& curve, double& amin, double& amid, double& amax)
- {
- getConverter(fAcc, p, acc, curve, amin, amid, amax);
- }
+ /**
+ * Used to edit accelerometer curves and mapping. Set curve and related mapping for a
+ * given UI parameter.
+ *
+ * @param p - the UI parameter index
+ * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
+ * (-1 means "no mapping")
+ * @param curve - between 0 and 3
+ * @param amin - mapping 'min' point
+ * @param amid - mapping 'middle' point
+ * @param amax - mapping 'max' point
+ *
+ */
+ void setAccConverter(int p, int acc, int curve, double amin, double amid, double amax)
+ {
+ setConverter(fAcc, p, acc, curve, amin, amid, amax);
+ }
- /**
- * Used to edit gyroscope curves and mapping. Get curve and related mapping for a given UI parameter.
- *
- * @param p - the UI parameter index
- * @param gyr - the gyr value to be retrieved (-1 means "no mapping")
- * @param curve - the curve value to be retrieved
- * @param amin - the amin value to be retrieved
- * @param amid - the amid value to be retrieved
- * @param amax - the amax value to be retrieved
- *
- */
- void getGyrConverter(int p, int& gyr, int& curve, double& amin, double& amid, double& amax)
- {
- getConverter(fGyr, p, gyr, curve, amin, amid, amax);
- }
+ /**
+ * Used to edit gyroscope curves and mapping. Set curve and related mapping for a
+ * given UI parameter.
+ *
+ * @param p - the UI parameter index
+ * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope (-1 means "no
+ * mapping")
+ * @param curve - between 0 and 3
+ * @param amin - mapping 'min' point
+ * @param amid - mapping 'middle' point
+ * @param amax - mapping 'max' point
+ *
+ */
+ void setGyrConverter(int p, int gyr, int curve, double amin, double amid, double amax)
+ {
+ setConverter(fGyr, p, gyr, curve, amin, amid, amax);
+ }
- /**
- * Set a new value coming from an gyroscope, propagate it to all relevant FAUSTFLOAT* zones.
- *
- * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
- * @param value - the new value
- *
- */
- void propagateGyr(int gyr, double value)
- {
- for (size_t i = 0; i < fGyr[gyr].size(); i++) {
- fGyr[gyr][i]->update(value);
- }
- }
+ /**
+ * Used to edit accelerometer curves and mapping. Get curve and related mapping for a
+ * given UI parameter.
+ *
+ * @param p - the UI parameter index
+ * @param acc - the acc value to be retrieved (-1 means "no mapping")
+ * @param curve - the curve value to be retrieved
+ * @param amin - the amin value to be retrieved
+ * @param amid - the amid value to be retrieved
+ * @param amax - the amax value to be retrieved
+ *
+ */
+ void getAccConverter(int p, int& acc, int& curve, double& amin, double& amid,
+ double& amax)
+ {
+ getConverter(fAcc, p, acc, curve, amin, amid, amax);
+ }
- /**
- * Get the number of FAUSTFLOAT* zones controlled with the accelerometer.
- *
- * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
- * @return the number of zones
- *
- */
- int getAccCount(int acc)
- {
- return (acc >= 0 && acc < 3) ? int(fAcc[acc].size()) : 0;
- }
+ /**
+ * Used to edit gyroscope curves and mapping. Get curve and related mapping for a
+ * given UI parameter.
+ *
+ * @param p - the UI parameter index
+ * @param gyr - the gyr value to be retrieved (-1 means "no mapping")
+ * @param curve - the curve value to be retrieved
+ * @param amin - the amin value to be retrieved
+ * @param amid - the amid value to be retrieved
+ * @param amax - the amax value to be retrieved
+ *
+ */
+ void getGyrConverter(int p, int& gyr, int& curve, double& amin, double& amid,
+ double& amax)
+ {
+ getConverter(fGyr, p, gyr, curve, amin, amid, amax);
+ }
- /**
- * Get the number of FAUSTFLOAT* zones controlled with the gyroscope.
- *
- * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
- * @param the number of zones
- *
- */
- int getGyrCount(int gyr)
- {
- return (gyr >= 0 && gyr < 3) ? int(fGyr[gyr].size()) : 0;
+ /**
+ * Set a new value coming from an gyroscope, propagate it to all relevant FAUSTFLOAT*
+ * zones.
+ *
+ * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
+ * @param value - the new value
+ *
+ */
+ void propagateGyr(int gyr, double value)
+ {
+ for (size_t i = 0; i < fGyr[gyr].size(); i++) {
+ fGyr[gyr][i]->update(value);
}
+ }
- // getScreenColor() : -1 means no screen color control (no screencolor metadata found)
- // otherwise return 0x00RRGGBB a ready to use color
- int getScreenColor()
- {
- if (fHasScreenControl) {
- int r = (fRedReader) ? fRedReader->getValue() : 0;
- int g = (fGreenReader) ? fGreenReader->getValue() : 0;
- int b = (fBlueReader) ? fBlueReader->getValue() : 0;
- return (r<<16) | (g<<8) | b;
- } else {
- return -1;
- }
- }
+ /**
+ * Get the number of FAUSTFLOAT* zones controlled with the accelerometer.
+ *
+ * @param acc - 0 for X accelerometer, 1 for Y accelerometer, 2 for Z accelerometer
+ * @return the number of zones
+ *
+ */
+ int getAccCount(int acc) { return (acc >= 0 && acc < 3) ? int(fAcc[acc].size()) : 0; }
+ /**
+ * Get the number of FAUSTFLOAT* zones controlled with the gyroscope.
+ *
+ * @param gyr - 0 for X gyroscope, 1 for Y gyroscope, 2 for Z gyroscope
+ * @param the number of zones
+ *
+ */
+ int getGyrCount(int gyr) { return (gyr >= 0 && gyr < 3) ? int(fGyr[gyr].size()) : 0; }
+
+ // getScreenColor() : -1 means no screen color control (no screencolor metadata found)
+ // otherwise return 0x00RRGGBB a ready to use color
+ int getScreenColor()
+ {
+ if (fHasScreenControl) {
+ int r = (fRedReader) ? fRedReader->getValue() : 0;
+ int g = (fGreenReader) ? fGreenReader->getValue() : 0;
+ int b = (fBlueReader) ? fBlueReader->getValue() : 0;
+ return (r << 16) | (g << 8) | b;
+ } else {
+ return -1;
+ }
+ }
};
#endif
// FAUST Generated Code
//----------------------------------------------------------------------------
-
#ifndef FAUSTFLOAT
#define FAUSTFLOAT float
-#endif
+#endif
+
+#include <math.h>
#include <algorithm>
#include <cmath>
#include <cstdint>
-#include <math.h>
-#ifndef FAUSTCLASS
+#ifndef FAUSTCLASS
#define FAUSTCLASS volumedsp
#endif
-#ifdef __APPLE__
+#ifdef __APPLE__
#define exp10f __exp10f
-#define exp10 __exp10
+#define exp10 __exp10
#endif
#if defined(_WIN32)
#define RESTRICT __restrict__
#endif
-
-class volumedsp : public dsp {
-
- private:
-
- FAUSTFLOAT fHslider0;
- FAUSTFLOAT fCheckbox0;
- int fSampleRate;
- float fConst0;
- float fConst1;
- float fRec0[2];
-
- public:
-
- void metadata(Meta* m) {
- m->declare("author", "Matt Horton, adapted from GRAME");
- m->declare("basics.lib/name", "Faust Basic Element Library");
- m->declare("basics.lib/version", "0.8");
- m->declare("compile_options", "-a faust2header.cpp -lang cpp -i -inpl -cn volumedsp -es 1 -mcd 16 -single -ftz 0");
- m->declare("description", "Volume Control Faust Plugin for JackTrip, based on Faust examples");
- m->declare("filename", "volumedsp.dsp");
- m->declare("license", "MIT Style STK-4.2");
- m->declare("maths.lib/author", "GRAME");
- m->declare("maths.lib/copyright", "GRAME");
- m->declare("maths.lib/license", "LGPL with exception");
- m->declare("maths.lib/name", "Faust Math Library");
- m->declare("maths.lib/version", "2.5");
- m->declare("name", "volume");
- m->declare("platform.lib/name", "Generic Platform Library");
- m->declare("platform.lib/version", "0.2");
- m->declare("signals.lib/name", "Faust Signal Routing Library");
- m->declare("signals.lib/version", "0.3");
- m->declare("version", "1.0");
- }
-
- virtual int getNumInputs() {
- return 1;
- }
- virtual int getNumOutputs() {
- return 1;
- }
-
- static void classInit(int /*sample_rate*/) {
- }
-
- virtual void instanceConstants(int sample_rate) {
- fSampleRate = sample_rate;
- fConst0 = 44.0999985f / std::min<float>(192000.0f, std::max<float>(1.0f, float(fSampleRate)));
- fConst1 = 1.0f - fConst0;
- }
-
- virtual void instanceResetUserInterface() {
- fHslider0 = FAUSTFLOAT(0.0f);
- fCheckbox0 = FAUSTFLOAT(0.0f);
- }
-
- virtual void instanceClear() {
- for (int l0 = 0; l0 < 2; l0 = l0 + 1) {
- fRec0[l0] = 0.0f;
- }
- }
-
- virtual void init(int sample_rate) {
- classInit(sample_rate);
- instanceInit(sample_rate);
- }
- virtual void instanceInit(int sample_rate) {
- instanceConstants(sample_rate);
- instanceResetUserInterface();
- instanceClear();
- }
-
- virtual volumedsp* clone() {
- return new volumedsp();
- }
-
- virtual int getSampleRate() {
- return fSampleRate;
- }
-
- virtual void buildUserInterface(UI* ui_interface) {
- ui_interface->openVerticalBox("Volume Control");
- ui_interface->declare(&fHslider0, "0", "");
- ui_interface->addHorizontalSlider("Volume", &fHslider0, FAUSTFLOAT(0.0f), FAUSTFLOAT(-40.0f), FAUSTFLOAT(0.0f), FAUSTFLOAT(0.100000001f));
- ui_interface->declare(&fCheckbox0, "1", "");
- ui_interface->addCheckButton("Mute", &fCheckbox0);
- ui_interface->closeBox();
- }
-
- virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs) {
- FAUSTFLOAT* input0 = inputs[0];
- FAUSTFLOAT* output0 = outputs[0];
- float fSlow0 = float(fHslider0);
- int iSlow1 = fSlow0 == -40.0f;
- int iSlow2 = int(float(fCheckbox0));
- float fSlow3 = fConst0 * std::pow(10.0f, 0.0500000007f * fSlow0);
- for (int i0 = 0; i0 < count; i0 = i0 + 1) {
- float fTemp0 = float(input0[i0]);
- fRec0[0] = fSlow3 + fConst1 * fRec0[1];
- float fThen0 = fTemp0 * fRec0[0];
- float fThen1 = ((iSlow2) ? 0.0f : fThen0);
- output0[i0] = FAUSTFLOAT(((iSlow1) ? 0.0f : fThen1));
- fRec0[1] = fRec0[0];
- }
- }
-
+class volumedsp : public dsp
+{
+ private:
+ FAUSTFLOAT fHslider0;
+ FAUSTFLOAT fCheckbox0;
+ int fSampleRate;
+ float fConst0;
+ float fConst1;
+ float fRec0[2];
+
+ public:
+ void metadata(Meta* m)
+ {
+ m->declare("author", "Matt Horton, adapted from GRAME");
+ m->declare("basics.lib/name", "Faust Basic Element Library");
+ m->declare("basics.lib/version", "0.8");
+ m->declare("compile_options",
+ "-a faust2header.cpp -lang cpp -i -inpl -cn volumedsp -es 1 -mcd 16 "
+ "-single -ftz 0");
+ m->declare("description",
+ "Volume Control Faust Plugin for JackTrip, based on Faust examples");
+ m->declare("filename", "volumedsp.dsp");
+ m->declare("license", "MIT Style STK-4.2");
+ m->declare("maths.lib/author", "GRAME");
+ m->declare("maths.lib/copyright", "GRAME");
+ m->declare("maths.lib/license", "LGPL with exception");
+ m->declare("maths.lib/name", "Faust Math Library");
+ m->declare("maths.lib/version", "2.5");
+ m->declare("name", "volume");
+ m->declare("platform.lib/name", "Generic Platform Library");
+ m->declare("platform.lib/version", "0.2");
+ m->declare("signals.lib/name", "Faust Signal Routing Library");
+ m->declare("signals.lib/version", "0.3");
+ m->declare("version", "1.0");
+ }
+
+ virtual int getNumInputs() { return 1; }
+ virtual int getNumOutputs() { return 1; }
+
+ static void classInit(int /*sample_rate*/) {}
+
+ virtual void instanceConstants(int sample_rate)
+ {
+ fSampleRate = sample_rate;
+ fConst0 = 44.0999985f
+ / std::min<float>(192000.0f, std::max<float>(1.0f, float(fSampleRate)));
+ fConst1 = 1.0f - fConst0;
+ }
+
+ virtual void instanceResetUserInterface()
+ {
+ fHslider0 = FAUSTFLOAT(0.0f);
+ fCheckbox0 = FAUSTFLOAT(0.0f);
+ }
+
+ virtual void instanceClear()
+ {
+ for (int l0 = 0; l0 < 2; l0 = l0 + 1) {
+ fRec0[l0] = 0.0f;
+ }
+ }
+
+ virtual void init(int sample_rate)
+ {
+ classInit(sample_rate);
+ instanceInit(sample_rate);
+ }
+ virtual void instanceInit(int sample_rate)
+ {
+ instanceConstants(sample_rate);
+ instanceResetUserInterface();
+ instanceClear();
+ }
+
+ virtual volumedsp* clone() { return new volumedsp(); }
+
+ virtual int getSampleRate() { return fSampleRate; }
+
+ virtual void buildUserInterface(UI* ui_interface)
+ {
+ ui_interface->openVerticalBox("Volume Control");
+ ui_interface->declare(&fHslider0, "0", "");
+ ui_interface->addHorizontalSlider("Volume", &fHslider0, FAUSTFLOAT(0.0f),
+ FAUSTFLOAT(-40.0f), FAUSTFLOAT(0.0f),
+ FAUSTFLOAT(0.100000001f));
+ ui_interface->declare(&fCheckbox0, "1", "");
+ ui_interface->addCheckButton("Mute", &fCheckbox0);
+ ui_interface->closeBox();
+ }
+
+ virtual void compute(int count, FAUSTFLOAT** inputs, FAUSTFLOAT** outputs)
+ {
+ FAUSTFLOAT* input0 = inputs[0];
+ FAUSTFLOAT* output0 = outputs[0];
+ float fSlow0 = float(fHslider0);
+ int iSlow1 = fSlow0 == -40.0f;
+ int iSlow2 = int(float(fCheckbox0));
+ float fSlow3 = fConst0 * std::pow(10.0f, 0.0500000007f * fSlow0);
+ for (int i0 = 0; i0 < count; i0 = i0 + 1) {
+ float fTemp0 = float(input0[i0]);
+ fRec0[0] = fSlow3 + fConst1 * fRec0[1];
+ float fThen0 = fTemp0 * fRec0[0];
+ float fThen1 = ((iSlow2) ? 0.0f : fThen0);
+ output0[i0] = FAUSTFLOAT(((iSlow1) ? 0.0f : fThen1));
+ fRec0[1] = fRec0[0];
+ }
+ }
};
-
#endif
Interpolator fF2A;
public:
- AccUpDownConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
- double fmax)
+ AccUpDownConverter(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
: fA2F(amin, amid, amax, fmin, fmax, fmin)
, fF2A(fmin, fmax, amin,
amax) // Special, pseudo inverse of a non monotonic function
Interpolator fF2A;
public:
- AccDownUpConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
- double fmax)
+ AccDownUpConverter(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
: fA2F(amin, amid, amax, fmax, fmin, fmax)
, fF2A(fmin, fmax, amin,
amax) // Special, pseudo inverse of a non monotonic function
virtual void update(double /*v*/) const {}
- virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/, double /*amax*/,
- double /*min*/, double /*init*/, double /*max*/)
+ virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/,
+ double /*amax*/, double /*min*/, double /*init*/,
+ double /*max*/)
{
}
virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
std::string path = std::string(path_aux);
auto it = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path);
- });
+ });
return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
}
float fTemp25 = fSlow5 * fRec2[0];
float fTemp26 = 1.0f - fRec1[0];
output0[i0] = FAUSTFLOAT(
- fRec0[0]
- * (0.5f * fRec1[0]
+ fRec0[0]
+ * (0.5f * fRec1[0]
* (fTemp25 + fRec2[2] + fTemp23 + fTemp24
+ fSlow3 * ((fTemp25 + fTemp24 + fRec2[2]) - fTemp23))
+ fTemp0 * fTemp26));
fRec44[0] = fTemp30 - (fTemp31 + fSlow5 * fRec44[2]);
float fTemp32 = fSlow5 * fRec44[0];
output1[i0] = FAUSTFLOAT(
- fRec0[0]
- * (0.5f * fRec1[0]
+ fRec0[0]
+ * (0.5f * fRec1[0]
* (fTemp32 + fRec44[2] + fTemp30 + fTemp31
+ fSlow3 * ((fTemp32 + fTemp31 + fRec44[2]) - fTemp30))
+ fTemp1 * fTemp26));
Interpolator fF2A;
public:
- AccUpDownConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
- double fmax)
+ AccUpDownConverter(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
: fA2F(amin, amid, amax, fmin, fmax, fmin)
, fF2A(fmin, fmax, amin,
amax) // Special, pseudo inverse of a non monotonic function
Interpolator fF2A;
public:
- AccDownUpConverter(double amin, double amid, double amax, double fmin, double /*fmid*/,
- double fmax)
+ AccDownUpConverter(double amin, double amid, double amax, double fmin,
+ double /*fmid*/, double fmax)
: fA2F(amin, amid, amax, fmax, fmin, fmax)
, fF2A(fmin, fmax, amin,
amax) // Special, pseudo inverse of a non monotonic function
virtual void update(double /*v*/) const {}
- virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/, double /*amax*/,
- double /*min*/, double /*init*/, double /*max*/)
+ virtual void setMappingValues(int /*curve*/, double /*amin*/, double /*amid*/,
+ double /*amax*/, double /*min*/, double /*init*/,
+ double /*max*/)
{
}
virtual void getMappingValues(double& /*amin*/, double& /*amid*/, double& /*amax*/) {}
std::string path = std::string(path_aux);
auto it = find_if(fItems.begin(), fItems.end(), [=](const Item& it) {
return (it.fLabel == path) || (it.fShortname == path) || (it.fPath == path);
- });
+ });
return (it != fItems.end()) ? int(it - fItems.begin()) : -1;
}
fRec44[0] = fTemp27 - (fTemp28 + fSlow5 * fRec44[2]);
float fTemp29 = fSlow5 * fRec44[0];
output0[i0] = FAUSTFLOAT(
- fRec0[0]
- * (0.5f * fRec1[0]
+ fRec0[0]
+ * (0.5f * fRec1[0]
* (fTemp22 + fRec2[2] + fTemp20 + fTemp21
+ fSlow3 * ((fTemp22 + fTemp21 + fRec2[2]) - fTemp20))
+ fTemp23 + fTemp23