Merge pull request #46 from jameshball/translate-effect

Add translate effect and other improvements
pull/170/head
James H Ball 2023-07-19 21:47:28 +01:00 zatwierdzone przez GitHub
commit 26535b7a69
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
8 zmienionych plików z 65 dodań i 102 usunięć

Wyświetl plik

@ -129,5 +129,6 @@ void MainComponent::resized() {
frequencyLabel.setBounds(bounds.removeFromTop(20)); frequencyLabel.setBounds(bounds.removeFromTop(20));
bounds.removeFromTop(padding); bounds.removeFromTop(padding);
visualiser.setBounds(bounds); auto minDim = juce::jmin(bounds.getWidth(), bounds.getHeight());
visualiser.setBounds(bounds.withSizeKeepingCentre(minDim, minDim));
} }

Wyświetl plik

@ -22,25 +22,9 @@ ObjComponent::ObjComponent(OscirenderAudioProcessor& p, OscirenderAudioProcessor
auto onRotationChange = [this]() { auto onRotationChange = [this]() {
juce::SpinLock::ScopedLockType lock(audioProcessor.parsersLock); juce::SpinLock::ScopedLockType lock(audioProcessor.parsersLock);
double x = fixedRotateX->getToggleState() ? 0 : rotateX.slider.getValue(); audioProcessor.rotateX->setValue(rotateX.slider.getValue());
double y = fixedRotateY->getToggleState() ? 0 : rotateY.slider.getValue(); audioProcessor.rotateY->setValue(rotateY.slider.getValue());
double z = fixedRotateZ->getToggleState() ? 0 : rotateZ.slider.getValue(); audioProcessor.rotateZ->setValue(rotateZ.slider.getValue());
audioProcessor.rotateX->setValue(x);
audioProcessor.rotateY->setValue(y);
audioProcessor.rotateZ->setValue(z);
if (fixedRotateX->getToggleState()) {
audioProcessor.currentRotateX->setValue(rotateX.slider.getValue());
audioProcessor.currentRotateX->apply();
}
if (fixedRotateY->getToggleState()) {
audioProcessor.currentRotateY->setValue(rotateY.slider.getValue());
audioProcessor.currentRotateY->apply();
}
if (fixedRotateZ->getToggleState()) {
audioProcessor.currentRotateZ->setValue(rotateZ.slider.getValue());
audioProcessor.currentRotateZ->apply();
}
audioProcessor.fixedRotateX = fixedRotateX->getToggleState(); audioProcessor.fixedRotateX = fixedRotateX->getToggleState();
audioProcessor.fixedRotateY = fixedRotateY->getToggleState(); audioProcessor.fixedRotateY = fixedRotateY->getToggleState();
@ -73,12 +57,14 @@ ObjComponent::ObjComponent(OscirenderAudioProcessor& p, OscirenderAudioProcessor
mouseRotate.setToggleState(false, juce::NotificationType::dontSendNotification); mouseRotate.setToggleState(false, juce::NotificationType::dontSendNotification);
juce::SpinLock::ScopedLockType lock(audioProcessor.parsersLock); juce::SpinLock::ScopedLockType lock(audioProcessor.parsersLock);
audioProcessor.currentRotateX->setValue(0); if (audioProcessor.getCurrentFileIndex() != -1) {
audioProcessor.currentRotateY->setValue(0); auto obj = audioProcessor.getCurrentFileParser()->getObject();
audioProcessor.currentRotateZ->setValue(0); if (obj != nullptr) {
audioProcessor.currentRotateX->apply(); obj->setCurrentRotationX(0);
audioProcessor.currentRotateY->apply(); obj->setCurrentRotationY(0);
audioProcessor.currentRotateZ->apply(); obj->setCurrentRotationZ(0);
}
}
}; };
auto doc = juce::XmlDocument::parse(BinaryData::fixed_rotate_svg); auto doc = juce::XmlDocument::parse(BinaryData::fixed_rotate_svg);

Wyświetl plik

@ -50,15 +50,22 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
)); ));
toggleableEffects.push_back(std::make_shared<Effect>( toggleableEffects.push_back(std::make_shared<Effect>(
std::make_shared<VectorCancellingEffect>(), std::make_shared<VectorCancellingEffect>(),
new EffectParameter("Vector cancelling", "vectorCancelling", 0.0, 0.0, 1.0) new EffectParameter("Vector Cancelling", "vectorCancelling", 0.0, 0.0, 1.0)
));
toggleableEffects.push_back(std::make_shared<Effect>(
std::make_shared<DistortEffect>(true),
new EffectParameter("Vertical shift", "verticalDistort", 0.0, 0.0, 1.0)
)); ));
toggleableEffects.push_back(std::make_shared<Effect>( toggleableEffects.push_back(std::make_shared<Effect>(
std::make_shared<DistortEffect>(false), std::make_shared<DistortEffect>(false),
new EffectParameter("Horizontal shift", "horizontalDistort", 0.0, 0.0, 1.0) new EffectParameter("Horizontal Distort", "horizontalDistort", 0.0, 0.0, 1.0)
));
toggleableEffects.push_back(std::make_shared<Effect>(
std::make_shared<DistortEffect>(true),
new EffectParameter("Vertical Distort", "verticalDistort", 0.0, 0.0, 1.0)
));
toggleableEffects.push_back(std::make_shared<Effect>(
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
input.x += values[0];
input.y += values[1];
return input;
}, std::vector<EffectParameter*>{new EffectParameter("Translate x", "translateX", 0.0, -1.0, 1.0), new EffectParameter("Translate y", "translateY", 0.0, -1.0, 1.0)}
)); ));
toggleableEffects.push_back(std::make_shared<Effect>( toggleableEffects.push_back(std::make_shared<Effect>(
std::make_shared<SmoothEffect>(), std::make_shared<SmoothEffect>(),
@ -103,19 +110,9 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
addParameter(parameter); addParameter(parameter);
} }
} }
hiddenEffects.push_back(currentRotateX);
hiddenEffects.push_back(currentRotateY);
hiddenEffects.push_back(currentRotateZ);
} }
OscirenderAudioProcessor::~OscirenderAudioProcessor() { OscirenderAudioProcessor::~OscirenderAudioProcessor() {}
for (auto effect : hiddenEffects) {
for (auto parameter : effect->parameters) {
delete parameter;
}
}
}
const juce::String OscirenderAudioProcessor::getName() const { const juce::String OscirenderAudioProcessor::getName() const {
return JucePlugin_Name; return JucePlugin_Name;

Wyświetl plik

@ -105,12 +105,21 @@ public:
return input; return input;
}, new EffectParameter("Focal length", "focalLength", 1.0, 0.0, 2.0) }, new EffectParameter("Focal length", "focalLength", 1.0, 0.0, 2.0)
); );
std::atomic<bool> fixedRotateX = false;
std::atomic<bool> fixedRotateY = false;
std::atomic<bool> fixedRotateZ = false;
std::shared_ptr<Effect> rotateX = std::make_shared<Effect>( std::shared_ptr<Effect> rotateX = std::make_shared<Effect>(
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) { [this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
if (getCurrentFileIndex() != -1) { if (getCurrentFileIndex() != -1) {
auto obj = getCurrentFileParser()->getObject(); auto obj = getCurrentFileParser()->getObject();
if (obj == nullptr) return input; if (obj == nullptr) return input;
obj->setBaseRotationX(values[0] * std::numbers::pi); auto rotation = values[0] * std::numbers::pi;
if (fixedRotateX) {
obj->setCurrentRotationX(rotation);
} else {
obj->setBaseRotationX(rotation);
}
} }
return input; return input;
}, new EffectParameter("Rotate x", "rotateX", 1.0, -1.0, 1.0) }, new EffectParameter("Rotate x", "rotateX", 1.0, -1.0, 1.0)
@ -120,7 +129,12 @@ public:
if (getCurrentFileIndex() != -1) { if (getCurrentFileIndex() != -1) {
auto obj = getCurrentFileParser()->getObject(); auto obj = getCurrentFileParser()->getObject();
if (obj == nullptr) return input; if (obj == nullptr) return input;
obj->setBaseRotationY(values[0] * std::numbers::pi); auto rotation = values[0] * std::numbers::pi;
if (fixedRotateY) {
obj->setCurrentRotationY(rotation);
} else {
obj->setBaseRotationY(rotation);
}
} }
return input; return input;
}, new EffectParameter("Rotate y", "rotateY", 1.0, -1.0, 1.0) }, new EffectParameter("Rotate y", "rotateY", 1.0, -1.0, 1.0)
@ -130,41 +144,16 @@ public:
if (getCurrentFileIndex() != -1) { if (getCurrentFileIndex() != -1) {
auto obj = getCurrentFileParser()->getObject(); auto obj = getCurrentFileParser()->getObject();
if (obj == nullptr) return input; if (obj == nullptr) return input;
obj->setBaseRotationZ(values[0] * std::numbers::pi); auto rotation = values[0] * std::numbers::pi;
if (fixedRotateZ) {
obj->setCurrentRotationZ(rotation);
} else {
obj->setBaseRotationZ(rotation);
}
} }
return input; return input;
}, new EffectParameter("Rotate z", "rotateZ", 0.0, -1.0, 1.0) }, new EffectParameter("Rotate z", "rotateZ", 0.0, -1.0, 1.0)
); );
std::shared_ptr<Effect> currentRotateX = std::make_shared<Effect>(
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
if (getCurrentFileIndex() != -1) {
auto obj = getCurrentFileParser()->getObject();
if (obj == nullptr) return input;
obj->setCurrentRotationX(values[0] * std::numbers::pi);
}
return input;
}, new EffectParameter("Current Rotate x", "currentRotateX", 0.0, 0.0, 1.0, 0.001, false)
);
std::shared_ptr<Effect> currentRotateY = std::make_shared<Effect>(
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
if (getCurrentFileIndex() != -1) {
auto obj = getCurrentFileParser()->getObject();
if (obj == nullptr) return input;
obj->setCurrentRotationY(values[0] * std::numbers::pi);
}
return input;
}, new EffectParameter("Current Rotate y", "currentRotateY", 0.0, 0.0, 1.0, 0.001, false)
);
std::shared_ptr<Effect> currentRotateZ = std::make_shared<Effect>(
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
if (getCurrentFileIndex() != -1) {
auto obj = getCurrentFileParser()->getObject();
if (obj == nullptr) return input;
obj->setCurrentRotationZ(values[0] * std::numbers::pi);
}
return input;
}, new EffectParameter("Current Rotate z", "currentRotateZ", 0.0, 0.0, 1.0, 0.001, false)
);
std::shared_ptr<Effect> rotateSpeed = std::make_shared<Effect>( std::shared_ptr<Effect> rotateSpeed = std::make_shared<Effect>(
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) { [this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {
if (getCurrentFileIndex() != -1) { if (getCurrentFileIndex() != -1) {
@ -175,9 +164,6 @@ public:
return input; return input;
}, new EffectParameter("Rotate speed", "rotateSpeed", 0.0, -1.0, 1.0) }, new EffectParameter("Rotate speed", "rotateSpeed", 0.0, -1.0, 1.0)
); );
std::atomic<bool> fixedRotateX = false;
std::atomic<bool> fixedRotateY = false;
std::atomic<bool> fixedRotateZ = false;
std::shared_ptr<DelayEffect> delayEffect = std::make_shared<DelayEffect>(); std::shared_ptr<DelayEffect> delayEffect = std::make_shared<DelayEffect>();
@ -227,9 +213,6 @@ private:
bool invalidateFrameBuffer = false; bool invalidateFrameBuffer = false;
std::vector<std::shared_ptr<Effect>> permanentEffects; std::vector<std::shared_ptr<Effect>> permanentEffects;
// any effects that are not added as a plugin parameter must be deleted manually
// as JUCE will not delete them upon destruction of the AudioProcessor
std::vector<std::shared_ptr<Effect>> hiddenEffects;
std::shared_ptr<Effect> traceMax = std::make_shared<Effect>( std::shared_ptr<Effect> traceMax = std::make_shared<Effect>(
[this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) { [this](int index, Vector2 input, const std::vector<double>& values, double sampleRate) {

Wyświetl plik

@ -259,7 +259,6 @@ public:
if (auto* rowComp = getComponentForRow (row)) if (auto* rowComp = getComponentForRow (row))
{ {
rowComp->setBounds (0, owner.getPositionForRow (row), w, owner.getRowHeight (row)); rowComp->setBounds (0, owner.getPositionForRow (row), w, owner.getRowHeight (row));
DBG (String (i) + " " + rowComp->getBounds().toString());
rowComp->update (row, owner.isRowSelected (row)); rowComp->update (row, owner.isRowSelected (row));
} }
} }

Wyświetl plik

@ -29,16 +29,12 @@ void VisualiserComponent::paint(juce::Graphics& g) {
g.fillAll(backgroundColour); g.fillAll(backgroundColour);
auto r = getLocalBounds().toFloat(); auto r = getLocalBounds().toFloat();
auto channelHeight = r.getHeight() / (float)numChannels; auto minDim = juce::jmin(r.getWidth(), r.getHeight());
g.setColour(waveformColour);
juce::SpinLock::ScopedLockType scope(lock); juce::SpinLock::ScopedLockType scope(lock);
if (buffer.size() > 0) { if (buffer.size() > 0) {
paintXY(g, r.removeFromRight(r.getHeight())); g.setColour(waveformColour);
paintXY(g, r.withSizeKeepingCentre(minDim, minDim));
for (int i = 0; i < numChannels; ++i) {
paintChannel(g, r.removeFromTop(channelHeight), i);
}
} }
} }
@ -77,17 +73,19 @@ void VisualiserComponent::paintChannel(juce::Graphics& g, juce::Rectangle<float>
} }
void VisualiserComponent::paintXY(juce::Graphics& g, juce::Rectangle<float> area) { void VisualiserComponent::paintXY(juce::Graphics& g, juce::Rectangle<float> area) {
juce::Path path; auto transform = juce::AffineTransform::fromTargetPoints(-1.0f, -1.0f, area.getX(), area.getBottom(), 1.0f, 1.0f, area.getRight(), area.getY(), 1.0f, -1.0f, area.getRight(), area.getBottom());
std::vector<juce::Line<float>> lines;
path.startNewSubPath(buffer[0], buffer[1]);
for (int i = 2; i < buffer.size(); i += 2) { for (int i = 2; i < buffer.size(); i += 2) {
path.lineTo(buffer[i + 0], buffer[i + 1]); lines.emplace_back(buffer[i - 2], buffer[i - 1], buffer[i], buffer[i + 1]);
} }
// apply affine transform to path to fit in area for (auto& line : lines) {
auto transform = juce::AffineTransform::fromTargetPoints(-1.0f, -1.0f, area.getX(), area.getBottom(), 1.0f, 1.0f, area.getRight(), area.getY(), 1.0f, -1.0f, area.getRight(), area.getBottom()); line.applyTransform(transform);
path.applyTransform(transform); float lengthScale = 1.0f / (line.getLength() + 1.0f);
double strength = 10;
g.strokePath(path, juce::PathStrokeType(1.0f)); lengthScale = std::log(strength * lengthScale + 1) / std::log(strength + 1);
g.setColour(waveformColour.withAlpha(lengthScale));
g.drawLine(line, 1.0f);
}
} }

Wyświetl plik

@ -23,8 +23,8 @@ private:
int numChannels = 2; int numChannels = 2;
juce::Colour backgroundColour, waveformColour; juce::Colour backgroundColour, waveformColour;
OscirenderAudioProcessor& audioProcessor; OscirenderAudioProcessor& audioProcessor;
std::shared_ptr<BufferConsumer> consumer = std::make_shared<BufferConsumer>(2048); std::shared_ptr<BufferConsumer> consumer = std::make_shared<BufferConsumer>(4096);
int precision = 2; int precision = 4;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VisualiserComponent) JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VisualiserComponent)
}; };

Wyświetl plik

@ -45,7 +45,6 @@ Vector2 LuaParser::draw() {
for (int i = 0; i < variableNames.size(); i++) { for (int i = 0; i < variableNames.size(); i++) {
lua_pushnumber(L, variables[i]); lua_pushnumber(L, variables[i]);
lua_setglobal(L, variableNames[i].toUTF8()); lua_setglobal(L, variableNames[i].toUTF8());
DBG("set " << variableNames[i] << " to " << variables[i]);
} }
variableNames.clear(); variableNames.clear();
variables.clear(); variables.clear();