kopia lustrzana https://github.com/jameshball/osci-render
Add drop-down for screen type, remove brightness slider, add ambient light slider, add real oscilloscope display
rodzic
330381f559
commit
12c755c697
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
*.psd
|
||||||
|
|
||||||
# ignore JUCE
|
# ignore JUCE
|
||||||
**/Builds
|
**/Builds
|
||||||
**/JuceLibraryCode
|
**/JuceLibraryCode
|
||||||
|
|
Plik binarny nie jest wyświetlany.
Po Szerokość: | Wysokość: | Rozmiar: 79 KiB |
|
@ -47,9 +47,9 @@ CommonPluginEditor::CommonPluginEditor(CommonAudioProcessor& p, juce::String app
|
||||||
};
|
};
|
||||||
|
|
||||||
visualiserSettings.setLookAndFeel(&getLookAndFeel());
|
visualiserSettings.setLookAndFeel(&getLookAndFeel());
|
||||||
visualiserSettings.setSize(550, 400);
|
visualiserSettings.setSize(550, 450);
|
||||||
visualiserSettingsWindow.setContentNonOwned(&visualiserSettings, true);
|
visualiserSettingsWindow.setContentNonOwned(&visualiserSettings, true);
|
||||||
visualiserSettingsWindow.centreWithSize(550, 400);
|
visualiserSettingsWindow.centreWithSize(550, 450);
|
||||||
#if JUCE_WINDOWS
|
#if JUCE_WINDOWS
|
||||||
// if not standalone, use native title bar for compatibility with DAWs
|
// if not standalone, use native title bar for compatibility with DAWs
|
||||||
visualiserSettingsWindow.setUsingNativeTitleBar(processor.wrapperType == juce::AudioProcessor::WrapperType::wrapperType_Standalone);
|
visualiserSettingsWindow.setUsingNativeTitleBar(processor.wrapperType == juce::AudioProcessor::WrapperType::wrapperType_Standalone);
|
||||||
|
|
|
@ -30,6 +30,10 @@ CommonAudioProcessor::CommonAudioProcessor()
|
||||||
for (auto parameter : visualiserParameters.booleans) {
|
for (auto parameter : visualiserParameters.booleans) {
|
||||||
booleanParameters.push_back(parameter);
|
booleanParameters.push_back(parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto parameter : visualiserParameters.integers) {
|
||||||
|
intParameters.push_back(parameter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommonAudioProcessor::addAllParameters() {
|
void CommonAudioProcessor::addAllParameters() {
|
||||||
|
|
|
@ -128,7 +128,7 @@ public:
|
||||||
std::shared_ptr<Effect> perspective = std::make_shared<Effect>(
|
std::shared_ptr<Effect> perspective = std::make_shared<Effect>(
|
||||||
perspectiveEffect,
|
perspectiveEffect,
|
||||||
std::vector<EffectParameter*>{
|
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),
|
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),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -7,6 +7,8 @@ std::string lineFragmentShader = R"(
|
||||||
|
|
||||||
uniform float uSize;
|
uniform float uSize;
|
||||||
uniform float uIntensity;
|
uniform float uIntensity;
|
||||||
|
uniform float uOffset;
|
||||||
|
uniform float uScale;
|
||||||
uniform sampler2D uScreen;
|
uniform sampler2D uScreen;
|
||||||
varying float vSize;
|
varying float vSize;
|
||||||
varying vec4 uvl;
|
varying vec4 uvl;
|
||||||
|
@ -27,6 +29,7 @@ float erf(float x) {
|
||||||
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
vec2 texCoord = (vTexCoord - 0.5) / uScale + 0.5 + uOffset;
|
||||||
float len = uvl.z;
|
float len = uvl.z;
|
||||||
vec2 xy = uvl.xy;
|
vec2 xy = uvl.xy;
|
||||||
float brightness;
|
float brightness;
|
||||||
|
@ -42,7 +45,7 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
brightness *= uvl.w;
|
brightness *= uvl.w;
|
||||||
gl_FragColor = 2.0 * texture2D(uScreen, vTexCoord) * brightness;
|
gl_FragColor = 2.0 * texture2D(uScreen, texCoord) * brightness;
|
||||||
gl_FragColor.a = 1.0;
|
gl_FragColor.a = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,10 @@ uniform float uSaturation;
|
||||||
uniform float uNoise;
|
uniform float uNoise;
|
||||||
uniform float uTime;
|
uniform float uTime;
|
||||||
uniform float uGlow;
|
uniform float uGlow;
|
||||||
|
uniform float uAmbient;
|
||||||
|
uniform float uRealScreen;
|
||||||
|
uniform vec2 uOffset;
|
||||||
|
uniform vec2 uScale;
|
||||||
uniform vec3 uColour;
|
uniform vec3 uColour;
|
||||||
varying vec2 vTexCoord;
|
varying vec2 vTexCoord;
|
||||||
varying vec2 vTexCoordCanvas;
|
varying vec2 vTexCoordCanvas;
|
||||||
|
@ -24,16 +28,21 @@ float noise(in vec2 uv, in float time) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
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.
|
// r components have grid; g components do not.
|
||||||
vec4 screen = texture2D(uTexture3, vTexCoord);
|
vec4 screen = texture2D(uTexture3, vTexCoord);
|
||||||
vec4 tightGlow = texture2D(uTexture1, vTexCoord);
|
vec4 tightGlow = texture2D(uTexture1, linePos);
|
||||||
vec4 scatter = texture2D(uTexture2, vTexCoord)+0.35;
|
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;
|
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);
|
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 tlight = 1.0-pow(2.0, -uExposure*light);
|
||||||
float tlight2 = tlight * tlight * tlight;
|
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 = desaturate(gl_FragColor.rgb, 1.0 - uSaturation);
|
||||||
gl_FragColor.rgb += uNoise * noise(gl_FragCoord.xy, uTime);
|
gl_FragColor.rgb += uNoise * noise(gl_FragCoord.xy, uTime);
|
||||||
gl_FragColor.a = 1.0;
|
gl_FragColor.a = 1.0;
|
||||||
|
|
|
@ -289,25 +289,26 @@ void VisualiserComponent::setRecording(bool recording) {
|
||||||
void VisualiserComponent::resized() {
|
void VisualiserComponent::resized() {
|
||||||
auto area = getLocalBounds();
|
auto area = getLocalBounds();
|
||||||
buttonRow = area.removeFromBottom(25);
|
buttonRow = area.removeFromBottom(25);
|
||||||
|
auto buttons = buttonRow;
|
||||||
if (parent == nullptr && !visualiserOnly) {
|
if (parent == nullptr && !visualiserOnly) {
|
||||||
fullScreenButton.setBounds(buttonRow.removeFromRight(30));
|
fullScreenButton.setBounds(buttons.removeFromRight(30));
|
||||||
}
|
}
|
||||||
if (child == nullptr && parent == nullptr && !visualiserOnly) {
|
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) {
|
//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()) {
|
if (record.getToggleState()) {
|
||||||
stopwatch.setVisible(true);
|
stopwatch.setVisible(true);
|
||||||
stopwatch.setBounds(buttonRow.removeFromRight(100));
|
stopwatch.setBounds(buttons.removeFromRight(100));
|
||||||
} else {
|
} else {
|
||||||
stopwatch.setVisible(false);
|
stopwatch.setVisible(false);
|
||||||
}
|
}
|
||||||
if (child == nullptr) {
|
if (child == nullptr) {
|
||||||
auto bounds = buttonRow.removeFromRight(160);
|
auto bounds = buttons.removeFromRight(160);
|
||||||
ffmpegDownloader.setBounds(bounds.withSizeKeepingCentre(bounds.getWidth() - 10, bounds.getHeight() - 10));
|
ffmpegDownloader.setBounds(bounds.withSizeKeepingCentre(bounds.getWidth() - 10, bounds.getHeight() - 10));
|
||||||
}
|
}
|
||||||
viewportArea = area;
|
viewportArea = area;
|
||||||
|
@ -377,7 +378,6 @@ void VisualiserComponent::newOpenGLContextCreated() {
|
||||||
|
|
||||||
juce::CriticalSection::ScopedLockType lock(samplesLock);
|
juce::CriticalSection::ScopedLockType lock(samplesLock);
|
||||||
|
|
||||||
juce::OpenGLHelpers::clear(juce::Colours::black);
|
|
||||||
glColorMask(true, true, true, true);
|
glColorMask(true, true, true, true);
|
||||||
|
|
||||||
viewportChanged(viewportArea);
|
viewportChanged(viewportArea);
|
||||||
|
@ -455,7 +455,7 @@ void VisualiserComponent::renderOpenGL() {
|
||||||
using namespace juce::gl;
|
using namespace juce::gl;
|
||||||
|
|
||||||
if (openGLContext.isActive()) {
|
if (openGLContext.isActive()) {
|
||||||
juce::OpenGLHelpers::clear(juce::Colours::black);
|
juce::OpenGLHelpers::clear(Colours::veryDark);
|
||||||
|
|
||||||
// we have a new buffer to render
|
// we have a new buffer to render
|
||||||
if (sampleBufferCount != prevSampleBufferCount) {
|
if (sampleBufferCount != prevSampleBufferCount) {
|
||||||
|
@ -586,8 +586,10 @@ Texture VisualiserComponent::makeTexture(int width, int height) {
|
||||||
// Set texture filtering and wrapping
|
// Set texture filtering and wrapping
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
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_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, 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_EDGE);
|
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
|
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("uFadeAmount", fadeAmount);
|
||||||
lineShader->setUniform("uNEdges", (GLfloat) nEdges);
|
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);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vertexIndexBuffer);
|
||||||
int nEdgesThisTime = xPoints.size() - 1;
|
int nEdgesThisTime = xPoints.size() - 1;
|
||||||
|
@ -847,12 +854,17 @@ void VisualiserComponent::drawCRT() {
|
||||||
|
|
||||||
activateTargetTexture(renderTexture);
|
activateTargetTexture(renderTexture);
|
||||||
setShader(outputShader.get());
|
setShader(outputShader.get());
|
||||||
float brightness = std::pow(2, settings.getBrightness() - 2);
|
outputShader->setUniform("uExposure", 0.25f);
|
||||||
outputShader->setUniform("uExposure", brightness);
|
|
||||||
outputShader->setUniform("uSaturation", (float) settings.getSaturation());
|
outputShader->setUniform("uSaturation", (float) settings.getSaturation());
|
||||||
outputShader->setUniform("uNoise", (float) settings.getNoise());
|
outputShader->setUniform("uNoise", (float) settings.getNoise());
|
||||||
outputShader->setUniform("uTime", time);
|
outputShader->setUniform("uTime", time);
|
||||||
outputShader->setUniform("uGlow", (float) settings.getGlow());
|
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);
|
outputShader->setUniform("uResizeForCanvas", lineTexture.width / 1024.0f);
|
||||||
juce::Colour colour = juce::Colour::fromHSV(settings.getHue() / 360.0f, 1.0, 1.0, 1.0);
|
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());
|
outputShader->setUniform("uColour", colour.getFloatRed(), colour.getFloatGreen(), colour.getFloatBlue());
|
||||||
|
@ -862,14 +874,16 @@ void VisualiserComponent::drawCRT() {
|
||||||
Texture VisualiserComponent::createScreenTexture() {
|
Texture VisualiserComponent::createScreenTexture() {
|
||||||
using namespace juce::gl;
|
using namespace juce::gl;
|
||||||
|
|
||||||
if (settings.getSmudgesEnabled()) {
|
if (screenType == ScreenType::Smudged || screenType == ScreenType::SmudgedGraticule) {
|
||||||
screenOpenGLTexture.loadImage(screenTextureImage);
|
screenOpenGLTexture.loadImage(screenTextureImage);
|
||||||
|
} else if (screenType == ScreenType::Real) {
|
||||||
|
screenOpenGLTexture.loadImage(oscilloscopeImage);
|
||||||
} else {
|
} else {
|
||||||
screenOpenGLTexture.loadImage(emptyScreenImage);
|
screenOpenGLTexture.loadImage(emptyScreenImage);
|
||||||
}
|
}
|
||||||
Texture texture = { screenOpenGLTexture.getTextureID(), screenTextureImage.getWidth(), screenTextureImage.getHeight() };
|
Texture texture = { screenOpenGLTexture.getTextureID(), screenTextureImage.getWidth(), screenTextureImage.getHeight() };
|
||||||
|
|
||||||
if (settings.getGraticuleEnabled()) {
|
if (screenType == ScreenType::Graticule || screenType == ScreenType::SmudgedGraticule) {
|
||||||
activateTargetTexture(texture);
|
activateTargetTexture(texture);
|
||||||
setNormalBlending();
|
setNormalBlending();
|
||||||
setShader(simpleShader.get());
|
setShader(simpleShader.get());
|
||||||
|
@ -919,7 +933,7 @@ Texture VisualiserComponent::createScreenTexture() {
|
||||||
glVertexAttribPointer(glGetAttribLocation(simpleShader->getProgramID(), "vertexPosition"), 2, GL_FLOAT, GL_FALSE, 0, nullptr);
|
glVertexAttribPointer(glGetAttribLocation(simpleShader->getProgramID(), "vertexPosition"), 2, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
simpleShader->setUniform("colour", 0.01f, 0.1f, 0.01f, 1.0f);
|
simpleShader->setUniform("colour", 0.01f, 0.1f, 0.01f, 1.0f);
|
||||||
glLineWidth(1.0f);
|
glLineWidth(2.0f);
|
||||||
glDrawArrays(GL_LINES, 0, data.size());
|
glDrawArrays(GL_LINES, 0, data.size());
|
||||||
glBindTexture(GL_TEXTURE_2D, targetTexture.value().id);
|
glBindTexture(GL_TEXTURE_2D, targetTexture.value().id);
|
||||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
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) {
|
void VisualiserComponent::paint(juce::Graphics& g) {
|
||||||
g.setColour(juce::Colours::black);
|
g.setColour(settings.getScreenType() == ScreenType::Real ? Colours::dark : Colours::veryDark);
|
||||||
g.fillRect(buttonRow);
|
g.fillRect(buttonRow);
|
||||||
if (!active) {
|
if (!active) {
|
||||||
// draw a translucent overlay
|
// 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) {
|
void VisualiserComponent::renderScope(const std::vector<float>& xPoints, const std::vector<float>& yPoints, const std::vector<float>& zPoints) {
|
||||||
time += 0.01f;
|
time += 0.01f;
|
||||||
|
|
||||||
if (graticuleEnabled != settings.getGraticuleEnabled() || smudgesEnabled != settings.getSmudgesEnabled()) {
|
if (screenType != settings.getScreenType()) {
|
||||||
graticuleEnabled = settings.getGraticuleEnabled();
|
screenType = settings.getScreenType();
|
||||||
smudgesEnabled = settings.getSmudgesEnabled();
|
|
||||||
screenTexture = createScreenTexture();
|
screenTexture = createScreenTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -172,6 +172,11 @@ private:
|
||||||
juce::OpenGLTexture screenOpenGLTexture;
|
juce::OpenGLTexture screenOpenGLTexture;
|
||||||
juce::Image screenTextureImage = juce::ImageFileFormat::loadFrom(BinaryData::noise_jpg, BinaryData::noise_jpgSize);
|
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 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;
|
Texture screenTexture;
|
||||||
std::optional<Texture> targetTexture = std::nullopt;
|
std::optional<Texture> targetTexture = std::nullopt;
|
||||||
|
|
||||||
|
@ -184,8 +189,7 @@ private:
|
||||||
juce::OpenGLShaderProgram* currentShader;
|
juce::OpenGLShaderProgram* currentShader;
|
||||||
|
|
||||||
float fadeAmount;
|
float fadeAmount;
|
||||||
bool smudgesEnabled = settings.getSmudgesEnabled();
|
ScreenType screenType = settings.getScreenType();
|
||||||
bool graticuleEnabled = settings.getGraticuleEnabled();
|
|
||||||
|
|
||||||
const double RESAMPLE_RATIO = 6.0;
|
const double RESAMPLE_RATIO = 6.0;
|
||||||
double sampleRate = -1;
|
double sampleRate = -1;
|
||||||
|
|
|
@ -3,8 +3,7 @@
|
||||||
#include "../PluginEditor.h"
|
#include "../PluginEditor.h"
|
||||||
|
|
||||||
|
|
||||||
VisualiserSettings::VisualiserSettings(VisualiserParameters& parameters, int numChannels) : parameters(parameters), numChannels(numChannels) {
|
VisualiserSettings::VisualiserSettings(VisualiserParameters& p, int numChannels) : parameters(p), numChannels(numChannels) {
|
||||||
addAndMakeVisible(brightness);
|
|
||||||
addAndMakeVisible(intensity);
|
addAndMakeVisible(intensity);
|
||||||
addAndMakeVisible(persistence);
|
addAndMakeVisible(persistence);
|
||||||
addAndMakeVisible(hue);
|
addAndMakeVisible(hue);
|
||||||
|
@ -12,14 +11,22 @@ VisualiserSettings::VisualiserSettings(VisualiserParameters& parameters, int num
|
||||||
addAndMakeVisible(focus);
|
addAndMakeVisible(focus);
|
||||||
addAndMakeVisible(noise);
|
addAndMakeVisible(noise);
|
||||||
addAndMakeVisible(glow);
|
addAndMakeVisible(glow);
|
||||||
|
addAndMakeVisible(ambient);
|
||||||
addAndMakeVisible(smooth);
|
addAndMakeVisible(smooth);
|
||||||
addChildComponent(sweepMs);
|
addChildComponent(sweepMs);
|
||||||
addAndMakeVisible(graticuleToggle);
|
|
||||||
addAndMakeVisible(smudgeToggle);
|
|
||||||
addAndMakeVisible(upsamplingToggle);
|
addAndMakeVisible(upsamplingToggle);
|
||||||
addAndMakeVisible(sweepToggle);
|
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();
|
intensity.setSliderOnValueChange();
|
||||||
persistence.setSliderOnValueChange();
|
persistence.setSliderOnValueChange();
|
||||||
hue.setSliderOnValueChange();
|
hue.setSliderOnValueChange();
|
||||||
|
@ -27,6 +34,7 @@ VisualiserSettings::VisualiserSettings(VisualiserParameters& parameters, int num
|
||||||
focus.setSliderOnValueChange();
|
focus.setSliderOnValueChange();
|
||||||
noise.setSliderOnValueChange();
|
noise.setSliderOnValueChange();
|
||||||
glow.setSliderOnValueChange();
|
glow.setSliderOnValueChange();
|
||||||
|
ambient.setSliderOnValueChange();
|
||||||
smooth.setSliderOnValueChange();
|
smooth.setSliderOnValueChange();
|
||||||
sweepMs.setSliderOnValueChange();
|
sweepMs.setSliderOnValueChange();
|
||||||
|
|
||||||
|
@ -39,9 +47,14 @@ VisualiserSettings::VisualiserSettings(VisualiserParameters& parameters, int num
|
||||||
VisualiserSettings::~VisualiserSettings() {}
|
VisualiserSettings::~VisualiserSettings() {}
|
||||||
|
|
||||||
void VisualiserSettings::resized() {
|
void VisualiserSettings::resized() {
|
||||||
auto area = getLocalBounds().reduced(20);
|
auto area = getLocalBounds().reduced(20, 0).withTrimmedBottom(20);
|
||||||
double rowHeight = 30;
|
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));
|
intensity.setBounds(area.removeFromTop(rowHeight));
|
||||||
persistence.setBounds(area.removeFromTop(rowHeight));
|
persistence.setBounds(area.removeFromTop(rowHeight));
|
||||||
hue.setBounds(area.removeFromTop(rowHeight));
|
hue.setBounds(area.removeFromTop(rowHeight));
|
||||||
|
@ -49,9 +62,9 @@ void VisualiserSettings::resized() {
|
||||||
focus.setBounds(area.removeFromTop(rowHeight));
|
focus.setBounds(area.removeFromTop(rowHeight));
|
||||||
noise.setBounds(area.removeFromTop(rowHeight));
|
noise.setBounds(area.removeFromTop(rowHeight));
|
||||||
glow.setBounds(area.removeFromTop(rowHeight));
|
glow.setBounds(area.removeFromTop(rowHeight));
|
||||||
|
ambient.setBounds(area.removeFromTop(rowHeight));
|
||||||
smooth.setBounds(area.removeFromTop(rowHeight));
|
smooth.setBounds(area.removeFromTop(rowHeight));
|
||||||
graticuleToggle.setBounds(area.removeFromTop(rowHeight));
|
|
||||||
smudgeToggle.setBounds(area.removeFromTop(rowHeight));
|
|
||||||
upsamplingToggle.setBounds(area.removeFromTop(rowHeight));
|
upsamplingToggle.setBounds(area.removeFromTop(rowHeight));
|
||||||
|
|
||||||
sweepToggle.setBounds(area.removeFromTop(rowHeight));
|
sweepToggle.setBounds(area.removeFromTop(rowHeight));
|
||||||
|
|
|
@ -9,10 +9,65 @@
|
||||||
#include "../components/SwitchButton.h"
|
#include "../components/SwitchButton.h"
|
||||||
#include "../audio/SmoothEffect.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 {
|
class VisualiserParameters {
|
||||||
public:
|
public:
|
||||||
BooleanParameter* graticuleEnabled = new BooleanParameter("Show Graticule", "graticuleEnabled", VERSION_HINT, true, "Show the graticule or grid lines over the oscilloscope display.");
|
ScreenTypeParameter* screenType = new ScreenTypeParameter("Screen Type", "screenType", VERSION_HINT, ScreenType::SmudgedGraticule);
|
||||||
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, true, "Upsamples the audio before visualising it to make it appear more realistic, at the expense of performance.");
|
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* 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.");
|
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
|
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>(
|
std::shared_ptr<Effect> intensityEffect = std::make_shared<Effect>(
|
||||||
new EffectParameter(
|
new EffectParameter(
|
||||||
"Intensity",
|
"Intensity",
|
||||||
|
@ -81,6 +128,14 @@ public:
|
||||||
VERSION_HINT, 0.3, 0.0, 1.0
|
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::shared_ptr<Effect> smoothEffect = std::make_shared<Effect>(
|
||||||
std::make_shared<SmoothEffect>(),
|
std::make_shared<SmoothEffect>(),
|
||||||
new EffectParameter(
|
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<std::shared_ptr<Effect>> effects = {persistenceEffect, hueEffect, intensityEffect, saturationEffect, focusEffect, noiseEffect, glowEffect, ambientEffect, sweepMsEffect};
|
||||||
std::vector<BooleanParameter*> booleans = {graticuleEnabled, smudgesEnabled, upsamplingEnabled, visualiserFullScreen, sweepEnabled};
|
std::vector<BooleanParameter*> booleans = {upsamplingEnabled, visualiserFullScreen, sweepEnabled};
|
||||||
|
std::vector<IntParameter*> integers = {screenType};
|
||||||
};
|
};
|
||||||
|
|
||||||
class VisualiserSettings : public juce::Component {
|
class VisualiserSettings : public juce::Component {
|
||||||
|
@ -110,10 +166,6 @@ public:
|
||||||
|
|
||||||
void resized() override;
|
void resized() override;
|
||||||
|
|
||||||
double getBrightness() {
|
|
||||||
return parameters.brightnessEffect->getActualValue() - 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
double getIntensity() {
|
double getIntensity() {
|
||||||
return parameters.intensityEffect->getActualValue() / 100;
|
return parameters.intensityEffect->getActualValue() / 100;
|
||||||
}
|
}
|
||||||
|
@ -142,12 +194,12 @@ public:
|
||||||
return parameters.glowEffect->getActualValue() * 3;
|
return parameters.glowEffect->getActualValue() * 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getGraticuleEnabled() {
|
double getAmbient() {
|
||||||
return parameters.graticuleEnabled->getBoolValue();
|
return parameters.ambientEffect->getActualValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getSmudgesEnabled() {
|
ScreenType getScreenType() {
|
||||||
return parameters.smudgesEnabled->getBoolValue();
|
return (ScreenType)parameters.screenType->getValueUnnormalised();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getUpsamplingEnabled() {
|
bool getUpsamplingEnabled() {
|
||||||
|
@ -158,7 +210,6 @@ public:
|
||||||
int numChannels;
|
int numChannels;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EffectComponent brightness{*parameters.brightnessEffect};
|
|
||||||
EffectComponent intensity{*parameters.intensityEffect};
|
EffectComponent intensity{*parameters.intensityEffect};
|
||||||
EffectComponent persistence{*parameters.persistenceEffect};
|
EffectComponent persistence{*parameters.persistenceEffect};
|
||||||
EffectComponent hue{*parameters.hueEffect};
|
EffectComponent hue{*parameters.hueEffect};
|
||||||
|
@ -166,11 +217,13 @@ private:
|
||||||
EffectComponent focus{*parameters.focusEffect};
|
EffectComponent focus{*parameters.focusEffect};
|
||||||
EffectComponent noise{*parameters.noiseEffect};
|
EffectComponent noise{*parameters.noiseEffect};
|
||||||
EffectComponent glow{*parameters.glowEffect};
|
EffectComponent glow{*parameters.glowEffect};
|
||||||
|
EffectComponent ambient{*parameters.ambientEffect};
|
||||||
EffectComponent smooth{*parameters.smoothEffect};
|
EffectComponent smooth{*parameters.smoothEffect};
|
||||||
EffectComponent sweepMs{*parameters.sweepMsEffect};
|
EffectComponent sweepMs{*parameters.sweepMsEffect};
|
||||||
|
|
||||||
jux::SwitchButton graticuleToggle{parameters.graticuleEnabled};
|
juce::Label screenTypeLabel{"Screen Type", "Screen Type"};
|
||||||
jux::SwitchButton smudgeToggle{parameters.smudgesEnabled};
|
juce::ComboBox screenType;
|
||||||
|
|
||||||
jux::SwitchButton upsamplingToggle{parameters.upsamplingEnabled};
|
jux::SwitchButton upsamplingToggle{parameters.upsamplingEnabled};
|
||||||
jux::SwitchButton sweepToggle{parameters.sweepEnabled};
|
jux::SwitchButton sweepToggle{parameters.sweepEnabled};
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
<GROUP id="{F3C16D02-63B4-E3DA-7498-901173C37D6C}" name="oscilloscope">
|
<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="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="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>
|
||||||
<GROUP id="{82BCD6F1-A8BF-F30B-5587-81EE70168883}" name="svg">
|
<GROUP id="{82BCD6F1-A8BF-F30B-5587-81EE70168883}" name="svg">
|
||||||
<FILE id="rl17ZK" name="cog.svg" compile="0" resource="1" file="Resources/svg/cog.svg"/>
|
<FILE id="rl17ZK" name="cog.svg" compile="0" resource="1" file="Resources/svg/cog.svg"/>
|
||||||
|
|
Ładowanie…
Reference in New Issue