Introduce more locks to prevent concurrency issues

pull/170/head
James Ball 2023-07-11 22:28:54 +01:00
rodzic 3ea8bad02b
commit 89452a4dd6
12 zmienionych plików z 60 dodań i 70 usunięć

Wyświetl plik

@ -31,8 +31,7 @@ OscirenderAudioProcessor::OscirenderAudioProcessor()
)
#endif
{
producer = std::make_unique<FrameProducer>(*this, std::make_shared<FileParser>());
producer->startThread();
producer.startThread();
juce::SpinLock::ScopedLockType lock(effectsLock);
@ -295,12 +294,12 @@ void OscirenderAudioProcessor::openFile(int index) {
void OscirenderAudioProcessor::changeCurrentFile(int index) {
if (index == -1) {
currentFile = -1;
producer->setSource(std::make_shared<FileParser>(), -1);
producer.setSource(std::make_shared<FileParser>(), -1);
}
if (index < 0 || index >= fileBlocks.size()) {
return;
}
producer->setSource(parsers[index], index);
producer.setSource(parsers[index], index);
currentFile = index;
invalidateFrameBuffer = true;
updateLuaValues();
@ -370,8 +369,6 @@ void OscirenderAudioProcessor::updateFrame() {
frameLength = Shape::totalLength(frame);
}
} else {
DBG("frame not ready!");
}
}

Wyświetl plik

@ -171,7 +171,7 @@ public:
std::vector<juce::String> fileNames;
std::atomic<int> currentFile = -1;
std::unique_ptr<FrameProducer> producer;
FrameProducer producer = FrameProducer(*this, std::make_shared<FileParser>());
BufferProducer audioProducer;

Wyświetl plik

@ -1,33 +1,15 @@
#include "SmoothEffect.h"
SmoothEffect::SmoothEffect() {
this->window = std::vector<Vector2>(MAX_WINDOW_SIZE);
}
SmoothEffect::SmoothEffect() {}
SmoothEffect::~SmoothEffect() {}
Vector2 SmoothEffect::apply(int index, Vector2 input, std::vector<EffectDetails> details, double frequency, double sampleRate) {
double value = details[0].value;
int newWindowSize = (int)(256 * value);
windowSize = std::max(1, std::min(MAX_WINDOW_SIZE, newWindowSize));
window[head++] = input;
if (head >= MAX_WINDOW_SIZE) {
head = 0;
}
double totalX = 0;
double totalY = 0;
int newHead = head - 1;
for (int i = 0; i < windowSize; i++) {
if (newHead < 0) {
newHead = MAX_WINDOW_SIZE - 1;
}
totalX += window[newHead].x;
totalY += window[newHead].y;
newHead--;
}
return Vector2(totalX / windowSize, totalY / windowSize);
double weight = details[0].value;
weight *= 0.95;
double strength = 1000000;
weight = std::log(strength * weight + 1) / std::log(strength + 1);
leftAvg = weight * leftAvg + (1 - weight) * input.x;
rightAvg = weight * rightAvg + (1 - weight) * input.y;
return Vector2(leftAvg, rightAvg);
}

Wyświetl plik

@ -9,8 +9,6 @@ public:
Vector2 apply(int index, Vector2 input, std::vector<EffectDetails> details, double frequency, double sampleRate) override;
private:
const int MAX_WINDOW_SIZE = 2048;
std::vector<Vector2> window;
int windowSize = 1;
int head = 0;
double leftAvg = 0;
double rightAvg = 0;
};

Wyświetl plik

@ -6,13 +6,13 @@ void DraggableListBoxItem::paint(juce::Graphics& g)
{
if (insertAfter)
{
g.setColour(juce::Colours::red);
g.fillRect(0, getHeight() - 3, getWidth(), 3);
g.setColour(juce::Colour(0xff00ff00));
g.fillRect(0, getHeight() - 4, getWidth(), 4);
}
else if (insertBefore)
{
g.setColour(juce::Colours::red);
g.fillRect(0, 0, getWidth(), 3);
g.setColour(juce::Colour(0xff00ff00));
g.fillRect(0, 0, getWidth(), 4);
}
}

Wyświetl plik

@ -54,10 +54,8 @@ void EffectComponent::resized() {
}
void EffectComponent::paint(juce::Graphics& g) {
g.fillAll(juce::Colours::lightgrey);
g.setColour(juce::Colours::black);
auto bounds = getLocalBounds();
g.drawRect(bounds);
g.fillAll(juce::Colours::black);
g.setColour(juce::Colours::white);
g.drawText(name, textBounds, juce::Justification::left);
}

Wyświetl plik

@ -3,7 +3,7 @@
EffectsListComponent::EffectsListComponent(DraggableListBox& lb, AudioEffectListBoxItemData& data, int rn, std::shared_ptr<Effect> effect) : DraggableListBoxItem(lb, data, rn), effect(effect) {
auto details = effect->getDetails();
for (int i = 0; i < details.size(); i++) {
std::shared_ptr<EffectComponent> effectComponent = std::make_shared<EffectComponent>(0, 1, 0.01, details[i], i == 0);
std::shared_ptr<EffectComponent> effectComponent = std::make_shared<EffectComponent>(0, 1, 0.001, details[i], i == 0);
// using weak_ptr to avoid circular reference and memory leak
std::weak_ptr<EffectComponent> weakEffectComponent = effectComponent;
effectComponent->slider.setValue(details[i].value, juce::dontSendNotification);
@ -48,21 +48,29 @@ EffectsListComponent::EffectsListComponent(DraggableListBox& lb, AudioEffectList
EffectsListComponent::~EffectsListComponent() {}
void EffectsListComponent::paint(juce::Graphics& g) {
DraggableListBoxItem::paint(g);
auto bounds = getLocalBounds();
g.fillAll(juce::Colours::darkgrey);
g.setColour(juce::Colours::white);
bounds.removeFromLeft(20);
// draw drag and drop handle using circles
g.setColour(juce::Colours::white);
double size = 4;
double leftPad = 4;
double spacing = 7;
double topPad = 7;
g.fillEllipse(leftPad, topPad, size, size);
g.fillEllipse(leftPad, topPad + spacing, size, size);
g.fillEllipse(leftPad, topPad + 2 * spacing, size, size);
g.fillEllipse(leftPad + spacing, topPad, size, size);
g.fillEllipse(leftPad + spacing, topPad + spacing, size, size);
g.fillEllipse(leftPad + spacing, topPad + 2 * spacing, size, size);
double topPad = 6;
double y = bounds.getHeight() / 2 - 15;
g.fillEllipse(leftPad, y + topPad, size, size);
g.fillEllipse(leftPad, y + topPad + spacing, size, size);
g.fillEllipse(leftPad, y + topPad + 2 * spacing, size, size);
g.fillEllipse(leftPad + spacing, y + topPad, size, size);
g.fillEllipse(leftPad + spacing, y + topPad + spacing, size, size);
g.fillEllipse(leftPad + spacing, y + topPad + 2 * spacing, size, size);
DraggableListBoxItem::paint(g);
}
void EffectsListComponent::paintOverChildren(juce::Graphics& g) {
auto bounds = getLocalBounds();
g.setColour(juce::Colours::white);
g.drawRect(bounds);
}
void EffectsListComponent::resized() {

Wyświetl plik

@ -93,6 +93,7 @@ public:
~EffectsListComponent();
void paint(juce::Graphics& g) override;
void paintOverChildren(juce::Graphics& g) override;
void resized() override;
protected:

Wyświetl plik

@ -6,6 +6,8 @@
FileParser::FileParser() {}
void FileParser::parse(juce::String extension, std::unique_ptr<juce::InputStream> stream) {
juce::SpinLock::ScopedLockType scope(lock);
object = nullptr;
camera = nullptr;
svg = nullptr;
@ -28,17 +30,14 @@ void FileParser::parse(juce::String extension, std::unique_ptr<juce::InputStream
}
std::vector<std::unique_ptr<Shape>> FileParser::nextFrame() {
auto tempObject = object;
auto tempCamera = camera;
auto tempSvg = svg;
auto tempText = text;
juce::SpinLock::ScopedLockType scope(lock);
if (tempObject != nullptr && tempCamera != nullptr) {
return tempCamera->draw(*tempObject);
} else if (tempSvg != nullptr) {
return tempSvg->draw();
} else if (tempText != nullptr) {
return tempText->draw();
if (object != nullptr && camera != nullptr) {
return camera->draw(*object);
} else if (svg != nullptr) {
return svg->draw();
} else if (text != nullptr) {
return text->draw();
}
auto tempShapes = std::vector<std::unique_ptr<Shape>>();
tempShapes.push_back(std::make_unique<CircleArc>(0, 0, 0.5, 0.5, std::numbers::pi / 4.0, 2 * std::numbers::pi));
@ -46,9 +45,10 @@ std::vector<std::unique_ptr<Shape>> FileParser::nextFrame() {
}
Vector2 FileParser::nextSample() {
auto tempLua = lua;
if (tempLua != nullptr) {
return tempLua->draw();
juce::SpinLock::ScopedLockType scope(lock);
if (lua != nullptr) {
return lua->draw();
}
}

Wyświetl plik

@ -30,6 +30,8 @@ private:
bool active = true;
bool sampleSource = false;
juce::SpinLock lock;
std::shared_ptr<WorldObject> object;
std::shared_ptr<Camera> camera;
std::shared_ptr<SvgParser> svg;

Wyświetl plik

@ -8,13 +8,16 @@ FrameProducer::~FrameProducer() {
}
void FrameProducer::run() {
while (!threadShouldExit() && frameSource->isActive()) {
while (!threadShouldExit()) {
// this lock is needed so that frameSource isn't deleted whilst nextFrame() is being called
juce::SpinLock::ScopedLockType scope(lock);
frameConsumer.addFrame(frameSource->nextFrame(), sourceFileIndex);
}
}
void FrameProducer::setSource(std::shared_ptr<FrameSource> source, int fileIndex) {
// TODO: should make this atomic
juce::SpinLock::ScopedLockType scope(lock);
frameSource->disable();
frameSource = source;
sourceFileIndex = fileIndex;
}

Wyświetl plik

@ -12,6 +12,7 @@ public:
void run() override;
void setSource(std::shared_ptr<FrameSource>, int fileIndex);
private:
juce::SpinLock lock;
FrameConsumer& frameConsumer;
std::shared_ptr<FrameSource> frameSource;
int sourceFileIndex = -1;