Add support for external audio input in lua effects again

pull/332/head
James H Ball 2025-09-20 16:50:48 +01:00
rodzic 936eac081d
commit 6aab6d3dc1
31 zmienionych plików z 40 dodań i 35 usunięć

Wyświetl plik

@ -577,8 +577,11 @@ void OscirenderAudioProcessor::processBlock(juce::AudioBuffer<float>& buffer, ju
bool isEnabled = effect->enabled != nullptr && effect->enabled->getValue();
bool isSelected = effect->selected == nullptr ? true : effect->selected->getBoolValue();
if (isEnabled && isSelected) {
// TODO: need to setExternalInput for Lua custom effect
if (effect->getId() == custom->getId()) {
effect->setExternalInput(&inputBuffer);
}
effect->processBlock(outputBuffer3d, midiMessages);
effect->setExternalInput(nullptr);
}
}
@ -586,8 +589,11 @@ void OscirenderAudioProcessor::processBlock(juce::AudioBuffer<float>& buffer, ju
const bool prevEnabled = (previewEffect->enabled != nullptr) && previewEffect->enabled->getValue();
const bool prevSelected = (previewEffect->selected == nullptr) ? true : previewEffect->selected->getBoolValue();
if (!(prevEnabled && prevSelected)) {
// TODO: need to setExternalInput for Lua custom effect
if (previewEffect->getId() == custom->getId()) {
previewEffect->setExternalInput(&inputBuffer);
}
previewEffect->processBlock(outputBuffer3d, midiMessages);
previewEffect->setExternalInput(nullptr);
}
}
}

Wyświetl plik

@ -5,7 +5,7 @@ class AutoGainControlEffect : public osci::EffectApplication {
public:
AutoGainControlEffect() {}
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
// Extract parameters from values
double intensity = values[0]; // How aggressively the gain is adjusted (0.0 - 1.0)
double targetLevel = values[1]; // The target RMS level to achieve (0.0 - 1.0)

Wyświetl plik

@ -4,7 +4,7 @@
class BitCrushEffect : public osci::EffectApplication {
public:
// algorithm from https://www.kvraudio.com/forum/viewtopic.php?t=163880
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
double effectScale = juce::jlimit(0.0f, 1.0f, values[0].load());
double value = values[1].load();
// change rage of value from 0-1 to 0.0-0.78

Wyświetl plik

@ -7,7 +7,7 @@
class BounceEffect : public osci::EffectApplication {
public:
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
// values[0] = size (0.05..1.0)
// values[1] = speed (0..)
// values[2] = angle (0..1 -> 0..2π)

Wyświetl plik

@ -3,7 +3,7 @@
class BulgeEffect : public osci::EffectApplication {
public:
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
double value = values[0];
double translatedBulge = -value + 1;

Wyświetl plik

@ -13,7 +13,7 @@ CustomEffect::~CustomEffect() {
parser->close(L);
}
osci::Point CustomEffect::apply(int index, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) {
osci::Point CustomEffect::apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) {
auto effectScale = values[0].load();
auto x = input.x;
@ -29,9 +29,8 @@ osci::Point CustomEffect::apply(int index, osci::Point input, const std::vector<
vars.x = x;
vars.y = y;
vars.z = z;
vars.ext_x = extInput.x;
vars.ext_y = extInput.y;
vars.ext_x = externalInput.x;
vars.ext_y = externalInput.y;
std::copy(luaValues, luaValues + 26, std::begin(vars.sliders));

Wyświetl plik

@ -11,7 +11,7 @@ public:
static const juce::String UNIQUE_ID;
static const juce::String FILE_NAME;
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override;
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override;
void updateCode(const juce::String& newCode);
juce::String getCode();

Wyświetl plik

@ -6,7 +6,7 @@ class DashedLineEffect : public osci::EffectApplication {
public:
DashedLineEffect(OscirenderAudioProcessor& p) : audioProcessor(p) {}
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
// if only 2 parameters are provided, this is being used as a 'trace effect'
// where the dash count is 1.
double dashCount = 1.0;

Wyświetl plik

@ -3,7 +3,7 @@
class DelayEffect : public osci::EffectApplication {
public:
osci::Point apply(int index, osci::Point vector, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int index, osci::Point vector, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
double decay = values[0];
double decayLength = values[1];
int delayBufferLength = (int)(sampleRate * decayLength);

Wyświetl plik

@ -4,7 +4,7 @@
class DistortEffect : public osci::EffectApplication {
public:
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
int flip = index % 2 == 0 ? 1 : -1;
osci::Point jitter = osci::Point(flip * values[0], flip * values[1], flip * values[2]);
return input + jitter;

Wyświetl plik

@ -6,7 +6,7 @@ class DuplicatorEffect : public osci::EffectApplication {
public:
DuplicatorEffect(OscirenderAudioProcessor& p) : audioProcessor(p) {}
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
const double twoPi = juce::MathConstants<double>::twoPi;
double copies = juce::jmax(1.0f, values[0].load());
double spread = juce::jlimit(0.0f, 1.0f, values[1].load());

Wyświetl plik

@ -3,7 +3,7 @@
class GodRayEffect : public osci::EffectApplication {
public:
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>&values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>&values, float sampleRate) override {
double noiseAmp = juce::jmax(0.0f, values[0].load());
double bias = values[1];
double biasExponent = std::pow(12.0, std::abs(bias));

Wyświetl plik

@ -6,7 +6,7 @@ class KaleidoscopeEffect : public osci::EffectApplication {
public:
KaleidoscopeEffect(OscirenderAudioProcessor& p) : audioProcessor(p) {}
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
const double pi = juce::MathConstants<double>::pi;
const double twoPi = juce::MathConstants<double>::twoPi;
double segments = juce::jmax(1.0f, values[0].load());

Wyświetl plik

@ -8,7 +8,7 @@ class MultiplexEffect : public osci::EffectApplication {
public:
explicit MultiplexEffect(OscirenderAudioProcessor &p) : audioProcessor(p) {}
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
jassert(values.size() == 5);
double gridX = values[0].load();

Wyświetl plik

@ -4,7 +4,7 @@
class PerspectiveEffect : public osci::EffectApplication {
public:
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
auto effectScale = values[0].load();
// Far plane clipping happens at about 1.2 deg for 100 far plane dist
float fovDegrees = juce::jlimit(1.5f, 179.0f, values[1].load());

Wyświetl plik

@ -5,7 +5,7 @@
// Inspired by xenontesla122
class PolygonBitCrushEffect : public osci::EffectApplication {
public:
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>&values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>&values, float sampleRate) override {
const double pi = juce::MathConstants<double>::pi;
const double twoPi = juce::MathConstants<double>::twoPi;
double effectScale = juce::jlimit(0.0f, 1.0f, values[0].load());

Wyświetl plik

@ -3,7 +3,7 @@
class RippleEffectApp : public osci::EffectApplication {
public:
osci::Point apply(int /*index*/, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int /*index*/, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
double phase = values[1] * std::numbers::pi;
double distance = 100 * values[2] * (input.x * input.x + input.y * input.y);
input.z += values[0] * juce::dsp::FastMathApproximations::sin(phase + distance);

Wyświetl plik

@ -3,7 +3,7 @@
class RotateEffectApp : public osci::EffectApplication {
public:
osci::Point apply(int /*index*/, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int /*index*/, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
input.rotate(values[0] * std::numbers::pi, values[1] * std::numbers::pi, values[2] * std::numbers::pi);
return input;
}

Wyświetl plik

@ -3,7 +3,7 @@
class ScaleEffectApp : public osci::EffectApplication {
public:
osci::Point apply(int /*index*/, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int /*index*/, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
return input * osci::Point(values[0], values[1], values[2]);
}

Wyświetl plik

@ -8,7 +8,7 @@ class SkewEffect : public osci::EffectApplication {
public:
SkewEffect() {}
osci::Point apply(int /*index*/, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int /*index*/, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
jassert(values.size() == 3);
double tx = values[0].load(); // skew X by Y
double ty = values[1].load(); // skew Y by Z

Wyświetl plik

@ -6,7 +6,7 @@ public:
SmoothEffect() = default;
explicit SmoothEffect(juce::String prefix, float defaultValue = 0.75f) : idPrefix(prefix), smoothingDefault(defaultValue) {}
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
double weight = juce::jmax(values[0].load(), 0.00001f);
weight *= 0.95;
double strength = 10;

Wyświetl plik

@ -3,7 +3,7 @@
class SpiralBitCrushEffect : public osci::EffectApplication {
public:
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>&values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>&values, float sampleRate) override {
// Completing one revolution in input space traverses the hypotenuse of one "domain" in log-polar space
double effectScale = juce::jlimit(0.0f, 1.0f, values[0].load());
double domainX = juce::jmax(2.0, std::floor(values[1].load() + 0.001));

Wyświetl plik

@ -3,7 +3,7 @@
class StereoEffect : public osci::EffectApplication {
public:
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
if (this->sampleRate != sampleRate) {
this->sampleRate = sampleRate;
initialiseBuffer(sampleRate);

Wyświetl plik

@ -3,7 +3,7 @@
class SwirlEffectApp : public osci::EffectApplication {
public:
osci::Point apply(int /*index*/, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int /*index*/, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
double length = 10 * values[0] * input.magnitude();
double newX = input.x * juce::dsp::FastMathApproximations::cos(length) - input.y * juce::dsp::FastMathApproximations::sin(length);
double newY = input.x * juce::dsp::FastMathApproximations::sin(length) + input.y * juce::dsp::FastMathApproximations::cos(length);

Wyświetl plik

@ -3,7 +3,7 @@
class TranslateEffectApp : public osci::EffectApplication {
public:
osci::Point apply(int /*index*/, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int /*index*/, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
return input + osci::Point(values[0], values[1], values[2]);
}

Wyświetl plik

@ -4,7 +4,7 @@
class TwistEffect : public osci::EffectApplication {
public:
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>&values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>&values, float sampleRate) override {
double twistStrength = values[0] * 4 * std::numbers::pi;
double twistTheta = twistStrength * input.y;
input.rotate(0.0, twistTheta, 0.0);

Wyświetl plik

@ -9,7 +9,7 @@ class UnfoldEffect : public osci::EffectApplication {
public:
explicit UnfoldEffect(OscirenderAudioProcessor &p) : audioProcessor(p) {}
osci::Point apply(int /*index*/, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int /*index*/, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
// values[0] = segments (can be fractional)
// values[1] = phase (0-1) selecting which segment is currently being drawn
double segments = juce::jmax(values[0].load(), 1.0f); // ensure at least 1 segment

Wyświetl plik

@ -3,7 +3,7 @@
class VectorCancellingEffect : public osci::EffectApplication {
public:
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
double value = values[0];
if (value < 0.001) {
return input;

Wyświetl plik

@ -3,7 +3,7 @@
class VortexEffect : public osci::EffectApplication {
public:
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>&values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>&values, float sampleRate) override {
// Treat input as complex number and raise to integer power
// Disallowing non-integer and negative exponents because of the branch cut
double effectScale = juce::jlimit(0.0f, 1.0f, values[0].load());

Wyświetl plik

@ -6,7 +6,7 @@ class WobbleEffect : public osci::EffectApplication {
public:
WobbleEffect(OscirenderAudioProcessor &p) : audioProcessor(p) {}
osci::Point apply(int index, osci::Point input, const std::vector<std::atomic<float>>& values, float sampleRate) override {
osci::Point apply(int index, osci::Point input, osci::Point externalInput, const std::vector<std::atomic<float>>& values, float sampleRate) override {
double wobblePhase = values[1] * std::numbers::pi;
double theta = nextPhase(audioProcessor.frequency, sampleRate) + wobblePhase;
double delta = 0.5 * values[0] * juce::dsp::FastMathApproximations::sin(theta);

@ -1 +1 @@
Subproject commit 12eab726d8e18d4f2850100b17faa683902ef15e
Subproject commit 806de731e97f01ffbd2a7555d6a7738a6687464d