Fix the most major mac bugs

pull/170/head
James Ball 2023-09-05 20:46:05 +01:00
rodzic c6c3b21e06
commit 81bea16c91
11 zmienionych plików z 54 dodań i 14 usunięć

Wyświetl plik

@ -416,8 +416,14 @@ void OscirenderAudioProcessor::processBlock(juce::AudioBuffer<float>& buffer, ju
auto totalNumOutputChannels = getTotalNumOutputChannels();
buffer.clear();
synth.renderNextBlock(buffer, midiMessages, 0, buffer.getNumSamples());
midiMessages.clear();
// TODO: Make this less hacky and more permanent
if (!playedNote) {
playedNote = true;
midiMessages.addEvent(juce::MidiMessage::noteOn(1, 60, 1.0f), 0);
}
synth.renderNextBlock(buffer, midiMessages, 0, buffer.getNumSamples());
auto* channelData = buffer.getArrayOfWritePointers();
@ -594,17 +600,24 @@ void OscirenderAudioProcessor::setStateInformation(const void* data, int sizeInB
}
}
void OscirenderAudioProcessor::read(std::vector<float>& buffer) {
std::shared_ptr<BufferConsumer> OscirenderAudioProcessor::consumerRegister(std::vector<float>& buffer) {
std::shared_ptr<BufferConsumer> consumer = std::make_shared<BufferConsumer>(buffer);
{
juce::SpinLock::ScopedLockType scope(consumerLock);
consumers.push_back(consumer);
}
juce::SpinLock::ScopedLockType scope(consumerLock);
consumers.push_back(consumer);
return consumer;
}
void OscirenderAudioProcessor::consumerRead(std::shared_ptr<BufferConsumer> consumer) {
consumer->waitUntilFull();
{
juce::SpinLock::ScopedLockType scope(consumerLock);
consumers.erase(std::remove(consumers.begin(), consumers.end(), consumer), consumers.end());
}
void OscirenderAudioProcessor::consumerStop(std::shared_ptr<BufferConsumer> consumer) {
if (consumer != nullptr) {
juce::SpinLock::ScopedLockType scope(consumerLock);
consumers.erase(std::remove(consumers.begin(), consumers.end(), consumer), consumers.end());
consumer->forceNotify();
}
}

Wyświetl plik

@ -58,7 +58,9 @@ public:
void changeProgramName(int index, const juce::String& newName) override;
void getStateInformation(juce::MemoryBlock& destData) override;
void setStateInformation(const void* data, int sizeInBytes) override;
void read(std::vector<float>& buffer);
std::shared_ptr<BufferConsumer> consumerRegister(std::vector<float>& buffer);
void consumerStop(std::shared_ptr<BufferConsumer> consumer);
void consumerRead(std::shared_ptr<BufferConsumer> consumer);
int VERSION_HINT = 1;
@ -216,6 +218,7 @@ private:
std::vector<std::shared_ptr<Effect>> allEffects;
std::vector<std::shared_ptr<Effect>> permanentEffects;
bool playedNote = false;
juce::Synthesiser synth;
juce::SpinLock consumerLock;

Wyświetl plik

@ -41,12 +41,14 @@ AudioWebSocketServer::AudioWebSocketServer(OscirenderAudioProcessor& audioProces
AudioWebSocketServer::~AudioWebSocketServer() {
server.stop();
ix::uninitNetSystem();
audioProcessor.consumerStop(consumer);
stopThread(1000);
}
void AudioWebSocketServer::run() {
while (!threadShouldExit()) {
audioProcessor.read(floatBuffer);
consumer = audioProcessor.consumerRegister(floatBuffer);
audioProcessor.consumerRead(consumer);
for (int i = 0; i < floatBuffer.size(); i++) {
short sample = floatBuffer[i] * 32767;

Wyświetl plik

@ -1,6 +1,7 @@
#pragma once
#include <JuceHeader.h>
#include "../ixwebsocket/IXWebSocketServer.h"
#include "../concurrency/BufferConsumer.h"
class OscirenderAudioProcessor;
class AudioWebSocketServer : juce::Thread {
@ -15,4 +16,6 @@ private:
OscirenderAudioProcessor& audioProcessor;
std::vector<float> floatBuffer = std::vector<float>(2 * 4096);
char buffer[4096 * 2 * 2];
std::shared_ptr<BufferConsumer> consumer;
};

Wyświetl plik

@ -6,12 +6,14 @@ PitchDetector::PitchDetector(OscirenderAudioProcessor& audioProcessor) : juce::T
}
PitchDetector::~PitchDetector() {
audioProcessor.consumerStop(consumer);
stopThread(1000);
}
void PitchDetector::run() {
while (!threadShouldExit()) {
audioProcessor.read(buffer);
consumer = audioProcessor.consumerRegister(buffer);
audioProcessor.consumerRead(consumer);
// buffer is for 2 channels, so we need to only use one
for (int i = 0; i < fftSize; i++) {

Wyświetl plik

@ -1,5 +1,6 @@
#pragma once
#include <JuceHeader.h>
#include "../concurrency/BufferConsumer.h"
class OscirenderAudioProcessor;
class PitchDetector : public juce::Thread, public juce::AsyncUpdater {
@ -19,6 +20,7 @@ private:
static constexpr int fftOrder = 15;
static constexpr int fftSize = 1 << fftOrder;
std::shared_ptr<BufferConsumer> consumer;
std::vector<float> buffer = std::vector<float>(2 * fftSize);
juce::dsp::FFT forwardFFT{fftOrder};
std::array<float, fftSize * 2> fftData;

Wyświetl plik

@ -7,6 +7,7 @@ VisualiserComponent::VisualiserComponent(int numChannels, OscirenderAudioProcess
}
VisualiserComponent::~VisualiserComponent() {
audioProcessor.consumerStop(consumer);
stopThread(1000);
}
@ -44,7 +45,8 @@ void VisualiserComponent::timerCallback() {
void VisualiserComponent::run() {
while (!threadShouldExit()) {
audioProcessor.read(tempBuffer);
consumer = audioProcessor.consumerRegister(tempBuffer);
audioProcessor.consumerRead(consumer);
setBuffer(tempBuffer);
}
}

Wyświetl plik

@ -25,6 +25,8 @@ private:
OscirenderAudioProcessor& audioProcessor;
std::vector<float> tempBuffer = std::vector<float>(2 * 4096);
int precision = 4;
std::shared_ptr<BufferConsumer> consumer;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VisualiserComponent)
};

Wyświetl plik

@ -47,6 +47,7 @@ VolumeComponent::VolumeComponent(OscirenderAudioProcessor& p) : audioProcessor(p
}
VolumeComponent::~VolumeComponent() {
audioProcessor.consumerStop(consumer);
stopThread(1000);
}
@ -92,7 +93,8 @@ void VolumeComponent::timerCallback() {
void VolumeComponent::run() {
while (!threadShouldExit()) {
audioProcessor.read(buffer);
consumer = audioProcessor.consumerRegister(buffer);
audioProcessor.consumerRead(consumer);
float leftVolume = 0;
float rightVolume = 0;

Wyświetl plik

@ -3,6 +3,7 @@
#include <JuceHeader.h>
#include "../PluginProcessor.h"
#include "../LookAndFeel.h"
#include "../concurrency/BufferConsumer.h"
class ThumbRadiusLookAndFeel : public OscirenderLookAndFeel {
public:
@ -84,6 +85,8 @@ private:
std::unique_ptr<juce::Drawable> volumeIcon;
std::unique_ptr<juce::Drawable> thresholdIcon;
std::shared_ptr<BufferConsumer> consumer;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(VolumeComponent)
};

Wyświetl plik

@ -54,6 +54,12 @@ public:
sema.release();
}
}
// to be used when the audio thread is being destroyed to
// make sure that everything waiting on it stops waiting.
void forceNotify() {
sema.release();
}
void write(double d) {
if (offset < buffer.size()) {