From 607fefa9d8cd7763066af3d6911946076f4105cb Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Mon, 1 Nov 2021 02:15:14 -0400 Subject: [PATCH] Fix loading of Wavetable if file is not found. --- src/WTLFO.cpp | 131 +++++++++++++++++++++------------------------- src/Wavetable.hpp | 6 ++- 2 files changed, 65 insertions(+), 72 deletions(-) diff --git a/src/WTLFO.cpp b/src/WTLFO.cpp index d5ca482..494c1ae 100644 --- a/src/WTLFO.cpp +++ b/src/WTLFO.cpp @@ -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(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(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(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(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(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(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); diff --git a/src/Wavetable.hpp b/src/Wavetable.hpp index 080afaa..0160ed8 100644 --- a/src/Wavetable.hpp +++ b/src/Wavetable.hpp @@ -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 data = system::readFile(path); + samples.clear(); if (ext == ".f32") { size_t len = data.size() / sizeof(float);