diff --git a/Source/MainComponent.cpp b/Source/MainComponent.cpp index 1ae528b..6a56306 100644 --- a/Source/MainComponent.cpp +++ b/Source/MainComponent.cpp @@ -129,5 +129,6 @@ void MainComponent::resized() { frequencyLabel.setBounds(bounds.removeFromTop(20)); bounds.removeFromTop(padding); - visualiser.setBounds(bounds); + auto minDim = juce::jmin(bounds.getWidth(), bounds.getHeight()); + visualiser.setBounds(bounds.withSizeKeepingCentre(minDim, minDim)); } diff --git a/Source/ObjComponent.cpp b/Source/ObjComponent.cpp index c852bf5..162e403 100644 --- a/Source/ObjComponent.cpp +++ b/Source/ObjComponent.cpp @@ -22,25 +22,9 @@ ObjComponent::ObjComponent(OscirenderAudioProcessor& p, OscirenderAudioProcessor auto onRotationChange = [this]() { juce::SpinLock::ScopedLockType lock(audioProcessor.parsersLock); - double x = fixedRotateX->getToggleState() ? 0 : rotateX.slider.getValue(); - double y = fixedRotateY->getToggleState() ? 0 : rotateY.slider.getValue(); - double z = fixedRotateZ->getToggleState() ? 0 : 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.rotateX->setValue(rotateX.slider.getValue()); + audioProcessor.rotateY->setValue(rotateY.slider.getValue()); + audioProcessor.rotateZ->setValue(rotateZ.slider.getValue()); audioProcessor.fixedRotateX = fixedRotateX->getToggleState(); audioProcessor.fixedRotateY = fixedRotateY->getToggleState(); @@ -73,12 +57,14 @@ ObjComponent::ObjComponent(OscirenderAudioProcessor& p, OscirenderAudioProcessor mouseRotate.setToggleState(false, juce::NotificationType::dontSendNotification); juce::SpinLock::ScopedLockType lock(audioProcessor.parsersLock); - audioProcessor.currentRotateX->setValue(0); - audioProcessor.currentRotateY->setValue(0); - audioProcessor.currentRotateZ->setValue(0); - audioProcessor.currentRotateX->apply(); - audioProcessor.currentRotateY->apply(); - audioProcessor.currentRotateZ->apply(); + if (audioProcessor.getCurrentFileIndex() != -1) { + auto obj = audioProcessor.getCurrentFileParser()->getObject(); + if (obj != nullptr) { + obj->setCurrentRotationX(0); + obj->setCurrentRotationY(0); + obj->setCurrentRotationZ(0); + } + } }; auto doc = juce::XmlDocument::parse(BinaryData::fixed_rotate_svg); diff --git a/Source/PluginProcessor.cpp b/Source/PluginProcessor.cpp index f8512b9..ec31daa 100644 --- a/Source/PluginProcessor.cpp +++ b/Source/PluginProcessor.cpp @@ -50,15 +50,22 @@ OscirenderAudioProcessor::OscirenderAudioProcessor() )); toggleableEffects.push_back(std::make_shared( std::make_shared(), - new EffectParameter("Vector cancelling", "vectorCancelling", 0.0, 0.0, 1.0) - )); - toggleableEffects.push_back(std::make_shared( - std::make_shared(true), - new EffectParameter("Vertical shift", "verticalDistort", 0.0, 0.0, 1.0) + new EffectParameter("Vector Cancelling", "vectorCancelling", 0.0, 0.0, 1.0) )); toggleableEffects.push_back(std::make_shared( std::make_shared(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( + std::make_shared(true), + new EffectParameter("Vertical Distort", "verticalDistort", 0.0, 0.0, 1.0) + )); + toggleableEffects.push_back(std::make_shared( + [this](int index, Vector2 input, const std::vector& values, double sampleRate) { + input.x += values[0]; + input.y += values[1]; + return input; + }, std::vector{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( std::make_shared(), @@ -103,19 +110,9 @@ OscirenderAudioProcessor::OscirenderAudioProcessor() addParameter(parameter); } } - - hiddenEffects.push_back(currentRotateX); - hiddenEffects.push_back(currentRotateY); - hiddenEffects.push_back(currentRotateZ); } -OscirenderAudioProcessor::~OscirenderAudioProcessor() { - for (auto effect : hiddenEffects) { - for (auto parameter : effect->parameters) { - delete parameter; - } - } -} +OscirenderAudioProcessor::~OscirenderAudioProcessor() {} const juce::String OscirenderAudioProcessor::getName() const { return JucePlugin_Name; diff --git a/Source/PluginProcessor.h b/Source/PluginProcessor.h index 0de71b7..a995c90 100644 --- a/Source/PluginProcessor.h +++ b/Source/PluginProcessor.h @@ -105,12 +105,21 @@ public: return input; }, new EffectParameter("Focal length", "focalLength", 1.0, 0.0, 2.0) ); + + std::atomic fixedRotateX = false; + std::atomic fixedRotateY = false; + std::atomic fixedRotateZ = false; std::shared_ptr rotateX = std::make_shared( [this](int index, Vector2 input, const std::vector& values, double sampleRate) { if (getCurrentFileIndex() != -1) { auto obj = getCurrentFileParser()->getObject(); 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; }, new EffectParameter("Rotate x", "rotateX", 1.0, -1.0, 1.0) @@ -120,7 +129,12 @@ public: if (getCurrentFileIndex() != -1) { auto obj = getCurrentFileParser()->getObject(); 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; }, new EffectParameter("Rotate y", "rotateY", 1.0, -1.0, 1.0) @@ -130,41 +144,16 @@ public: if (getCurrentFileIndex() != -1) { auto obj = getCurrentFileParser()->getObject(); 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; }, new EffectParameter("Rotate z", "rotateZ", 0.0, -1.0, 1.0) ); - std::shared_ptr currentRotateX = std::make_shared( - [this](int index, Vector2 input, const std::vector& 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 currentRotateY = std::make_shared( - [this](int index, Vector2 input, const std::vector& 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 currentRotateZ = std::make_shared( - [this](int index, Vector2 input, const std::vector& 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 rotateSpeed = std::make_shared( [this](int index, Vector2 input, const std::vector& values, double sampleRate) { if (getCurrentFileIndex() != -1) { @@ -175,9 +164,6 @@ public: return input; }, new EffectParameter("Rotate speed", "rotateSpeed", 0.0, -1.0, 1.0) ); - std::atomic fixedRotateX = false; - std::atomic fixedRotateY = false; - std::atomic fixedRotateZ = false; std::shared_ptr delayEffect = std::make_shared(); @@ -227,9 +213,6 @@ private: bool invalidateFrameBuffer = false; std::vector> 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> hiddenEffects; std::shared_ptr traceMax = std::make_shared( [this](int index, Vector2 input, const std::vector& values, double sampleRate) { diff --git a/Source/components/VListBox.cpp b/Source/components/VListBox.cpp index 855bee5..c5242f2 100644 --- a/Source/components/VListBox.cpp +++ b/Source/components/VListBox.cpp @@ -259,7 +259,6 @@ public: if (auto* rowComp = getComponentForRow (row)) { rowComp->setBounds (0, owner.getPositionForRow (row), w, owner.getRowHeight (row)); - DBG (String (i) + " " + rowComp->getBounds().toString()); rowComp->update (row, owner.isRowSelected (row)); } } diff --git a/Source/components/VisualiserComponent.cpp b/Source/components/VisualiserComponent.cpp index fb3734c..4b6d02f 100644 --- a/Source/components/VisualiserComponent.cpp +++ b/Source/components/VisualiserComponent.cpp @@ -29,16 +29,12 @@ void VisualiserComponent::paint(juce::Graphics& g) { g.fillAll(backgroundColour); 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); if (buffer.size() > 0) { - paintXY(g, r.removeFromRight(r.getHeight())); - - for (int i = 0; i < numChannels; ++i) { - paintChannel(g, r.removeFromTop(channelHeight), i); - } + g.setColour(waveformColour); + paintXY(g, r.withSizeKeepingCentre(minDim, minDim)); } } @@ -77,17 +73,19 @@ void VisualiserComponent::paintChannel(juce::Graphics& g, juce::Rectangle } void VisualiserComponent::paintXY(juce::Graphics& g, juce::Rectangle area) { - juce::Path path; - - path.startNewSubPath(buffer[0], buffer[1]); + 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> lines; 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 - 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()); - path.applyTransform(transform); - - g.strokePath(path, juce::PathStrokeType(1.0f)); + for (auto& line : lines) { + line.applyTransform(transform); + float lengthScale = 1.0f / (line.getLength() + 1.0f); + double strength = 10; + lengthScale = std::log(strength * lengthScale + 1) / std::log(strength + 1); + g.setColour(waveformColour.withAlpha(lengthScale)); + g.drawLine(line, 1.0f); + } } diff --git a/Source/components/VisualiserComponent.h b/Source/components/VisualiserComponent.h index 248770e..eca3469 100644 --- a/Source/components/VisualiserComponent.h +++ b/Source/components/VisualiserComponent.h @@ -23,8 +23,8 @@ private: int numChannels = 2; juce::Colour backgroundColour, waveformColour; OscirenderAudioProcessor& audioProcessor; - std::shared_ptr consumer = std::make_shared(2048); - int precision = 2; + std::shared_ptr consumer = std::make_shared(4096); + int precision = 4; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VisualiserComponent) }; \ No newline at end of file diff --git a/Source/lua/LuaParser.cpp b/Source/lua/LuaParser.cpp index e555437..9f66dde 100644 --- a/Source/lua/LuaParser.cpp +++ b/Source/lua/LuaParser.cpp @@ -45,7 +45,6 @@ Vector2 LuaParser::draw() { for (int i = 0; i < variableNames.size(); i++) { lua_pushnumber(L, variables[i]); lua_setglobal(L, variableNames[i].toUTF8()); - DBG("set " << variableNames[i] << " to " << variables[i]); } variableNames.clear(); variables.clear();