New upstream version 2.3.0+ds
authorIOhannes m zmölnig (Debian/GNU) <umlaeute@debian.org>
Thu, 16 May 2024 22:16:58 +0000 (00:16 +0200)
committerIOhannes m zmölnig (Debian/GNU) <umlaeute@debian.org>
Thu, 16 May 2024 22:16:58 +0000 (00:16 +0200)
54 files changed:
Dockerfile
docs/changelog.yml
meson.build
releases/edge/mac-manifests.json
releases/edge/win-manifests.json
releases/stable/linux-manifests.json
releases/stable/mac-manifests.json
releases/stable/win-manifests.json
src/AudioInterface.cpp
src/AudioTester.h
src/DataProtocol.h
src/JMess.cpp
src/JackAudioInterface.cpp
src/JackTrip.cpp
src/JackTrip.h
src/JackTripWorker.cpp
src/JackTripWorker.h
src/Limiter.h
src/PacketHeader.cpp
src/PacketHeader.h
src/ProcessPlugin.cpp
src/QtStaticPlugins.cpp [new file with mode: 0644]
src/Regulator.cpp
src/Regulator.h
src/UdpDataProtocol.cpp
src/UdpHubListener.cpp
src/UdpHubListener.h
src/compressordsp.h
src/freeverbdsp.h
src/freeverbmonodsp.h
src/gui/Browse.qml
src/gui/DeviceWarning.qml
src/gui/LearnMoreButton.qml [new file with mode: 0644]
src/gui/Recommendations.qml
src/gui/Studio.qml
src/gui/qjacktrip.qrc
src/gui/qjacktrip.ui
src/gui/virtualstudio.cpp
src/gui/virtualstudio.h
src/gui/vsAudio.cpp
src/gui/vsAudio.h
src/gui/vsServerInfo.cpp
src/gui/vsServerInfo.h
src/jacktrip_globals.h
src/jacktrip_types.h
src/limiterdsp.h
src/main.cpp
src/meterdsp.h
src/monitordsp.h
src/stereotomonodsp.h
src/tonedsp.h
src/volumedsp.h
src/zitarevdsp.h
src/zitarevmonodsp.h

index 9acd0ef943e365fc9eb89330945881f71633656c..2fa1bc0f634b87332451b9b0f9128e905baccf3f 100644 (file)
@@ -17,20 +17,28 @@ ARG JACK_VERSION=latest
 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/
@@ -42,9 +50,6 @@ 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 \
@@ -56,7 +61,7 @@ RUN useradd -r -m -N -G audio -s /usr/sbin/nologin 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
index f51ab4c1a1f8b0c9a470e194c93464e7e56eff1d..43624317014584fd344072cdb4378d9dc2980864 100644 (file)
@@ -1,3 +1,20 @@
+- 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:
index d79bd430777e0174491bc0af7051f09ec6079f41..74ea6616c68276c608224cfcaaa4ea0ec6d09860 100644 (file)
@@ -31,9 +31,9 @@ defines = ['-DWAIRTOHUB']
 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')
@@ -238,8 +238,52 @@ else
        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
@@ -320,4 +364,4 @@ summary({'JACK': jack_dep.found(),
 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')
index cbbd227dad2b85e0587f38f91dc6cd8adc9976fb..efc813718c62959081dd3324fb66703684753580 100644 (file)
@@ -1,6 +1,16 @@
 {
   "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",
index ac561234e59caea141f10a5c29944b8e7c6632f0..9a71d2137d854be7638117fc63aeed7401bd1a7a 100644 (file)
@@ -1,6 +1,16 @@
 {
   "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",
index 48460accd57a03357d57d7843898997e23d67dcd..514ed828948f212a8dc3cbe0bf2a19f0f4f8da3b 100644 (file)
@@ -1,6 +1,16 @@
 {
   "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",
index e5ddeef576f9e7684841f7ee8acaae0df009f19e..7caef64889f666d06409aebd47d46fa49e3345f8 100644 (file)
@@ -1,6 +1,16 @@
 {
   "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",
index 5681cf16abff35daef287a059d010174a406b05d..e8451bec472fdbce8b2d0823a5e6c85c59a708a0 100644 (file)
@@ -1,6 +1,16 @@
 {
   "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",
index 0f684f146af6a1c5ee64fc76547036b44032cbf3..918f696296d721c763add80811c15d84a3815619 100644 (file)
@@ -375,7 +375,7 @@ void AudioInterface::audioOutputCallback(QVarLengthArray<sample_t*>& out_buffer,
                                                    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];
@@ -819,16 +819,17 @@ void AudioInterface::setDevicesWarningMsg(warningMessageT msg)
         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:
@@ -856,7 +857,8 @@ void AudioInterface::setDevicesErrorMsg(errorMessageT msg)
             "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
@@ -877,7 +879,8 @@ void AudioInterface::setDevicesErrorMsg(errorMessageT msg)
     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:
index f8430a32d19f965a1f2dc33ded8040825c23055b..0d31be1d0e6024f90af732b7a6e7e86fc170e921 100644 (file)
@@ -41,7 +41,7 @@
 #include <iostream>
 
 #include "jacktrip_types.h"  // sample_t
-//#include <ctime>
+// #include <ctime>
 #include <QVarLengthArray>
 #include <chrono>
 #include <cmath>
index c4c4032a60649184ca89ad157d52ec27ffd3067c..5c5c1a8c4839c8c7b513e4def60b5025ef1362df 100644 (file)
@@ -47,7 +47,7 @@
 #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>
index 8517334fae03a09159cd858bfffa766c13567448..2b967f276cda1cb9a7fba4cb76c2ce194927970d 100644 (file)
@@ -98,10 +98,10 @@ JMess::~JMess()
 
 ///////////////////////////////
 // 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
index 72218276be62274736d7f729c9feaaf02eaa18ed..b78b385b03948c1cd34b52683fa55c4f7197b8b6 100644 (file)
@@ -46,9 +46,9 @@
 #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>
@@ -125,12 +125,12 @@ void JackAudioInterface::setupClient()
         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
index 2e8b2b7c8ab31db54e304c76c69c26bb56610e91..ad5bd5b4a055b71453c3625d0e7c4ce4c0b3d8cb 100644 (file)
@@ -3,7 +3,7 @@
   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
@@ -108,7 +108,6 @@ JackTrip::JackTrip(jacktripModeT JacktripMode, dataProtocolT DataProtocolType,
 #endif  // endwhere
     , mBufferQueueLength(BufferQueueLength)
     , mBufferStrategy(1)
-    , mRegulatorThreadPtr(NULL)
     , mBroadcastQueueLength(0)
     , mSampleRate(gDefaultSampleRate)
     , mDeviceID(gDefaultDeviceID)
@@ -423,21 +422,12 @@ void JackTrip::setupRingBuffers()
                 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
@@ -779,7 +769,7 @@ void JackTrip::onStatTimer()
             //                     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 << "/"
@@ -1582,11 +1572,11 @@ bool JackTrip::checkIfPortIsBinded(int port)
     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;
 }
index 49b78bee88438b0f8ce204949288feac5355dbdf..166106b327722d312fddb944c43a6373fefc33f7 100644 (file)
@@ -3,7 +3,7 @@
   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
@@ -227,7 +227,6 @@ class JackTrip : public QObject
     {
         mBufferStrategy = BufferStrategy;
     }
-    void setRegulatorThread(QThread* ptr) { mRegulatorThreadPtr = ptr; }
     /// \brief Sets (override) Audio Bit Resolution after construction
     virtual void setAudioBitResolution(
         AudioInterface::audioBitResolutionT AudioBitResolution)
@@ -665,7 +664,6 @@ class JackTrip : public QObject
 #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
index b6327946443ceebadf9cca08d579b6da2f2a051f..2c59173678ba78ee8521109e3255254c0ebaf21e 100644 (file)
@@ -45,7 +45,7 @@
 
 #include "JackTrip.h"
 #include "UdpHubListener.h"
-//#include "NetKS.h"
+// #include "NetKS.h"
 #include "LoopBack.h"
 #include "Settings.h"
 #ifdef WAIR  // wair
@@ -194,7 +194,6 @@ void JackTripWorker::start()
     mJackTrip->setBindPorts(mServerPort);
     // jacktrip.setPeerPorts(mClientPort);
     mJackTrip->setBufferStrategy(mBufferStrategy);
-    mJackTrip->setRegulatorThread(mRegulatorThreadPtr);
     mJackTrip->setNetIssuesSimulation(mSimulatedLossRate, mSimulatedJitterRate,
                                       mSimulatedDelayRel);
     mJackTrip->setBroadcast(mBroadcastQueue);
index 686e32d9aa9ecc3a5774d3516a918227a3918eb9..dc31a1581c28c8b864db3d5bc0930baae734f6cf 100644 (file)
@@ -104,7 +104,6 @@ class JackTripWorker : public QObject
     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;
@@ -176,14 +175,13 @@ class JackTripWorker : public QObject
 
     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
index 165a5c807304e144bbd056a8ec6400ecc90130c7..e55a92d1f8107485e073fefbbce2706fc5de42b6 100644 (file)
@@ -42,7 +42,7 @@
 #ifndef __LIMITER_H__
 #define __LIMITER_H__
 
-//#define SINE_TEST
+// #define SINE_TEST
 
 #ifdef SINE_TEST
 #include "limitertest.h"
index 54f6e3fe83797d1b0ebd49215ce0c7cc396ca35d..5792456925073bfff1e11b7d541f0334bb8733e2 100644 (file)
@@ -71,9 +71,9 @@ inline int gettimeofday(struct timeval* p, [[maybe_unused]] void* tz)
 #endif
 #endif
 
-//#######################################################################
-//####################### PacketHeader ##################################
-//#######################################################################
+// #######################################################################
+// ####################### PacketHeader ##################################
+// #######################################################################
 //***********************************************************************
 PacketHeader::PacketHeader(JackTrip* jacktrip)
     : mBufferRequiresSameSettings(false), mJackTrip(jacktrip), mSeqNumber(0)
@@ -90,9 +90,9 @@ uint64_t PacketHeader::usecTime()
         (tv.tv_usec));  // plus the microseconds. Type suseconds_t, range [-1, 1000000]
 }
 
-//#######################################################################
-//####################### DefaultHeader #################################
-//#######################################################################
+// #######################################################################
+// ####################### DefaultHeader #################################
+// #######################################################################
 //***********************************************************************
 DefaultHeader::DefaultHeader(JackTrip* jacktrip) : PacketHeader(jacktrip)
 {
@@ -276,9 +276,9 @@ uint8_t DefaultHeader::getPeerNumOutgoingChannels(int8_t* full_packet) const
     return peer_header->NumOutgoingChannelsToNet;
 }
 
-//#######################################################################
-//####################### JamLinkHeader #################################
-//#######################################################################
+// #######################################################################
+// ####################### JamLinkHeader #################################
+// #######################################################################
 //***********************************************************************
 JamLinkHeader::JamLinkHeader(JackTrip* jacktrip) : PacketHeader(jacktrip)
 {
@@ -349,8 +349,8 @@ void JamLinkHeader::fillHeaderCommonFromAudio()
     }
 }
 
-//#######################################################################
-//####################### EmptyHeader #################################
-//#######################################################################
+// #######################################################################
+// ####################### EmptyHeader #################################
+// #######################################################################
 //***********************************************************************
 EmptyHeader::EmptyHeader(JackTrip* jacktrip) : PacketHeader(jacktrip) {}
index c31b4ba86e59f63fc9e01e81571f3b01a72b741e..84c0351170f9e6a5aa3b75fb97c5b19f8e5b3e7b 100644 (file)
@@ -39,7 +39,7 @@
 #define __PACKETHEADER_H__
 
 #include <iostream>
-//#include <tr1/memory> // for shared_ptr
+// #include <tr1/memory> // for shared_ptr
 #include <QObject>
 #include <QString>
 #include <cstring>
@@ -101,9 +101,9 @@ struct JamLinkHeaderStuct : public HeaderStruct {
     uint32_t TimeStamp;  ///< Time Stamp
 };
 
-//#######################################################################
-//####################### PacketHeader ##################################
-//#######################################################################
+// #######################################################################
+// ####################### PacketHeader ##################################
+// #######################################################################
 /** \brief Base class for header type. Subclass this struct to
  * create a new header.
  */
@@ -171,9 +171,9 @@ class PacketHeader : public QObject
     uint16_t mSeqNumber;
 };
 
-//#######################################################################
-//####################### DefaultHeader #################################
-//#######################################################################
+// #######################################################################
+// ####################### DefaultHeader #################################
+// #######################################################################
 /** \brief Default Header
  */
 class DefaultHeader : public PacketHeader
@@ -215,9 +215,9 @@ class DefaultHeader : public PacketHeader
     DefaultHeaderStruct mHeader;  ///< Default Header Struct
 };
 
-//#######################################################################
-//####################### JamLinkHeader #################################
-//#######################################################################
+// #######################################################################
+// ####################### JamLinkHeader #################################
+// #######################################################################
 
 /** \brief JamLink Header
  */
@@ -273,9 +273,9 @@ class JamLinkHeader : public PacketHeader
     JamLinkHeaderStuct mHeader;  ///< JamLink Header Struct
 };
 
-//#######################################################################
-//####################### EmptyHeader #################################
-//#######################################################################
+// #######################################################################
+// ####################### EmptyHeader #################################
+// #######################################################################
 
 /** \brief Empty Header to use with systems that don't include a header.
  */
index 6f708aab430768f941177064e15cc25bef9c83b2..4dcc4bd323bdc15e7642a2c3dca20772450aeb16 100644 (file)
@@ -1,4 +1,4 @@
-//#include "ProcessPlugin.h"
+// #include "ProcessPlugin.h"
 
 /*
 //----------------------------------------------------------------------------
diff --git a/src/QtStaticPlugins.cpp b/src/QtStaticPlugins.cpp
new file mode 100644 (file)
index 0000000..8e9e079
--- /dev/null
@@ -0,0 +1,4 @@
+#include <QtPlugin>
+
+// used to load tls backend for linux static builds
+Q_IMPORT_PLUGIN(QTlsBackendOpenSSL)
index a6361509a10d16537fdcaeed87a8629c2ff1c0ab..a92a72479eaec0f6a9d74aed81130f56991a3565 100644 (file)
@@ -3,7 +3,7 @@
   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
@@ -32,7 +32,7 @@
 /**
  * \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;
@@ -157,299 +287,280 @@ Regulator::Regulator(int rcvChannels, int bit_res, int FPP, int qLen, int bqLen,
         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;
@@ -458,34 +569,35 @@ void Regulator::pullPacket()
         // 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
@@ -493,9 +605,10 @@ void Regulator::pullPacket()
     }
 
 PACKETOK : {
-    if (mSkip) {
+    if (skipped) {
         processPacket(true);
-        pullStat->plcOverruns += mSkip;
+        pullStat->plcOverruns += skipped;
+        return true;
     } else
         processPacket(false);
     goto OUTPUT;
@@ -509,15 +622,14 @@ UNDERRUN : {
     }
     // "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;
 };
 
 //*******************************************************************************
@@ -526,87 +638,20 @@ void Regulator::processPacket(bool glitch)
     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
 
@@ -629,145 +674,63 @@ void Regulator::sampleToBits(sample_t sample, int ch, int frame)
         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;
 }
 
 //*******************************************************************************
@@ -784,9 +747,6 @@ StdDev::StdDev(int id, QElapsedTimer* timer, int w) : mId(id), mTimer(timer), wi
     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);
@@ -803,8 +763,6 @@ void StdDev::reset()
 
 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);
@@ -818,35 +776,40 @@ double StdDev::smooth(double avg, double current)
     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;
@@ -859,10 +822,9 @@ bool StdDev::tick()
     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;
@@ -883,7 +845,7 @@ bool StdDev::tick()
         }
     }
 
-    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;
@@ -891,35 +853,202 @@ bool StdDev::tick()
 
     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;
     }
 
@@ -935,15 +1064,12 @@ bool Regulator::getStats(RingBuffer::IOStat* stat, bool reset)
         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;
@@ -957,7 +1083,10 @@ bool Regulator::getStats(RingBuffer::IOStat* stat, bool reset)
     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;
 }
index 208acbaf6f395be2a8deb0dd63600553e3d1b663..c65c3d2c71b6915ee39b74c9f3f93d620ea97be3 100644 (file)
@@ -3,7 +3,7 @@
   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
@@ -32,7 +32,7 @@
 /**
  * \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"
@@ -62,41 +62,96 @@ class RegulatorWorker;
 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;
@@ -105,9 +160,6 @@ class StdDev
     double lastMean;
     double lastMin;
     double lastMax;
-    int lastPlcOverruns;
-    int lastPlcUnderruns;
-    double lastPLCdspElapsed;
     double lastStdDev;
     double longTermStdDev;
     double longTermStdDevAcc;
@@ -118,7 +170,7 @@ class StdDev
    private:
     double smooth(double avg, double current);
     void reset();
-    QElapsedTimer* mTimer;
+    QElapsedTimer* mTimer = nullptr;
     std::vector<double> data;
     double mean;
     int window;
@@ -132,16 +184,12 @@ class Regulator : public RingBuffer
 {
    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))
@@ -150,7 +198,10 @@ class Regulator : public RingBuffer
     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);
     }
 
@@ -160,98 +211,103 @@ class Regulator : public RingBuffer
 
     /// @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;
 };
 
@@ -262,7 +318,7 @@ class RegulatorWorker : public QObject
    public:
     RegulatorWorker(Regulator* rPtr)
         : mRegulatorPtr(rPtr)
-        , mPacketQueue(rPtr->getPacketSize())
+        , mPacketQueue(rPtr->mPeerBytes)
         , mPacketQueueTarget(1)
         , mLastUnderrun(0)
         , mSkipQueueUpdate(true)
@@ -354,7 +410,7 @@ class RegulatorWorker : public QObject
         ++mPacketQueueTarget;
         std::cout << "PLC worker queue: adjusting target=" << mPacketQueueTarget
                   << " (max=" << maxPackets
-                  << ", lastDspElapsed=" << mRegulatorPtr->getLastDspElapsed() << ")"
+                  << ", lastDspElapsed=" << mRegulatorPtr->mStatsMaxPLCdspElapsed << ")"
                   << std::endl;
         if (mPacketQueueTarget == maxPackets) {
             emit signalMaxQueueSize();
index 65082bc6e9aeb10ac813950b55eb643fe04e4a16..417ee82fe428e9e06d6f3fa7ceb68d2c9eb7ee16 100644 (file)
@@ -35,7 +35,7 @@
  * \date June 2008
  */
 
-//#define MANUAL_POLL
+// #define MANUAL_POLL
 
 #include "UdpDataProtocol.h"
 
@@ -49,7 +49,7 @@
 #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")
@@ -397,7 +397,7 @@ functions. DWORD n_bytes; WSABUF buffer; int error; buffer.len = n; buffer.buf =
                            sizeof(mPeerAddr));
     }
     return n_bytes;
-    //#endif
+    // #endif
 }
 
 //*******************************************************************************
index 1848976686943257cbb1cbcec450d120a413a21b..ecd588fbde15daa393e148e79103e5a91ed938bf 100644 (file)
@@ -80,7 +80,6 @@ UdpHubListener::UdpHubListener(int server_port, int server_udp_port, QObject* pa
            "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);
@@ -124,11 +123,6 @@ UdpHubListener::~UdpHubListener()
 {
     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);
@@ -153,7 +147,6 @@ void UdpHubListener::start()
         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;
     }
@@ -221,7 +214,6 @@ void UdpHubListener::start()
         }
 
         if (error) {
-            std::cerr << "ERROR: " << error_message.toStdString() << endl;
             emit signalError(error_message);
             return;
         }
@@ -237,17 +229,6 @@ void UdpHubListener::start()
     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();
 }
 
@@ -364,7 +345,6 @@ void UdpHubListener::receivedClientInfo(QSslSocket* clientConnection)
         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);
@@ -688,11 +668,6 @@ void UdpHubListener::stopAllThreads()
             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
index 81b9838830b7f45ac91fd181e651562b62bf8962..a810025615c09cd39bdd924c89212adf3f620198 100644 (file)
@@ -190,9 +190,6 @@ class UdpHubListener : public QObject
     int mIOStatTimeout;
     QSharedPointer<std::ostream> mIOStatStream;
 
-    /// thread used to pull packets from Regulator (if mBufferStrategy==3)
-    QThread* mRegulatorThreadPtr;
-
     int mBufferStrategy;
     int mBroadcastQueue;
     double mSimulatedLossRate;
index 2fcd14fd740077453dca833d0d515773c1996f43..fc7161125bccda7edd0ee73d1cf5efdb8f994869 100644 (file)
@@ -1133,8 +1133,8 @@ class FAUST_API AccUpDownConverter : public UpdatableValueConverter
     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
@@ -1170,8 +1170,8 @@ class FAUST_API AccDownUpConverter : public UpdatableValueConverter
     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
@@ -1210,8 +1210,9 @@ class FAUST_API ZoneControl
 
     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*/) {}
@@ -1704,7 +1705,7 @@ class APIUI
         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;
     }
 
index f22c8f028e944288745af69471c2fdbed68e3982..2b7c661820556e8ff7131ceaa3c4394be048ba22 100644 (file)
@@ -1133,8 +1133,8 @@ class FAUST_API AccUpDownConverter : public UpdatableValueConverter
     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
@@ -1170,8 +1170,8 @@ class FAUST_API AccDownUpConverter : public UpdatableValueConverter
     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
@@ -1210,8 +1210,9 @@ class FAUST_API ZoneControl
 
     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*/) {}
@@ -1704,7 +1705,7 @@ class APIUI
         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;
     }
 
index 8c291a4d02a2d25dc12f9b65bc6d8a312b5b7509..e7cea89564a51d0351d758fe3e097f18727e5986 100644 (file)
@@ -1130,8 +1130,8 @@ class FAUST_API AccUpDownConverter : public UpdatableValueConverter
     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
@@ -1167,8 +1167,8 @@ class FAUST_API AccDownUpConverter : public UpdatableValueConverter
     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
@@ -1207,8 +1207,9 @@ class FAUST_API ZoneControl
 
     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*/) {}
@@ -1701,7 +1702,7 @@ class APIUI
         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;
     }
 
index d5bb6dd204997d8b08fc0f0032787f6c338fc938..d632152ae283a3d781e2a52771d3bec5b6d2f2cc 100644 (file)
@@ -85,6 +85,7 @@ Item {
             available: modelData.canConnect
             connected: false
             studioId: modelData.id ? modelData.id : ""
+            streamId: modelData.streamId ? modelData.streamId : ""
             inviteKeyString: modelData.inviteKey ? modelData.inviteKey : ""
             sampleRate: modelData.sampleRate
         }
index 3b65e3815dec4d9cf75de4360c060ae162dc76ad..4b8302a71920a0f560d3bd4b42c387b6953db1f2 100644 (file)
@@ -43,9 +43,16 @@ Item {
         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);
+            }
+        }
     }
 }
diff --git a/src/gui/LearnMoreButton.qml b/src/gui/LearnMoreButton.qml
new file mode 100644 (file)
index 0000000..aa26177
--- /dev/null
@@ -0,0 +1,30 @@
+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
+    }
+}
index b8de3a1f0ef376bf94907acb696be795f4f4f4d7..6d4e9495c912037d78a08d0528873f016adb264c 100644 (file)
@@ -121,7 +121,7 @@ Item {
 
         AppIcon {
             id: ethernetRecommendationLogo
-            y: 120
+            y: 90
             anchors.horizontalCenter: parent.horizontalCenter
             width: 179
             height: 128
@@ -145,7 +145,7 @@ Item {
                 + "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
@@ -153,6 +153,13 @@ Item {
             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 {
@@ -187,7 +194,7 @@ Item {
 
         AppIcon {
             id: fiberRecommendationLogo
-            y: 120
+            y: 90
             anchors.horizontalCenter: parent.horizontalCenter
             width: 179
             height: 128
@@ -211,7 +218,7 @@ Item {
                 + "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
@@ -219,6 +226,12 @@ Item {
             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
@@ -254,7 +267,7 @@ Item {
 
         AppIcon {
             id: headphoneWarningLogo
-            y: 120
+            y: 90
             anchors.horizontalCenter: parent.horizontalCenter
             width: 118
             height: 128
@@ -280,7 +293,7 @@ Item {
                 + "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
@@ -324,7 +337,7 @@ Item {
 
         AppIcon {
             id: audioInterfaceRecommendationLogo
-            y: 120
+            y: 90
             anchors.horizontalCenter: parent.horizontalCenter
             width: 118
             height: 128
@@ -351,7 +364,7 @@ Item {
                 + "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
@@ -375,14 +388,13 @@ Item {
             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
@@ -390,6 +402,15 @@ Item {
             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 {
@@ -439,7 +460,7 @@ Item {
             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
@@ -532,7 +553,7 @@ Item {
             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
index 582e90ac306691058ff82ba48ed7b403881b8313..726ac52ff45528c05890e44dc5e5b015c382373d 100644 (file)
@@ -13,6 +13,7 @@ Rectangle {
     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
@@ -33,8 +34,10 @@ Rectangle {
     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"
@@ -259,7 +262,7 @@ Rectangle {
         }
         Timer {
             id: copiedResetTimer
-            interval: 2000; running: false; repeat: false
+            interval: 3000; running: false; repeat: false
             onTriggered: inviteCopied = false;
         }
         onClicked: {
@@ -286,12 +289,12 @@ Rectangle {
         }
         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
@@ -303,8 +306,35 @@ Rectangle {
                 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 {
@@ -323,28 +353,38 @@ 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
@@ -352,9 +392,9 @@ Rectangle {
     }
 
     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
index 8ef3a189b57feea70ccdb3870c6253c320fb05d6..7f5e0dcc0a37b01ca3a44628a4fe5be9df5d6d23 100644 (file)
@@ -8,6 +8,7 @@
     <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>
index 757afe3deec4e901f67a72d1c0539e4e20843372..b6d0dd5bc4b684707ea114d2fa82aa1307d943a2 100644 (file)
@@ -1398,22 +1398,22 @@ for better quality at the expense of latency.</string>
           </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>
index 321fdb981028605b3f145ad701ef08a9d74806b3..7223a9920155f994ac64b4ca8240a9cbfbfb3353 100644 (file)
@@ -241,7 +241,7 @@ void VirtualStudio::show()
             "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);
@@ -639,7 +639,6 @@ void VirtualStudio::joinStudio()
     // pop studioToJoin
     const QString targetId = m_studioToJoin;
     setStudioToJoin("");
-    emit studioToJoinChanged();
 
     // stop audio if already running (settings or setup windows)
     m_audioConfigPtr->stopAudio(true);
@@ -741,7 +740,7 @@ void VirtualStudio::logout()
     }
 
     logoutURL.setQuery(query);
-    launchBrowser(logoutURL);
+    QDesktopServices::openUrl(logoutURL);
 
     m_auth->logout();
 
@@ -896,27 +895,8 @@ void VirtualStudio::completeConnection()
         // 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
@@ -1048,63 +1028,6 @@ void VirtualStudio::disconnect()
 #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"));
@@ -1391,17 +1314,6 @@ void VirtualStudio::restartStudioSocket()
     }
 }
 
-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;
@@ -1523,6 +1435,8 @@ void VirtualStudio::getServerList(bool signalRefresh, int index)
                     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(
index f5d60e13ac730634c0a9c8d5fcf1ff13e886ca50..fbd02c66a5500717e43f5a9985891b899f2584cf 100644 (file)
@@ -193,8 +193,6 @@ class VirtualStudio : public QObject
     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();
@@ -249,7 +247,6 @@ class VirtualStudio : public QObject
     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();
index 41970c2034a45fb3d9153b517d58ec6167f2314e..a9fda8fd51ad6e1365162367e8719278b4d6b7c6 100644 (file)
@@ -532,7 +532,10 @@ void VsAudio::loadSettings()
     }
 
     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();
index c91beb5bdd3013af5532e190576eda890928b875..ab53fb69fe9d63e75c7d6fd984c02b7f52b871db 100644 (file)
@@ -387,8 +387,7 @@ class VsAudio : public QObject
     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;
 };
index 59c60dfc738b5a19b9836ab13cd760f1671aaa0a..9ea50101583701bfbbc166fd9564d66bbdef76f0 100644 (file)
@@ -57,6 +57,7 @@ VsServerInfo& VsServerInfo::operator=(const VsServerInfo& info)
     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;
@@ -275,6 +276,16 @@ void VsServerInfo::setSessionId(const QString& sessionId)
     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;
index 14db149e0b192af1e6f67b0e400cfe0205c2d18e..5112c6414b247d0c85f16e8abc83b9fd8916706d 100644 (file)
@@ -60,6 +60,7 @@ class VsServerInfo : public QObject
     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)
@@ -110,6 +111,8 @@ class VsServerInfo : public QObject
     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;
@@ -138,6 +141,7 @@ class VsServerInfo : public QObject
     QString m_bannerURL;
     QString m_id;
     QString m_sessionId;
+    QString m_streamId;
     QString m_status;
     QString m_cloudId;
     QString m_inviteKey;
index f354fa2199eeeb804e8df69a5d4a2c33f77cfaab..a7bc3e324761a5264ee8aa57680d620973a68792 100644 (file)
@@ -40,7 +40,7 @@
 
 #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
index 0a8c49473f65bc8981a9e0328c7444bccb784eba..ea90e1fc565a111368e478973a83d82dff75be09 100644 (file)
@@ -38,7 +38,7 @@
 #ifndef __JACKTRIP_TYPES_H__
 #define __JACKTRIP_TYPES_H__
 
-//#include <jack/types.h>
+// #include <jack/types.h>
 #include <QtGlobal>  //For QT4 types
 
 // namespace JackTripNamespace
index 6e942cdb7c0d635767bfaa2900b5d58e959112ab..b6371d191863fe3992368e07a0a3da55832d594d 100644 (file)
@@ -1702,7 +1702,7 @@ class APIUI
         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;
     }
 
index 40788a593ad59b55c0c9c1a44596b60d894750e9..58d91dd0cf2d881e2406dd8f1c1ee823d9238b77 100644 (file)
@@ -57,7 +57,7 @@
 #include <QStandardPaths>
 #include <QTextStream>
 // TODO: Add support for QtWebView
-//#include <QtWebView>
+// #include <QtWebView>
 #include <QtWebEngineQuick/qtwebenginequickglobal.h>
 
 #include "JTApplication.h"
@@ -216,6 +216,11 @@ void qtMessageHandler([[maybe_unused]] QtMsgType type,
 #endif  // NO_GUI
 }
 
+void outputError(const QString& msg)
+{
+    std::cerr << "Error: " << msg.toStdString() << std::endl;
+}
+
 #ifndef _WIN32
 static int setupUnixSignalHandler(void (*handler)(int))
 {
@@ -462,13 +467,16 @@ int main(int argc, char* argv[])
     } 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());
@@ -478,6 +486,8 @@ int main(int argc, char* argv[])
                 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
@@ -495,6 +505,7 @@ int main(int argc, char* argv[])
                 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
index 24dff345704941a2d07df4b52743d2a773ac4de7..68ab24871a06f419051969f1c16b6d6bd10cb893 100644 (file)
@@ -1133,8 +1133,8 @@ class FAUST_API AccUpDownConverter : public UpdatableValueConverter
     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
@@ -1170,8 +1170,8 @@ class FAUST_API AccDownUpConverter : public UpdatableValueConverter
     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
@@ -1210,8 +1210,9 @@ class FAUST_API ZoneControl
 
     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*/) {}
@@ -1704,7 +1705,7 @@ class APIUI
         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;
     }
 
@@ -2051,9 +2052,9 @@ class meterdsp : public dsp
                                              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))));
         }
     }
 };
index c99d5db0caaa960084f9d0ef8789a428572b77f8..44bbe6e65e5fd0cd0736334dba31f22787dd8756 100644 (file)
@@ -4,11 +4,12 @@ license: "MIT Style STK-4.2"
 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
 //
@@ -25,16 +26,16 @@ Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn monitordsp -es 1
  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
@@ -55,16 +56,16 @@ Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn monitordsp -es 1
  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
@@ -76,29 +77,29 @@ Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn monitordsp -es 1
 
 #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
@@ -115,15 +116,14 @@ struct FAUST_API Meta;
  */
 
 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
@@ -137,145 +137,161 @@ struct FAUST_API dsp_memory_manager {
      * 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);
+    }
 };
 
 /**
@@ -283,87 +299,78 @@ class FAUST_API decorator_dsp : public dsp {
  * 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;
@@ -398,11 +405,12 @@ architecture section is not modified.
 #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
@@ -412,16 +420,16 @@ architecture section is not modified.
  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
@@ -431,9 +439,9 @@ architecture section is not modified.
 #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() {}
@@ -450,16 +458,16 @@ struct FAUST_API 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
@@ -469,7 +477,6 @@ struct FAUST_API Meta {
 #ifndef __UI_H__
 #define __UI_H__
 
-
 #ifndef FAUSTFLOAT
 #define FAUSTFLOAT float
 #endif
@@ -483,38 +490,43 @@ struct FAUST_API Meta {
 
 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
@@ -536,16 +548,16 @@ struct FAUST_API UI : public UIReal<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
@@ -555,187 +567,199 @@ struct FAUST_API UI : public UIReal<FAUSTFLOAT> {
 #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__
@@ -748,16 +772,16 @@ class FAUST_API 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
@@ -770,52 +794,53 @@ class FAUST_API PathBuilder {
 /***************************************************************************************
  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)
@@ -826,458 +851,485 @@ class FAUST_API PathBuilder {
 // 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
@@ -1285,688 +1337,742 @@ class FAUST_API ZoneReader {
 
 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
@@ -1979,23 +2085,23 @@ class APIUI : public PathBuilder, public Meta, public UI
 //  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)
@@ -2004,113 +2110,115 @@ class APIUI : public PathBuilder, public Meta, public UI
 #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
index 40a1403a14e0413b60ef3ffd00c013572f01f916..1633a9f7e298bc9c2c5e6db8a55f75d01ed042a4 100644 (file)
@@ -4,11 +4,12 @@ license: "MIT Style STK-4.2"
 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
 //
@@ -25,16 +26,16 @@ Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn stereotomonodsp
  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
@@ -73,29 +74,29 @@ Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn stereotomonodsp
 
 #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
@@ -112,15 +113,14 @@ struct FAUST_API Meta;
  */
 
 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
@@ -128,151 +128,167 @@ struct FAUST_API dsp_memory_manager {
      * @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);
+    }
 };
 
 /**
@@ -280,86 +296,77 @@ class FAUST_API decorator_dsp : public dsp {
  * 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;
@@ -394,11 +401,12 @@ architecture section is not modified.
 #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
@@ -408,16 +416,16 @@ architecture section is not modified.
  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
@@ -427,9 +435,9 @@ architecture section is not modified.
 #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() {}
@@ -446,16 +454,16 @@ struct FAUST_API 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
@@ -465,7 +473,6 @@ struct FAUST_API Meta {
 #ifndef __UI_H__
 #define __UI_H__
 
-
 #ifndef FAUSTFLOAT
 #define FAUSTFLOAT float
 #endif
@@ -479,40 +486,47 @@ struct FAUST_API Meta {
 
 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); }
 };
@@ -532,16 +546,16 @@ struct FAUST_API UI : public UIReal<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
@@ -551,187 +565,199 @@ struct FAUST_API UI : public UIReal<FAUSTFLOAT> {
 #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__
@@ -744,16 +770,16 @@ class FAUST_API 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
@@ -766,52 +792,53 @@ class FAUST_API PathBuilder {
 /***************************************************************************************
  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)
@@ -822,458 +849,488 @@ class FAUST_API PathBuilder {
 // 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
@@ -1281,688 +1338,742 @@ class FAUST_API ZoneReader {
 
 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
@@ -1975,22 +2086,21 @@ class APIUI : public PathBuilder, public Meta, public UI
 //  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)
@@ -1999,80 +2109,69 @@ class APIUI : public PathBuilder, public Meta, public UI
 #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
index e999299cf64663005a3c65acd70f030df0b1ffbf..84af3a12f4744a8df3a8b5f3c4b141289a890b1d 100644 (file)
@@ -1,11 +1,12 @@
 /* ------------------------------------------------------------
 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
 //
@@ -22,16 +23,16 @@ Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn tonedsp -es 1 -m
  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
@@ -70,29 +71,29 @@ Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn tonedsp -es 1 -m
 
 #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
@@ -109,15 +110,14 @@ struct FAUST_API Meta;
  */
 
 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
@@ -125,151 +125,167 @@ struct FAUST_API dsp_memory_manager {
      * @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);
+    }
 };
 
 /**
@@ -277,86 +293,77 @@ class FAUST_API decorator_dsp : public dsp {
  * 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;
@@ -391,11 +398,12 @@ architecture section is not modified.
 #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
@@ -405,16 +413,16 @@ architecture section is not modified.
  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
@@ -424,9 +432,9 @@ architecture section is not modified.
 #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() {}
@@ -443,16 +451,16 @@ struct FAUST_API 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
@@ -462,7 +470,6 @@ struct FAUST_API Meta {
 #ifndef __UI_H__
 #define __UI_H__
 
-
 #ifndef FAUSTFLOAT
 #define FAUSTFLOAT float
 #endif
@@ -476,40 +483,45 @@ struct FAUST_API Meta {
 
 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); }
 };
@@ -529,16 +541,16 @@ struct FAUST_API UI : public UIReal<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
@@ -548,187 +560,199 @@ struct FAUST_API UI : public UIReal<FAUSTFLOAT> {
 #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__
@@ -741,16 +765,16 @@ class FAUST_API 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
@@ -763,52 +787,53 @@ class FAUST_API PathBuilder {
 /***************************************************************************************
  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)
@@ -819,458 +844,485 @@ class FAUST_API PathBuilder {
 // 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
@@ -1278,688 +1330,742 @@ class FAUST_API ZoneReader {
 
 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
@@ -1972,23 +2078,23 @@ class APIUI : public PathBuilder, public Meta, public UI
 //  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)
@@ -1997,241 +2103,305 @@ class APIUI : public PathBuilder, public Meta, public UI
 #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
index f3df2124233d142ebc968b76127e1bd4a14386ef..88db980a878a136dd394e6d22e7b3377c4d0af64 100644 (file)
@@ -4,11 +4,12 @@ license: "MIT Style STK-4.2"
 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
 //
@@ -25,16 +26,16 @@ Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn volumedsp -es 1
  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
@@ -73,29 +74,29 @@ Compilation options: -a faust2header.cpp -lang cpp -i -inpl -cn volumedsp -es 1
 
 #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
@@ -112,15 +113,14 @@ struct FAUST_API Meta;
  */
 
 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
@@ -128,151 +128,167 @@ struct FAUST_API dsp_memory_manager {
      * @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);
+    }
 };
 
 /**
@@ -280,85 +296,76 @@ class FAUST_API decorator_dsp : public dsp {
  * 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();
@@ -393,11 +400,12 @@ architecture section is not modified.
 #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
@@ -407,16 +415,16 @@ architecture section is not modified.
  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
@@ -426,9 +434,9 @@ architecture section is not modified.
 #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() {}
@@ -445,16 +453,16 @@ struct FAUST_API 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
@@ -464,7 +472,6 @@ struct FAUST_API Meta {
 #ifndef __UI_H__
 #define __UI_H__
 
-
 #ifndef FAUSTFLOAT
 #define FAUSTFLOAT float
 #endif
@@ -478,40 +485,45 @@ struct FAUST_API Meta {
 
 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); }
 };
@@ -531,16 +543,16 @@ struct FAUST_API UI : public UIReal<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
@@ -550,187 +562,199 @@ struct FAUST_API UI : public UIReal<FAUSTFLOAT> {
 #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__
@@ -743,16 +767,16 @@ class FAUST_API 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
@@ -765,52 +789,53 @@ class FAUST_API PathBuilder {
 /***************************************************************************************
  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)
@@ -821,458 +846,485 @@ class FAUST_API PathBuilder {
 // 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
@@ -1280,563 +1332,617 @@ class FAUST_API ZoneReader {
 
 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
@@ -1849,23 +1955,23 @@ class APIUI : public PathBuilder, public Meta, public UI
 //  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)
@@ -1874,113 +1980,113 @@ class APIUI : public PathBuilder, public Meta, public UI
 #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
index 0ee6905ca45c9c5eb1772afee35c0318abf960f4..b7e839a7e09a9d4a556184417ed55361bf10e0cf 100644 (file)
@@ -1130,8 +1130,8 @@ class FAUST_API AccUpDownConverter : public UpdatableValueConverter
     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
@@ -1167,8 +1167,8 @@ class FAUST_API AccDownUpConverter : public UpdatableValueConverter
     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
@@ -1207,8 +1207,9 @@ class FAUST_API ZoneControl
 
     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*/) {}
@@ -1701,7 +1702,7 @@ class APIUI
         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;
     }
 
@@ -2773,8 +2774,8 @@ class zitarevdsp : public dsp
             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));
@@ -2789,8 +2790,8 @@ class zitarevdsp : public dsp
             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));
index 4f0475b11215cc351832dd156547d352b57f06a5..4df88079187140a3795d6d1e78a73ecba4383536 100644 (file)
@@ -1130,8 +1130,8 @@ class FAUST_API AccUpDownConverter : public UpdatableValueConverter
     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
@@ -1167,8 +1167,8 @@ class FAUST_API AccDownUpConverter : public UpdatableValueConverter
     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
@@ -1207,8 +1207,9 @@ class FAUST_API ZoneControl
 
     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*/) {}
@@ -1701,7 +1702,7 @@ class APIUI
         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;
     }
 
@@ -2793,8 +2794,8 @@ class zitarevmonodsp : public dsp
             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