Fix laggy visualiser component on lower sample rates

pull/170/head
James Ball 2023-12-21 17:24:39 +00:00
rodzic 2fa34819d9
commit 972a9840cd
5 zmienionych plików z 32 dodań i 16 usunięć

Wyświetl plik

@ -11,6 +11,7 @@ OscirenderAudioProcessorEditor::OscirenderAudioProcessorEditor(OscirenderAudioPr
#if JUCE_MAC
if (audioProcessor.wrapperType == juce::AudioProcessor::WrapperType::wrapperType_Standalone) {
usingNativeMenuBar = true;
menuBarModel.setMacMainMenu(&menuBarModel);
}
#endif
@ -77,6 +78,12 @@ OscirenderAudioProcessorEditor::~OscirenderAudioProcessorEditor() {
juce::MessageManagerLock lock;
audioProcessor.broadcaster.removeChangeListener(this);
audioProcessor.fileChangeBroadcaster.removeChangeListener(this);
#if JUCE_MAC
if (usingNativeMenuBar) {
menuBarModel.setMacMainMenu(nullptr);
}
#endif
}
// parsersLock must be held

Wyświetl plik

@ -237,6 +237,7 @@ void OscirenderAudioProcessor::prepareToPlay(double sampleRate, int samplesPerBl
currentSampleRate = sampleRate;
pitchDetector.setSampleRate(sampleRate);
synth.setCurrentPlaybackSampleRate(sampleRate);
retriggerMidi = true;
}
void OscirenderAudioProcessor::releaseResources() {
@ -556,9 +557,10 @@ void OscirenderAudioProcessor::processBlock(juce::AudioBuffer<float>& buffer, ju
}
}
// if midi has just been disabled
if (prevMidiEnabled && !usingMidi) {
// if midi has just been disabled or we need to retrigger
if (!usingMidi && (retriggerMidi || prevMidiEnabled)) {
midiMessages.addEvent(juce::MidiMessage::noteOn(1, 60, 1.0f), 17);
retriggerMidi = false;
}
prevMidiEnabled = usingMidi;

Wyświetl plik

@ -327,6 +327,7 @@ private:
ShapeSound::Ptr defaultSound = new ShapeSound(std::make_shared<FileParser>());
PublicSynthesiser synth;
bool retriggerMidi = true;
AudioWebSocketServer softwareOscilloscopeServer{*this};
ObjectServer objectServer{*this};

Wyświetl plik

@ -2,6 +2,7 @@
VisualiserComponent::VisualiserComponent(int numChannels, OscirenderAudioProcessor& p) : numChannels(numChannels), backgroundColour(juce::Colours::black), waveformColour(juce::Colour(0xff00ff00)), audioProcessor(p), juce::Thread("VisualiserComponent") {
setOpaque(true);
resetBuffer();
startTimerHz(60);
startThread();
}
@ -58,6 +59,10 @@ void VisualiserComponent::timerCallback() {
void VisualiserComponent::run() {
while (!threadShouldExit()) {
if (sampleRate != (int) audioProcessor.currentSampleRate) {
resetBuffer();
}
consumer = audioProcessor.consumerRegister(tempBuffer);
audioProcessor.consumerRead(consumer);
setBuffer(tempBuffer);
@ -110,26 +115,20 @@ void VisualiserComponent::paintXY(juce::Graphics& g, juce::Rectangle<float> area
}
double strength = 15;
double strengthLast = 5;
double widthDivisor = 130;
double widthDivisorLast = 130;
juce::Colour waveColor = waveformColour;
juce::Colour waveColorLast = waveColor;
for (auto& line : prevLines) {
line.applyTransform(transform);
float lengthScale = (line.getLength() + 0.001);
float lengthScaleLog = std::log(strengthLast * (1.f / lengthScale) + 1) / std::log(strengthLast + 1);
g.setColour(waveColorLast.withAlpha(std::max(0.f, std::min(lengthScaleLog, 1.f))));
g.drawLine(line, area.getWidth() * (lengthScaleLog * 0.3 + 0.7) / widthDivisorLast);
}
prevLines = lines;
for (auto& line : lines) {
line.applyTransform(transform);
float lengthScale = (line.getLength() + 0.001);
float normalisedLength = line.getLength() * (sampleRate / DEFAULT_SAMPLE_RATE);
float lengthScale = (normalisedLength + 0.001);
float lengthScaleLog = std::log(strength * (1 / lengthScale) + 1) / std::log(strength + 1);
g.setColour(waveColor.withAlpha(std::max(0.f, std::min(lengthScaleLog, 1.f))).withSaturation(std::pow(lengthScale, 2)));
g.drawLine(line, area.getWidth() * (lengthScaleLog * 0.3 + 0.7) / widthDivisor);
}
}
void VisualiserComponent::resetBuffer() {
sampleRate = (int) audioProcessor.currentSampleRate;
tempBuffer = std::vector<float>(2 * sampleRate * BUFFER_LENGTH_SECS);
}

Wyświetl plik

@ -21,18 +21,25 @@ public:
void mouseDown(const juce::MouseEvent& event) override;
private:
const double BUFFER_LENGTH_SECS = 0.02;
const double DEFAULT_SAMPLE_RATE = 192000.0;
juce::CriticalSection lock;
std::vector<float> buffer;
std::vector<juce::Line<float>> prevLines;
int numChannels = 2;
juce::Colour backgroundColour, waveformColour;
OscirenderAudioProcessor& audioProcessor;
std::vector<float> tempBuffer = std::vector<float>(2 * 4096);
int sampleRate = DEFAULT_SAMPLE_RATE;
std::vector<float> tempBuffer;
int precision = 4;
std::atomic<bool> active = true;
std::shared_ptr<BufferConsumer> consumer;
void resetBuffer();
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VisualiserComponent)
};