Browse Source

Add AudioPort struct and hints; Implement CV and Sidechain in LV2

pull/6/head
falkTX 10 years ago
parent
commit
f32b41625d
4 changed files with 159 additions and 8 deletions
  1. +63
    -0
      distrho/DistrhoPlugin.hpp
  2. +26
    -0
      distrho/src/DistrhoPlugin.cpp
  3. +41
    -0
      distrho/src/DistrhoPluginInternal.hpp
  4. +29
    -8
      distrho/src/DistrhoPluginLV2export.cpp

+ 63
- 0
distrho/DistrhoPlugin.hpp View File

@@ -185,6 +185,29 @@ START_NAMESPACE_DISTRHO

#endif

/* ------------------------------------------------------------------------------------------------------------
* Audio Port Hints */

/**
@defgroup AudioPortHints Audio Port Hints

Various audio port hints.
@see AudioPort::hints
@{
*/

/**
Audio port can be used as control voltage (LV2 only).
*/
static const uint32_t kAudioPortIsCV = 0x1;

/**
Audio port should be used as sidechan (LV2 only).
*/
static const uint32_t kAudioPortIsSidechain = 0x2;

/** @} */

/* ------------------------------------------------------------------------------------------------------------
* Parameter Hints */

@@ -243,6 +266,40 @@ static const uint32_t kParameterIsCV = 0x20;
@{
*/

/**
Audio Port.
*/
struct AudioPort {
/**
Hints describing this audio port.
@see AudioPortHints
*/
uint32_t hints;

/**
The name of this audio port.
An audio port name can contain any character, but hosts might have a hard time with non-ascii ones.
The name doesn't have to be unique within a plugin instance, but it's recommended.
*/
d_string name;

/**
The symbol of this audio port.
An audio port symbol is a short restricted name used as a machine and human readable identifier.
The first character must be one of _, a-z or A-Z and subsequent characters can be from _, a-z, A-Z and 0-9.
@note: Audio port and parameter symbols MUST be unique within a plugin instance.
*/
d_string symbol;

/**
Default constructor for a regular audio port.
*/
AudioPort() noexcept
: hints(0x0),
name(),
symbol() {}
};

/**
Parameter ranges.
This is used to set the default, minimum and maximum values of a parameter.
@@ -670,6 +727,12 @@ protected:
/* --------------------------------------------------------------------------------------------------------
* Init */

/**
Initialize the audio port @a index.
This function will be called once, shortly after the plugin is created.
*/
virtual void d_initAudioPort(bool input, uint32_t index, AudioPort& port);

/**
Initialize the parameter @a index.
This function will be called once, shortly after the plugin is created.


+ 26
- 0
distrho/src/DistrhoPlugin.cpp View File

@@ -28,6 +28,7 @@ double d_lastSampleRate = 0.0;
* Static fallback data, see DistrhoPluginInternal.hpp */

const d_string PluginExporter::sFallbackString;
const AudioPort PluginExporter::sFallbackAudioPort;
const ParameterRanges PluginExporter::sFallbackRanges;

/* ------------------------------------------------------------------------------------------------------------
@@ -36,6 +37,10 @@ const ParameterRanges PluginExporter::sFallbackRanges;
Plugin::Plugin(const uint32_t parameterCount, const uint32_t programCount, const uint32_t stateCount)
: pData(new PrivateData())
{
#if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
pData->audioPorts = new AudioPort[DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS];
#endif

if (parameterCount > 0)
{
pData->parameterCount = parameterCount;
@@ -104,6 +109,27 @@ bool Plugin::d_writeMidiEvent(const MidiEvent& /*midiEvent*/) noexcept
}
#endif

/* ------------------------------------------------------------------------------------------------------------
* Init */

void Plugin::d_initAudioPort(bool input, uint32_t index, AudioPort& port)
{
if (port.hints & kAudioPortIsCV)
{
port.name = input ? "CV Input " : "CV Output ";
port.name += d_string(index+1);
port.symbol = input ? "cv_in_" : "cv_out_";
port.symbol += d_string(index+1);
}
else
{
port.name = input ? "Audio Input " : "Audio Output ";
port.name += d_string(index+1);
port.symbol = input ? "audio_in_" : "audio_out_";
port.symbol += d_string(index+1);
}
}

/* ------------------------------------------------------------------------------------------------------------
* Callbacks (optional) */



+ 41
- 0
distrho/src/DistrhoPluginInternal.hpp View File

@@ -38,6 +38,10 @@ extern double d_lastSampleRate;
struct Plugin::PrivateData {
bool isProcessing;

#if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
AudioPort* audioPorts;
#endif

uint32_t parameterCount;
Parameter* parameters;

@@ -65,6 +69,9 @@ struct Plugin::PrivateData {

PrivateData() noexcept
: isProcessing(false),
#if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
audioPorts(nullptr),
#endif
parameterCount(0),
parameters(nullptr),
#if DISTRHO_PLUGIN_WANT_PROGRAMS
@@ -88,6 +95,14 @@ struct Plugin::PrivateData {

~PrivateData() noexcept
{
#if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
if (audioPorts != nullptr)
{
delete[] audioPorts;
audioPorts = nullptr;
}
#endif

if (parameters != nullptr)
{
delete[] parameters;
@@ -132,6 +147,16 @@ public:
DISTRHO_SAFE_ASSERT_RETURN(fPlugin != nullptr,);
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr,);

#if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
{
uint32_t j=0;
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i, ++j)
fPlugin->d_initAudioPort(true, i, fData->audioPorts[j]);
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i, ++j)
fPlugin->d_initAudioPort(false, i, fData->audioPorts[j]);
}
#endif

for (uint32_t i=0, count=fData->parameterCount; i < count; ++i)
fPlugin->d_initParameter(i, fData->parameters[i]);

@@ -211,6 +236,21 @@ public:
}
#endif

#if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0
const AudioPort& getAudioPort(const bool input, const uint32_t index) const noexcept
{
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, sFallbackAudioPort);

if (input) {
DISTRHO_SAFE_ASSERT_RETURN(index < DISTRHO_PLUGIN_NUM_INPUTS, sFallbackAudioPort);
} else {
DISTRHO_SAFE_ASSERT_RETURN(index < DISTRHO_PLUGIN_NUM_OUTPUTS, sFallbackAudioPort);
}

return fData->audioPorts[index + (input ? 0 : DISTRHO_PLUGIN_NUM_INPUTS)];
}
#endif

uint32_t getParameterCount() const noexcept
{
DISTRHO_SAFE_ASSERT_RETURN(fData != nullptr, 0);
@@ -458,6 +498,7 @@ private:
// Static fallback data, see DistrhoPlugin.cpp

static const d_string sFallbackString;
static const AudioPort sFallbackAudioPort;
static const ParameterRanges sFallbackRanges;

DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(PluginExporter)


+ 29
- 8
distrho/src/DistrhoPluginLV2export.cpp View File

@@ -109,6 +109,7 @@ void lv2_generate_ttl(const char* const basename)
# else
manifestString += " ui:binary <" + pluginDLL + "." DISTRHO_DLL_EXTENSION "> ;\n";
#endif
manifestString += "\n";
manifestString += " lv2:extensionData ui:idleInterface ,\n";
# if DISTRHO_PLUGIN_WANT_PROGRAMS
manifestString += " ui:showInterface ,\n";
@@ -116,9 +117,11 @@ void lv2_generate_ttl(const char* const basename)
# else
manifestString += " ui:showInterface ;\n";
# endif
manifestString += "\n";
manifestString += " lv2:optionalFeature ui:noUserResize ,\n";
manifestString += " ui:resize ,\n";
manifestString += " ui:touch ;\n";
manifestString += "\n";
# if DISTRHO_PLUGIN_WANT_DIRECT_ACCESS
manifestString += " lv2:requiredFeature <" LV2_DATA_ACCESS_URI "> ,\n";
manifestString += " <" LV2_INSTANCE_ACCESS_URI "> ,\n";
@@ -205,18 +208,27 @@ void lv2_generate_ttl(const char* const basename)
#if DISTRHO_PLUGIN_NUM_INPUTS > 0
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_INPUTS; ++i, ++portIndex)
{
const AudioPort& port(plugin.getAudioPort(true, i));

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

pluginString += " a lv2:InputPort, lv2:AudioPort ;\n";
if (port.hints & kAudioPortIsCV)
pluginString += " a lv2:InputPort, lv2:CVPort ;\n";
else
pluginString += " a lv2:InputPort, lv2:AudioPort ;\n";

pluginString += " lv2:index " + d_string(portIndex) + " ;\n";
pluginString += " lv2:symbol \"lv2_audio_in_" + d_string(i+1) + "\" ;\n";
pluginString += " lv2:name \"Audio Input " + d_string(i+1) + "\" ;\n";
pluginString += " lv2:symbol \"" + port.symbol + "\" ;\n";
pluginString += " lv2:name \"" + port.name + "\" ;\n";

if (port.hints & kAudioPortIsSidechain)
pluginString += " lv2:portProperty lv2:isSideChain;\n";

if (i+1 == DISTRHO_PLUGIN_NUM_INPUTS)
pluginString += " ] ;\n\n";
pluginString += " ] ;\n";
else
pluginString += " ] ,\n";
}
@@ -226,18 +238,27 @@ void lv2_generate_ttl(const char* const basename)
#if DISTRHO_PLUGIN_NUM_OUTPUTS > 0
for (uint32_t i=0; i < DISTRHO_PLUGIN_NUM_OUTPUTS; ++i, ++portIndex)
{
const AudioPort& port(plugin.getAudioPort(false, i));

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

pluginString += " a lv2:OutputPort, lv2:AudioPort ;\n";
if (port.hints & kAudioPortIsCV)
pluginString += " a lv2:OutputPort, lv2:CVPort ;\n";
else
pluginString += " a lv2:OutputPort, lv2:AudioPort ;\n";

pluginString += " lv2:index " + d_string(portIndex) + " ;\n";
pluginString += " lv2:symbol \"lv2_audio_out_" + d_string(i+1) + "\" ;\n";
pluginString += " lv2:name \"Audio Output " + d_string(i+1) + "\" ;\n";
pluginString += " lv2:symbol \"" + port.symbol + "\" ;\n";
pluginString += " lv2:name \"" + port.name + "\" ;\n";

if (port.hints & kAudioPortIsSidechain)
pluginString += " lv2:portProperty lv2:isSideChain;\n";

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


Loading…
Cancel
Save