Browse Source

Replace Wavetable mutex with lock-free hack.

tags/v2.0.3
Andrew Belt 2 years ago
parent
commit
45b4a6ebfa
3 changed files with 25 additions and 29 deletions
  1. +1
    -5
      src/WTLFO.cpp
  2. +1
    -5
      src/WTVCO.cpp
  3. +23
    -19
      src/Wavetable.hpp

+ 1
- 5
src/WTLFO.cpp View File

@@ -138,13 +138,9 @@ struct WTLFO : Module {

int channels = std::max(1, inputs[FM_INPUT].getChannels());

if (!wavetable.mutex.try_lock())
return;
DEFER({wavetable.mutex.unlock();});

// Check valid wave and wavetable size
int waveCount = wavetable.getWaveCount();
if (wavetable.waveLen >= 2 && waveCount >= 1) {
if (!wavetable.loading && wavetable.waveLen >= 2 && waveCount >= 1) {
// Iterate channels
for (int c = 0; c < channels; c += 4) {
// Calculate frequency in Hz


+ 1
- 5
src/WTVCO.cpp View File

@@ -150,12 +150,8 @@ struct WTVCO : Module {

int channels = std::max({1, inputs[PITCH_INPUT].getChannels(), inputs[FM_INPUT].getChannels()});

if (!wavetable.mutex.try_lock())
return;
DEFER({wavetable.mutex.unlock();});

int waveCount = wavetable.getWaveCount();
if (wavetable.waveLen >= 2 && waveCount >= 1) {
if (!wavetable.loading && wavetable.waveLen >= 2 && waveCount >= 1) {
// Iterate channels
for (int c = 0; c < channels; c += 4) {
// Calculate frequency in Hz


+ 23
- 19
src/Wavetable.hpp View File

@@ -2,7 +2,7 @@
#include <rack.hpp>
#include <osdialog.h>
#include "dr_wav.h"
#include <mutex>
#include <thread>


static const char WAVETABLE_FILTERS[] = "WAV (.wav):wav,WAV;Raw:f32,i8,i16,i24,i32,*";
@@ -11,12 +11,12 @@ static std::string wavetableDir;

/** Loads and stores wavetable samples and metadata */
struct Wavetable {
/** Number of points in each wave */
size_t waveLen = 0;
/** All waves concatenated
(waveCount, waveLen)
*/
std::vector<float> samples;
/** Number of points in each wave */
size_t waveLen = 0;
/** Name of loaded wavetable. */
std::string filename;

@@ -25,9 +25,12 @@ struct Wavetable {
size_t quality = 0;
/** Number of filtered wavetables. Automatically computed from waveLen. */
size_t octaves = 0;
/** (octave, waveCount, waveLen * quality) */
/** Waves bandlimited at each octave
(octave, waveCount, waveLen * quality)
*/
std::vector<float> interpolatedSamples;
mutable std::recursive_mutex mutex;

bool loading = false;

Wavetable() {}

@@ -42,10 +45,12 @@ struct Wavetable {
}

void reset() {
std::lock_guard<std::recursive_mutex> lock(mutex);
filename = "Basic.wav";
waveLen = 1024;
samples.clear();
loading = true;
DEFER({loading = false;});
// HACK Sleep 100us so DSP thread is likely to finish processing before we resize the vector
std::this_thread::sleep_for(std::chrono::duration<double>(100e-6));
samples.resize(waveLen * 4);

// Sine
@@ -72,7 +77,6 @@ struct Wavetable {
}

void setQuality(size_t quality) {
std::lock_guard<std::recursive_mutex> lock(mutex);
if (quality == this->quality)
return;
this->quality = quality;
@@ -80,7 +84,6 @@ struct Wavetable {
}

void setWaveLen(size_t waveLen) {
std::lock_guard<std::recursive_mutex> lock(mutex);
if (waveLen == this->waveLen)
return;
this->waveLen = waveLen;
@@ -95,7 +98,6 @@ struct Wavetable {
}

void interpolate() {
std::lock_guard<std::recursive_mutex> lock(mutex);
if (quality == 0)
return;
if (waveLen < 2)
@@ -140,7 +142,6 @@ struct Wavetable {
}

json_t* toJson() const {
std::lock_guard<std::recursive_mutex> lock(mutex);
json_t* rootJ = json_object();
// waveLen
json_object_set_new(rootJ, "waveLen", json_integer(waveLen));
@@ -150,7 +151,6 @@ struct Wavetable {
}

void fromJson(json_t* rootJ) {
std::lock_guard<std::recursive_mutex> lock(mutex);
// waveLen
json_t* waveLenJ = json_object_get(rootJ, "waveLen");
if (waveLenJ)
@@ -162,7 +162,11 @@ struct Wavetable {
}

void load(std::string path) {
std::lock_guard<std::recursive_mutex> lock(mutex);
loading = true;
DEFER({loading = false;});
// HACK Sleep 100us so DSP thread is likely to finish processing before we resize the vector
std::this_thread::sleep_for(std::chrono::duration<double>(100e-6));

std::string ext = string::lowercase(system::getExtension(path));
if (ext == ".wav") {
// Load WAV
@@ -242,7 +246,9 @@ struct Wavetable {
}

void save(std::string path) const {
std::lock_guard<std::recursive_mutex> lock(mutex);
if (samples.size() == 0)
return;

drwav_data_format format;
format.container = drwav_container_riff;
format.format = DR_WAVE_FORMAT_PCM;
@@ -254,10 +260,9 @@ struct Wavetable {
if (!drwav_init_file_write(&wav, path.c_str(), &format, NULL))
return;

size_t len = samples.size();
int16_t* buf = new int16_t[len];
drwav_f32_to_s16(buf, samples.data(), len);
drwav_write_pcm_frames(&wav, len, buf);
int16_t* buf = new int16_t[samples.size()];
drwav_f32_to_s16(buf, samples.data(), samples.size());
drwav_write_pcm_frames(&wav, samples.size(), buf);
delete[] buf;

drwav_uninit(&wav);
@@ -326,7 +331,6 @@ struct WTDisplay : LedDisplay {

// Get module data or defaults
const Wavetable& wavetable = module ? module->wavetable : defaultWavetable;
std::lock_guard<std::recursive_mutex> lock(wavetable.mutex);
float lastPos = module ? module->lastPos : 0.f;

// Draw filename text


Loading…
Cancel
Save