Save size and layout of application and adjust afterglow effect

pull/281/head
James H Ball 2025-02-02 23:09:42 +00:00
rodzic 7aa3ed203b
commit e00f57aaac
13 zmienionych plików z 153 dodań i 40 usunięć

Wyświetl plik

@ -2,7 +2,7 @@
#include "CommonPluginEditor.h"
#include <juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h>
CommonPluginEditor::CommonPluginEditor(CommonAudioProcessor& p, juce::String appName, juce::String projectFileType, int width, int height)
CommonPluginEditor::CommonPluginEditor(CommonAudioProcessor& p, juce::String appName, juce::String projectFileType, int defaultWidth, int defaultHeight)
: AudioProcessorEditor(&p), audioProcessor(p), appName(appName), projectFileType(projectFileType)
{
if (!applicationFolder.exists()) {
@ -37,6 +37,9 @@ CommonPluginEditor::CommonPluginEditor(CommonAudioProcessor& p, juce::String app
}
addAndMakeVisible(visualiser);
int width = std::any_cast<int>(audioProcessor.getProperty("appWidth", defaultWidth));
int height = std::any_cast<int>(audioProcessor.getProperty("appHeight", defaultHeight));
visualiserSettings.setLookAndFeel(&getLookAndFeel());
visualiserSettings.setSize(550, VISUALISER_SETTINGS_HEIGHT);
@ -65,6 +68,11 @@ CommonPluginEditor::CommonPluginEditor(CommonAudioProcessor& p, juce::String app
#endif
}
void CommonPluginEditor::resized() {
audioProcessor.setProperty("appWidth", getWidth());
audioProcessor.setProperty("appHeight", getHeight());
}
void CommonPluginEditor::initialiseMenuBar(juce::MenuBarModel& menuBarModel) {
menuBar.setModel(&menuBarModel);
}

Wyświetl plik

@ -23,6 +23,7 @@ public:
void openAudioSettings();
void openRecordingSettings();
void resetToDefault();
void resized() override;
private:
CommonAudioProcessor& audioProcessor;

Wyświetl plik

@ -225,3 +225,79 @@ void CommonAudioProcessor::removeAudioPlayerListener(AudioPlayerListener* listen
juce::SpinLock::ScopedLockType lock(audioPlayerListenersLock);
audioPlayerListeners.erase(std::remove(audioPlayerListeners.begin(), audioPlayerListeners.end(), listener), audioPlayerListeners.end());
}
std::any CommonAudioProcessor::getProperty(const std::string& key) {
juce::SpinLock::ScopedLockType lock(propertiesLock);
return properties[key];
}
std::any CommonAudioProcessor::getProperty(const std::string& key, std::any defaultValue) {
juce::SpinLock::ScopedLockType lock(propertiesLock);
auto it = properties.find(key);
if (it == properties.end()) {
properties[key] = defaultValue;
return defaultValue;
}
return it->second;
}
void CommonAudioProcessor::setProperty(const std::string& key, std::any value) {
juce::SpinLock::ScopedLockType lock(propertiesLock);
properties[key] = value;
}
void CommonAudioProcessor::saveProperties(juce::XmlElement& xml) {
juce::SpinLock::ScopedLockType lock(propertiesLock);
auto propertiesXml = xml.createNewChildElement("properties");
for (auto& property : properties) {
auto element = propertiesXml->createNewChildElement("property");
element->setAttribute("key", property.first);
if (std::any_cast<int>(&property.second) != nullptr) {
element->setAttribute("type", "int");
element->setAttribute("value", std::any_cast<int>(property.second));
} else if (std::any_cast<float>(&property.second) != nullptr) {
element->setAttribute("type", "float");
element->setAttribute("value", std::any_cast<float>(property.second));
} else if (std::any_cast<double>(&property.second) != nullptr) {
element->setAttribute("type", "double");
element->setAttribute("value", std::any_cast<double>(property.second));
} else if (std::any_cast<bool>(&property.second) != nullptr) {
element->setAttribute("type", "bool");
element->setAttribute("value", std::any_cast<bool>(property.second));
} else if (std::any_cast<juce::String>(&property.second) != nullptr) {
element->setAttribute("type", "string");
element->setAttribute("value", std::any_cast<juce::String>(property.second));
} else {
jassertfalse;
}
}
}
void CommonAudioProcessor::loadProperties(juce::XmlElement& xml) {
juce::SpinLock::ScopedLockType lock(propertiesLock);
auto propertiesXml = xml.getChildByName("properties");
if (propertiesXml != nullptr) {
for (auto property : propertiesXml->getChildIterator()) {
auto key = property->getStringAttribute("key").toStdString();
auto type = property->getStringAttribute("type");
if (type == "int") {
properties[key] = property->getIntAttribute("value");
} else if (type == "float") {
properties[key] = property->getDoubleAttribute("value");
} else if (type == "double") {
properties[key] = property->getDoubleAttribute("value");
} else if (type == "bool") {
properties[key] = property->getBoolAttribute("value");
} else if (type == "string") {
properties[key] = property->getStringAttribute("value");
} else {
jassertfalse;
}
}
}
}

Wyświetl plik

@ -9,6 +9,7 @@
#pragma once
#include <JuceHeader.h>
#include <any>
#include "concurrency/AudioBackgroundThread.h"
#include "concurrency/AudioBackgroundThreadManager.h"
#include "audio/SampleRateManager.h"
@ -59,6 +60,9 @@ public:
void stopAudioFile();
void addAudioPlayerListener(AudioPlayerListener* listener);
void removeAudioPlayerListener(AudioPlayerListener* listener);
std::any getProperty(const std::string& key);
std::any getProperty(const std::string& key, std::any defaultValue);
void setProperty(const std::string& key, std::any value);
juce::SpinLock audioPlayerListenersLock;
std::vector<AudioPlayerListener*> audioPlayerListeners;
@ -122,6 +126,12 @@ protected:
BooleanParameter* getBooleanParameter(juce::String id);
FloatParameter* getFloatParameter(juce::String id);
IntParameter* getIntParameter(juce::String id);
void saveProperties(juce::XmlElement& xml);
void loadProperties(juce::XmlElement& xml);
juce::SpinLock propertiesLock;
std::unordered_map<std::string, std::any> properties;
//==============================================================================
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CommonAudioProcessor)

Wyświetl plik

@ -2,8 +2,7 @@
#include "PluginEditor.h"
#include <juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h>
OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioProcessor& p)
: CommonPluginEditor(p, "osci-render", "osci", 1100, 750), audioProcessor(p), collapseButton("Collapse", juce::Colours::white, juce::Colours::white, juce::Colours::white) {
OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioProcessor& p) : CommonPluginEditor(p, "osci-render", "osci", 1100, 750), audioProcessor(p), collapseButton("Collapse", juce::Colours::white, juce::Colours::white, juce::Colours::white) {
#if !SOSCI_FEATURES
addAndMakeVisible(upgradeButton);
upgradeButton.onClick = [this] {
@ -28,16 +27,9 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr
addAndMakeVisible(collapseButton);
collapseButton.onClick = [this] {
{
juce::SpinLock::ScopedLockType lock(audioProcessor.parsersLock);
int originalIndex = audioProcessor.getCurrentFileIndex();
int index = editingCustomFunction ? 0 : audioProcessor.getCurrentFileIndex() + 1;
if (originalIndex != -1 || editingCustomFunction) {
codeEditors[index]->setVisible(!codeEditors[index]->isVisible());
updateCodeEditor(!editingCustomFunction && isBinaryFile(audioProcessor.getCurrentFileName()));
}
}
setCodeEditorVisible(std::nullopt);
};
juce::Path path;
path.addTriangle(0.0f, 0.5f, 1.0f, 1.0f, 1.0f, 0.0f);
collapseButton.setShape(path, false, true, true);
@ -55,17 +47,20 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr
audioProcessor.fileChangeBroadcaster.addChangeListener(this);
audioProcessor.broadcaster.addChangeListener(this);
}
double codeEditorLayoutPreferredSize = std::any_cast<double>(audioProcessor.getProperty("codeEditorLayoutPreferredSize", -0.7));
double luaLayoutPreferredSize = std::any_cast<double>(audioProcessor.getProperty("luaLayoutPreferredSize", -0.7));
layout.setItemLayout(0, -0.3, -1.0, -0.7);
layout.setItemLayout(0, -0.3, -1.0, codeEditorLayoutPreferredSize);
layout.setItemLayout(1, RESIZER_BAR_SIZE, RESIZER_BAR_SIZE, RESIZER_BAR_SIZE);
layout.setItemLayout(2, -0.0, -1.0, -0.3);
layout.setItemLayout(2, -0.0, -1.0, -(1.0 + codeEditorLayoutPreferredSize));
addAndMakeVisible(settings);
addAndMakeVisible(resizerBar);
luaLayout.setItemLayout(0, -0.3, -1.0, -0.7);
luaLayout.setItemLayout(0, -0.3, -1.0, luaLayoutPreferredSize);
luaLayout.setItemLayout(1, RESIZER_BAR_SIZE, RESIZER_BAR_SIZE, RESIZER_BAR_SIZE);
luaLayout.setItemLayout(2, -0.1, -1.0, -0.3);
luaLayout.setItemLayout(2, -0.1, -1.0, -(1.0 + luaLayoutPreferredSize));
addAndMakeVisible(lua);
addAndMakeVisible(luaResizerBar);
@ -96,6 +91,16 @@ OscirenderAudioProcessorEditor::~OscirenderAudioProcessorEditor() {
audioProcessor.fileChangeBroadcaster.removeChangeListener(this);
}
void OscirenderAudioProcessorEditor::setCodeEditorVisible(std::optional<bool> visible) {
juce::SpinLock::ScopedLockType lock(audioProcessor.parsersLock);
int originalIndex = audioProcessor.getCurrentFileIndex();
int index = editingCustomFunction ? 0 : audioProcessor.getCurrentFileIndex() + 1;
if (originalIndex != -1 || editingCustomFunction) {
codeEditors[index]->setVisible(visible.has_value() ? visible.value() : !codeEditors[index]->isVisible());
updateCodeEditor(!editingCustomFunction && isBinaryFile(audioProcessor.getCurrentFileName()));
}
}
bool OscirenderAudioProcessorEditor::isInterestedInFileDrag(const juce::StringArray& files) {
if (files.size() != 1) {
return false;
@ -146,7 +151,8 @@ void OscirenderAudioProcessorEditor::initialiseCodeEditors() {
for (int i = 0; i < audioProcessor.numFiles(); i++) {
addCodeEditor(i);
}
fileUpdated(audioProcessor.getCurrentFileName());
bool codeEditorVisible = std::any_cast<bool>(audioProcessor.getProperty("codeEditorVisible", false));
fileUpdated(audioProcessor.getCurrentFileName(), codeEditorVisible);
}
void OscirenderAudioProcessorEditor::paint(juce::Graphics& g) {
@ -154,6 +160,8 @@ void OscirenderAudioProcessorEditor::paint(juce::Graphics& g) {
}
void OscirenderAudioProcessorEditor::resized() {
CommonPluginEditor::resized();
auto area = getLocalBounds();
if (audioProcessor.visualiserParameters.visualiserFullScreen->getBoolValue()) {
@ -254,6 +262,10 @@ void OscirenderAudioProcessorEditor::resized() {
}
settings.setBounds(area);
audioProcessor.setProperty("codeEditorLayoutPreferredSize", layout.getItemCurrentRelativeSize(0));
audioProcessor.setProperty("luaLayoutPreferredSize", luaLayout.getItemCurrentRelativeSize(0));
repaint();
}
@ -335,6 +347,9 @@ void OscirenderAudioProcessorEditor::updateCodeEditor(bool binaryFile, bool shou
updatingDocumentsWithParserLock = false;
}
}
audioProcessor.setProperty("codeEditorVisible", visible);
triggerAsyncUpdate();
}
@ -371,7 +386,7 @@ void OscirenderAudioProcessorEditor::toggleLayout(juce::StretchableLayoutManager
layout.getItemLayout(2, minSize, maxSize, preferredSize);
layout.getItemLayout(0, otherMinSize, otherMaxSize, otherPreferredSize);
if (preferredSize == CLOSED_PREF_SIZE) {
if (layout.getItemCurrentAbsoluteSize(2) <= CLOSED_PREF_SIZE) {
double otherPrefSize = -(1 + prefSize);
if (prefSize > 0) {
otherPrefSize = -1.0;

Wyświetl plik

@ -78,6 +78,7 @@ public:
void codeDocumentTextDeleted(int startIndex, int endIndex) override;
void updateCodeDocument();
void updateCodeEditor(bool binaryFile, bool shouldOpenEditor = false);
void setCodeEditorVisible(std::optional<bool> visible);
bool keyPressed(const juce::KeyPress& key) override;
void mouseDown(const juce::MouseEvent& event) override;

Wyświetl plik

@ -665,6 +665,8 @@ void OscirenderAudioProcessor::getStateInformation(juce::MemoryBlock& destData)
xml->setAttribute("currentFile", currentFile);
recordingParameters.save(xml.get());
saveProperties(*xml);
copyXmlToBinary(*xml, destData);
}
@ -780,6 +782,8 @@ void OscirenderAudioProcessor::setStateInformation(const void* data, int sizeInB
changeCurrentFile(xml->getIntAttribute("currentFile", -1));
recordingParameters.load(xml.get());
loadProperties(*xml);
broadcaster.sendChangeMessage();
prevMidiEnabled = !midiEnabled->getBoolValue();

Wyświetl plik

@ -10,14 +10,17 @@ SettingsComponent::SettingsComponent(OscirenderAudioProcessor& p, OscirenderAudi
addAndMakeVisible(midi);
addChildComponent(txt);
addChildComponent(frame);
double midiLayoutPreferredSize = std::any_cast<double>(audioProcessor.getProperty("midiLayoutPreferredSize", pluginEditor.CLOSED_PREF_SIZE));
double mainLayoutPreferredSize = std::any_cast<double>(audioProcessor.getProperty("mainLayoutPreferredSize", -0.4));
midiLayout.setItemLayout(0, -0.1, -1.0, -1.0);
midiLayout.setItemLayout(0, -0.1, -1.0, -(1.0 + midiLayoutPreferredSize));
midiLayout.setItemLayout(1, pluginEditor.RESIZER_BAR_SIZE, pluginEditor.RESIZER_BAR_SIZE, pluginEditor.RESIZER_BAR_SIZE);
midiLayout.setItemLayout(2, pluginEditor.CLOSED_PREF_SIZE, -0.9, pluginEditor.CLOSED_PREF_SIZE);
mainLayout.setItemLayout(0, -0.1, -0.9, -0.4);
midiLayout.setItemLayout(2, pluginEditor.CLOSED_PREF_SIZE, -0.9, midiLayoutPreferredSize);
mainLayout.setItemLayout(0, -0.1, -0.9, mainLayoutPreferredSize);
mainLayout.setItemLayout(1, pluginEditor.RESIZER_BAR_SIZE, pluginEditor.RESIZER_BAR_SIZE, pluginEditor.RESIZER_BAR_SIZE);
mainLayout.setItemLayout(2, -0.1, -0.9, -0.6);
mainLayout.setItemLayout(2, -0.1, -0.9, -(1.0 + mainLayoutPreferredSize));
}
@ -59,6 +62,9 @@ void SettingsComponent::resized() {
}
effects.setBounds(dummyBounds);
audioProcessor.setProperty("midiLayoutPreferredSize", midiLayout.getItemCurrentRelativeSize(2));
audioProcessor.setProperty("mainLayoutPreferredSize", mainLayout.getItemCurrentRelativeSize(0));
repaint();
}

Wyświetl plik

@ -50,6 +50,7 @@ void SosciPluginEditor::paint(juce::Graphics& g) {
}
void SosciPluginEditor::resized() {
CommonPluginEditor::resized();
auto area = getLocalBounds();
if (audioProcessor.visualiserParameters.visualiserFullScreen->getBoolValue()) {

Wyświetl plik

@ -122,6 +122,8 @@ void SosciAudioProcessor::getStateInformation(juce::MemoryBlock& destData) {
}
recordingParameters.save(xml.get());
saveProperties(*xml);
copyXmlToBinary(*xml, destData);
}
@ -182,6 +184,8 @@ void SosciAudioProcessor::setStateInformation(const void* data, int sizeInBytes)
}
recordingParameters.load(xml.get());
loadProperties(*xml);
}
}

Wyświetl plik

@ -12,7 +12,9 @@ float hypTan(float x) {
void main() {
vec4 line = texture2D(uTexture0, vTexCoord);
float fade = fadeAmount * hypTan(min(line.r / afterglowAmount, 10.0));
float x = min(line.r / afterglowAmount, 10.0);
float minFade = 0.1 * (1.0 - clamp(afterglowAmount / 10.0, 0.0, 1.0));
float fade = fadeAmount * ((1.0 - minFade) * hypTan(x) + minFade);
fade = clamp(fade, 0.0, fadeAmount);
gl_FragColor = vec4(0.0, 0.0, 0.0, fade);

Wyświetl plik

@ -1176,17 +1176,11 @@ void VisualiserComponent::drawCRT() {
#if SOSCI_FEATURES
outputShader->setUniform("uScreenSaturation", (float) settings.getScreenSaturation());
outputShader->setUniform("uHueShift", (float) settings.getScreenHue() / 360.0f);
<<<<<<< Updated upstream
#else
outputShader->setUniform("uScreenSaturation", 1.0f);
outputShader->setUniform("uHueShift", 0.0f);
=======
outputShader->setUniform("uOverexposure", (float) settings.getOverexposure());
#else
outputShader->setUniform("uScreenSaturation", 1.0f);
outputShader->setUniform("uHueShift", 0.0f);
outputShader->setUniform("uOverexposure", 0.5f);
>>>>>>> Stashed changes
#endif
outputShader->setUniform("uNoise", (float) settings.getNoise());
outputShader->setUniform("uRandom", juce::Random::getSystemRandom().nextFloat());

Wyświetl plik

@ -119,9 +119,7 @@ public:
"Afterglow",
"Controls how quickly the image disappears after glowing brightly. Closely related to persistence.",
"afterglow",
VERSION_HINT, 1.5, 0.0, 5.0
<<<<<<< Updated upstream
=======
VERSION_HINT, 1.0, 0.0, 10.0
)
);
std::shared_ptr<Effect> overexposureEffect = std::make_shared<Effect>(
@ -130,7 +128,6 @@ public:
"Controls at which point the line becomes overexposed and clips, turning white.",
"overexposure",
VERSION_HINT, 0.5, 0.0, 1.0
>>>>>>> Stashed changes
)
);
std::shared_ptr<StereoEffect> stereoEffectApplication = std::make_shared<StereoEffect>();
@ -286,10 +283,7 @@ public:
afterglowEffect,
screenSaturationEffect,
screenHueEffect,
<<<<<<< Updated upstream
=======
overexposureEffect,
>>>>>>> Stashed changes
#endif
};
std::vector<std::shared_ptr<Effect>> audioEffects = {
@ -464,10 +458,7 @@ private:
std::make_shared<EffectComponent>(*parameters.glowEffect),
#if SOSCI_FEATURES
std::make_shared<EffectComponent>(*parameters.afterglowEffect),
<<<<<<< Updated upstream
=======
std::make_shared<EffectComponent>(*parameters.overexposureEffect),
>>>>>>> Stashed changes
#else
std::make_shared<EffectComponent>(*parameters.ambientEffect),
#endif