Browse Source

Fix loading of Wavetable if file is not found.

tags/v2.0.1
Andrew Belt 3 years ago
parent
commit
607fefa9d8
2 changed files with 65 additions and 72 deletions
  1. +61
    -70
      src/WTLFO.cpp
  2. +4
    -2
      src/Wavetable.hpp

+ 61
- 70
src/WTLFO.cpp View File

@@ -119,14 +119,6 @@ struct WTLFO : Module {
}
}

void clearOutput() {
outputs[WAVE_OUTPUT].setVoltage(0.f);
outputs[WAVE_OUTPUT].setChannels(1);
lights[PHASE_LIGHT + 0].setBrightness(0.f);
lights[PHASE_LIGHT + 1].setBrightness(0.f);
lights[PHASE_LIGHT + 2].setBrightness(0.f);
}

void process(const ProcessArgs& args) override {
if (offsetTrigger.process(params[OFFSET_PARAM].getValue() > 0.f))
offset ^= true;
@@ -158,72 +150,71 @@ struct WTLFO : Module {
float posCvParam = params[POS_CV_PARAM].getValue();

// Check valid wave and wavetable size
if (wavetable.waveLen < 2) {
clearOutput();
return;
}
int waveCount = wavetable.getWaveCount();
if (waveCount < 1) {
clearOutput();
return;
}

// Iterate channels
for (int c = 0; c < channels; c += 4) {
// Calculate frequency in Hz
float_4 pitch = freqParam + inputs[FM_INPUT].getVoltageSimd<float_4>(c) * fmParam;
float_4 freq = clockFreq / 2.f * dsp::approxExp2_taylor5(pitch + 30.f) / std::pow(2.f, 30.f);
freq = simd::fmin(freq, 1024.f);

// Accumulate phase
float_4 phase = phases[c / 4];
phase += freq * args.sampleTime;
// Wrap phase
phase -= simd::trunc(phase);
// Reset phase
float_4 reset = resetTriggers[c / 4].process(simd::rescale(inputs[RESET_INPUT].getPolyVoltageSimd<float_4>(c), 0.1f, 2.f, 0.f, 1.f));
phase = simd::ifelse(reset, 0.f, phase);
phases[c / 4] = phase;
// Scale phase from 0 to waveLen
phase *= wavetable.waveLen;

// Get wavetable position, scaled from 0 to (waveCount - 1)
float_4 pos = posParam + inputs[POS_INPUT].getPolyVoltageSimd<float_4>(c) * posCvParam / 10.f;
pos = simd::clamp(pos);
pos *= (waveCount - 1);

if (c == 0)
lastPos = pos[0];

// Get wavetable points
float_4 out = 0.f;
for (int cc = 0; cc < 4 && c + cc < channels; cc++) {
// Get wave indexes
float phaseF = phase[cc] - std::trunc(phase[cc]);
size_t i0 = std::trunc(phase[cc]);
size_t i1 = (i0 + 1) % wavetable.waveLen;
// Get pos indexes
float posF = pos[cc] - std::trunc(pos[cc]);
size_t pos0 = std::trunc(pos[cc]);
size_t pos1 = pos0 + 1;
// Get waves
float out0 = crossfade(wavetable.at(pos0, i0), wavetable.at(pos0, i1), phaseF);
if (posF > 0.f) {
float out1 = crossfade(wavetable.at(pos1, i0), wavetable.at(pos1, i1), phaseF);
out[cc] = crossfade(out0, out1, posF);
}
else {
out[cc] = out0;
if (wavetable.waveLen >= 2 && waveCount >= 1) {
// Iterate channels
for (int c = 0; c < channels; c += 4) {
// Calculate frequency in Hz
float_4 pitch = freqParam + inputs[FM_INPUT].getVoltageSimd<float_4>(c) * fmParam;
float_4 freq = clockFreq / 2.f * dsp::approxExp2_taylor5(pitch + 30.f) / std::pow(2.f, 30.f);
freq = simd::fmin(freq, 1024.f);

// Accumulate phase
float_4 phase = phases[c / 4];
phase += freq * args.sampleTime;
// Wrap phase
phase -= simd::trunc(phase);
// Reset phase
float_4 reset = resetTriggers[c / 4].process(simd::rescale(inputs[RESET_INPUT].getPolyVoltageSimd<float_4>(c), 0.1f, 2.f, 0.f, 1.f));
phase = simd::ifelse(reset, 0.f, phase);
phases[c / 4] = phase;
// Scale phase from 0 to waveLen
phase *= wavetable.waveLen;

// Get wavetable position, scaled from 0 to (waveCount - 1)
float_4 pos = posParam + inputs[POS_INPUT].getPolyVoltageSimd<float_4>(c) * posCvParam / 10.f;
pos = simd::clamp(pos);
pos *= (waveCount - 1);

if (c == 0)
lastPos = pos[0];

// Get wavetable points
float_4 out = 0.f;
for (int cc = 0; cc < 4 && c + cc < channels; cc++) {
// Get wave indexes
float phaseF = phase[cc] - std::trunc(phase[cc]);
size_t i0 = std::trunc(phase[cc]);
size_t i1 = (i0 + 1) % wavetable.waveLen;
// Get pos indexes
float posF = pos[cc] - std::trunc(pos[cc]);
size_t pos0 = std::trunc(pos[cc]);
size_t pos1 = pos0 + 1;
// Get waves
float out0 = crossfade(wavetable.at(pos0, i0), wavetable.at(pos0, i1), phaseF);
if (posF > 0.f) {
float out1 = crossfade(wavetable.at(pos1, i0), wavetable.at(pos1, i1), phaseF);
out[cc] = crossfade(out0, out1, posF);
}
else {
out[cc] = out0;
}
}
}

// Invert and offset
if (invert)
out *= -1.f;
if (offset)
out += 1.f;
// Invert and offset
if (invert)
out *= -1.f;
if (offset)
out += 1.f;

outputs[WAVE_OUTPUT].setVoltageSimd(out * 5.f, c);
outputs[WAVE_OUTPUT].setVoltageSimd(out * 5.f, c);
}
}
else {
// Wavetable is invalid, so set 0V
for (int c = 0; c < channels; c += 4) {
outputs[WAVE_OUTPUT].setVoltageSimd(float_4(0.f), c);
}
}

outputs[WAVE_OUTPUT].setChannels(channels);


+ 4
- 2
src/Wavetable.hpp View File

@@ -84,6 +84,8 @@ struct Wavetable {

/** Returns the number of waves in the wavetable. */
size_t getWaveCount() const {
if (waveLen == 0)
return 0;
return samples.size() / waveLen;
}

@@ -145,8 +147,6 @@ struct Wavetable {
}

void load(std::string path) {
samples.clear();

std::string ext = string::lowercase(system::getExtension(path));
if (ext == ".wav") {
// Load WAV
@@ -158,6 +158,7 @@ struct Wavetable {
#endif
return;

samples.clear();
samples.resize(wav.totalPCMFrameCount * wav.channels);

drwav_read_pcm_frames_f32(&wav, wav.totalPCMFrameCount, samples.data());
@@ -166,6 +167,7 @@ struct Wavetable {
else {
// Load bytes from file
std::vector<uint8_t> data = system::readFile(path);
samples.clear();

if (ext == ".f32") {
size_t len = data.size() / sizeof(float);


Loading…
Cancel
Save