Introduce first cut of live shifter

This commit is contained in:
Chris Cannam
2023-06-29 16:49:30 +01:00
parent 1eddafd7a7
commit 5935d17ee0
14 changed files with 4284 additions and 2 deletions

View File

@@ -0,0 +1,582 @@
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
/*
Rubber Band Library
An audio time-stretching and pitch-shifting library.
Copyright 2007-2023 Particular Programs Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version. See the file
COPYING included with this distribution for more information.
Alternatively, if you have a valid commercial licence for the
Rubber Band Library obtained by agreement with the copyright
holders, you may redistribute and/or modify it under the terms
described in that licence.
If you wish to distribute code using the Rubber Band Library
under terms other than those of the GNU General Public License,
you must obtain a valid commercial licence before doing so.
*/
#include "RubberBandLivePitchShifter.h"
#include "RubberBandLiveShifter.h"
#include <iostream>
#include <cmath>
using namespace RubberBand;
using std::cout;
using std::cerr;
using std::endl;
using std::min;
#ifdef RB_PLUGIN_LADSPA
const char *const
RubberBandLivePitchShifter::portNamesMono[PortCountMono] =
{
"latency",
"Cents",
"Semitones",
"Octaves",
"Formant Preserving",
"Wet-Dry Mix",
"Input",
"Output"
};
const char *const
RubberBandLivePitchShifter::portNamesStereo[PortCountStereo] =
{
"latency",
"Cents",
"Semitones",
"Octaves",
"Formant Preserving",
"Wet-Dry Mix",
"Input L",
"Output L",
"Input R",
"Output R"
};
const LADSPA_PortDescriptor
RubberBandLivePitchShifter::portsMono[PortCountMono] =
{
LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO
};
const LADSPA_PortDescriptor
RubberBandLivePitchShifter::portsStereo[PortCountStereo] =
{
LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO
};
const LADSPA_PortRangeHint
RubberBandLivePitchShifter::hintsMono[PortCountMono] =
{
{ 0, 0, 0 }, // latency
{ LADSPA_HINT_DEFAULT_0 | // cents
LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_BOUNDED_ABOVE,
-100.0, 100.0 },
{ LADSPA_HINT_DEFAULT_0 | // semitones
LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_BOUNDED_ABOVE |
LADSPA_HINT_INTEGER,
-12.0, 12.0 },
{ LADSPA_HINT_DEFAULT_0 | // octaves
LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_BOUNDED_ABOVE |
LADSPA_HINT_INTEGER,
-2.0, 2.0 },
{ LADSPA_HINT_DEFAULT_0 | // formant preserving
LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_BOUNDED_ABOVE |
LADSPA_HINT_TOGGLED,
0.0, 1.0 },
{ LADSPA_HINT_DEFAULT_0 | // wet-dry mix
LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_BOUNDED_ABOVE,
0.0, 1.0 },
{ 0, 0, 0 },
{ 0, 0, 0 }
};
const LADSPA_PortRangeHint
RubberBandLivePitchShifter::hintsStereo[PortCountStereo] =
{
{ 0, 0, 0 }, // latency
{ LADSPA_HINT_DEFAULT_0 | // cents
LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_BOUNDED_ABOVE,
-100.0, 100.0 },
{ LADSPA_HINT_DEFAULT_0 | // semitones
LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_BOUNDED_ABOVE |
LADSPA_HINT_INTEGER,
-12.0, 12.0 },
{ LADSPA_HINT_DEFAULT_0 | // octaves
LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_BOUNDED_ABOVE |
LADSPA_HINT_INTEGER,
-2.0, 2.0 },
{ LADSPA_HINT_DEFAULT_0 | // formant preserving
LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_BOUNDED_ABOVE |
LADSPA_HINT_TOGGLED,
0.0, 1.0 },
{ LADSPA_HINT_DEFAULT_0 | // wet-dry mix
LADSPA_HINT_BOUNDED_BELOW |
LADSPA_HINT_BOUNDED_ABOVE,
0.0, 1.0 },
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 },
{ 0, 0, 0 }
};
const LADSPA_Properties
RubberBandLivePitchShifter::properties = LADSPA_PROPERTY_HARD_RT_CAPABLE;
const LADSPA_Descriptor
RubberBandLivePitchShifter::ladspaDescriptorMono =
{
29791, // "Unique" ID
"rubberband-live-pitchshifter-mono", // Label
properties,
"Rubber Band Live Mono Pitch Shifter", // Name
"Breakfast Quay",
"GPL",
PortCountMono,
portsMono,
portNamesMono,
hintsMono,
nullptr, // Implementation data
instantiate,
connectPort,
activate,
run,
nullptr, // Run adding
nullptr, // Set run adding gain
deactivate,
cleanup
};
const LADSPA_Descriptor
RubberBandLivePitchShifter::ladspaDescriptorStereo =
{
97921, // "Unique" ID
"rubberband-live-pitchshifter-stereo", // Label
properties,
"Rubber Band Live Stereo Pitch Shifter", // Name
"Breakfast Quay",
"GPL",
PortCountStereo,
portsStereo,
portNamesStereo,
hintsStereo,
nullptr, // Implementation data
instantiate,
connectPort,
activate,
run,
nullptr, // Run adding
nullptr, // Set run adding gain
deactivate,
cleanup
};
const LADSPA_Descriptor *
RubberBandLivePitchShifter::getDescriptor(unsigned long index)
{
if (index == 0) return &ladspaDescriptorMono;
if (index == 1) return &ladspaDescriptorStereo;
else return 0;
}
#else
const LV2_Descriptor
RubberBandLivePitchShifter::lv2DescriptorMono =
{
"http://breakfastquay.com/rdf/lv2-rubberband-live#mono",
instantiate,
connectPort,
activate,
run,
deactivate,
cleanup,
nullptr
};
const LV2_Descriptor
RubberBandLivePitchShifter::lv2DescriptorStereo =
{
"http://breakfastquay.com/rdf/lv2-rubberband-live#stereo",
instantiate,
connectPort,
activate,
run,
deactivate,
cleanup,
nullptr
};
const LV2_Descriptor *
RubberBandLivePitchShifter::getDescriptor(uint32_t index)
{
if (index == 0) return &lv2DescriptorMono;
if (index == 1) return &lv2DescriptorStereo;
else return 0;
}
#endif
RubberBandLivePitchShifter::RubberBandLivePitchShifter(int sampleRate, size_t channels) :
m_latency(nullptr),
m_cents(nullptr),
m_semitones(nullptr),
m_octaves(nullptr),
m_formant(nullptr),
m_wetDry(nullptr),
m_ratio(1.0),
m_prevRatio(1.0),
m_currentFormant(false),
m_shifter(new RubberBandLiveShifter
(sampleRate, channels,
RubberBandLiveShifter::OptionWindowLong |
RubberBandLiveShifter::OptionPitchModeB |
RubberBandLiveShifter::OptionChannelsTogether)),
m_sampleRate(sampleRate),
m_channels(channels),
m_blockSize(0),
m_bufferSize(65536),
m_delay(0)
{
m_input = new float *[m_channels];
m_output = new float *[m_channels];
m_irb = new RingBuffer<float> *[m_channels];
m_orb = new RingBuffer<float> *[m_channels];
m_ib = new float *[m_channels];
m_ob = new float *[m_channels];
m_delayMixBuffer = new RingBuffer<float> *[m_channels];
m_blockSize = m_shifter->getBlockSize();
m_delay = m_shifter->getStartDelay();
for (int c = 0; c < m_channels; ++c) {
m_irb[c] = new RingBuffer<float>(m_bufferSize);
m_orb[c] = new RingBuffer<float>(m_bufferSize);
m_irb[c]->zero(m_blockSize);
m_ib[c] = new float[m_blockSize];
m_ob[c] = new float[m_blockSize];
m_delayMixBuffer[c] = new RingBuffer<float>(m_bufferSize + m_delay);
m_irb[c]->zero(m_delay);
}
activateImpl();
}
RubberBandLivePitchShifter::~RubberBandLivePitchShifter()
{
delete m_shifter;
for (int c = 0; c < m_channels; ++c) {
delete m_irb[c];
delete m_orb[c];
delete[] m_ib[c];
delete[] m_ob[c];
delete m_delayMixBuffer[c];
}
delete[] m_irb;
delete[] m_orb;
delete[] m_ib;
delete[] m_ob;
delete[] m_delayMixBuffer;
delete[] m_output;
delete[] m_input;
}
#ifdef RB_PLUGIN_LADSPA
LADSPA_Handle
RubberBandLivePitchShifter::instantiate(const LADSPA_Descriptor *desc, unsigned long rate)
{
if (desc->PortCount == ladspaDescriptorMono.PortCount) {
return new RubberBandLivePitchShifter(rate, 1);
} else if (desc->PortCount == ladspaDescriptorStereo.PortCount) {
return new RubberBandLivePitchShifter(rate, 2);
}
return nullptr;
}
#else
LV2_Handle
RubberBandLivePitchShifter::instantiate(const LV2_Descriptor *desc, double rate,
const char *, const LV2_Feature *const *)
{
if (rate < 1.0) {
std::cerr << "RubberBandLivePitchShifter::instantiate: invalid sample rate "
<< rate << " provided" << std::endl;
return nullptr;
}
size_t srate = size_t(round(rate));
if (std::string(desc->URI) == lv2DescriptorMono.URI) {
return new RubberBandLivePitchShifter(srate, 1);
} else if (std::string(desc->URI) == lv2DescriptorStereo.URI) {
return new RubberBandLivePitchShifter(srate, 2);
} else {
std::cerr << "RubberBandLivePitchShifter::instantiate: unrecognised URI "
<< desc->URI << " requested" << std::endl;
return nullptr;
}
}
#endif
#ifdef RB_PLUGIN_LADSPA
void
RubberBandLivePitchShifter::connectPort(LADSPA_Handle handle,
unsigned long port, LADSPA_Data *location)
#else
void
RubberBandLivePitchShifter::connectPort(LV2_Handle handle,
uint32_t port, void *location)
#endif
{
RubberBandLivePitchShifter *shifter = (RubberBandLivePitchShifter *)handle;
float **ports[PortCountStereo] = {
&shifter->m_latency,
&shifter->m_cents,
&shifter->m_semitones,
&shifter->m_octaves,
&shifter->m_formant,
&shifter->m_wetDry,
&shifter->m_input[0],
&shifter->m_output[0],
&shifter->m_input[1],
&shifter->m_output[1]
};
if (shifter->m_channels == 1) {
if (port >= PortCountMono) return;
} else {
if (port >= PortCountStereo) return;
}
*ports[port] = (float *)location;
if (shifter->m_latency) {
*(shifter->m_latency) = shifter->getLatency();
}
}
#ifdef RB_PLUGIN_LADSPA
void
RubberBandLivePitchShifter::activate(LADSPA_Handle handle)
#else
void
RubberBandLivePitchShifter::activate(LV2_Handle handle)
#endif
{
RubberBandLivePitchShifter *shifter = (RubberBandLivePitchShifter *)handle;
shifter->activateImpl();
}
#ifdef RB_PLUGIN_LADSPA
void
RubberBandLivePitchShifter::run(LADSPA_Handle handle, unsigned long samples)
#else
void
RubberBandLivePitchShifter::run(LV2_Handle handle, uint32_t samples)
#endif
{
RubberBandLivePitchShifter *shifter = (RubberBandLivePitchShifter *)handle;
shifter->runImpl(samples);
}
#ifdef RB_PLUGIN_LADSPA
void
RubberBandLivePitchShifter::deactivate(LADSPA_Handle handle)
#else
void
RubberBandLivePitchShifter::deactivate(LV2_Handle handle)
#endif
{
activate(handle); // both functions just reset the plugin
}
#ifdef RB_PLUGIN_LADSPA
void
RubberBandLivePitchShifter::cleanup(LADSPA_Handle handle)
#else
void
RubberBandLivePitchShifter::cleanup(LV2_Handle handle)
#endif
{
delete (RubberBandLivePitchShifter *)handle;
}
void
RubberBandLivePitchShifter::activateImpl()
{
updateRatio();
m_prevRatio = m_ratio;
m_shifter->reset();
m_shifter->setPitchScale(m_ratio);
for (int c = 0; c < m_channels; ++c) {
m_irb[c]->reset();
m_irb[c]->zero(m_blockSize);
m_orb[c]->reset();
m_delayMixBuffer[c]->reset();
m_delayMixBuffer[c]->zero(m_delay);
}
}
void
RubberBandLivePitchShifter::updateRatio()
{
// The octaves, semitones, and cents parameters are supposed to be
// integral: we want to enforce that, just to avoid
// inconsistencies between hosts if some respect the hints more
// than others
#ifdef RB_PLUGIN_LADSPA
// But we don't want to change the long-standing behaviour of the
// LADSPA plugin, so let's leave this as-is and only do "the right
// thing" for LV2
double oct = (m_octaves ? *m_octaves : 0.0);
oct += (m_semitones ? *m_semitones : 0.0) / 12;
oct += (m_cents ? *m_cents : 0.0) / 1200;
m_ratio = pow(2.0, oct);
#else
// LV2
double octaves = round(m_octaves ? *m_octaves : 0.0);
if (octaves < -2.0) octaves = -2.0;
if (octaves > 2.0) octaves = 2.0;
double semitones = round(m_semitones ? *m_semitones : 0.0);
if (semitones < -12.0) semitones = -12.0;
if (semitones > 12.0) semitones = 12.0;
double cents = round(m_cents ? *m_cents : 0.0);
if (cents < -100.0) cents = -100.0;
if (cents > 100.0) cents = 100.0;
m_ratio = pow(2.0,
octaves +
semitones / 12.0 +
cents / 1200.0);
#endif
}
void
RubberBandLivePitchShifter::updateFormant()
{
if (!m_formant) return;
bool f = (*m_formant > 0.5f);
if (f == m_currentFormant) return;
RubberBandLiveShifter *s = m_shifter;
s->setFormantOption(f ?
RubberBandLiveShifter::OptionFormantPreserved :
RubberBandLiveShifter::OptionFormantShifted);
m_currentFormant = f;
}
int
RubberBandLivePitchShifter::getLatency() const
{
return m_shifter->getStartDelay() + m_blockSize;
}
void
RubberBandLivePitchShifter::runImpl(uint32_t insamples)
{
updateRatio();
if (m_ratio != m_prevRatio) {
m_shifter->setPitchScale(m_ratio);
m_prevRatio = m_ratio;
}
updateFormant();
if (m_latency) {
*m_latency = getLatency();
}
for (int c = 0; c < m_channels; ++c) {
m_irb[c]->write(m_input[c], insamples);
m_delayMixBuffer[c]->write(m_input[c], insamples);
}
while (m_irb[0]->getReadSpace() >= m_blockSize) {
for (int c = 0; c < m_channels; ++c) {
m_irb[c]->read(m_ib[c], m_blockSize);
}
m_shifter->shift(m_ib, m_ob);
for (int c = 0; c < m_channels; ++c) {
m_orb[c]->write(m_ob[c], m_blockSize);
}
}
for (int c = 0; c < m_channels; ++c) {
m_orb[c]->read(m_output[c], insamples);
}
float mix = 0.0;
if (m_wetDry) mix = *m_wetDry;
for (int c = 0; c < m_channels; ++c) {
if (mix > 0.0) {
for (uint32_t i = 0; i < insamples; ++i) {
float dry = m_delayMixBuffer[c]->readOne();
m_output[c][i] *= (1.0 - mix);
m_output[c][i] += dry * mix;
}
} else {
m_delayMixBuffer[c]->skip(insamples);
}
}
}

View File

@@ -0,0 +1,148 @@
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
/*
Rubber Band Library
An audio time-stretching and pitch-shifting library.
Copyright 2007-2023 Particular Programs Ltd.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version. See the file
COPYING included with this distribution for more information.
Alternatively, if you have a valid commercial licence for the
Rubber Band Library obtained by agreement with the copyright
holders, you may redistribute and/or modify it under the terms
described in that licence.
If you wish to distribute code using the Rubber Band Library
under terms other than those of the GNU General Public License,
you must obtain a valid commercial licence before doing so.
*/
#ifndef RUBBER_BAND_LIVE_SHIFTER_H
#define RUBBER_BAND_LIVE_SHIFTER_H
#ifdef RB_PLUGIN_LADSPA
#ifdef RB_PLUGIN_LV2
#error "Only one of RB_PLUGIN_LADSPA and RB_PLUGIN_LV2 may be defined at once"
#endif
#else
#ifndef RB_PLUGIN_LV2
#error "Including code must define either RB_PLUGIN_LADSPA or RB_PLUGIN_LV2"
#endif
#endif
#ifdef RB_PLUGIN_LADSPA
#include <ladspa.h>
#else
#include <lv2.h>
#endif
#include "common/RingBuffer.h"
namespace RubberBand {
class RubberBandLiveShifter;
}
class RubberBandLivePitchShifter
{
public:
#ifdef RB_PLUGIN_LADSPA
static const LADSPA_Descriptor *getDescriptor(unsigned long index);
#else
static const LV2_Descriptor *getDescriptor(uint32_t index);
#endif
protected:
RubberBandLivePitchShifter(int sampleRate, size_t channels);
~RubberBandLivePitchShifter();
enum {
LatencyPort = 0,
CentsPort = 1,
SemitonesPort = 2,
OctavesPort = 3,
FormantPort = 4,
WetDryPort = 5,
InputPort1 = 6,
OutputPort1 = 7,
PortCountMono = OutputPort1 + 1,
InputPort2 = 8,
OutputPort2 = 9,
PortCountStereo = OutputPort2 + 1
};
#ifdef RB_PLUGIN_LADSPA
static const char *const portNamesMono[PortCountMono];
static const LADSPA_PortDescriptor portsMono[PortCountMono];
static const LADSPA_PortRangeHint hintsMono[PortCountMono];
static const char *const portNamesStereo[PortCountStereo];
static const LADSPA_PortDescriptor portsStereo[PortCountStereo];
static const LADSPA_PortRangeHint hintsStereo[PortCountStereo];
static const LADSPA_Properties properties;
static const LADSPA_Descriptor ladspaDescriptorMono;
static const LADSPA_Descriptor ladspaDescriptorStereo;
static LADSPA_Handle instantiate(const LADSPA_Descriptor *, unsigned long);
static void connectPort(LADSPA_Handle, unsigned long, LADSPA_Data *);
static void activate(LADSPA_Handle);
static void run(LADSPA_Handle, unsigned long);
static void deactivate(LADSPA_Handle);
static void cleanup(LADSPA_Handle);
#else
static const LV2_Descriptor lv2DescriptorMono;
static const LV2_Descriptor lv2DescriptorStereo;
static LV2_Handle instantiate(const LV2_Descriptor *, double,
const char *, const LV2_Feature *const *);
static void connectPort(LV2_Handle, uint32_t, void *);
static void activate(LV2_Handle);
static void run(LV2_Handle, uint32_t);
static void deactivate(LV2_Handle);
static void cleanup(LV2_Handle);
#endif
void activateImpl();
void runImpl(uint32_t count);
void process();
void updateRatio();
void updateFormant();
float **m_input;
float **m_output;
float *m_latency;
float *m_cents;
float *m_semitones;
float *m_octaves;
float *m_formant;
float *m_wetDry;
double m_ratio;
double m_prevRatio;
bool m_currentFormant;
RubberBand::RubberBandLiveShifter *m_shifter;
RubberBand::RingBuffer<float> **m_irb;
RubberBand::RingBuffer<float> **m_orb;
float **m_ib;
float **m_ob;
RubberBand::RingBuffer<float> **m_delayMixBuffer;
int m_sampleRate;
int m_channels;
int m_blockSize;
int m_bufferSize;
int m_delay;
int getLatency() const;
};
#endif

View File

@@ -2,3 +2,5 @@ ladspa:ladspa-rubberband:rubberband-pitchshifter-mono::Frequency > Pitch shifter
ladspa:ladspa-rubberband:rubberband-pitchshifter-stereo::Frequency > Pitch shifters
ladspa:ladspa-rubberband:rubberband-r3-pitchshifter-mono::Frequency > Pitch shifters
ladspa:ladspa-rubberband:rubberband-r3-pitchshifter-stereo::Frequency > Pitch shifters
ladspa:ladspa-rubberband:rubberband-live-pitchshifter-mono::Frequency > Pitch shifters
ladspa:ladspa-rubberband:rubberband-live-pitchshifter-stereo::Frequency > Pitch shifters

View File

@@ -9,6 +9,10 @@
<ladspa:PitchPlugin rdf:about="&ladspa;2979"/>
<ladspa:PitchPlugin rdf:about="&ladspa;9792"/>
<ladspa:PitchPlugin rdf:about="&ladspa;29790"/>
<ladspa:PitchPlugin rdf:about="&ladspa;97920"/>
<ladspa:PitchPlugin rdf:about="&ladspa;29791"/>
<ladspa:PitchPlugin rdf:about="&ladspa;97921"/>
</rdf:RDF>

View File

@@ -25,6 +25,7 @@
#undef RB_PLUGIN_LV2
#include "RubberBandPitchShifter.cpp"
#include "RubberBandR3PitchShifter.cpp"
#include "RubberBandLivePitchShifter.cpp"
#include <stdio.h>
@@ -34,8 +35,10 @@ const LADSPA_Descriptor *ladspa_descriptor(unsigned long index)
{
if (index < 2) {
return RubberBandPitchShifter::getDescriptor(index);
} else {
} else if (index < 4) {
return RubberBandR3PitchShifter::getDescriptor(index - 2);
} else {
return RubberBandLivePitchShifter::getDescriptor(index - 4);
}
}

View File

@@ -25,6 +25,7 @@
#undef RB_PLUGIN_LADSPA
#include "RubberBandPitchShifter.cpp"
#include "RubberBandR3PitchShifter.cpp"
#include "RubberBandLivePitchShifter.cpp"
#include <stdio.h>
@@ -35,8 +36,10 @@ const LV2_Descriptor *lv2_descriptor(uint32_t index)
{
if (index < 2) {
return RubberBandPitchShifter::getDescriptor(index);
} else {
} else if (index < 4) {
return RubberBandR3PitchShifter::getDescriptor(index - 2);
} else {
return RubberBandLivePitchShifter::getDescriptor(index - 4);
}
}

View File

@@ -201,6 +201,43 @@ rubberband:r3mono
lv2:designation pg:center ;
] .
rubberband:livemono
a doap:Project, lv2:Plugin, lv2:PitchPlugin ;
doap:name "Rubber Band Live Mono Pitch Shifter" ;
doap:license <http://usefulinc.com/doap/licenses/gpl> ;
foaf:maker :maker ;
doap:developer :maker ;
doap:maintainer :maker ;
# Minor version will be 2x the Rubber Band API minor version
lv2:minorVersion 4 ;
lv2:microVersion 1 ;
lv2:optionalFeature lv2:hardRTCapable ;
pg:mainInput rubberband:mono_in_group ;
pg:mainOutput rubberband:mono_out_group ;
dc:replaces <urn:ladspa:29791> ;
lv2:port :latencyPort ,
:centsPort ,
:semitonesPort ,
:octavesPort ,
:formantPortR3 ,
:wetDryPortR3 ,
[ a lv2:AudioPort, lv2:InputPort ;
lv2:index 6 ;
lv2:symbol "input" ;
lv2:name "Input" ;
lv2:shortName "Input" ;
pg:group rubberband:mono_in_group ;
lv2:designation pg:center ;
], [
a lv2:AudioPort, lv2:OutputPort ;
lv2:index 7 ;
lv2:symbol "output" ;
lv2:name "Output" ;
lv2:shortName "Output" ;
pg:group rubberband:mono_out_group ;
lv2:designation pg:center ;
] .
rubberband:stereo
a doap:Project, lv2:Plugin, lv2:PitchPlugin ;
doap:name "Rubber Band Stereo Pitch Shifter" ;
@@ -306,3 +343,55 @@ rubberband:r3stereo
lv2:designation pg:right ;
] .
rubberband:livestereo
a doap:Project, lv2:Plugin, lv2:PitchPlugin ;
doap:name "Rubber Band Live Stereo Pitch Shifter" ;
doap:license <http://usefulinc.com/doap/licenses/gpl> ;
foaf:maker :maker ;
doap:developer :maker ;
doap:maintainer :maker ;
# Minor version will be 2x the Rubber Band API minor version
lv2:minorVersion 4 ;
lv2:microVersion 1 ;
lv2:optionalFeature lv2:hardRTCapable ;
pg:mainInput rubberband:stereo_in_group ;
pg:mainOutput rubberband:stereo_out_group ;
dc:replaces <urn:ladspa:97921> ;
lv2:port :latencyPort ,
:centsPort ,
:semitonesPort ,
:octavesPort ,
:formantPortR3 ,
:wetDryPortR3 ,
[ a lv2:AudioPort, lv2:InputPort ;
lv2:index 6 ;
lv2:symbol "input_l" ;
lv2:name "Input L" ;
lv2:shortName "Input L" ;
pg:group rubberband:stereo_in_group ;
lv2:designation pg:left ;
], [
a lv2:AudioPort, lv2:OutputPort ;
lv2:index 7 ;
lv2:symbol "output_l" ;
lv2:name "Output L" ;
lv2:shortName "Output L" ;
pg:group rubberband:stereo_out_group ;
lv2:designation pg:left ;
], [ a lv2:AudioPort, lv2:InputPort ;
lv2:index 8 ;
lv2:symbol "input_r" ;
lv2:name "Input R" ;
lv2:shortName "Input R" ;
pg:group rubberband:stereo_in_group ;
lv2:designation pg:right ;
], [
a lv2:AudioPort, lv2:OutputPort ;
lv2:index 9 ;
lv2:symbol "output_r" ;
lv2:name "Output R" ;
lv2:shortName "Output R" ;
pg:group rubberband:stereo_out_group ;
lv2:designation pg:right ;
] .

View File

@@ -12,6 +12,11 @@ rubberband:r3mono
lv2:binary <lv2-rubberband.so> ;
rdfs:seeAlso <lv2-rubberband.ttl> .
rubberband:livemono
a lv2:Plugin ;
lv2:binary <lv2-rubberband.so> ;
rdfs:seeAlso <lv2-rubberband.ttl> .
rubberband:stereo
a lv2:Plugin ;
lv2:binary <lv2-rubberband.so> ;
@@ -22,3 +27,8 @@ rubberband:r3stereo
lv2:binary <lv2-rubberband.so> ;
rdfs:seeAlso <lv2-rubberband.ttl> .
rubberband:livestereo
a lv2:Plugin ;
lv2:binary <lv2-rubberband.so> ;
rdfs:seeAlso <lv2-rubberband.ttl> .