Browse Source

Add CV range flags, implement jack meta-data

Signed-off-by: falkTX <falktx@falktx.com>
pull/281/head
falkTX 4 years ago
parent
commit
ead50d1c85
Signed by: falkTX <falktx@falktx.com> GPG Key ID: CDBAA37ABC74FBA0
3 changed files with 197 additions and 7 deletions
  1. +26
    -0
      distrho/DistrhoPlugin.hpp
  2. +80
    -3
      distrho/src/DistrhoPluginJack.cpp
  3. +91
    -4
      distrho/src/DistrhoPluginLV2export.cpp

+ 26
- 0
distrho/DistrhoPlugin.hpp View File

@@ -44,6 +44,32 @@ static const uint32_t kAudioPortIsCV = 0x1;
*/
static const uint32_t kAudioPortIsSidechain = 0x2;

/**
CV port has bipolar range (-1 to +1, or -5 to +5 if scaled).
This is merely a hint to tell the host what value range to expect.
*/
static const uint32_t kCVPortHasBipolarRange = 0x10;

/**
CV port has negative unipolar range (0 to +1, or 0 to +10 if scaled).
This is merely a hint to tell the host what value range to expect.
*/
static const uint32_t kCVPortHasNegativeUnipolarRange = 0x20;

/**
CV port has positive unipolar range (-1 to 0, or -10 to 0 if scaled).
This is merely a hint to tell the host what value range to expect.
*/
static const uint32_t kCVPortHasPositiveUnipolarRange = 0x40;

/**
CV port has scaled range to match real values (-5 to +5v bipolar, +/-10 to 0v unipolar).
One range flag is required if this flag is set.

When enabled, this makes the port a mod:CVPort, compatible with the MOD Devices platform.
*/
static const uint32_t kCVPortHasScaledRange = 0x80;

/** @} */

/* ------------------------------------------------------------------------------------------------------------


+ 80
- 3
distrho/src/DistrhoPluginJack.cpp View File

@@ -25,8 +25,11 @@
#endif

#include "jack/jack.h"
#include "jack/metadata.h"
#include "jack/midiport.h"
#include "jack/transport.h"
#include "jack/uuid.h"
#include "lv2/lv2.h"

#ifndef DISTRHO_OS_WINDOWS
# include <signal.h>
@@ -119,15 +122,18 @@ public:
# if DISTRHO_PLUGIN_NUM_INPUTS > 0
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i)
{
std::snprintf(strBuf, 0xff, "in%i", i+1);
fPortAudioIns[i] = jack_port_register(fClient, strBuf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
const AudioPort& port(fPlugin.getAudioPort(true, i));
fPortAudioIns[i] = jack_port_register(fClient, port.symbol, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0);
setAudioPortMetadata(port, fPortAudioIns[i], i);
}
# endif
# if DISTRHO_PLUGIN_NUM_OUTPUTS > 0
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i)
{
std::snprintf(strBuf, 0xff, "out%i", i+1);
fPortAudioOuts[i] = jack_port_register(fClient, strBuf, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
const AudioPort& port(fPlugin.getAudioPort(false, i));
fPortAudioOuts[i] = jack_port_register(fClient, port.symbol, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
setAudioPortMetadata(port, fPortAudioOuts[i], i);
}
# endif
#endif
@@ -561,6 +567,77 @@ private:
# endif
#endif

void setAudioPortMetadata(const AudioPort& port, jack_port_t* const jackport, const uint32_t index)
{
DISTRHO_SAFE_ASSERT_RETURN(jackport != nullptr,);

const jack_uuid_t uuid = jack_port_uuid(jackport);

if (jack_uuid_empty(uuid))
return;

jack_set_property(fClient, uuid, JACK_METADATA_PRETTY_NAME, port.name, "text/plain");

{
char strBuf[0xff];
snprintf(strBuf, sizeof(0xff)-1, "%u", index);
jack_set_property(fClient, uuid, JACK_METADATA_ORDER, strBuf, "http://www.w3.org/2001/XMLSchema#integer");
}

if (port.hints & kAudioPortIsCV)
{
jack_set_property(fClient, uuid, JACK_METADATA_SIGNAL_TYPE, "CV", "text/plain");
}
else
{
jack_set_property(fClient, uuid, JACK_METADATA_SIGNAL_TYPE, "AUDIO", "text/plain");
return;
}

// set cv ranges
const bool cvPortScaled = port.hints & kCVPortHasScaledRange;

if (port.hints & kCVPortHasBipolarRange)
{
if (cvPortScaled)
{
jack_set_property(fClient, uuid, LV2_CORE__minimum, "-5", "http://www.w3.org/2001/XMLSchema#integer");
jack_set_property(fClient, uuid, LV2_CORE__maximum, "5", "http://www.w3.org/2001/XMLSchema#integer");
}
else
{
jack_set_property(fClient, uuid, LV2_CORE__minimum, "-1", "http://www.w3.org/2001/XMLSchema#integer");
jack_set_property(fClient, uuid, LV2_CORE__maximum, "1", "http://www.w3.org/2001/XMLSchema#integer");
}
}
else if (port.hints & kCVPortHasNegativeUnipolarRange)
{
if (cvPortScaled)
{
jack_set_property(fClient, uuid, LV2_CORE__minimum, "-10", "http://www.w3.org/2001/XMLSchema#integer");
jack_set_property(fClient, uuid, LV2_CORE__maximum, "0", "http://www.w3.org/2001/XMLSchema#integer");
}
else
{
jack_set_property(fClient, uuid, LV2_CORE__minimum, "-1", "http://www.w3.org/2001/XMLSchema#integer");
jack_set_property(fClient, uuid, LV2_CORE__maximum, "0", "http://www.w3.org/2001/XMLSchema#integer");
}
}
else if (port.hints & kCVPortHasPositiveUnipolarRange)
{
if (cvPortScaled)
{
jack_set_property(fClient, uuid, LV2_CORE__minimum, "0", "http://www.w3.org/2001/XMLSchema#integer");
jack_set_property(fClient, uuid, LV2_CORE__maximum, "10", "http://www.w3.org/2001/XMLSchema#integer");
}
else
{
jack_set_property(fClient, uuid, LV2_CORE__minimum, "0", "http://www.w3.org/2001/XMLSchema#integer");
jack_set_property(fClient, uuid, LV2_CORE__maximum, "1", "http://www.w3.org/2001/XMLSchema#integer");
}
}
}

// -------------------------------------------------------------------
// Callbacks



+ 91
- 4
distrho/src/DistrhoPluginLV2export.cpp View File

@@ -22,6 +22,7 @@
#include "lv2/instance-access.h"
#include "lv2/midi.h"
#include "lv2/options.h"
#include "lv2/parameters.h"
#include "lv2/patch.h"
#include "lv2/port-props.h"
#include "lv2/presets.h"
@@ -332,9 +333,7 @@ void lv2_generate_ttl(const char* const basename)
pluginString += "@prefix doap: <http://usefulinc.com/ns/doap#> .\n";
pluginString += "@prefix foaf: <http://xmlns.com/foaf/0.1/> .\n";
pluginString += "@prefix lv2: <" LV2_CORE_PREFIX "> .\n";
#ifdef DISTRHO_PLUGIN_BRAND
pluginString += "@prefix mod: <http://moddevices.com/ns/mod#> .\n";
#endif
pluginString += "@prefix opts: <" LV2_OPTIONS_PREFIX "> .\n";
pluginString += "@prefix patch: <" LV2_PATCH_PREFIX "> .\n";
pluginString += "@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n";
@@ -410,13 +409,16 @@ void lv2_generate_ttl(const char* const basename)
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i, ++portIndex)
{
const AudioPort& port(plugin.getAudioPort(true, i));
const bool cvPortScaled = port.hints & kCVPortHasScaledRange;

if (i == 0)
pluginString += " lv2:port [\n";
else
pluginString += " [\n";

if (port.hints & kAudioPortIsCV)
if (cvPortScaled)
pluginString += " a lv2:InputPort, lv2:CVPort, mod:CVPort ;\n";
else if (port.hints & kAudioPortIsCV)
pluginString += " a lv2:InputPort, lv2:CVPort ;\n";
else
pluginString += " a lv2:InputPort, lv2:AudioPort ;\n";
@@ -428,6 +430,47 @@ void lv2_generate_ttl(const char* const basename)
if (port.hints & kAudioPortIsSidechain)
pluginString += " lv2:portProperty lv2:isSideChain;\n";

// set ranges
if (port.hints & kCVPortHasBipolarRange)
{
if (cvPortScaled)
{
pluginString += " lv2:minimum -5.0 ;\n";
pluginString += " lv2:maximum 5.0 ;\n";
}
else
{
pluginString += " lv2:minimum -1.0 ;\n";
pluginString += " lv2:maximum 1.0 ;\n";
}
}
else if (port.hints & kCVPortHasNegativeUnipolarRange)
{
if (cvPortScaled)
{
pluginString += " lv2:minimum -10.0 ;\n";
pluginString += " lv2:maximum 0.0 ;\n";
}
else
{
pluginString += " lv2:minimum -1.0 ;\n";
pluginString += " lv2:maximum 0.0 ;\n";
}
}
else if (port.hints & kCVPortHasPositiveUnipolarRange)
{
if (cvPortScaled)
{
pluginString += " lv2:minimum 0.0 ;\n";
pluginString += " lv2:maximum 10.0 ;\n";
}
else
{
pluginString += " lv2:minimum 0.0 ;\n";
pluginString += " lv2:maximum 1.0 ;\n";
}
}

if (i+1 == DISTRHO_PLUGIN_NUM_INPUTS)
pluginString += " ] ;\n";
else
@@ -440,13 +483,16 @@ void lv2_generate_ttl(const char* const basename)
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i, ++portIndex)
{
const AudioPort& port(plugin.getAudioPort(false, i));
const bool cvPortScaled = port.hints & kCVPortHasScaledRange;

if (i == 0)
pluginString += " lv2:port [\n";
else
pluginString += " [\n";

if (port.hints & kAudioPortIsCV)
if (cvPortScaled)
pluginString += " a lv2:OutputPort, lv2:CVPort, mod:CVPort ;\n";
else if (port.hints & kAudioPortIsCV)
pluginString += " a lv2:OutputPort, lv2:CVPort ;\n";
else
pluginString += " a lv2:OutputPort, lv2:AudioPort ;\n";
@@ -458,6 +504,47 @@ void lv2_generate_ttl(const char* const basename)
if (port.hints & kAudioPortIsSidechain)
pluginString += " lv2:portProperty lv2:isSideChain;\n";

// set ranges
if (port.hints & kCVPortHasBipolarRange)
{
if (cvPortScaled)
{
pluginString += " lv2:minimum -5.0 ;\n";
pluginString += " lv2:maximum 5.0 ;\n";
}
else
{
pluginString += " lv2:minimum -1.0 ;\n";
pluginString += " lv2:maximum 1.0 ;\n";
}
}
else if (port.hints & kCVPortHasNegativeUnipolarRange)
{
if (cvPortScaled)
{
pluginString += " lv2:minimum -10.0 ;\n";
pluginString += " lv2:maximum 0.0 ;\n";
}
else
{
pluginString += " lv2:minimum -1.0 ;\n";
pluginString += " lv2:maximum 0.0 ;\n";
}
}
else if (port.hints & kCVPortHasPositiveUnipolarRange)
{
if (cvPortScaled)
{
pluginString += " lv2:minimum 0.0 ;\n";
pluginString += " lv2:maximum 10.0 ;\n";
}
else
{
pluginString += " lv2:minimum 0.0 ;\n";
pluginString += " lv2:maximum 1.0 ;\n";
}
}

if (i+1 == DISTRHO_PLUGIN_NUM_OUTPUTS)
pluginString += " ] ;\n";
else


Loading…
Cancel
Save