Add drop-down for screen type, remove brightness slider, add ambient light slider, add real oscilloscope display

pre-release-3
James H Ball 2024-12-26 23:00:52 +00:00
rodzic 330381f559
commit 12c755c697
12 zmienionych plików z 164 dodań i 62 usunięć

2
.gitignore vendored
Wyświetl plik

@ -5,6 +5,8 @@
.DS_Store
*.psd
# ignore JUCE
**/Builds
**/JuceLibraryCode

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 79 KiB

Wyświetl plik

@ -47,9 +47,9 @@ CommonPluginEditor::CommonPluginEditor(CommonAudioProcessor& p, juce::String app
};
visualiserSettings.setLookAndFeel(&getLookAndFeel());
visualiserSettings.setSize(550, 400);
visualiserSettings.setSize(550, 450);
visualiserSettingsWindow.setContentNonOwned(&visualiserSettings, true);
visualiserSettingsWindow.centreWithSize(550, 400);
visualiserSettingsWindow.centreWithSize(550, 450);
#if JUCE_WINDOWS
// if not standalone, use native title bar for compatibility with DAWs
visualiserSettingsWindow.setUsingNativeTitleBar(processor.wrapperType == juce::AudioProcessor::WrapperType::wrapperType_Standalone);

Wyświetl plik

@ -30,6 +30,10 @@ CommonAudioProcessor::CommonAudioProcessor()
for (auto parameter : visualiserParameters.booleans) {
booleanParameters.push_back(parameter);
}
for (auto parameter : visualiserParameters.integers) {
intParameters.push_back(parameter);
}
}
void CommonAudioProcessor::addAllParameters() {

Wyświetl plik

@ -128,7 +128,7 @@ public:
std::shared_ptr<Effect> perspective = std::make_shared<Effect>(
perspectiveEffect,
std::vector<EffectParameter*>{
new EffectParameter("3D Perspective", "Controls the strength of the 3D perspective projection.", "perspectiveStrength", VERSION_HINT, 1.0, 0.0, 1.0),
new EffectParameter("Perspective", "Controls the strength of the 3D perspective projection.", "perspectiveStrength", VERSION_HINT, 1.0, 0.0, 1.0),
new EffectParameter("Focal Length", "Controls the focal length of the 3D perspective effect. A higher focal length makes the image look more flat, and a lower focal length makes the image look more 3D.", "perspectiveFocalLength", VERSION_HINT, 2.0, 0.0, 10.0),
}
);

Wyświetl plik

@ -7,6 +7,8 @@ std::string lineFragmentShader = R"(
uniform float uSize;
uniform float uIntensity;
uniform float uOffset;
uniform float uScale;
uniform sampler2D uScreen;
varying float vSize;
varying vec4 uvl;
@ -27,6 +29,7 @@ float erf(float x) {
void main() {
vec2 texCoord = (vTexCoord - 0.5) / uScale + 0.5 + uOffset;
float len = uvl.z;
vec2 xy = uvl.xy;
float brightness;
@ -42,7 +45,7 @@ void main() {
}
brightness *= uvl.w;
gl_FragColor = 2.0 * texture2D(uScreen, vTexCoord) * brightness;
gl_FragColor = 2.0 * texture2D(uScreen, texCoord) * brightness;
gl_FragColor.a = 1.0;
}

Wyświetl plik

@ -9,6 +9,10 @@ uniform float uSaturation;
uniform float uNoise;
uniform float uTime;
uniform float uGlow;
uniform float uAmbient;
uniform float uRealScreen;
uniform vec2 uOffset;
uniform vec2 uScale;
uniform vec3 uColour;
varying vec2 vTexCoord;
varying vec2 vTexCoordCanvas;
@ -24,16 +28,21 @@ float noise(in vec2 uv, in float time) {
}
void main() {
vec4 line = texture2D(uTexture0, vTexCoordCanvas);
vec2 linePos = (vTexCoordCanvas - 0.5) / uScale + 0.5 + uOffset;
vec4 line = texture2D(uTexture0, linePos);
// r components have grid; g components do not.
vec4 screen = texture2D(uTexture3, vTexCoord);
vec4 tightGlow = texture2D(uTexture1, vTexCoord);
vec4 scatter = texture2D(uTexture2, vTexCoord)+0.35;
vec4 tightGlow = texture2D(uTexture1, linePos);
vec4 scatter = texture2D(uTexture2, linePos) + (1.0 - uRealScreen) * max(uAmbient - 0.45, 0.0);
float light = line.r + uGlow * 1.5 * screen.g * screen.g * tightGlow.r;
light += uGlow * 0.3 * scatter.g * (2.0 + 1.0 * screen.g + 0.5 * screen.r);
float tlight = 1.0-pow(2.0, -uExposure*light);
float tlight2 = tlight * tlight * tlight;
gl_FragColor.rgb = mix(uColour, vec3(1.0), 0.3+tlight2*tlight2*0.5)*tlight;
gl_FragColor.rgb = mix(uColour, vec3(1.0), 0.3+tlight2*tlight2*0.5) * tlight;
if (uRealScreen > 0.5) {
float ambient = pow(2.0, uExposure) * uAmbient;
gl_FragColor.rgb += ambient * screen.rgb;
}
gl_FragColor.rgb = desaturate(gl_FragColor.rgb, 1.0 - uSaturation);
gl_FragColor.rgb += uNoise * noise(gl_FragCoord.xy, uTime);
gl_FragColor.a = 1.0;

Wyświetl plik

@ -289,25 +289,26 @@ void VisualiserComponent::setRecording(bool recording) {
void VisualiserComponent::resized() {
auto area = getLocalBounds();
buttonRow = area.removeFromBottom(25);
auto buttons = buttonRow;
if (parent == nullptr && !visualiserOnly) {
fullScreenButton.setBounds(buttonRow.removeFromRight(30));
fullScreenButton.setBounds(buttons.removeFromRight(30));
}
if (child == nullptr && parent == nullptr && !visualiserOnly) {
popOutButton.setBounds(buttonRow.removeFromRight(30));
popOutButton.setBounds(buttons.removeFromRight(30));
}
settingsButton.setBounds(buttonRow.removeFromRight(30));
settingsButton.setBounds(buttons.removeFromRight(30));
//if (visualiserOnly) {
sharedTextureButton.setBounds(buttonRow.removeFromRight(30));
sharedTextureButton.setBounds(buttons.removeFromRight(30));
//}
record.setBounds(buttonRow.removeFromRight(25));
record.setBounds(buttons.removeFromRight(25));
if (record.getToggleState()) {
stopwatch.setVisible(true);
stopwatch.setBounds(buttonRow.removeFromRight(100));
stopwatch.setBounds(buttons.removeFromRight(100));
} else {
stopwatch.setVisible(false);
}
if (child == nullptr) {
auto bounds = buttonRow.removeFromRight(160);
auto bounds = buttons.removeFromRight(160);
ffmpegDownloader.setBounds(bounds.withSizeKeepingCentre(bounds.getWidth() - 10, bounds.getHeight() - 10));
}
viewportArea = area;
@ -377,7 +378,6 @@ void VisualiserComponent::newOpenGLContextCreated() {
juce::CriticalSection::ScopedLockType lock(samplesLock);
juce::OpenGLHelpers::clear(juce::Colours::black);
glColorMask(true, true, true, true);
viewportChanged(viewportArea);
@ -455,7 +455,7 @@ void VisualiserComponent::renderOpenGL() {
using namespace juce::gl;
if (openGLContext.isActive()) {
juce::OpenGLHelpers::clear(juce::Colours::black);
juce::OpenGLHelpers::clear(Colours::veryDark);
// we have a new buffer to render
if (sampleBufferCount != prevSampleBufferCount) {
@ -586,8 +586,10 @@ Texture VisualiserComponent::makeTexture(int width, int height) {
// Set texture filtering and wrapping
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
float borderColor[] = { 0.0f, 0.0f, 0.0f, 1.0f };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
glBindTexture(GL_TEXTURE_2D, 0); // Unbind
@ -780,6 +782,11 @@ void VisualiserComponent::drawLine(const std::vector<float>& xPoints, const std:
lineShader->setUniform("uFadeAmount", fadeAmount);
lineShader->setUniform("uNEdges", (GLfloat) nEdges);
OsciPoint offset = settings.getScreenType() == ScreenType::Real ? REAL_SCREEN_OFFSET : OsciPoint();
OsciPoint scale = settings.getScreenType() == ScreenType::Real ? REAL_SCREEN_SCALE : OsciPoint(1);
lineShader->setUniform("uOffset", (float) offset.x, (float) offset.y);
lineShader->setUniform("uScale", (float) scale.x, (float) scale.y);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
int nEdgesThisTime = xPoints.size() - 1;
@ -847,12 +854,17 @@ void VisualiserComponent::drawCRT() {
activateTargetTexture(renderTexture);
setShader(outputShader.get());
float brightness = std::pow(2, settings.getBrightness() - 2);
outputShader->setUniform("uExposure", brightness);
outputShader->setUniform("uExposure", 0.25f);
outputShader->setUniform("uSaturation", (float) settings.getSaturation());
outputShader->setUniform("uNoise", (float) settings.getNoise());
outputShader->setUniform("uTime", time);
outputShader->setUniform("uGlow", (float) settings.getGlow());
outputShader->setUniform("uAmbient", (float) settings.getAmbient());
OsciPoint offset = settings.getScreenType() == ScreenType::Real ? REAL_SCREEN_OFFSET : OsciPoint();
OsciPoint scale = settings.getScreenType() == ScreenType::Real ? REAL_SCREEN_SCALE : OsciPoint(1);
outputShader->setUniform("uOffset", (float) offset.x, (float) offset.y);
outputShader->setUniform("uScale", (float) scale.x, (float) scale.y);
outputShader->setUniform("uRealScreen", settings.getScreenType() == ScreenType::Real ? 1.0f : 0.0f);
outputShader->setUniform("uResizeForCanvas", lineTexture.width / 1024.0f);
juce::Colour colour = juce::Colour::fromHSV(settings.getHue() / 360.0f, 1.0, 1.0, 1.0);
outputShader->setUniform("uColour", colour.getFloatRed(), colour.getFloatGreen(), colour.getFloatBlue());
@ -862,14 +874,16 @@ void VisualiserComponent::drawCRT() {
Texture VisualiserComponent::createScreenTexture() {
using namespace juce::gl;
if (settings.getSmudgesEnabled()) {
if (screenType == ScreenType::Smudged || screenType == ScreenType::SmudgedGraticule) {
screenOpenGLTexture.loadImage(screenTextureImage);
} else if (screenType == ScreenType::Real) {
screenOpenGLTexture.loadImage(oscilloscopeImage);
} else {
screenOpenGLTexture.loadImage(emptyScreenImage);
}
Texture texture = { screenOpenGLTexture.getTextureID(), screenTextureImage.getWidth(), screenTextureImage.getHeight() };
if (settings.getGraticuleEnabled()) {
if (screenType == ScreenType::Graticule || screenType == ScreenType::SmudgedGraticule) {
activateTargetTexture(texture);
setNormalBlending();
setShader(simpleShader.get());
@ -919,7 +933,7 @@ Texture VisualiserComponent::createScreenTexture() {
glVertexAttribPointer(glGetAttribLocation(simpleShader->getProgramID(), "vertexPosition"), 2, GL_FLOAT, GL_FALSE, 0, nullptr);
glBindBuffer(GL_ARRAY_BUFFER, 0);
simpleShader->setUniform("colour", 0.01f, 0.1f, 0.01f, 1.0f);
glLineWidth(1.0f);
glLineWidth(2.0f);
glDrawArrays(GL_LINES, 0, data.size());
glBindTexture(GL_TEXTURE_2D, targetTexture.value().id);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
@ -950,7 +964,7 @@ void VisualiserComponent::checkGLErrors(const juce::String& location) {
void VisualiserComponent::paint(juce::Graphics& g) {
g.setColour(juce::Colours::black);
g.setColour(settings.getScreenType() == ScreenType::Real ? Colours::dark : Colours::veryDark);
g.fillRect(buttonRow);
if (!active) {
// draw a translucent overlay
@ -967,9 +981,8 @@ void VisualiserComponent::paint(juce::Graphics& g) {
void VisualiserComponent::renderScope(const std::vector<float>& xPoints, const std::vector<float>& yPoints, const std::vector<float>& zPoints) {
time += 0.01f;
if (graticuleEnabled != settings.getGraticuleEnabled() || smudgesEnabled != settings.getSmudgesEnabled()) {
graticuleEnabled = settings.getGraticuleEnabled();
smudgesEnabled = settings.getSmudgesEnabled();
if (screenType != settings.getScreenType()) {
screenType = settings.getScreenType();
screenTexture = createScreenTexture();
}

Wyświetl plik

@ -172,6 +172,11 @@ private:
juce::OpenGLTexture screenOpenGLTexture;
juce::Image screenTextureImage = juce::ImageFileFormat::loadFrom(BinaryData::noise_jpg, BinaryData::noise_jpgSize);
juce::Image emptyScreenImage = juce::ImageFileFormat::loadFrom(BinaryData::empty_jpg, BinaryData::empty_jpgSize);
juce::Image oscilloscopeImage = juce::ImageFileFormat::loadFrom(BinaryData::real_jpg, BinaryData::real_jpgSize);
OsciPoint REAL_SCREEN_OFFSET = { 0.02, -0.15 };
OsciPoint REAL_SCREEN_SCALE = { 0.6 };
Texture screenTexture;
std::optional<Texture> targetTexture = std::nullopt;
@ -184,8 +189,7 @@ private:
juce::OpenGLShaderProgram* currentShader;
float fadeAmount;
bool smudgesEnabled = settings.getSmudgesEnabled();
bool graticuleEnabled = settings.getGraticuleEnabled();
ScreenType screenType = settings.getScreenType();
const double RESAMPLE_RATIO = 6.0;
double sampleRate = -1;

Wyświetl plik

@ -3,8 +3,7 @@
#include "../PluginEditor.h"
VisualiserSettings::VisualiserSettings(VisualiserParameters& parameters, int numChannels) : parameters(parameters), numChannels(numChannels) {
addAndMakeVisible(brightness);
VisualiserSettings::VisualiserSettings(VisualiserParameters& p, int numChannels) : parameters(p), numChannels(numChannels) {
addAndMakeVisible(intensity);
addAndMakeVisible(persistence);
addAndMakeVisible(hue);
@ -12,14 +11,22 @@ VisualiserSettings::VisualiserSettings(VisualiserParameters& parameters, int num
addAndMakeVisible(focus);
addAndMakeVisible(noise);
addAndMakeVisible(glow);
addAndMakeVisible(ambient);
addAndMakeVisible(smooth);
addChildComponent(sweepMs);
addAndMakeVisible(graticuleToggle);
addAndMakeVisible(smudgeToggle);
addAndMakeVisible(upsamplingToggle);
addAndMakeVisible(sweepToggle);
addAndMakeVisible(screenTypeLabel);
addAndMakeVisible(screenType);
for (int i = 1; i <= parameters.screenType->max; i++) {
screenType.addItem(parameters.screenType->getText(parameters.screenType->getNormalisedValue(i)), i);
}
screenType.setSelectedId(parameters.screenType->getValueUnnormalised());
screenType.onChange = [this] {
parameters.screenType->setUnnormalisedValueNotifyingHost(screenType.getSelectedId());
};
brightness.setSliderOnValueChange();
intensity.setSliderOnValueChange();
persistence.setSliderOnValueChange();
hue.setSliderOnValueChange();
@ -27,6 +34,7 @@ VisualiserSettings::VisualiserSettings(VisualiserParameters& parameters, int num
focus.setSliderOnValueChange();
noise.setSliderOnValueChange();
glow.setSliderOnValueChange();
ambient.setSliderOnValueChange();
smooth.setSliderOnValueChange();
sweepMs.setSliderOnValueChange();
@ -39,9 +47,14 @@ VisualiserSettings::VisualiserSettings(VisualiserParameters& parameters, int num
VisualiserSettings::~VisualiserSettings() {}
void VisualiserSettings::resized() {
auto area = getLocalBounds().reduced(20);
auto area = getLocalBounds().reduced(20, 0).withTrimmedBottom(20);
double rowHeight = 30;
brightness.setBounds(area.removeFromTop(rowHeight));
auto screenTypeArea = area.removeFromTop(2 * rowHeight);
screenTypeArea = screenTypeArea.withSizeKeepingCentre(300, rowHeight);
screenTypeLabel.setBounds(screenTypeArea.removeFromLeft(120));
screenType.setBounds(screenTypeArea.removeFromRight(180));
intensity.setBounds(area.removeFromTop(rowHeight));
persistence.setBounds(area.removeFromTop(rowHeight));
hue.setBounds(area.removeFromTop(rowHeight));
@ -49,9 +62,9 @@ void VisualiserSettings::resized() {
focus.setBounds(area.removeFromTop(rowHeight));
noise.setBounds(area.removeFromTop(rowHeight));
glow.setBounds(area.removeFromTop(rowHeight));
ambient.setBounds(area.removeFromTop(rowHeight));
smooth.setBounds(area.removeFromTop(rowHeight));
graticuleToggle.setBounds(area.removeFromTop(rowHeight));
smudgeToggle.setBounds(area.removeFromTop(rowHeight));
upsamplingToggle.setBounds(area.removeFromTop(rowHeight));
sweepToggle.setBounds(area.removeFromTop(rowHeight));

Wyświetl plik

@ -9,10 +9,65 @@
#include "../components/SwitchButton.h"
#include "../audio/SmoothEffect.h"
enum class ScreenType : int {
Empty = 1,
Graticule = 2,
Smudged = 3,
SmudgedGraticule = 4,
Real = 5
};
class ScreenTypeParameter : public IntParameter {
public:
ScreenTypeParameter(juce::String name, juce::String id, int versionHint, ScreenType value) : IntParameter(name, id, versionHint, (int) value, 1, 5) {}
juce::String getText(float value, int maximumStringLength = 100) const override {
switch ((ScreenType)(int)getUnnormalisedValue(value)) {
case ScreenType::Empty:
return "Empty";
case ScreenType::Graticule:
return "Graticule";
case ScreenType::Smudged:
return "Smudged";
case ScreenType::SmudgedGraticule:
return "Smudged Graticule";
case ScreenType::Real:
return "Real Oscilloscope";
default:
return "Unknown";
}
}
float getValueForText(const juce::String& text) const override {
int unnormalisedValue;
if (text == "Empty") {
unnormalisedValue = (int)ScreenType::Empty;
} else if (text == "Graticule") {
unnormalisedValue = (int)ScreenType::Graticule;
} else if (text == "Smudged") {
unnormalisedValue = (int)ScreenType::Smudged;
} else if (text == "Smudged Graticule") {
unnormalisedValue = (int)ScreenType::SmudgedGraticule;
} else if (text == "Real Oscilloscope") {
unnormalisedValue = (int)ScreenType::Real;
} else {
unnormalisedValue = (int)ScreenType::Empty;
}
return getNormalisedValue(unnormalisedValue);
}
void save(juce::XmlElement* xml) {
xml->setAttribute("screenType", getText(getValue()));
}
void load(juce::XmlElement* xml) {
setValueNotifyingHost(getValueForText(xml->getStringAttribute("screenType")));
}
};
class VisualiserParameters {
public:
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.");
ScreenTypeParameter* screenType = new ScreenTypeParameter("Screen Type", "screenType", VERSION_HINT, ScreenType::SmudgedGraticule);
BooleanParameter* upsamplingEnabled = new BooleanParameter("Upsample Audio", "upsamplingEnabled", VERSION_HINT, true, "Upsamples the audio before visualising it to make it appear more realistic, at the expense of performance.");
BooleanParameter* sweepEnabled = new BooleanParameter("Sweep", "sweepEnabled", VERSION_HINT, false, "Plots the audio signal over time, sweeping from left to right");
BooleanParameter* visualiserFullScreen = new BooleanParameter("Visualiser Fullscreen", "visualiserFullScreen", VERSION_HINT, false, "Makes the software visualiser fullscreen.");
@ -33,14 +88,6 @@ public:
VERSION_HINT, 125, 0, 359, 1
)
);
std::shared_ptr<Effect> brightnessEffect = std::make_shared<Effect>(
new EffectParameter(
"Brightness",
"Controls how bright the light glows for on the oscilloscope display.",
"brightness",
VERSION_HINT, 2.0, 0.0, 10.0
)
);
std::shared_ptr<Effect> intensityEffect = std::make_shared<Effect>(
new EffectParameter(
"Intensity",
@ -81,6 +128,14 @@ public:
VERSION_HINT, 0.3, 0.0, 1.0
)
);
std::shared_ptr<Effect> ambientEffect = std::make_shared<Effect>(
new EffectParameter(
"Ambient Light",
"Controls how much ambient light is added to the oscilloscope display.",
"ambient",
VERSION_HINT, 0.8, 0.0, 5.0
)
);
std::shared_ptr<Effect> smoothEffect = std::make_shared<Effect>(
std::make_shared<SmoothEffect>(),
new EffectParameter(
@ -99,8 +154,9 @@ public:
)
);
std::vector<std::shared_ptr<Effect>> effects = {persistenceEffect, hueEffect, brightnessEffect, intensityEffect, saturationEffect, focusEffect, noiseEffect, glowEffect, sweepMsEffect};
std::vector<BooleanParameter*> booleans = {graticuleEnabled, smudgesEnabled, upsamplingEnabled, visualiserFullScreen, sweepEnabled};
std::vector<std::shared_ptr<Effect>> effects = {persistenceEffect, hueEffect, intensityEffect, saturationEffect, focusEffect, noiseEffect, glowEffect, ambientEffect, sweepMsEffect};
std::vector<BooleanParameter*> booleans = {upsamplingEnabled, visualiserFullScreen, sweepEnabled};
std::vector<IntParameter*> integers = {screenType};
};
class VisualiserSettings : public juce::Component {
@ -110,10 +166,6 @@ public:
void resized() override;
double getBrightness() {
return parameters.brightnessEffect->getActualValue() - 2;
}
double getIntensity() {
return parameters.intensityEffect->getActualValue() / 100;
}
@ -142,12 +194,12 @@ public:
return parameters.glowEffect->getActualValue() * 3;
}
bool getGraticuleEnabled() {
return parameters.graticuleEnabled->getBoolValue();
double getAmbient() {
return parameters.ambientEffect->getActualValue();
}
bool getSmudgesEnabled() {
return parameters.smudgesEnabled->getBoolValue();
ScreenType getScreenType() {
return (ScreenType)parameters.screenType->getValueUnnormalised();
}
bool getUpsamplingEnabled() {
@ -158,7 +210,6 @@ public:
int numChannels;
private:
EffectComponent brightness{*parameters.brightnessEffect};
EffectComponent intensity{*parameters.intensityEffect};
EffectComponent persistence{*parameters.persistenceEffect};
EffectComponent hue{*parameters.hueEffect};
@ -166,11 +217,13 @@ private:
EffectComponent focus{*parameters.focusEffect};
EffectComponent noise{*parameters.noiseEffect};
EffectComponent glow{*parameters.glowEffect};
EffectComponent ambient{*parameters.ambientEffect};
EffectComponent smooth{*parameters.smoothEffect};
EffectComponent sweepMs{*parameters.sweepMsEffect};
jux::SwitchButton graticuleToggle{parameters.graticuleEnabled};
jux::SwitchButton smudgeToggle{parameters.smudgesEnabled};
juce::Label screenTypeLabel{"Screen Type", "Screen Type"};
juce::ComboBox screenType;
jux::SwitchButton upsamplingToggle{parameters.upsamplingEnabled};
jux::SwitchButton sweepToggle{parameters.sweepEnabled};

Wyświetl plik

@ -34,6 +34,7 @@
<GROUP id="{F3C16D02-63B4-E3DA-7498-901173C37D6C}" name="oscilloscope">
<FILE id="qpPhpN" name="empty.jpg" compile="0" resource="1" file="Resources/oscilloscope/empty.jpg"/>
<FILE id="dNtZYs" name="noise.jpg" compile="0" resource="1" file="Resources/oscilloscope/noise.jpg"/>
<FILE id="FyEDbA" name="real.jpg" compile="0" resource="1" file="Resources/oscilloscope/real.jpg"/>
</GROUP>
<GROUP id="{82BCD6F1-A8BF-F30B-5587-81EE70168883}" name="svg">
<FILE id="rl17ZK" name="cog.svg" compile="0" resource="1" file="Resources/svg/cog.svg"/>