kopia lustrzana https://github.com/jameshball/osci-render
Fix several bugs on Windows, make more stable, and make visualiser consistent across sample rates
rodzic
8deba8dc7c
commit
9bfdca7b99
|
@ -119,6 +119,15 @@
|
|||
|
||||
let isDebug = true;
|
||||
let paused = false;
|
||||
Juce.getNativeFunction("isPaused")().then(isPaused => {
|
||||
paused = isPaused;
|
||||
if (isPaused) {
|
||||
overlay.style.display = "flex";
|
||||
} else {
|
||||
overlay.style.display = "none";
|
||||
}
|
||||
});
|
||||
|
||||
let openInAnotherWindow = false;
|
||||
let externalSampleRate = 96000;
|
||||
let externalBufferSize = 1920;
|
||||
|
|
|
@ -247,7 +247,7 @@ var Render =
|
|||
|
||||
drawLineTexture : function(xPoints, yPoints)
|
||||
{
|
||||
this.fadeAmount = Math.pow(0.5, controls.persistence)*0.2*AudioSystem.bufferSize/512 ;
|
||||
this.fadeAmount = Math.min(1, Math.pow(0.5, controls.persistence) * 0.4);
|
||||
this.activateTargetTexture(this.lineTexture);
|
||||
this.fade();
|
||||
//gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
@ -432,9 +432,12 @@ var Render =
|
|||
gl.uniform1f(program.uGain, Math.pow(2.0,controls.mainGain)*450/512);
|
||||
if (controls.invertXY) gl.uniform1f(program.uInvert, -1.0);
|
||||
else gl.uniform1f(program.uInvert, 1.0);
|
||||
if (controls.disableFilter) gl.uniform1f(program.uIntensity, 0.005*(Filter.steps+1.5));
|
||||
|
||||
var intensity = 0.02 * (41000 / externalSampleRate);
|
||||
|
||||
if (controls.disableFilter) gl.uniform1f(program.uIntensity, intensity *(Filter.steps+1.5));
|
||||
// +1.5 needed above for some reason for the brightness to match
|
||||
else gl.uniform1f(program.uIntensity, 0.005);
|
||||
else gl.uniform1f(program.uIntensity, intensity);
|
||||
gl.uniform1f(program.uFadeAmount, this.fadeAmount);
|
||||
gl.uniform1f(program.uNEdges, this.nEdges);
|
||||
|
||||
|
@ -745,11 +748,10 @@ function drawCRTFrame(timeStamp) {
|
|||
var xSamples = new Float32Array(externalBufferSize);
|
||||
var ySamples = new Float32Array(externalBufferSize);
|
||||
|
||||
const bufferSizeFn = Juce.getNativeFunction("bufferSize");
|
||||
Juce.getNativeFunction("bufferSize")().then(bufferSize => {
|
||||
externalBufferSize = bufferSize;
|
||||
Juce.getNativeFunction("sampleRate")().then(sampleRate => {
|
||||
externalSampleRate = sampleRate;
|
||||
externalSampleRate = sampleRate;
|
||||
xSamples = new Float32Array(externalBufferSize);
|
||||
ySamples = new Float32Array(externalBufferSize);
|
||||
Render.init();
|
||||
|
|
|
@ -161,14 +161,14 @@ public:
|
|||
// visualiser settings
|
||||
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, 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, 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.");
|
||||
std::shared_ptr<Effect> persistenceEffect = std::make_shared<Effect>(
|
||||
new EffectParameter(
|
||||
"Persistence",
|
||||
"Controls how long the light glows for on the oscilloscope display.",
|
||||
"persistence",
|
||||
VERSION_HINT, 0.0, -1.0, 2.0
|
||||
VERSION_HINT, 0.5, 0, 6.0
|
||||
)
|
||||
);
|
||||
std::shared_ptr<Effect> hueEffect = std::make_shared<Effect>(
|
||||
|
@ -184,7 +184,7 @@ public:
|
|||
"Intensity",
|
||||
"Controls how bright the light glows for on the oscilloscope display.",
|
||||
"intensity",
|
||||
VERSION_HINT, 1.0, -2.0, 2.0
|
||||
VERSION_HINT, 3.0, 0.0, 10.0
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
@ -68,7 +68,6 @@ void MainMenuBarModel::menuItemSelected(int menuItemID, int topLevelMenuIndex) {
|
|||
break;
|
||||
case 1: {
|
||||
audioProcessor.legacyVisualiserEnabled->setBoolValueNotifyingHost(!audioProcessor.legacyVisualiserEnabled->getBoolValue());
|
||||
editor.visualiser.setVisualiserType(audioProcessor.legacyVisualiserEnabled->getBoolValue());
|
||||
menuItemsChanged();
|
||||
} break;
|
||||
case 2: {
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include "VisualiserComponent.h"
|
||||
|
||||
VisualiserComponent::VisualiserComponent(OscirenderAudioProcessor& p, VisualiserComponent* parent, bool useOldVisualiser) : backgroundColour(juce::Colours::black), waveformColour(juce::Colour(0xff00ff00)), audioProcessor(p), oldVisualiser(useOldVisualiser), juce::Thread("VisualiserComponent"), parent(parent) {
|
||||
setVisualiserType(oldVisualiser);
|
||||
|
||||
resetBuffer();
|
||||
startTimerHz(60);
|
||||
startThread();
|
||||
|
@ -11,13 +13,11 @@ VisualiserComponent::VisualiserComponent(OscirenderAudioProcessor& p, Visualiser
|
|||
settings.setLookAndFeel(&getLookAndFeel());
|
||||
settings.setSize(550, 230);
|
||||
settingsWindow.setContentNonOwned(&settings, true);
|
||||
settingsWindow.centreWithSize(550, 230);
|
||||
|
||||
setMouseCursor(juce::MouseCursor::PointingHandCursor);
|
||||
setWantsKeyboardFocus(true);
|
||||
|
||||
addAndMakeVisible(browser);
|
||||
setVisualiserType(oldVisualiser);
|
||||
|
||||
roughness.textBox.setValue(audioProcessor.roughness);
|
||||
roughness.textBox.onValueChange = [this]() {
|
||||
audioProcessor.roughness = (int) roughness.textBox.getValue();
|
||||
|
@ -140,8 +140,8 @@ void VisualiserComponent::run() {
|
|||
juce::WeakReference<VisualiserComponent> visualiser(this);
|
||||
if (!oldVisualiser) {
|
||||
juce::MessageManager::callAsync([this, visualiser] () {
|
||||
if (visualiser) {
|
||||
browser.emitEventIfBrowserIsVisible("audioUpdated", juce::Base64::toBase64(buffer.data(), buffer.size() * sizeof(float)));
|
||||
if (visualiser != nullptr && browser != nullptr) {
|
||||
browser->emitEventIfBrowserIsVisible("audioUpdated", juce::Base64::toBase64(buffer.data(), buffer.size() * sizeof(float)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -223,13 +223,14 @@ void VisualiserComponent::setFullScreen(bool fullScreen) {}
|
|||
|
||||
void VisualiserComponent::setVisualiserType(bool oldVisualiser) {
|
||||
this->oldVisualiser = oldVisualiser;
|
||||
if (oldVisualiser) {
|
||||
// required to hide the browser - it is buggy if we use setVisible(false) on Windows
|
||||
browser.goToURL("about:blank");
|
||||
} else {
|
||||
browser.goToURL(juce::WebBrowserComponent::getResourceProviderRoot() + "oscilloscope.html");
|
||||
if (child != nullptr) {
|
||||
child->setVisualiserType(oldVisualiser);
|
||||
}
|
||||
if (oldVisualiser) {
|
||||
browser.reset();
|
||||
} else {
|
||||
initialiseBrowser();
|
||||
}
|
||||
resized();
|
||||
}
|
||||
|
||||
void VisualiserComponent::paintXY(juce::Graphics& g, juce::Rectangle<float> area) {
|
||||
|
@ -262,19 +263,73 @@ void VisualiserComponent::paintXY(juce::Graphics& g, juce::Rectangle<float> area
|
|||
}
|
||||
}
|
||||
|
||||
void VisualiserComponent::initialiseBrowser() {
|
||||
browser = std::make_unique<juce::WebBrowserComponent>(
|
||||
juce::WebBrowserComponent::Options()
|
||||
.withNativeIntegrationEnabled()
|
||||
.withResourceProvider(provider)
|
||||
.withBackend(juce::WebBrowserComponent::Options::Backend::webview2)
|
||||
.withKeepPageLoadedWhenBrowserIsHidden()
|
||||
.withWinWebView2Options(
|
||||
juce::WebBrowserComponent::Options::WinWebView2{}
|
||||
.withUserDataFolder(juce::File::getSpecialLocation(juce::File::SpecialLocationType::userApplicationDataDirectory).getChildFile("osci-render"))
|
||||
.withStatusBarDisabled()
|
||||
.withBuiltInErrorPageDisabled()
|
||||
)
|
||||
.withNativeFunction("toggleFullscreen", [this](auto& var, auto complete) {
|
||||
enableFullScreen();
|
||||
})
|
||||
.withNativeFunction("popout", [this](auto& var, auto complete) {
|
||||
popoutWindow();
|
||||
})
|
||||
.withNativeFunction("settings", [this](auto& var, auto complete) {
|
||||
openSettings();
|
||||
})
|
||||
.withNativeFunction("isDebug", [this](auto& var, auto complete) {
|
||||
#if JUCE_DEBUG
|
||||
complete(true);
|
||||
#else
|
||||
complete(false);
|
||||
#endif
|
||||
})
|
||||
.withNativeFunction("isOverlay", [this](auto& var, auto complete) {
|
||||
complete(parent != nullptr);
|
||||
})
|
||||
.withNativeFunction("isPaused", [this](auto& var, auto complete) {
|
||||
complete(!active);
|
||||
})
|
||||
.withNativeFunction("pause", [this](auto& var, auto complete) {
|
||||
setPaused(active);
|
||||
})
|
||||
.withNativeFunction("getSettings", [this](auto& var, auto complete) {
|
||||
complete(settings.getSettings());
|
||||
})
|
||||
.withNativeFunction("bufferSize", [this](auto& var, auto complete) {
|
||||
complete((int) tempBuffer.size() / 2);
|
||||
})
|
||||
.withNativeFunction("sampleRate", [this](auto& var, auto complete) {
|
||||
complete(sampleRate);
|
||||
})
|
||||
);
|
||||
|
||||
addAndMakeVisible(*browser);
|
||||
browser->goToURL(juce::WebBrowserComponent::getResourceProviderRoot() + "oscilloscope.html");
|
||||
resized();
|
||||
}
|
||||
|
||||
void VisualiserComponent::resetBuffer() {
|
||||
sampleRate = (int) audioProcessor.currentSampleRate;
|
||||
tempBuffer = std::vector<float>(2 * sampleRate * BUFFER_LENGTH_SECS);
|
||||
if (!oldVisualiser) {
|
||||
browser.goToURL(juce::WebBrowserComponent::getResourceProviderRoot() + "oscilloscope.html");
|
||||
if (!oldVisualiser && isShowing()) {
|
||||
juce::MessageManager::callAsync([this] () {
|
||||
initialiseBrowser();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void VisualiserComponent::resized() {
|
||||
if (oldVisualiser) {
|
||||
browser.setBounds(0, 0, 0, 0);
|
||||
} else {
|
||||
browser.setBounds(getLocalBounds());
|
||||
if (!oldVisualiser) {
|
||||
browser->setBounds(getLocalBounds());
|
||||
}
|
||||
auto area = getLocalBounds();
|
||||
area.removeFromBottom(5);
|
||||
|
@ -290,11 +345,11 @@ void VisualiserComponent::resized() {
|
|||
}
|
||||
|
||||
void VisualiserComponent::childChanged() {
|
||||
browser.emitEventIfBrowserIsVisible("childPresent", child != nullptr);
|
||||
browser->emitEventIfBrowserIsVisible("childPresent", child != nullptr);
|
||||
}
|
||||
|
||||
void VisualiserComponent::popoutWindow() {
|
||||
auto visualiser = new VisualiserComponent(audioProcessor, this);
|
||||
auto visualiser = new VisualiserComponent(audioProcessor, this, oldVisualiser);
|
||||
visualiser->settings.setLookAndFeel(&getLookAndFeel());
|
||||
child = visualiser;
|
||||
childChanged();
|
||||
|
@ -305,6 +360,7 @@ void VisualiserComponent::popoutWindow() {
|
|||
popout->setUsingNativeTitleBar(true);
|
||||
popout->setResizable(true, false);
|
||||
popout->setVisible(true);
|
||||
popout->centreWithSize(300, 300);
|
||||
setPaused(true);
|
||||
resized();
|
||||
popOutButton.setVisible(false);
|
||||
|
|
|
@ -21,9 +21,6 @@ public:
|
|||
VisualiserComponent(OscirenderAudioProcessor& p, VisualiserComponent* parent = nullptr, bool useOldVisualiser = false);
|
||||
~VisualiserComponent() override;
|
||||
|
||||
void setIntensity(double intensity);
|
||||
void setPersistence(double persistence);
|
||||
void setHue(double hue);
|
||||
void openSettings();
|
||||
void childChanged();
|
||||
void enableFullScreen();
|
||||
|
@ -109,46 +106,10 @@ private:
|
|||
juce::WebBrowserComponent::Resource resource = { data, mimeType };
|
||||
return resource;
|
||||
};
|
||||
|
||||
std::unique_ptr<juce::WebBrowserComponent> browser = nullptr;
|
||||
|
||||
juce::WebBrowserComponent browser = juce::WebBrowserComponent(
|
||||
juce::WebBrowserComponent::Options()
|
||||
.withNativeIntegrationEnabled()
|
||||
.withResourceProvider(provider)
|
||||
.withBackend(juce::WebBrowserComponent::Options::Backend::webview2)
|
||||
.withWinWebView2Options(juce::WebBrowserComponent::Options::WinWebView2{})
|
||||
.withNativeFunction("toggleFullscreen", [this](auto& var, auto complete) {
|
||||
enableFullScreen();
|
||||
})
|
||||
.withNativeFunction("popout", [this](auto& var, auto complete) {
|
||||
popoutWindow();
|
||||
})
|
||||
.withNativeFunction("settings", [this](auto& var, auto complete) {
|
||||
openSettings();
|
||||
})
|
||||
.withNativeFunction("isDebug", [this](auto& var, auto complete) {
|
||||
#if JUCE_DEBUG
|
||||
complete(true);
|
||||
#else
|
||||
complete(false);
|
||||
#endif
|
||||
})
|
||||
.withNativeFunction("isOverlay", [this](auto& var, auto complete) {
|
||||
complete(parent != nullptr);
|
||||
})
|
||||
.withNativeFunction("pause", [this](auto& var, auto complete) {
|
||||
setPaused(active);
|
||||
})
|
||||
.withNativeFunction("getSettings", [this](auto& var, auto complete) {
|
||||
complete(settings.getSettings());
|
||||
})
|
||||
.withNativeFunction("bufferSize", [this](auto& var, auto complete) {
|
||||
complete((int) tempBuffer.size() / 2);
|
||||
})
|
||||
.withNativeFunction("sampleRate", [this](auto& var, auto complete) {
|
||||
complete(sampleRate);
|
||||
})
|
||||
);
|
||||
|
||||
void initialiseBrowser();
|
||||
void resetBuffer();
|
||||
void popoutWindow();
|
||||
|
||||
|
|
|
@ -30,8 +30,8 @@ void VisualiserSettings::resized() {
|
|||
|
||||
juce::var VisualiserSettings::getSettings() {
|
||||
auto settings = new juce::DynamicObject();
|
||||
settings->setProperty("intensity", audioProcessor.intensityEffect->getActualValue());
|
||||
settings->setProperty("persistence", audioProcessor.persistenceEffect->getActualValue());
|
||||
settings->setProperty("intensity", audioProcessor.intensityEffect->getActualValue() - 2);
|
||||
settings->setProperty("persistence", audioProcessor.persistenceEffect->getActualValue() - 1.33);
|
||||
settings->setProperty("hue", audioProcessor.hueEffect->getActualValue());
|
||||
settings->setProperty("graticule", audioProcessor.graticuleEnabled->getBoolValue());
|
||||
settings->setProperty("smudges", audioProcessor.smudgesEnabled->getBoolValue());
|
||||
|
|
Ładowanie…
Reference in New Issue