kopia lustrzana https://github.com/jameshball/osci-render
Refactor software oscilloscope and remove legacy visualiser
rodzic
ee7e040fa6
commit
7f12ee9490
|
@ -4,7 +4,7 @@
|
|||
#include "PluginProcessor.h"
|
||||
#include "parser/FileParser.h"
|
||||
#include "parser/FrameProducer.h"
|
||||
#include "components/VisualiserComponent.h"
|
||||
#include "visualiser/VisualiserComponent.h"
|
||||
#include "audio/PitchDetector.h"
|
||||
#include "UGen/ugen_JuceEnvelopeComponent.h"
|
||||
#include "components/SvgButton.h"
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "LookAndFeel.h"
|
||||
#include "components/ErrorCodeEditorComponent.h"
|
||||
#include "components/LuaConsole.h"
|
||||
#include "components/VisualiserSettings.h"
|
||||
#include "visualiser/VisualiserSettings.h"
|
||||
|
||||
class OscirenderAudioProcessorEditor : public juce::AudioProcessorEditor, private juce::CodeDocument::Listener, public juce::AsyncUpdater, public juce::ChangeListener {
|
||||
public:
|
||||
|
@ -54,7 +54,7 @@ public:
|
|||
|
||||
VisualiserSettings visualiserSettings = VisualiserSettings(audioProcessor.visualiserParameters);
|
||||
SettingsWindow visualiserSettingsWindow = SettingsWindow("Visualiser Settings");
|
||||
VisualiserComponent visualiser{audioProcessor, audioProcessor.threadManager, visualiserSettings, nullptr, audioProcessor.visualiserParameters.legacyVisualiserEnabled->getBoolValue()};
|
||||
VisualiserComponent visualiser{audioProcessor.threadManager, visualiserSettings, nullptr};
|
||||
|
||||
SettingsComponent settings{audioProcessor, *this};
|
||||
|
||||
|
|
|
@ -182,7 +182,6 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
|
|||
booleanParameters.push_back(visualiserParameters.graticuleEnabled);
|
||||
booleanParameters.push_back(visualiserParameters.smudgesEnabled);
|
||||
booleanParameters.push_back(visualiserParameters.upsamplingEnabled);
|
||||
booleanParameters.push_back(visualiserParameters.legacyVisualiserEnabled);
|
||||
booleanParameters.push_back(visualiserParameters.visualiserFullScreen);
|
||||
|
||||
for (auto parameter : booleanParameters) {
|
||||
|
@ -824,11 +823,6 @@ void OscirenderAudioProcessor::getStateInformation(juce::MemoryBlock& destData)
|
|||
fileXml->addTextElement(base64);
|
||||
}
|
||||
xml->setAttribute("currentFile", currentFile);
|
||||
|
||||
auto visualiserXml = xml->createNewChildElement("visualiser");
|
||||
visualiserXml->setAttribute("roughness", visualiserParameters.roughness);
|
||||
visualiserXml->setAttribute("intensity", visualiserParameters.intensity);
|
||||
|
||||
copyXmlToBinary(*xml, destData);
|
||||
}
|
||||
|
||||
|
@ -942,12 +936,6 @@ void OscirenderAudioProcessor::setStateInformation(const void* data, int sizeInB
|
|||
}
|
||||
}
|
||||
changeCurrentFile(xml->getIntAttribute("currentFile", -1));
|
||||
|
||||
auto visualiserXml = xml->getChildByName("visualiser");
|
||||
if (visualiserXml != nullptr) {
|
||||
visualiserParameters.roughness = visualiserXml->getIntAttribute("roughness");
|
||||
visualiserParameters.intensity = visualiserXml->getDoubleAttribute("intensity");
|
||||
}
|
||||
|
||||
broadcaster.sendChangeMessage();
|
||||
prevMidiEnabled = !midiEnabled->getBoolValue();
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "shape/Shape.h"
|
||||
#include "concurrency/AudioBackgroundThread.h"
|
||||
#include "concurrency/AudioBackgroundThreadManager.h"
|
||||
#include "components/VisualiserSettings.h"
|
||||
#include "visualiser/VisualiserSettings.h"
|
||||
#include "audio/Effect.h"
|
||||
#include "audio/ShapeSound.h"
|
||||
#include "audio/ShapeVoice.h"
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
#include <JuceHeader.h>
|
||||
#include "SosciPluginProcessor.h"
|
||||
#include "components/VisualiserComponent.h"
|
||||
#include "visualiser/VisualiserComponent.h"
|
||||
#include "LookAndFeel.h"
|
||||
#include "components/VisualiserSettings.h"
|
||||
#include "visualiser/VisualiserSettings.h"
|
||||
#include "components/SosciMainMenuBarModel.h"
|
||||
#include "components/SvgButton.h"
|
||||
|
||||
|
@ -31,7 +31,7 @@ public:
|
|||
|
||||
VisualiserSettings visualiserSettings = VisualiserSettings(audioProcessor.parameters, 3);
|
||||
SettingsWindow visualiserSettingsWindow = SettingsWindow("Visualiser Settings");
|
||||
VisualiserComponent visualiser{audioProcessor, audioProcessor.threadManager, visualiserSettings, nullptr, false, true};
|
||||
VisualiserComponent visualiser{audioProcessor.threadManager, visualiserSettings, nullptr, true};
|
||||
|
||||
std::unique_ptr<juce::FileChooser> chooser;
|
||||
SosciMainMenuBarModel menuBarModel{*this, audioProcessor};
|
||||
|
|
|
@ -39,7 +39,6 @@ SosciAudioProcessor::SosciAudioProcessor()
|
|||
booleanParameters.push_back(parameters.graticuleEnabled);
|
||||
booleanParameters.push_back(parameters.smudgesEnabled);
|
||||
booleanParameters.push_back(parameters.upsamplingEnabled);
|
||||
booleanParameters.push_back(parameters.legacyVisualiserEnabled);
|
||||
booleanParameters.push_back(parameters.visualiserFullScreen);
|
||||
|
||||
for (auto parameter : booleanParameters) {
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
#include "concurrency/AudioBackgroundThread.h"
|
||||
#include "concurrency/AudioBackgroundThreadManager.h"
|
||||
#include "audio/SampleRateManager.h"
|
||||
#include "components/VisualiserSettings.h"
|
||||
#include "visualiser/VisualiserSettings.h"
|
||||
#include "audio/Effect.h"
|
||||
|
||||
//==============================================================================
|
||||
|
|
|
@ -2,26 +2,15 @@
|
|||
#include "../PluginEditor.h"
|
||||
#include "../PluginProcessor.h"
|
||||
|
||||
MainMenuBarModel::MainMenuBarModel(OscirenderAudioProcessor& p, OscirenderAudioProcessorEditor& editor) : audioProcessor(p), editor(editor) {
|
||||
audioProcessor.visualiserParameters.legacyVisualiserEnabled->addListener(this);
|
||||
}
|
||||
MainMenuBarModel::MainMenuBarModel(OscirenderAudioProcessor& p, OscirenderAudioProcessorEditor& editor) : audioProcessor(p), editor(editor) {}
|
||||
|
||||
MainMenuBarModel::~MainMenuBarModel() {
|
||||
audioProcessor.visualiserParameters.legacyVisualiserEnabled->removeListener(this);
|
||||
}
|
||||
|
||||
void MainMenuBarModel::parameterValueChanged(int parameterIndex, float legacyVisualiserEnabled) {
|
||||
editor.visualiser.setVisualiserType(legacyVisualiserEnabled >= 0.5f);
|
||||
menuItemsChanged();
|
||||
}
|
||||
|
||||
void MainMenuBarModel::parameterGestureChanged(int parameterIndex, bool gestureIsStarting) {}
|
||||
MainMenuBarModel::~MainMenuBarModel() {}
|
||||
|
||||
juce::StringArray MainMenuBarModel::getMenuBarNames() {
|
||||
if (editor.processor.wrapperType == juce::AudioProcessor::WrapperType::wrapperType_Standalone) {
|
||||
return juce::StringArray("File", "View", "About", "Audio");
|
||||
return juce::StringArray("File", "About", "Audio");
|
||||
} else {
|
||||
return juce::StringArray("File", "View", "About");
|
||||
return juce::StringArray("File", "About");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,10 +25,8 @@ juce::PopupMenu MainMenuBarModel::getMenuForIndex(int topLevelMenuIndex, const j
|
|||
menu.addItem(4, "Create New Project");
|
||||
}
|
||||
} else if (topLevelMenuIndex == 1) {
|
||||
menu.addItem(1, "Use Legacy Visualiser", true, audioProcessor.visualiserParameters.legacyVisualiserEnabled->getBoolValue());
|
||||
} else if (topLevelMenuIndex == 2) {
|
||||
menu.addItem(1, "About osci-render");
|
||||
} else if (topLevelMenuIndex == 3) {
|
||||
} else if (topLevelMenuIndex == 2) {
|
||||
menu.addItem(1, "Settings");
|
||||
}
|
||||
|
||||
|
@ -67,10 +54,6 @@ void MainMenuBarModel::menuItemSelected(int menuItemID, int topLevelMenuIndex) {
|
|||
}
|
||||
break;
|
||||
case 1: {
|
||||
audioProcessor.visualiserParameters.legacyVisualiserEnabled->setBoolValueNotifyingHost(!audioProcessor.visualiserParameters.legacyVisualiserEnabled->getBoolValue());
|
||||
menuItemsChanged();
|
||||
} break;
|
||||
case 2: {
|
||||
juce::DialogWindow::LaunchOptions options;
|
||||
AboutComponent* about = new AboutComponent(BinaryData::logo_png, BinaryData::logo_pngSize,
|
||||
juce::String(ProjectInfo::projectName) + " by " + ProjectInfo::companyName + "\n"
|
||||
|
@ -96,7 +79,7 @@ void MainMenuBarModel::menuItemSelected(int menuItemID, int topLevelMenuIndex) {
|
|||
|
||||
juce::DialogWindow* dw = options.launchAsync();
|
||||
} break;
|
||||
case 3:
|
||||
case 2:
|
||||
editor.openAudioSettings();
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
class OscirenderAudioProcessorEditor;
|
||||
class OscirenderAudioProcessor;
|
||||
class MainMenuBarModel : public juce::MenuBarModel, public juce::AudioProcessorParameter::Listener {
|
||||
class MainMenuBarModel : public juce::MenuBarModel {
|
||||
public:
|
||||
MainMenuBarModel(OscirenderAudioProcessor& p, OscirenderAudioProcessorEditor& editor);
|
||||
~MainMenuBarModel();
|
||||
|
@ -14,8 +14,6 @@ public:
|
|||
juce::PopupMenu getMenuForIndex(int topLevelMenuIndex, const juce::String& menuName) override;
|
||||
void menuItemSelected(int menuItemID, int topLevelMenuIndex) override;
|
||||
void menuBarActivated(bool isActive);
|
||||
void parameterValueChanged(int parameterIndex, float newValue) override;
|
||||
void parameterGestureChanged(int parameterIndex, bool gestureIsStarting) override;
|
||||
|
||||
private:
|
||||
OscirenderAudioProcessor& audioProcessor;
|
||||
|
|
|
@ -1,285 +0,0 @@
|
|||
#include "../LookAndFeel.h"
|
||||
#include "VisualiserComponent.h"
|
||||
|
||||
VisualiserComponent::VisualiserComponent(SampleRateManager& sampleRateManager, AudioBackgroundThreadManager& threadManager, VisualiserSettings& settings, VisualiserComponent* parent, bool useOldVisualiser, bool visualiserOnly) : settings(settings), backgroundColour(juce::Colours::black), waveformColour(juce::Colour(0xff00ff00)), sampleRateManager(sampleRateManager), threadManager(threadManager), oldVisualiser(useOldVisualiser), visualiserOnly(visualiserOnly), AudioBackgroundThread("VisualiserComponent", threadManager), parent(parent) {
|
||||
addChildComponent(openGLVisualiser);
|
||||
setVisualiserType(oldVisualiser);
|
||||
startTimerHz(60);
|
||||
setShouldBeRunning(true);
|
||||
|
||||
addAndMakeVisible(record);
|
||||
record.setPulseAnimation(true);
|
||||
record.onClick = [this] {
|
||||
toggleRecording();
|
||||
stopwatch.stop();
|
||||
stopwatch.reset();
|
||||
if (record.getToggleState()) {
|
||||
stopwatch.start();
|
||||
}
|
||||
resized();
|
||||
};
|
||||
|
||||
addAndMakeVisible(stopwatch);
|
||||
|
||||
setMouseCursor(juce::MouseCursor::PointingHandCursor);
|
||||
setWantsKeyboardFocus(true);
|
||||
|
||||
roughness.textBox.setValue(settings.parameters.roughness);
|
||||
roughness.textBox.onValueChange = [this]() {
|
||||
this->settings.parameters.roughness = (int) roughness.textBox.getValue();
|
||||
};
|
||||
intensity.textBox.setValue(settings.parameters.intensity);
|
||||
intensity.textBox.onValueChange = [this]() {
|
||||
this->settings.parameters.intensity = intensity.textBox.getValue();
|
||||
};
|
||||
|
||||
if (parent == nullptr && !visualiserOnly) {
|
||||
addAndMakeVisible(fullScreenButton);
|
||||
}
|
||||
if (child == nullptr && parent == nullptr && !visualiserOnly) {
|
||||
addAndMakeVisible(popOutButton);
|
||||
}
|
||||
addAndMakeVisible(settingsButton);
|
||||
|
||||
fullScreenButton.onClick = [this]() {
|
||||
enableFullScreen();
|
||||
};
|
||||
|
||||
settingsButton.onClick = [this]() {
|
||||
if (oldVisualiser) {
|
||||
juce::PopupMenu menu;
|
||||
|
||||
menu.addCustomItem(1, roughness, 160, 40, false);
|
||||
menu.addCustomItem(1, intensity, 160, 40, false);
|
||||
|
||||
menu.showMenuAsync(juce::PopupMenu::Options(), [this](int result) {});
|
||||
} else if (openSettings != nullptr) {
|
||||
openSettings();
|
||||
}
|
||||
};
|
||||
|
||||
popOutButton.onClick = [this]() {
|
||||
popoutWindow();
|
||||
};
|
||||
|
||||
setFullScreen(false);
|
||||
}
|
||||
|
||||
VisualiserComponent::~VisualiserComponent() {
|
||||
masterReference.clear();
|
||||
}
|
||||
|
||||
void VisualiserComponent::setFullScreenCallback(std::function<void(FullScreenMode)> callback) {
|
||||
fullScreenCallback = callback;
|
||||
}
|
||||
|
||||
void VisualiserComponent::enableFullScreen() {
|
||||
if (fullScreenCallback) {
|
||||
fullScreenCallback(FullScreenMode::TOGGLE);
|
||||
}
|
||||
grabKeyboardFocus();
|
||||
}
|
||||
|
||||
void VisualiserComponent::mouseDoubleClick(const juce::MouseEvent& event) {
|
||||
enableFullScreen();
|
||||
}
|
||||
|
||||
void VisualiserComponent::setBuffer(const std::vector<OsciPoint>& newBuffer) {
|
||||
juce::CriticalSection::ScopedLockType scope(lock);
|
||||
if (!oldVisualiser) {
|
||||
openGLVisualiser.updateBuffer(newBuffer);
|
||||
return;
|
||||
}
|
||||
buffer.clear();
|
||||
int stride = oldVisualiser ? roughness.textBox.getValue() : 1;
|
||||
for (int i = 0; i < newBuffer.size(); i += stride) {
|
||||
buffer.push_back(newBuffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void VisualiserComponent::setColours(juce::Colour bk, juce::Colour fg) {
|
||||
backgroundColour = bk;
|
||||
waveformColour = fg;
|
||||
}
|
||||
|
||||
void VisualiserComponent::paint(juce::Graphics& g) {
|
||||
g.fillAll(Colours::veryDark);
|
||||
if (oldVisualiser) {
|
||||
g.setColour(backgroundColour);
|
||||
g.fillRoundedRectangle(getLocalBounds().toFloat(), OscirenderLookAndFeel::RECT_RADIUS);
|
||||
|
||||
auto r = getLocalBounds().toFloat();
|
||||
r.removeFromBottom(25);
|
||||
auto minDim = juce::jmin(r.getWidth(), r.getHeight());
|
||||
|
||||
{
|
||||
juce::CriticalSection::ScopedLockType scope(lock);
|
||||
if (buffer.size() > 0) {
|
||||
g.setColour(waveformColour);
|
||||
paintXY(g, r.withSizeKeepingCentre(minDim, minDim));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!active) {
|
||||
// add translucent layer
|
||||
g.setColour(juce::Colours::black.withAlpha(0.5f));
|
||||
g.fillRoundedRectangle(r, OscirenderLookAndFeel::RECT_RADIUS);
|
||||
|
||||
// add text
|
||||
g.setColour(juce::Colours::white);
|
||||
g.setFont(14.0f);
|
||||
auto text = child != nullptr ? "Open in separate window" : "Paused";
|
||||
g.drawFittedText(text, r.toNearestInt(), juce::Justification::centred, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VisualiserComponent::timerCallback() {
|
||||
if (oldVisualiser) {
|
||||
repaint();
|
||||
}
|
||||
}
|
||||
|
||||
void VisualiserComponent::runTask(const std::vector<OsciPoint>& points) {
|
||||
setBuffer(points);
|
||||
}
|
||||
|
||||
int VisualiserComponent::prepareTask(double sampleRate, int bufferSize) {
|
||||
return sampleRate * BUFFER_LENGTH_SECS;
|
||||
}
|
||||
|
||||
void VisualiserComponent::setPaused(bool paused) {
|
||||
openGLVisualiser.setPaused(paused);
|
||||
active = !paused;
|
||||
if (active) {
|
||||
startTimerHz(60);
|
||||
} else {
|
||||
stopTimer();
|
||||
}
|
||||
setShouldBeRunning(active);
|
||||
repaint();
|
||||
}
|
||||
|
||||
void VisualiserComponent::mouseDown(const juce::MouseEvent& event) {
|
||||
if (event.mods.isLeftButtonDown() && child == nullptr) {
|
||||
setPaused(active);
|
||||
}
|
||||
}
|
||||
|
||||
bool VisualiserComponent::keyPressed(const juce::KeyPress& key) {
|
||||
if (key.isKeyCode(juce::KeyPress::escapeKey)) {
|
||||
if (fullScreenCallback) {
|
||||
fullScreenCallback(FullScreenMode::MAIN_COMPONENT);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void VisualiserComponent::setFullScreen(bool fullScreen) {}
|
||||
|
||||
void VisualiserComponent::setVisualiserType(bool oldVisualiser) {
|
||||
this->oldVisualiser = oldVisualiser;
|
||||
if (child != nullptr) {
|
||||
child->setVisualiserType(oldVisualiser);
|
||||
}
|
||||
if (oldVisualiser) {
|
||||
if (closeSettings != nullptr) {
|
||||
closeSettings();
|
||||
}
|
||||
}
|
||||
openGLVisualiser.setVisible(!oldVisualiser);
|
||||
resized();
|
||||
repaint();
|
||||
}
|
||||
|
||||
void VisualiserComponent::paintXY(juce::Graphics& g, juce::Rectangle<float> 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());
|
||||
std::vector<juce::Line<float>> lines;
|
||||
|
||||
for (int i = 2; i < buffer.size(); i++) {
|
||||
lines.emplace_back(buffer[i - 1].x, buffer[i - 1].y, buffer[i].x, buffer[i].y);
|
||||
}
|
||||
|
||||
double strength = 15;
|
||||
double widthDivisor = 160;
|
||||
double lengthIntensityScale = 700;
|
||||
juce::Colour waveColor = waveformColour;
|
||||
|
||||
for (auto& line : lines) {
|
||||
double thickness = area.getWidth() / widthDivisor;
|
||||
float normalisedLength = line.getLength() * (sampleRate / DEFAULT_SAMPLE_RATE) / roughness.textBox.getValue();
|
||||
line.applyTransform(transform);
|
||||
double beamIntensity = intensity.textBox.getValue();
|
||||
double lengthScale = (lengthIntensityScale * 0.5 + lengthIntensityScale * (1 - beamIntensity)) * (normalisedLength + 0.001);
|
||||
double lengthScaleLog = std::log(strength * (1 / lengthScale) + 1) / std::log(strength + 1);
|
||||
g.setColour(waveColor.withAlpha((float) std::max(0.0, std::min(lengthScaleLog * beamIntensity, 1.0))).withSaturation(lengthScale / 4));
|
||||
|
||||
if (normalisedLength < 0.00001) {
|
||||
g.fillEllipse(line.getStartX(), line.getStartY(), thickness, thickness);
|
||||
} else {
|
||||
g.drawLine(line, thickness);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VisualiserComponent::toggleRecording() {
|
||||
|
||||
}
|
||||
|
||||
void VisualiserComponent::haltRecording() {
|
||||
record.setToggleState(false, juce::NotificationType::dontSendNotification);
|
||||
}
|
||||
|
||||
void VisualiserComponent::resized() {
|
||||
auto area = getLocalBounds();
|
||||
juce::Rectangle<int> topRow;
|
||||
if (visualiserOnly) {
|
||||
topRow = area.removeFromTop(25);
|
||||
} else {
|
||||
topRow = area.removeFromBottom(25);
|
||||
}
|
||||
if (parent == nullptr && !visualiserOnly) {
|
||||
fullScreenButton.setBounds(topRow.removeFromRight(30));
|
||||
}
|
||||
if (child == nullptr && parent == nullptr && !visualiserOnly) {
|
||||
popOutButton.setBounds(topRow.removeFromRight(30));
|
||||
}
|
||||
settingsButton.setBounds(topRow.removeFromRight(30));
|
||||
record.setBounds(topRow.removeFromRight(25));
|
||||
if (record.getToggleState()) {
|
||||
stopwatch.setVisible(true);
|
||||
stopwatch.setBounds(topRow.removeFromRight(100));
|
||||
} else {
|
||||
stopwatch.setVisible(false);
|
||||
}
|
||||
if (!oldVisualiser) {
|
||||
openGLVisualiser.setBounds(area);
|
||||
}
|
||||
}
|
||||
|
||||
void VisualiserComponent::popoutWindow() {
|
||||
haltRecording();
|
||||
auto visualiser = new VisualiserComponent(sampleRateManager, threadManager, settings, this, oldVisualiser);
|
||||
visualiser->settings.setLookAndFeel(&getLookAndFeel());
|
||||
visualiser->openSettings = openSettings;
|
||||
visualiser->closeSettings = closeSettings;
|
||||
visualiser->recordingHalted = recordingHalted;
|
||||
child = visualiser;
|
||||
childUpdated();
|
||||
visualiser->setSize(300, 325);
|
||||
popout = std::make_unique<VisualiserWindow>("Software Oscilloscope", this);
|
||||
popout->setContentOwned(visualiser, true);
|
||||
popout->setUsingNativeTitleBar(true);
|
||||
popout->setResizable(true, false);
|
||||
popout->setVisible(true);
|
||||
popout->centreWithSize(300, 325);
|
||||
setPaused(true);
|
||||
resized();
|
||||
}
|
||||
|
||||
void VisualiserComponent::childUpdated() {
|
||||
popOutButton.setVisible(child == nullptr);
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <JuceHeader.h>
|
||||
#include "../LookAndFeel.h"
|
||||
#include "../concurrency/AudioBackgroundThread.h"
|
||||
#include "../audio/SampleRateManager.h"
|
||||
#include "../components/LabelledTextBox.h"
|
||||
#include "../components/SvgButton.h"
|
||||
#include "VisualiserSettings.h"
|
||||
#include "VisualiserOpenGLComponent.h"
|
||||
#include "../components/StopwatchComponent.h"
|
||||
|
||||
enum class FullScreenMode {
|
||||
TOGGLE,
|
||||
FULL_SCREEN,
|
||||
MAIN_COMPONENT,
|
||||
};
|
||||
|
||||
class VisualiserWindow;
|
||||
class VisualiserComponent : public juce::Component, public juce::Timer, public AudioBackgroundThread, public juce::MouseListener, public juce::SettableTooltipClient {
|
||||
public:
|
||||
VisualiserComponent(SampleRateManager& sampleRateManager, AudioBackgroundThreadManager& threadManager, VisualiserSettings& settings, VisualiserComponent* parent = nullptr, bool useOldVisualiser = false, bool visualiserOnly = false);
|
||||
~VisualiserComponent() override;
|
||||
|
||||
std::function<void()> openSettings;
|
||||
std::function<void()> closeSettings;
|
||||
|
||||
void enableFullScreen();
|
||||
void setFullScreenCallback(std::function<void(FullScreenMode)> callback);
|
||||
void mouseDoubleClick(const juce::MouseEvent& event) override;
|
||||
void setBuffer(const std::vector<OsciPoint>& buffer);
|
||||
void setColours(juce::Colour backgroundColour, juce::Colour waveformColour);
|
||||
void paintXY(juce::Graphics&, juce::Rectangle<float> bounds);
|
||||
void paint(juce::Graphics&) override;
|
||||
void resized() override;
|
||||
void timerCallback() override;
|
||||
int prepareTask(double sampleRate, int samplesPerBlock) override;
|
||||
void runTask(const std::vector<OsciPoint>& points) override;
|
||||
void setPaused(bool paused);
|
||||
void mouseDown(const juce::MouseEvent& event) override;
|
||||
bool keyPressed(const juce::KeyPress& key) override;
|
||||
void setFullScreen(bool fullScreen);
|
||||
void setVisualiserType(bool oldVisualiser);
|
||||
void toggleRecording();
|
||||
void haltRecording();
|
||||
void childUpdated();
|
||||
|
||||
VisualiserComponent* parent = nullptr;
|
||||
VisualiserComponent* child = nullptr;
|
||||
std::unique_ptr<VisualiserWindow> popout = nullptr;
|
||||
|
||||
std::atomic<bool> active = true;
|
||||
|
||||
std::function<void()> recordingHalted;
|
||||
|
||||
private:
|
||||
// 60fps
|
||||
const double BUFFER_LENGTH_SECS = 1/60.0;
|
||||
const double DEFAULT_SAMPLE_RATE = 192000.0;
|
||||
|
||||
std::atomic<int> timerId;
|
||||
std::atomic<int> lastMouseX;
|
||||
std::atomic<int> lastMouseY;
|
||||
|
||||
std::atomic<bool> oldVisualiser;
|
||||
|
||||
bool visualiserOnly;
|
||||
|
||||
juce::CriticalSection lock;
|
||||
std::vector<OsciPoint> buffer;
|
||||
std::vector<juce::Line<float>> prevLines;
|
||||
juce::Colour backgroundColour, waveformColour;
|
||||
SampleRateManager& sampleRateManager;
|
||||
AudioBackgroundThreadManager& threadManager;
|
||||
int sampleRate = DEFAULT_SAMPLE_RATE;
|
||||
LabelledTextBox roughness{"Roughness", 1, 8, 1};
|
||||
LabelledTextBox intensity{"Intensity", 0, 1, 0.01};
|
||||
|
||||
SvgButton fullScreenButton{ "fullScreen", BinaryData::fullscreen_svg, juce::Colours::white, juce::Colours::white };
|
||||
SvgButton popOutButton{ "popOut", BinaryData::open_in_new_svg, juce::Colours::white, juce::Colours::white };
|
||||
SvgButton settingsButton{ "settings", BinaryData::cog_svg, juce::Colours::white, juce::Colours::white };
|
||||
|
||||
int precision = 4;
|
||||
|
||||
std::function<void(FullScreenMode)> fullScreenCallback;
|
||||
|
||||
VisualiserSettings& settings;
|
||||
|
||||
VisualiserOpenGLComponent openGLVisualiser {settings, sampleRateManager};
|
||||
std::unique_ptr<juce::FileChooser> chooser;
|
||||
juce::File tempVideoFile;
|
||||
|
||||
StopwatchComponent stopwatch;
|
||||
SvgButton record{"Record", BinaryData::record_svg, juce::Colours::red, juce::Colours::red.withAlpha(0.01f)};
|
||||
|
||||
void popoutWindow();
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VisualiserComponent)
|
||||
JUCE_DECLARE_WEAK_REFERENCEABLE(VisualiserComponent)
|
||||
};
|
||||
|
||||
class VisualiserWindow : public juce::DocumentWindow {
|
||||
public:
|
||||
VisualiserWindow(juce::String name, VisualiserComponent* parent) : parent(parent), wasPaused(!parent->active), juce::DocumentWindow(name, juce::Colours::black, juce::DocumentWindow::TitleBarButtons::allButtons) {}
|
||||
|
||||
void closeButtonPressed() override {
|
||||
parent->setPaused(wasPaused);
|
||||
parent->child = nullptr;
|
||||
parent->childUpdated();
|
||||
parent->resized();
|
||||
parent->popout.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
VisualiserComponent* parent;
|
||||
bool wasPaused;
|
||||
};
|
|
@ -1,3 +1,5 @@
|
|||
std::string blurFragmentShader = R"(
|
||||
|
||||
uniform sampler2D uTexture0;
|
||||
uniform vec2 uOffset;
|
||||
varying vec2 vTexCoord;
|
||||
|
@ -23,3 +25,5 @@ void main() {
|
|||
sum += texture2D(uTexture0, vTexCoord + uOffset*8.0) * 0.000078;
|
||||
gl_FragColor = sum;
|
||||
}
|
||||
|
||||
)";
|
|
@ -1,3 +1,5 @@
|
|||
std::string blurVertexShader = R"(
|
||||
|
||||
attribute vec2 aPos;
|
||||
varying vec2 vTexCoord;
|
||||
|
||||
|
@ -5,3 +7,5 @@ void main() {
|
|||
gl_Position = vec4(aPos, 0.0, 1.0);
|
||||
vTexCoord = (0.5*aPos+0.5);
|
||||
}
|
||||
|
||||
)";
|
|
@ -1,3 +1,5 @@
|
|||
std::string lineFragmentShader = R"(
|
||||
|
||||
#define EPS 1E-6
|
||||
#define TAU 6.283185307179586
|
||||
#define TAUR 2.5066282746310002
|
||||
|
@ -43,3 +45,5 @@ void main() {
|
|||
gl_FragColor = 2.0 * texture2D(uScreen, vTexCoord) * brightness;
|
||||
gl_FragColor.a = 1.0;
|
||||
}
|
||||
|
||||
)";
|
|
@ -1,3 +1,5 @@
|
|||
std::string lineVertexShader = R"(
|
||||
|
||||
#define EPS 1E-6
|
||||
|
||||
uniform float uInvert;
|
||||
|
@ -66,3 +68,5 @@ void main () {
|
|||
//seed = mod(sin(seed*seed), 7.0);
|
||||
//if (mod(seed/2.0, 1.0)<0.5) gl_Position = vec4(10.0);
|
||||
}
|
||||
|
||||
)";
|
|
@ -1,3 +1,5 @@
|
|||
std::string outputFragmentShader = R"(
|
||||
|
||||
uniform sampler2D uTexture0; //line
|
||||
uniform sampler2D uTexture1; //tight glow
|
||||
uniform sampler2D uTexture2; //big glow
|
||||
|
@ -35,3 +37,5 @@ void main() {
|
|||
gl_FragColor.rgb += (1.0 / 255.0) * gradientNoise(gl_FragCoord.xy) - (0.5 / 255.0);
|
||||
gl_FragColor.a = 1.0;
|
||||
}
|
||||
|
||||
)";
|
|
@ -1,3 +1,5 @@
|
|||
std::string outputVertexShader = R"(
|
||||
|
||||
attribute vec2 aPos;
|
||||
varying vec2 vTexCoord;
|
||||
varying vec2 vTexCoordCanvas;
|
||||
|
@ -8,3 +10,5 @@ void main() {
|
|||
vTexCoord = (0.5 * aPos + 0.5);
|
||||
vTexCoordCanvas = vTexCoord * uResizeForCanvas;
|
||||
}
|
||||
|
||||
)";
|
|
@ -1,5 +1,9 @@
|
|||
std::string simpleFragmentShader = R"(
|
||||
|
||||
uniform vec4 colour;
|
||||
|
||||
void main() {
|
||||
gl_FragColor = colour;
|
||||
}
|
||||
|
||||
)";
|
|
@ -1,5 +1,9 @@
|
|||
std::string simpleVertexShader = R"(
|
||||
|
||||
attribute vec2 vertexPosition;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(vertexPosition, 0.0, 1.0);
|
||||
}
|
||||
|
||||
)";
|
|
@ -1,3 +1,5 @@
|
|||
std::string texturedFragmentShader = R"(
|
||||
|
||||
uniform sampler2D uTexture0;
|
||||
varying vec2 vTexCoord;
|
||||
|
||||
|
@ -5,3 +7,5 @@ void main() {
|
|||
gl_FragColor = texture2D(uTexture0, vTexCoord);
|
||||
gl_FragColor.a = 1.0;
|
||||
}
|
||||
|
||||
)";
|
|
@ -1,3 +1,5 @@
|
|||
std::string texturedVertexShader = R"(
|
||||
|
||||
attribute vec2 aPos;
|
||||
varying vec2 vTexCoord;
|
||||
uniform float uResizeForCanvas;
|
||||
|
@ -6,3 +8,5 @@ void main() {
|
|||
gl_Position = vec4(aPos, 0.0, 1.0);
|
||||
vTexCoord = (0.5 * aPos + 0.5) * uResizeForCanvas;
|
||||
}
|
||||
|
||||
)";
|
|
@ -1,20 +1,194 @@
|
|||
#define CPP_GLSL_INCLUDE
|
||||
|
||||
#include "../LookAndFeel.h"
|
||||
#include "VisualiserOpenGLComponent.h"
|
||||
#include "VisualiserComponent.h"
|
||||
#include "BlurFragmentShader.glsl"
|
||||
#include "BlurVertexShader.glsl"
|
||||
#include "LineFragmentShader.glsl"
|
||||
#include "LineVertexShader.glsl"
|
||||
#include "OutputFragmentShader.glsl"
|
||||
#include "OutputVertexShader.glsl"
|
||||
#include "SimpleFragmentShader.glsl"
|
||||
#include "SimpleVertexShader.glsl"
|
||||
#include "TexturedFragmentShader.glsl"
|
||||
#include "TexturedVertexShader.glsl"
|
||||
|
||||
VisualiserComponent::VisualiserComponent(AudioBackgroundThreadManager& threadManager, VisualiserSettings& settings, VisualiserComponent* parent, bool visualiserOnly) : settings(settings), threadManager(threadManager), visualiserOnly(visualiserOnly), AudioBackgroundThread("VisualiserComponent", threadManager), parent(parent) {
|
||||
setShouldBeRunning(true);
|
||||
|
||||
addAndMakeVisible(record);
|
||||
record.setPulseAnimation(true);
|
||||
record.onClick = [this] {
|
||||
toggleRecording();
|
||||
stopwatch.stop();
|
||||
stopwatch.reset();
|
||||
if (record.getToggleState()) {
|
||||
stopwatch.start();
|
||||
}
|
||||
resized();
|
||||
};
|
||||
|
||||
addAndMakeVisible(stopwatch);
|
||||
|
||||
setMouseCursor(juce::MouseCursor::PointingHandCursor);
|
||||
setWantsKeyboardFocus(true);
|
||||
|
||||
if (parent == nullptr && !visualiserOnly) {
|
||||
addAndMakeVisible(fullScreenButton);
|
||||
}
|
||||
if (child == nullptr && parent == nullptr && !visualiserOnly) {
|
||||
addAndMakeVisible(popOutButton);
|
||||
}
|
||||
addAndMakeVisible(settingsButton);
|
||||
|
||||
fullScreenButton.onClick = [this]() {
|
||||
enableFullScreen();
|
||||
};
|
||||
|
||||
settingsButton.onClick = [this]() {
|
||||
openSettings();
|
||||
};
|
||||
|
||||
popOutButton.onClick = [this]() {
|
||||
popoutWindow();
|
||||
};
|
||||
|
||||
VisualiserOpenGLComponent::VisualiserOpenGLComponent(VisualiserSettings& settings, SampleRateManager& sampleRateManager) : settings(settings), sampleRateManager(sampleRateManager) {
|
||||
setFullScreen(false);
|
||||
|
||||
openGLContext.setRenderer(this);
|
||||
openGLContext.attachTo(*this);
|
||||
setInterceptsMouseClicks(false, false);
|
||||
}
|
||||
|
||||
VisualiserOpenGLComponent::~VisualiserOpenGLComponent() {
|
||||
VisualiserComponent::~VisualiserComponent() {
|
||||
openGLContext.detach();
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::newOpenGLContextCreated() {
|
||||
void VisualiserComponent::setFullScreenCallback(std::function<void(FullScreenMode)> callback) {
|
||||
fullScreenCallback = callback;
|
||||
}
|
||||
|
||||
void VisualiserComponent::enableFullScreen() {
|
||||
if (fullScreenCallback) {
|
||||
fullScreenCallback(FullScreenMode::TOGGLE);
|
||||
}
|
||||
grabKeyboardFocus();
|
||||
}
|
||||
|
||||
void VisualiserComponent::mouseDoubleClick(const juce::MouseEvent& event) {
|
||||
enableFullScreen();
|
||||
}
|
||||
|
||||
void VisualiserComponent::setBuffer(const std::vector<OsciPoint>& buffer) {
|
||||
juce::CriticalSection::ScopedLockType lock(samplesLock);
|
||||
|
||||
if (xSamples.size() != buffer.size()) {
|
||||
needsReattach = true;
|
||||
}
|
||||
xSamples.clear();
|
||||
ySamples.clear();
|
||||
zSamples.clear();
|
||||
for (auto& point : buffer) {
|
||||
xSamples.push_back(point.x);
|
||||
ySamples.push_back(point.y);
|
||||
zSamples.push_back(point.z);
|
||||
}
|
||||
|
||||
triggerAsyncUpdate();
|
||||
}
|
||||
|
||||
void VisualiserComponent::runTask(const std::vector<OsciPoint>& points) {
|
||||
setBuffer(points);
|
||||
}
|
||||
|
||||
int VisualiserComponent::prepareTask(double sampleRate, int bufferSize) {
|
||||
this->sampleRate = sampleRate;
|
||||
xResampler.prepare(sampleRate, RESAMPLE_RATIO);
|
||||
yResampler.prepare(sampleRate, RESAMPLE_RATIO);
|
||||
zResampler.prepare(sampleRate, RESAMPLE_RATIO);
|
||||
return sampleRate / FRAME_RATE;
|
||||
}
|
||||
|
||||
void VisualiserComponent::setPaused(bool paused) {
|
||||
active = !paused;
|
||||
setShouldBeRunning(active);
|
||||
repaint();
|
||||
}
|
||||
|
||||
void VisualiserComponent::mouseDown(const juce::MouseEvent& event) {
|
||||
if (event.mods.isLeftButtonDown() && child == nullptr) {
|
||||
setPaused(active);
|
||||
}
|
||||
}
|
||||
|
||||
bool VisualiserComponent::keyPressed(const juce::KeyPress& key) {
|
||||
if (key.isKeyCode(juce::KeyPress::escapeKey)) {
|
||||
if (fullScreenCallback) {
|
||||
fullScreenCallback(FullScreenMode::MAIN_COMPONENT);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void VisualiserComponent::setFullScreen(bool fullScreen) {}
|
||||
|
||||
void VisualiserComponent::toggleRecording() {
|
||||
|
||||
}
|
||||
|
||||
void VisualiserComponent::haltRecording() {
|
||||
record.setToggleState(false, juce::NotificationType::dontSendNotification);
|
||||
}
|
||||
|
||||
void VisualiserComponent::resized() {
|
||||
auto area = getLocalBounds();
|
||||
if (visualiserOnly) {
|
||||
buttonRow = area.removeFromTop(25);
|
||||
} else {
|
||||
buttonRow = area.removeFromBottom(25);
|
||||
}
|
||||
if (parent == nullptr && !visualiserOnly) {
|
||||
fullScreenButton.setBounds(buttonRow.removeFromRight(30));
|
||||
}
|
||||
if (child == nullptr && parent == nullptr && !visualiserOnly) {
|
||||
popOutButton.setBounds(buttonRow.removeFromRight(30));
|
||||
}
|
||||
settingsButton.setBounds(buttonRow.removeFromRight(30));
|
||||
record.setBounds(buttonRow.removeFromRight(25));
|
||||
if (record.getToggleState()) {
|
||||
stopwatch.setVisible(true);
|
||||
stopwatch.setBounds(buttonRow.removeFromRight(100));
|
||||
} else {
|
||||
stopwatch.setVisible(false);
|
||||
}
|
||||
viewportArea = area;
|
||||
viewportChanged(viewportArea);
|
||||
}
|
||||
|
||||
void VisualiserComponent::popoutWindow() {
|
||||
haltRecording();
|
||||
auto visualiser = new VisualiserComponent(threadManager, settings, this);
|
||||
visualiser->settings.setLookAndFeel(&getLookAndFeel());
|
||||
visualiser->openSettings = openSettings;
|
||||
visualiser->closeSettings = closeSettings;
|
||||
visualiser->recordingHalted = recordingHalted;
|
||||
child = visualiser;
|
||||
childUpdated();
|
||||
visualiser->setSize(300, 325);
|
||||
popout = std::make_unique<VisualiserWindow>("Software Oscilloscope", this);
|
||||
popout->setContentOwned(visualiser, true);
|
||||
popout->setUsingNativeTitleBar(true);
|
||||
popout->setResizable(true, false);
|
||||
popout->setVisible(true);
|
||||
popout->centreWithSize(300, 325);
|
||||
setPaused(true);
|
||||
resized();
|
||||
}
|
||||
|
||||
void VisualiserComponent::childUpdated() {
|
||||
popOutButton.setVisible(child == nullptr);
|
||||
}
|
||||
|
||||
void VisualiserComponent::newOpenGLContextCreated() {
|
||||
using namespace juce::gl;
|
||||
|
||||
juce::CriticalSection::ScopedLockType lock(samplesLock);
|
||||
|
@ -22,35 +196,35 @@ void VisualiserOpenGLComponent::newOpenGLContextCreated() {
|
|||
juce::OpenGLHelpers::clear(juce::Colours::black);
|
||||
glColorMask(true, true, true, true);
|
||||
|
||||
viewportChanged();
|
||||
viewportChanged(viewportArea);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
|
||||
fullScreenQuad = { -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, -1.0f };
|
||||
|
||||
simpleShader = std::make_unique<juce::OpenGLShaderProgram>(openGLContext);
|
||||
simpleShader->addVertexShader(juce::OpenGLHelpers::translateVertexShaderToV3(BinaryData::SimpleVertexShader_glsl));
|
||||
simpleShader->addFragmentShader(BinaryData::SimpleFragmentShader_glsl);
|
||||
simpleShader->addVertexShader(juce::OpenGLHelpers::translateVertexShaderToV3(simpleVertexShader));
|
||||
simpleShader->addFragmentShader(simpleFragmentShader);
|
||||
simpleShader->link();
|
||||
|
||||
lineShader = std::make_unique<juce::OpenGLShaderProgram>(openGLContext);
|
||||
lineShader->addVertexShader(juce::OpenGLHelpers::translateVertexShaderToV3(BinaryData::LineVertexShader_glsl));
|
||||
lineShader->addFragmentShader(BinaryData::LineFragmentShader_glsl);
|
||||
lineShader->addVertexShader(juce::OpenGLHelpers::translateVertexShaderToV3(lineVertexShader));
|
||||
lineShader->addFragmentShader(lineFragmentShader);
|
||||
lineShader->link();
|
||||
|
||||
outputShader = std::make_unique<juce::OpenGLShaderProgram>(openGLContext);
|
||||
outputShader->addVertexShader(juce::OpenGLHelpers::translateVertexShaderToV3(BinaryData::OutputVertexShader_glsl));
|
||||
outputShader->addFragmentShader(BinaryData::OutputFragmentShader_glsl);
|
||||
outputShader->addVertexShader(juce::OpenGLHelpers::translateVertexShaderToV3(outputVertexShader));
|
||||
outputShader->addFragmentShader(outputFragmentShader);
|
||||
outputShader->link();
|
||||
|
||||
texturedShader = std::make_unique<juce::OpenGLShaderProgram>(openGLContext);
|
||||
texturedShader->addVertexShader(juce::OpenGLHelpers::translateVertexShaderToV3(BinaryData::TexturedVertexShader_glsl));
|
||||
texturedShader->addFragmentShader(BinaryData::TexturedFragmentShader_glsl);
|
||||
texturedShader->addVertexShader(juce::OpenGLHelpers::translateVertexShaderToV3(texturedVertexShader));
|
||||
texturedShader->addFragmentShader(texturedFragmentShader);
|
||||
texturedShader->link();
|
||||
|
||||
blurShader = std::make_unique<juce::OpenGLShaderProgram>(openGLContext);
|
||||
blurShader->addVertexShader(juce::OpenGLHelpers::translateVertexShaderToV3(BinaryData::BlurVertexShader_glsl));
|
||||
blurShader->addFragmentShader(BinaryData::BlurFragmentShader_glsl);
|
||||
blurShader->addVertexShader(juce::OpenGLHelpers::translateVertexShaderToV3(blurVertexShader));
|
||||
blurShader->addFragmentShader(blurFragmentShader);
|
||||
blurShader->link();
|
||||
|
||||
glGenBuffers(1, &vertexBuffer);
|
||||
|
@ -59,7 +233,7 @@ void VisualiserOpenGLComponent::newOpenGLContextCreated() {
|
|||
setupArrays(smoothedXSamples.size());
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::openGLContextClosing() {
|
||||
void VisualiserComponent::openGLContextClosing() {
|
||||
using namespace juce::gl;
|
||||
|
||||
glDeleteBuffers(1, &quadIndexBuffer);
|
||||
|
@ -80,43 +254,21 @@ void VisualiserOpenGLComponent::openGLContextClosing() {
|
|||
outputShader.reset();
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::updateBuffer(const std::vector<OsciPoint>& buffer) {
|
||||
juce::CriticalSection::ScopedLockType lock(samplesLock);
|
||||
|
||||
if (xSamples.size() != buffer.size()) {
|
||||
needsReattach = true;
|
||||
void VisualiserComponent::handleAsyncUpdate() {
|
||||
{
|
||||
juce::CriticalSection::ScopedLockType lock(samplesLock);
|
||||
|
||||
int newResampledSize = xSamples.size() * RESAMPLE_RATIO;
|
||||
|
||||
smoothedXSamples.resize(newResampledSize);
|
||||
smoothedYSamples.resize(newResampledSize);
|
||||
smoothedZSamples.resize(newResampledSize);
|
||||
smoothedZSamples.resize(newResampledSize);
|
||||
|
||||
xResampler.process(xSamples.data(), smoothedXSamples.data(), xSamples.size());
|
||||
yResampler.process(ySamples.data(), smoothedYSamples.data(), ySamples.size());
|
||||
zResampler.process(zSamples.data(), smoothedZSamples.data(), zSamples.size());
|
||||
}
|
||||
xSamples.clear();
|
||||
ySamples.clear();
|
||||
zSamples.clear();
|
||||
for (auto& point : buffer) {
|
||||
xSamples.push_back(point.x);
|
||||
ySamples.push_back(point.y);
|
||||
zSamples.push_back(point.z);
|
||||
}
|
||||
|
||||
triggerAsyncUpdate();
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::handleAsyncUpdate() {
|
||||
juce::CriticalSection::ScopedLockType lock(samplesLock);
|
||||
|
||||
int newResampledSize = xSamples.size() * RESAMPLE_RATIO;
|
||||
|
||||
smoothedXSamples.resize(newResampledSize);
|
||||
smoothedYSamples.resize(newResampledSize);
|
||||
smoothedZSamples.resize(newResampledSize);
|
||||
|
||||
if (sampleRate != sampleRateManager.getSampleRate()) {
|
||||
sampleRate = sampleRateManager.getSampleRate();
|
||||
xResampler.prepare(sampleRate, RESAMPLE_RATIO);
|
||||
yResampler.prepare(sampleRate, RESAMPLE_RATIO);
|
||||
zResampler.prepare(sampleRate, RESAMPLE_RATIO);
|
||||
}
|
||||
|
||||
xResampler.process(xSamples.data(), smoothedXSamples.data(), xSamples.size());
|
||||
yResampler.process(ySamples.data(), smoothedYSamples.data(), ySamples.size());
|
||||
zResampler.process(zSamples.data(), smoothedZSamples.data(), zSamples.size());
|
||||
|
||||
if (needsReattach) {
|
||||
openGLContext.detach();
|
||||
|
@ -126,44 +278,47 @@ void VisualiserOpenGLComponent::handleAsyncUpdate() {
|
|||
repaint();
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::renderOpenGL() {
|
||||
void VisualiserComponent::renderOpenGL() {
|
||||
if (openGLContext.isActive()) {
|
||||
juce::CriticalSection::ScopedLockType lock(samplesLock);
|
||||
|
||||
if (graticuleEnabled != settings.getGraticuleEnabled() || smudgesEnabled != settings.getSmudgesEnabled()) {
|
||||
graticuleEnabled = settings.getGraticuleEnabled();
|
||||
smudgesEnabled = settings.getSmudgesEnabled();
|
||||
screenTexture = createScreenTexture();
|
||||
juce::OpenGLHelpers::clear(juce::Colours::black);
|
||||
if (active) {
|
||||
juce::CriticalSection::ScopedLockType lock(samplesLock);
|
||||
|
||||
if (graticuleEnabled != settings.getGraticuleEnabled() || smudgesEnabled != settings.getSmudgesEnabled()) {
|
||||
graticuleEnabled = settings.getGraticuleEnabled();
|
||||
smudgesEnabled = settings.getSmudgesEnabled();
|
||||
screenTexture = createScreenTexture();
|
||||
}
|
||||
|
||||
renderScale = (float) openGLContext.getRenderingScale();
|
||||
|
||||
drawLineTexture(smoothedXSamples, smoothedYSamples, smoothedZSamples);
|
||||
checkGLErrors("drawLineTexture");
|
||||
drawCRT();
|
||||
checkGLErrors("drawCRT");
|
||||
}
|
||||
|
||||
renderScale = (float) openGLContext.getRenderingScale();
|
||||
|
||||
drawLineTexture(smoothedXSamples, smoothedYSamples, smoothedZSamples);
|
||||
checkGLErrors("drawLineTexture");
|
||||
drawCRT();
|
||||
checkGLErrors("drawCRT");
|
||||
}
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::resized() {
|
||||
viewportChanged();
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::viewportChanged() {
|
||||
void VisualiserComponent::viewportChanged(juce::Rectangle<int> area) {
|
||||
using namespace juce::gl;
|
||||
|
||||
if (openGLContext.isAttached()) {
|
||||
float realWidth = getWidth() * renderScale;
|
||||
float realHeight = getHeight() * renderScale;
|
||||
float realWidth = area.getWidth() * renderScale;
|
||||
float realHeight = area.getHeight() * renderScale;
|
||||
|
||||
float xOffset = getWidth() * renderScale - realWidth;
|
||||
float yOffset = getHeight() * renderScale - realHeight;
|
||||
|
||||
float minDim = juce::jmin(realWidth, realHeight);
|
||||
float x = (realWidth - minDim) / 2;
|
||||
float y = (realHeight - minDim) / 2;
|
||||
float x = (realWidth - minDim) / 2 + area.getX() * renderScale + xOffset;
|
||||
float y = (realHeight - minDim) / 2 + area.getY() * renderScale + yOffset;
|
||||
|
||||
glViewport(juce::roundToInt(x), juce::roundToInt(y), juce::roundToInt(minDim), juce::roundToInt(minDim));
|
||||
}
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::setupArrays(int nPoints) {
|
||||
void VisualiserComponent::setupArrays(int nPoints) {
|
||||
using namespace juce::gl;
|
||||
|
||||
if (nPoints == 0) {
|
||||
|
@ -207,7 +362,7 @@ void VisualiserOpenGLComponent::setupArrays(int nPoints) {
|
|||
scratchVertices.resize(12 * nPoints);
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::setupTextures() {
|
||||
void VisualiserComponent::setupTextures() {
|
||||
using namespace juce::gl;
|
||||
|
||||
// Create the framebuffer
|
||||
|
@ -226,7 +381,7 @@ void VisualiserOpenGLComponent::setupTextures() {
|
|||
glBindFramebuffer(GL_FRAMEBUFFER, 0); // Unbind
|
||||
}
|
||||
|
||||
Texture VisualiserOpenGLComponent::makeTexture(int width, int height) {
|
||||
Texture VisualiserComponent::makeTexture(int width, int height) {
|
||||
using namespace juce::gl;
|
||||
|
||||
GLuint textureID;
|
||||
|
@ -245,7 +400,7 @@ Texture VisualiserOpenGLComponent::makeTexture(int width, int height) {
|
|||
return { textureID, width, height };
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::drawLineTexture(const std::vector<float>& xPoints, const std::vector<float>& yPoints, const std::vector<float>& zPoints) {
|
||||
void VisualiserComponent::drawLineTexture(const std::vector<float>& xPoints, const std::vector<float>& yPoints, const std::vector<float>& zPoints) {
|
||||
using namespace juce::gl;
|
||||
|
||||
fadeAmount = juce::jmin(1.0, std::pow(0.5, settings.getPersistence()) * 0.4);
|
||||
|
@ -255,7 +410,7 @@ void VisualiserOpenGLComponent::drawLineTexture(const std::vector<float>& xPoint
|
|||
glBindTexture(GL_TEXTURE_2D, targetTexture.value().id);
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::saveTextureToFile(GLuint textureID, int width, int height, const juce::File& file) {
|
||||
void VisualiserComponent::saveTextureToFile(GLuint textureID, int width, int height, const juce::File& file) {
|
||||
using namespace juce::gl;
|
||||
|
||||
// Bind the texture to read its data
|
||||
|
@ -301,7 +456,7 @@ void VisualiserOpenGLComponent::saveTextureToFile(GLuint textureID, int width, i
|
|||
}
|
||||
|
||||
|
||||
void VisualiserOpenGLComponent::activateTargetTexture(std::optional<Texture> texture) {
|
||||
void VisualiserComponent::activateTargetTexture(std::optional<Texture> texture) {
|
||||
using namespace juce::gl;
|
||||
|
||||
if (texture.has_value()) {
|
||||
|
@ -310,17 +465,17 @@ void VisualiserOpenGLComponent::activateTargetTexture(std::optional<Texture> tex
|
|||
glViewport(0, 0, texture.value().width, texture.value().height);
|
||||
} else {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
viewportChanged();
|
||||
viewportChanged(viewportArea);
|
||||
}
|
||||
targetTexture = texture;
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::setShader(juce::OpenGLShaderProgram* program) {
|
||||
void VisualiserComponent::setShader(juce::OpenGLShaderProgram* program) {
|
||||
currentShader = program;
|
||||
program->use();
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::drawTexture(std::optional<Texture> texture0, std::optional<Texture> texture1, std::optional<Texture> texture2, std::optional<Texture> texture3) {
|
||||
void VisualiserComponent::drawTexture(std::optional<Texture> texture0, std::optional<Texture> texture1, std::optional<Texture> texture2, std::optional<Texture> texture3) {
|
||||
using namespace juce::gl;
|
||||
|
||||
glEnableVertexAttribArray(glGetAttribLocation(currentShader->getProgramID(), "aPos"));
|
||||
|
@ -360,19 +515,19 @@ void VisualiserOpenGLComponent::drawTexture(std::optional<Texture> texture0, std
|
|||
}
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::setAdditiveBlending() {
|
||||
void VisualiserComponent::setAdditiveBlending() {
|
||||
using namespace juce::gl;
|
||||
|
||||
glBlendFunc(GL_ONE, GL_ONE);
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::setNormalBlending() {
|
||||
void VisualiserComponent::setNormalBlending() {
|
||||
using namespace juce::gl;
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::drawLine(const std::vector<float>& xPoints, const std::vector<float>& yPoints, const std::vector<float>& zPoints) {
|
||||
void VisualiserComponent::drawLine(const std::vector<float>& xPoints, const std::vector<float>& yPoints, const std::vector<float>& zPoints) {
|
||||
using namespace juce::gl;
|
||||
|
||||
setAdditiveBlending();
|
||||
|
@ -408,7 +563,7 @@ void VisualiserOpenGLComponent::drawLine(const std::vector<float>& xPoints, cons
|
|||
lineShader->setUniform("uGain", 450.0f / 512.0f);
|
||||
lineShader->setUniform("uInvert", 1.0f);
|
||||
|
||||
float intensity = settings.getIntensity() * (41000.0f / sampleRateManager.getSampleRate());
|
||||
float intensity = settings.getIntensity() * (41000.0f / sampleRate);
|
||||
if (settings.getUpsamplingEnabled()) {
|
||||
lineShader->setUniform("uIntensity", intensity);
|
||||
} else {
|
||||
|
@ -429,7 +584,7 @@ void VisualiserOpenGLComponent::drawLine(const std::vector<float>& xPoints, cons
|
|||
glDisableVertexAttribArray(glGetAttribLocation(lineShader->getProgramID(), "aIdx"));
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::fade() {
|
||||
void VisualiserComponent::fade() {
|
||||
using namespace juce::gl;
|
||||
|
||||
setNormalBlending();
|
||||
|
@ -446,7 +601,7 @@ void VisualiserOpenGLComponent::fade() {
|
|||
glDisableVertexAttribArray(glGetAttribLocation(simpleShader->getProgramID(), "vertexPosition"));
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::drawCRT() {
|
||||
void VisualiserComponent::drawCRT() {
|
||||
setNormalBlending();
|
||||
|
||||
activateTargetTexture(blur1Texture);
|
||||
|
@ -493,7 +648,7 @@ void VisualiserOpenGLComponent::drawCRT() {
|
|||
drawTexture(lineTexture, blur1Texture, blur3Texture, screenTexture);
|
||||
}
|
||||
|
||||
Texture VisualiserOpenGLComponent::createScreenTexture() {
|
||||
Texture VisualiserComponent::createScreenTexture() {
|
||||
using namespace juce::gl;
|
||||
|
||||
if (settings.getSmudgesEnabled()) {
|
||||
|
@ -562,7 +717,7 @@ Texture VisualiserOpenGLComponent::createScreenTexture() {
|
|||
return texture;
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::checkGLErrors(const juce::String& location) {
|
||||
void VisualiserComponent::checkGLErrors(const juce::String& location) {
|
||||
using namespace juce::gl;
|
||||
|
||||
GLenum error;
|
||||
|
@ -582,18 +737,14 @@ void VisualiserOpenGLComponent::checkGLErrors(const juce::String& location) {
|
|||
}
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::setPaused(bool paused) {
|
||||
this->paused = paused;
|
||||
repaint();
|
||||
}
|
||||
|
||||
void VisualiserOpenGLComponent::paint(juce::Graphics& g) {
|
||||
if (paused) {
|
||||
g.setColour(juce::Colours::black.withAlpha(0.5f));
|
||||
g.fillRect(getLocalBounds());
|
||||
|
||||
void VisualiserComponent::paint(juce::Graphics& g) {
|
||||
g.setColour(juce::Colours::black);
|
||||
g.fillRect(buttonRow);
|
||||
if (!active) {
|
||||
g.setColour(juce::Colours::white);
|
||||
g.setFont(30.0f);
|
||||
g.drawText("Paused", getLocalBounds(), juce::Justification::centred);
|
||||
juce::String text = child == nullptr ? "Paused" : "Open in another window";
|
||||
g.drawText(text, viewportArea, juce::Justification::centred);
|
||||
}
|
||||
}
|
|
@ -1,9 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <JuceHeader.h>
|
||||
#include "../LookAndFeel.h"
|
||||
#include "../concurrency/AudioBackgroundThread.h"
|
||||
#include "../components/SvgButton.h"
|
||||
#include "VisualiserSettings.h"
|
||||
#include "../audio/SampleRateManager.h"
|
||||
#include "../shape/OsciPoint.h"
|
||||
#include "../components/StopwatchComponent.h"
|
||||
|
||||
enum class FullScreenMode {
|
||||
TOGGLE,
|
||||
FULL_SCREEN,
|
||||
MAIN_COMPONENT,
|
||||
};
|
||||
|
||||
struct Texture {
|
||||
GLuint id;
|
||||
|
@ -11,23 +20,73 @@ struct Texture {
|
|||
int height;
|
||||
};
|
||||
|
||||
class VisualiserOpenGLComponent : public juce::Component, public juce::OpenGLRenderer, public juce::AsyncUpdater {
|
||||
class VisualiserWindow;
|
||||
class VisualiserComponent : public juce::Component, public AudioBackgroundThread, public juce::MouseListener, public juce::OpenGLRenderer, public juce::AsyncUpdater {
|
||||
public:
|
||||
VisualiserOpenGLComponent(VisualiserSettings& settings, SampleRateManager& sampleRateManager);
|
||||
~VisualiserOpenGLComponent() override;
|
||||
VisualiserComponent(AudioBackgroundThreadManager& threadManager, VisualiserSettings& settings, VisualiserComponent* parent = nullptr, bool visualiserOnly = false);
|
||||
~VisualiserComponent() override;
|
||||
|
||||
std::function<void()> openSettings;
|
||||
std::function<void()> closeSettings;
|
||||
|
||||
void enableFullScreen();
|
||||
void setFullScreenCallback(std::function<void(FullScreenMode)> callback);
|
||||
void mouseDoubleClick(const juce::MouseEvent& event) override;
|
||||
void setBuffer(const std::vector<OsciPoint>& buffer);
|
||||
void resized() override;
|
||||
void paint(juce::Graphics& g) override;
|
||||
int prepareTask(double sampleRate, int samplesPerBlock) override;
|
||||
void runTask(const std::vector<OsciPoint>& points) override;
|
||||
void setPaused(bool paused);
|
||||
void mouseDown(const juce::MouseEvent& event) override;
|
||||
bool keyPressed(const juce::KeyPress& key) override;
|
||||
void handleAsyncUpdate() override;
|
||||
void newOpenGLContextCreated() override;
|
||||
void renderOpenGL() override;
|
||||
void openGLContextClosing() override;
|
||||
void resized() override;
|
||||
void paint(juce::Graphics& g) override;
|
||||
void updateBuffer(const std::vector<OsciPoint>& buffer);
|
||||
void setPaused(bool paused);
|
||||
void handleAsyncUpdate() override;
|
||||
void setFullScreen(bool fullScreen);
|
||||
void toggleRecording();
|
||||
void haltRecording();
|
||||
void childUpdated();
|
||||
|
||||
VisualiserComponent* parent = nullptr;
|
||||
VisualiserComponent* child = nullptr;
|
||||
std::unique_ptr<VisualiserWindow> popout = nullptr;
|
||||
|
||||
std::atomic<bool> active = true;
|
||||
|
||||
std::function<void()> recordingHalted;
|
||||
|
||||
private:
|
||||
const double FRAME_RATE = 60.0;
|
||||
|
||||
bool visualiserOnly;
|
||||
|
||||
AudioBackgroundThreadManager& threadManager;
|
||||
|
||||
SvgButton fullScreenButton{ "fullScreen", BinaryData::fullscreen_svg, juce::Colours::white, juce::Colours::white };
|
||||
SvgButton popOutButton{ "popOut", BinaryData::open_in_new_svg, juce::Colours::white, juce::Colours::white };
|
||||
SvgButton settingsButton{ "settings", BinaryData::cog_svg, juce::Colours::white, juce::Colours::white };
|
||||
|
||||
std::function<void(FullScreenMode)> fullScreenCallback;
|
||||
|
||||
VisualiserSettings& settings;
|
||||
|
||||
std::unique_ptr<juce::FileChooser> chooser;
|
||||
juce::File tempVideoFile;
|
||||
|
||||
StopwatchComponent stopwatch;
|
||||
SvgButton record{"Record", BinaryData::record_svg, juce::Colours::red, juce::Colours::red.withAlpha(0.01f)};
|
||||
|
||||
void popoutWindow();
|
||||
|
||||
// OPENGL
|
||||
|
||||
juce::OpenGLContext openGLContext;
|
||||
|
||||
juce::Rectangle<int> buttonRow;
|
||||
juce::Rectangle<int> viewportArea;
|
||||
|
||||
float renderScale = 1.0f;
|
||||
|
||||
GLuint quadIndexBuffer = 0;
|
||||
|
@ -68,14 +127,10 @@ private:
|
|||
std::unique_ptr<juce::OpenGLShaderProgram> outputShader;
|
||||
juce::OpenGLShaderProgram* currentShader;
|
||||
|
||||
VisualiserSettings& settings;
|
||||
SampleRateManager& sampleRateManager;
|
||||
float fadeAmount;
|
||||
bool smudgesEnabled = settings.getSmudgesEnabled();
|
||||
bool graticuleEnabled = settings.getGraticuleEnabled();
|
||||
|
||||
bool paused = false;
|
||||
|
||||
const double RESAMPLE_RATIO = 6.0;
|
||||
double sampleRate = -1;
|
||||
chowdsp::ResamplingTypes::LanczosResampler<2048, 8> xResampler;
|
||||
|
@ -96,9 +151,25 @@ private:
|
|||
void fade();
|
||||
void drawCRT();
|
||||
void checkGLErrors(const juce::String& location);
|
||||
void viewportChanged();
|
||||
void viewportChanged(juce::Rectangle<int> area);
|
||||
Texture createScreenTexture();
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VisualiserOpenGLComponent)
|
||||
|
||||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VisualiserComponent)
|
||||
};
|
||||
|
||||
class VisualiserWindow : public juce::DocumentWindow {
|
||||
public:
|
||||
VisualiserWindow(juce::String name, VisualiserComponent* parent) : parent(parent), wasPaused(!parent->active), juce::DocumentWindow(name, juce::Colours::black, juce::DocumentWindow::TitleBarButtons::allButtons) {}
|
||||
|
||||
void closeButtonPressed() override {
|
||||
parent->setPaused(wasPaused);
|
||||
parent->child = nullptr;
|
||||
parent->childUpdated();
|
||||
parent->resized();
|
||||
parent->popout.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
VisualiserComponent* parent;
|
||||
bool wasPaused;
|
||||
};
|
|
@ -10,13 +10,9 @@
|
|||
|
||||
class VisualiserParameters {
|
||||
public:
|
||||
std::atomic<int> roughness = 4;
|
||||
std::atomic<double> intensity = 1.0;
|
||||
|
||||
BooleanParameter* graticuleEnabled = new BooleanParameter("Show Graticule", "graticuleEnabled", VERSION_HINT, true, "Show the graticule or grid lines over the oscilloscope display.");
|
||||
BooleanParameter* smudgesEnabled = new BooleanParameter("Show Smudges", "smudgesEnabled", VERSION_HINT, true, "Adds a subtle layer of dirt/smudges to the oscilloscope display to make it look more realistic.");
|
||||
BooleanParameter* upsamplingEnabled = new BooleanParameter("Upsample Audio", "upsamplingEnabled", VERSION_HINT, false, "Upsamples the audio before visualising it to make it appear more realistic, at the expense of performance.");
|
||||
BooleanParameter* legacyVisualiserEnabled = new BooleanParameter("Use Legacy Visualiser", "legacyVisualiserEnabled", VERSION_HINT, false, "Replaces the realistic oscilloscope visualiser with the legacy visualiser. This may improve performance.");
|
||||
BooleanParameter* visualiserFullScreen = new BooleanParameter("Visualiser Fullscreen", "visualiserFullScreen", VERSION_HINT, false, "Makes the software visualiser fullscreen.");
|
||||
|
||||
std::shared_ptr<Effect> persistenceEffect = std::make_shared<Effect>(
|
|
@ -54,28 +54,6 @@
|
|||
<FILE id="N9Q6Zg" name="greek.txt" compile="0" resource="1" file="Resources/text/greek.txt"/>
|
||||
<FILE id="OABuJy" name="helloworld.txt" compile="0" resource="1" file="Resources/text/helloworld.txt"/>
|
||||
</GROUP>
|
||||
<GROUP id="{4CF78D2F-9583-3931-AC9C-E26821FA8A38}" name="visualiser">
|
||||
<FILE id="uEd2jz" name="BlurFragmentShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/BlurFragmentShader.glsl"/>
|
||||
<FILE id="DG8mXB" name="BlurVertexShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/BlurVertexShader.glsl"/>
|
||||
<FILE id="tLvJZI" name="LineFragmentShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/LineFragmentShader.glsl"/>
|
||||
<FILE id="FWis2l" name="LineVertexShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/LineVertexShader.glsl"/>
|
||||
<FILE id="T8tAlt" name="OutputFragmentShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/OutputFragmentShader.glsl"/>
|
||||
<FILE id="RYUdS3" name="OutputVertexShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/OutputVertexShader.glsl"/>
|
||||
<FILE id="Jj50qw" name="SimpleFragmentShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/SimpleFragmentShader.glsl"/>
|
||||
<FILE id="jwWJN2" name="SimpleVertexShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/SimpleVertexShader.glsl"/>
|
||||
<FILE id="IkEMkv" name="TexturedFragmentShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/TexturedFragmentShader.glsl"/>
|
||||
<FILE id="JNBqis" name="TexturedVertexShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/TexturedVertexShader.glsl"/>
|
||||
</GROUP>
|
||||
</GROUP>
|
||||
<GROUP id="{75439074-E50C-362F-1EDF-8B4BE9011259}" name="Source">
|
||||
<GROUP id="{85A33213-D880-BD92-70D8-1901DA6D23F0}" name="audio">
|
||||
|
@ -187,18 +165,6 @@
|
|||
<FILE id="QQzSwh" name="SliderTextBox.h" compile="0" resource="0" file="Source/components/SliderTextBox.h"/>
|
||||
<FILE id="QrDKRZ" name="SvgButton.h" compile="0" resource="0" file="Source/components/SvgButton.h"/>
|
||||
<FILE id="qzfstC" name="SwitchButton.h" compile="0" resource="0" file="Source/components/SwitchButton.h"/>
|
||||
<FILE id="w2BHaX" name="VisualiserComponent.cpp" compile="1" resource="0"
|
||||
file="Source/components/VisualiserComponent.cpp"/>
|
||||
<FILE id="QFef4T" name="VisualiserComponent.h" compile="0" resource="0"
|
||||
file="Source/components/VisualiserComponent.h"/>
|
||||
<FILE id="kz22Iu" name="VisualiserOpenGLComponent.cpp" compile="1"
|
||||
resource="0" file="Source/components/VisualiserOpenGLComponent.cpp"/>
|
||||
<FILE id="EyhCOm" name="VisualiserOpenGLComponent.h" compile="0" resource="0"
|
||||
file="Source/components/VisualiserOpenGLComponent.h"/>
|
||||
<FILE id="VDt1r3" name="VisualiserSettings.cpp" compile="1" resource="0"
|
||||
file="Source/components/VisualiserSettings.cpp"/>
|
||||
<FILE id="IqelJa" name="VisualiserSettings.h" compile="0" resource="0"
|
||||
file="Source/components/VisualiserSettings.h"/>
|
||||
<FILE id="icFMpl" name="VListBox.cpp" compile="1" resource="0" file="Source/components/VListBox.cpp"/>
|
||||
<FILE id="mvp8je" name="VListBox.h" compile="0" resource="0" file="Source/components/VListBox.h"/>
|
||||
<FILE id="s8EVcE" name="VolumeComponent.cpp" compile="1" resource="0"
|
||||
|
@ -614,6 +580,36 @@
|
|||
<FILE id="mC1tUv" name="ugen_JuceUtility.h" compile="0" resource="0"
|
||||
file="Source/UGen/ugen_JuceUtility.h"/>
|
||||
</GROUP>
|
||||
<GROUP id="{16A8DC64-BA02-898D-4DBA-AA3DDF6F9297}" name="visualiser">
|
||||
<FILE id="kfMvdQ" name="BlurFragmentShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/BlurFragmentShader.glsl" xcodeResource="0"/>
|
||||
<FILE id="c59gvD" name="BlurVertexShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/BlurVertexShader.glsl" xcodeResource="0"/>
|
||||
<FILE id="WZFPXF" name="LineFragmentShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/LineFragmentShader.glsl" xcodeResource="0"/>
|
||||
<FILE id="iS2Ipw" name="LineVertexShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/LineVertexShader.glsl" xcodeResource="0"/>
|
||||
<FILE id="hrzO1G" name="OutputFragmentShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/OutputFragmentShader.glsl" xcodeResource="0"/>
|
||||
<FILE id="A0CrLF" name="OutputVertexShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/OutputVertexShader.glsl" xcodeResource="0"/>
|
||||
<FILE id="Gwupwc" name="SimpleFragmentShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/SimpleFragmentShader.glsl"/>
|
||||
<FILE id="RX1oPv" name="SimpleVertexShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/SimpleVertexShader.glsl"/>
|
||||
<FILE id="zR2PyI" name="TexturedFragmentShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/TexturedFragmentShader.glsl"/>
|
||||
<FILE id="TSORlO" name="TexturedVertexShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/TexturedVertexShader.glsl"/>
|
||||
<FILE id="Ju0mVn" name="VisualiserComponent.cpp" compile="1" resource="0"
|
||||
file="Source/visualiser/VisualiserComponent.cpp"/>
|
||||
<FILE id="frfxSR" name="VisualiserComponent.h" compile="0" resource="0"
|
||||
file="Source/visualiser/VisualiserComponent.h"/>
|
||||
<FILE id="iZM7s0" name="VisualiserSettings.cpp" compile="1" resource="0"
|
||||
file="Source/visualiser/VisualiserSettings.cpp"/>
|
||||
<FILE id="CaPdPD" name="VisualiserSettings.h" compile="0" resource="0"
|
||||
file="Source/visualiser/VisualiserSettings.h"/>
|
||||
</GROUP>
|
||||
<GROUP id="{DC345620-B6F6-F3B9-D359-C265590B0F00}" name="wav">
|
||||
<FILE id="vYzJlF" name="WavParser.cpp" compile="1" resource="0" file="Source/wav/WavParser.cpp"/>
|
||||
<FILE id="ZRT5Xk" name="WavParser.h" compile="0" resource="0" file="Source/wav/WavParser.h"/>
|
||||
|
|
64
sosci.jucer
64
sosci.jucer
|
@ -40,28 +40,6 @@
|
|||
<FILE id="rFYmV8" name="timer.svg" compile="0" resource="1" file="Resources/svg/timer.svg"/>
|
||||
<FILE id="qC6QiP" name="volume.svg" compile="0" resource="1" file="Resources/svg/volume.svg"/>
|
||||
</GROUP>
|
||||
<GROUP id="{30FB8C4D-D6E9-397E-AFCF-F0E3DB8D3452}" name="visualiser">
|
||||
<FILE id="ubvkbM" name="BlurFragmentShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/BlurFragmentShader.glsl"/>
|
||||
<FILE id="yx3ze8" name="BlurVertexShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/BlurVertexShader.glsl"/>
|
||||
<FILE id="TFSFmo" name="LineFragmentShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/LineFragmentShader.glsl"/>
|
||||
<FILE id="HFl7ZR" name="LineVertexShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/LineVertexShader.glsl"/>
|
||||
<FILE id="cbvxCE" name="OutputFragmentShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/OutputFragmentShader.glsl"/>
|
||||
<FILE id="pFp9Fz" name="OutputVertexShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/OutputVertexShader.glsl"/>
|
||||
<FILE id="iaabuJ" name="SimpleFragmentShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/SimpleFragmentShader.glsl"/>
|
||||
<FILE id="IeFRq9" name="SimpleVertexShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/SimpleVertexShader.glsl"/>
|
||||
<FILE id="TAi8uQ" name="TexturedFragmentShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/TexturedFragmentShader.glsl"/>
|
||||
<FILE id="H28hvi" name="TexturedVertexShader.glsl" compile="0" resource="1"
|
||||
file="Resources/visualiser/TexturedVertexShader.glsl"/>
|
||||
</GROUP>
|
||||
</GROUP>
|
||||
<GROUP id="{75439074-E50C-362F-1EDF-8B4BE9011259}" name="Source">
|
||||
<GROUP id="{85A33213-D880-BD92-70D8-1901DA6D23F0}" name="audio">
|
||||
|
@ -95,18 +73,6 @@
|
|||
file="Source/components/StopwatchComponent.h"/>
|
||||
<FILE id="f2kkHV" name="SvgButton.h" compile="0" resource="0" file="Source/components/SvgButton.h"/>
|
||||
<FILE id="qzfstC" name="SwitchButton.h" compile="0" resource="0" file="Source/components/SwitchButton.h"/>
|
||||
<FILE id="CAr661" name="VisualiserComponent.cpp" compile="1" resource="0"
|
||||
file="Source/components/VisualiserComponent.cpp"/>
|
||||
<FILE id="wEqs55" name="VisualiserComponent.h" compile="0" resource="0"
|
||||
file="Source/components/VisualiserComponent.h"/>
|
||||
<FILE id="Hdm7tx" name="VisualiserOpenGLComponent.cpp" compile="1"
|
||||
resource="0" file="Source/components/VisualiserOpenGLComponent.cpp"/>
|
||||
<FILE id="KdwehX" name="VisualiserOpenGLComponent.h" compile="0" resource="0"
|
||||
file="Source/components/VisualiserOpenGLComponent.h"/>
|
||||
<FILE id="JxmEAH" name="VisualiserSettings.cpp" compile="1" resource="0"
|
||||
file="Source/components/VisualiserSettings.cpp"/>
|
||||
<FILE id="cY2WUE" name="VisualiserSettings.h" compile="0" resource="0"
|
||||
file="Source/components/VisualiserSettings.h"/>
|
||||
</GROUP>
|
||||
<GROUP id="{9F5970A9-8094-E7F3-7AC1-812AE5589B9F}" name="concurrency">
|
||||
<FILE id="wAUzPb" name="AudioBackgroundThread.cpp" compile="1" resource="0"
|
||||
|
@ -127,6 +93,36 @@
|
|||
<FILE id="G5fbub" name="Shape.cpp" compile="1" resource="0" file="Source/shape/Shape.cpp"/>
|
||||
<FILE id="NmptSY" name="Shape.h" compile="0" resource="0" file="Source/shape/Shape.h"/>
|
||||
</GROUP>
|
||||
<GROUP id="{04ACA01B-2ADE-8356-BF1E-32942E0F3CFA}" name="visualiser">
|
||||
<FILE id="Y4j91J" name="BlurFragmentShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/BlurFragmentShader.glsl"/>
|
||||
<FILE id="Fimn0E" name="BlurVertexShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/BlurVertexShader.glsl"/>
|
||||
<FILE id="R6Yr8V" name="LineFragmentShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/LineFragmentShader.glsl"/>
|
||||
<FILE id="aK7kZN" name="LineVertexShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/LineVertexShader.glsl"/>
|
||||
<FILE id="BnnCmE" name="OutputFragmentShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/OutputFragmentShader.glsl"/>
|
||||
<FILE id="df9jjf" name="OutputVertexShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/OutputVertexShader.glsl"/>
|
||||
<FILE id="ePJ1g0" name="SimpleFragmentShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/SimpleFragmentShader.glsl"/>
|
||||
<FILE id="GFGIEu" name="SimpleVertexShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/SimpleVertexShader.glsl"/>
|
||||
<FILE id="bie77n" name="TexturedFragmentShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/TexturedFragmentShader.glsl"/>
|
||||
<FILE id="EW75fo" name="TexturedVertexShader.glsl" compile="0" resource="0"
|
||||
file="Source/visualiser/TexturedVertexShader.glsl"/>
|
||||
<FILE id="pxVOD9" name="VisualiserComponent.cpp" compile="1" resource="0"
|
||||
file="Source/visualiser/VisualiserComponent.cpp"/>
|
||||
<FILE id="MH6n0v" name="VisualiserComponent.h" compile="0" resource="0"
|
||||
file="Source/visualiser/VisualiserComponent.h"/>
|
||||
<FILE id="wdZb9U" name="VisualiserSettings.cpp" compile="1" resource="0"
|
||||
file="Source/visualiser/VisualiserSettings.cpp"/>
|
||||
<FILE id="v3pCdC" name="VisualiserSettings.h" compile="0" resource="0"
|
||||
file="Source/visualiser/VisualiserSettings.h"/>
|
||||
</GROUP>
|
||||
<FILE id="d2zFqF" name="LookAndFeel.cpp" compile="1" resource="0" file="Source/LookAndFeel.cpp"/>
|
||||
<FILE id="TJDqWs" name="LookAndFeel.h" compile="0" resource="0" file="Source/LookAndFeel.h"/>
|
||||
<FILE id="ajg1QS" name="SosciPluginEditor.cpp" compile="1" resource="0"
|
||||
|
|
Ładowanie…
Reference in New Issue