Skip to content

Commit

Permalink
move (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
connorlbark authored Dec 27, 2024
1 parent 0034d48 commit bba034d
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 110 deletions.
4 changes: 2 additions & 2 deletions siderialib/include/effects/Disperse.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ namespace siderialib {
sfloat _lastOutR = 0.f;

LFO _lfo;
BiquadFilter _postLpfL;
BiquadFilter _postLpfR;

void updateSpread();
void updateDispersionAndPosition();
Expand Down Expand Up @@ -95,6 +93,8 @@ namespace siderialib {
inline sfloat getModDepth() const { return this->_modDepth; }
void setMix(sfloat mix);
inline sfloat getMix() const { return this->_mix; }
void setTone(sfloat tone);
inline sfloat getTone() const { return _tone; }

void setPingPongType(DispersePingPong pingPong);

Expand Down
18 changes: 0 additions & 18 deletions siderialib/include/effects/delay/ModulatedDelay.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,6 @@ namespace siderialib

LFO *_mod;

// 2-stage lpf placed before writing to circular buffer, so in essence, filters delayed sounds many times
BiquadFilter _lpf1L;
BiquadFilter _lpf1R;
BiquadFilter _lpf2L;
BiquadFilter _lpf2R;
// 2-stage hpf
BiquadFilter _hpf1L;
BiquadFilter _hpf1R;
BiquadFilter _hpf2L;
BiquadFilter _hpf2R;

bool _enableLpf;
bool _enableHpf;

bool _pingPong;
PingPongDirection _pingPongDirection = PingPongDirection::LEFT;

Expand Down Expand Up @@ -74,10 +60,6 @@ namespace siderialib
void setPan(sfloat pan) { this->_pan = pan; }
sfloat getPan() const { return this->_pan; }

void setLpfParams(sfloat cutoff, sfloat Q, sfloat dBGain);
void setHpfParams(sfloat cuoff, sfloat Q, sfloat dBGain);
void enableLpf(bool enabled) { this->_enableLpf = enabled; }
void enableHpf(bool enabled) { this->_enableHpf = enabled; }
void enablePingPong(bool enabled) { this->_pingPong = enabled; }
};
}
60 changes: 29 additions & 31 deletions siderialib/include/effects/disperse/DisperseParallelVoice.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#pragma once


#include <cstdarg>
#include "effects/delay/ModulatedDelay.h"
#include "DisperseConstants.h"

Expand All @@ -15,48 +13,48 @@ namespace siderialib {

sfloat _lastOutL = 0.0;
sfloat _lastOutR = 0.0;
public:
DisperseParallelVoice() = default;

void addVoice(ModulatedDelay* delay) {
if (_numActiveVoices >= DISPERSE_NUM_VOICES) {
return;
}

_delays[_numActiveVoices] = delay;
_numActiveVoices++;
}
bool _enableTone = false;
// 2-stage lpf placed before writing to circular buffer, so in essence, filters delayed sounds many times
bool useLpf = false;
BiquadFilter _lpf1L;
BiquadFilter _lpf1R;
BiquadFilter _lpf2L;
BiquadFilter _lpf2R;

void clearVoices() {
for (int i = 0; i < _numActiveVoices; i++) {
_delays[i] = nullptr;
}
sfloat sampleRate = 0.0;

_numActiveVoices = 0;
}
bool useHpf = false;
// 2-stage hpf
BiquadFilter _hpf1L;
BiquadFilter _hpf1R;
BiquadFilter _hpf2L;
BiquadFilter _hpf2R;

void initialize() {
}
void applyFilters();
public:
DisperseParallelVoice() = default;

void addVoice(ModulatedDelay* delay);

void clearVoices();

void initialize(sfloat samplingRate);

void tick(sfloat L, sfloat R) {
sfloat parallelL = L;
sfloat parallelR = R;
void tick(sfloat L, sfloat R);

for (int i = 0; i < _numActiveVoices; i++) {
_delays[i]->tick(L, R);
parallelL = _delays[i]->lastOutL();
parallelR = _delays[i]->lastOutR();
}
void setTone(sfloat tone);

_lastOutL = parallelL;
_lastOutR = parallelR;
void enableTone(bool enable) {
_enableTone = enable;
}

sfloat lastOutL() const {
inline sfloat lastOutL() const {
return _lastOutL;
}

sfloat lastOutR() const {
inline sfloat lastOutR() const {
return _lastOutR;
}
};
Expand Down
21 changes: 15 additions & 6 deletions siderialib/src/effects/Disperse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@ void Disperse::setPingPongType(siderialib::DispersePingPong pingPong) {
this->updatePingPong();
}

void Disperse::updateTone() {
for (int i = 0; i < DISPERSE_NUM_VOICES; i++) {
_voices[i].setTone(_tone);
}
}

void Disperse::setTone(sfloat tone) {
this->_tone = tone;
updateTone();
}

sfloat Disperse::lastOutR() const {
return _lastOutR;
}
Expand Down Expand Up @@ -160,13 +171,12 @@ void Disperse::setResampleFactor(siderialib::sfloat ratio) {
void Disperse::initialize(sfloat sampleRate) {
this->_sampleRate = sampleRate;
_lfo.initialize(sampleRate);
_postLpfL.initialize(_sampleRate, BiquadType::LPF, 8000.0, 0.7);
_postLpfR.initialize(_sampleRate, BiquadType::LPF, 8000.0, 0.7);

int maxDelaySamps = std::ceil((DISPERSE_MAX_DELAY_MS/1000.0) * _sampleRate);
for (int i = 0; i < DISPERSE_NUM_VOICES; i++) {
_delays[i].initialize(&_lfo, _sampleRate, maxDelaySamps);
_delays[i].enableLpf(false);
_voices[i].initialize(_sampleRate);
_voices[i].enableTone(false);
}

setArrangement(DisperseArrangement::FULL_PARALLEL);
Expand All @@ -193,12 +203,11 @@ void Disperse::initialize(sfloat *voiceBufs[DISPERSE_NUM_VOICES],
sfloat sampleRate) {
this->_sampleRate = sampleRate;
_lfo.initialize(sampleRate);
_postLpfL.initialize(_sampleRate, BiquadType::LPF, 8000.0f, 0.7f);
_postLpfR.initialize(_sampleRate, BiquadType::LPF, 8000.0f, 0.7f);

for (int i = 0; i < DISPERSE_NUM_VOICES; i++) {
_delays[i].initialize(&_lfo, _sampleRate, voiceBufs[i], bufLength);
_delays[i].enableLpf(false);
_voices[i].initialize(_sampleRate);
_voices[i].enableTone(false);
}

setArrangement(DisperseArrangement::FULL_PARALLEL);
Expand Down
45 changes: 0 additions & 45 deletions siderialib/src/effects/delay/ModulatedDelay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,6 @@ void ModulatedDelay::tick(sfloat L, sfloat R) {
}

void ModulatedDelay::writeToBuffer(sfloat L, sfloat R) {

if (_enableLpf) {
L = this->_lpf1L.tick(this->_lpf2L.tick(L));
R = this->_lpf1R.tick(this->_lpf2R.tick(R));
}

if (_enableHpf) {
L = this->_hpf1L.tick(this->_hpf2L.tick(L));
R = this->_hpf1R.tick(this->_hpf2R.tick(R));

}

this->_buf.writeCircular(L, R);
}

Expand All @@ -58,19 +46,6 @@ void ModulatedDelay::initialize(LFO *lfo, float sampleRate, int maxDelaySamps) {
this->_mix = 1.0f;

this->_mod = lfo;

this->_enableLpf = false;
this->_enableHpf = false;
this->_lpf1L.initialize(_sampleRate, BiquadType::LPF, _sampleRate/2.f, 1.0);
this->_lpf1R.initialize(_sampleRate, BiquadType::LPF, _sampleRate/2.f, 1.0);
this->_lpf2L.initialize(_sampleRate, BiquadType::LPF, _sampleRate/2.f, 1.0);
this->_lpf2R.initialize(_sampleRate, BiquadType::LPF, _sampleRate/2.f, 1.0);

this->_hpf1L.initialize(_sampleRate, BiquadType::HPF, _sampleRate/2.f, 1.0);
this->_hpf1R.initialize(_sampleRate, BiquadType::HPF, _sampleRate/2.f, 1.0);
this->_hpf2L.initialize(_sampleRate, BiquadType::HPF, _sampleRate/2.f, 1.0);
this->_hpf2R.initialize(_sampleRate, BiquadType::HPF, _sampleRate/2.f, 1.0);

}

void ModulatedDelay::initialize(LFO *lfo, float sampleRate, sfloat *buf, int bufLength) {
Expand All @@ -82,13 +57,6 @@ void ModulatedDelay::initialize(LFO *lfo, float sampleRate, sfloat *buf, int buf
this->_mix = 1.0f;

this->_mod = lfo;

this->_enableLpf = false;
this->_lpf1L.initialize(sampleRate, BiquadType::LPF, sampleRate/2.f, 1.0);
this->_lpf1R.initialize(sampleRate, BiquadType::LPF, sampleRate/2.f, 1.0);
this->_lpf2L.initialize(sampleRate, BiquadType::LPF, sampleRate/2.f, 1.0);
this->_lpf2R.initialize(sampleRate, BiquadType::LPF, sampleRate/2.f, 1.0);

}

sfloat ModulatedDelay::lastOutL() const {
Expand All @@ -99,16 +67,3 @@ sfloat ModulatedDelay::lastOutR() const {
return _lastOutR;
}

void ModulatedDelay::setLpfParams(sfloat cutoff, sfloat Q, sfloat dBGain) {
this->_lpf1L.setParams(cutoff, Q, dBGain);
this->_lpf1R.setParams(cutoff, Q, dBGain);
this->_lpf2L.setParams(cutoff, Q, dBGain);
this->_lpf2R.setParams(cutoff, Q, dBGain);
}

void ModulatedDelay::setHpfParams(sfloat cutoff, sfloat Q, sfloat dBGain) {
this->_hpf1L.setParams(cutoff, Q, dBGain);
this->_hpf1R.setParams(cutoff, Q, dBGain);
this->_hpf2L.setParams(cutoff, Q, dBGain);
this->_hpf2R.setParams(cutoff, Q, dBGain);
}
90 changes: 90 additions & 0 deletions siderialib/src/effects/disperse/DisperseParallelVoice.cpp
Original file line number Diff line number Diff line change
@@ -1 +1,91 @@
#include "effects/disperse/DisperseParallelVoice.h"

using namespace siderialib;

void DisperseParallelVoice::addVoice(siderialib::ModulatedDelay *delay) {
if (_numActiveVoices >= DISPERSE_NUM_VOICES) {
return;
}

_delays[_numActiveVoices] = delay;
_numActiveVoices++;
}

void DisperseParallelVoice::clearVoices() {
for (int i = 0; i < _numActiveVoices; i++) {
_delays[i] = nullptr;
}

_numActiveVoices = 0;
}

void DisperseParallelVoice::initialize(sfloat samplingRate) {
_lpf1L.initialize(samplingRate, BiquadType::LPF, samplingRate / 2.f, 1.0);
_lpf1R.initialize(samplingRate, BiquadType::LPF, samplingRate / 2.f, 1.0);
_lpf2L.initialize(samplingRate, BiquadType::LPF, samplingRate / 2.f, 1.0);
_lpf2R.initialize(samplingRate, BiquadType::LPF, samplingRate / 2.f, 1.0);

_hpf1L.initialize(samplingRate, BiquadType::HPF, 0.0, 1.0);
_hpf1R.initialize(samplingRate, BiquadType::HPF, 0.0, 1.0);
_hpf2L.initialize(samplingRate, BiquadType::HPF, 0.0, 1.0);
_hpf2R.initialize(samplingRate, BiquadType::HPF, 0.0, 1.0);

this->sampleRate = samplingRate;
}


void DisperseParallelVoice::tick(siderialib::sfloat L, siderialib::sfloat R) {
sfloat parallelL = L;
sfloat parallelR = R;

for (int i = 0; i < _numActiveVoices; i++) {
_delays[i]->tick(L, R);
parallelL = _delays[i]->lastOutL();
parallelR = _delays[i]->lastOutR();
}

_lastOutL = parallelL;
_lastOutR = parallelR;

if (_enableTone) {
applyFilters();
}
}

void DisperseParallelVoice::applyFilters() {
if (useLpf) {
_lastOutL = _lpf1L.tick(_lastOutL);
_lastOutR = _lpf1R.tick(_lastOutR);
_lastOutL = _lpf2L.tick(_lastOutL);
_lastOutR = _lpf2R.tick(_lastOutR);
}

if (useHpf) {
_lastOutL = _hpf1L.tick(_lastOutL);
_lastOutR = _hpf1R.tick(_lastOutR);
_lastOutL = _hpf2L.tick(_lastOutL);
_lastOutR = _hpf2R.tick(_lastOutR);
}
}

void DisperseParallelVoice::setTone(siderialib::sfloat tone) {
if (tone > 0.5) {
useHpf = true;
useLpf = false;

sfloat cutoff = (sampleRate / 2.f) * (tone - 0.5f) * 2.f;
_hpf1L.setCutoff(cutoff);
_hpf1R.setCutoff(cutoff);
_hpf2L.setCutoff(cutoff);
_hpf2R.setCutoff(cutoff);
} else {
useHpf = false;
useLpf = true;

sfloat cutoff = (sampleRate / 2.f) * tone * 2.f;
_lpf1L.setCutoff(cutoff);
_lpf1R.setCutoff(cutoff);
_lpf2L.setCutoff(cutoff);
_lpf2R.setCutoff(cutoff);
}
}
4 changes: 4 additions & 0 deletions siderialib/src/effects/filter/BiquadFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ using namespace siderialib;


void BiquadFilter::recalcParams() {

// todo: find some way to cache these values
// since we usually set the same cutoff and Q
// to multiple filters at once
double thetac = TWOPI * _cutoffHz / (double)this->_samplingRate;
double K = tan(thetac / 2.0);
double W = K * K;
Expand Down
14 changes: 6 additions & 8 deletions spkr/spkr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ void applyDelay(std::vector<std::vector<double>> in, std::vector<std::vector<dou
delay.setDelayMs(500.0f);
delay.setFeedback(0.0f);

delay.enableLpf(true);
delay.setLpfParams(4000.0f, 0.7f, 12.0f);

delay.setMix(1.0f);

for (int i = 0; i < in.at(0).size(); i++) {
Expand All @@ -39,16 +36,16 @@ void apply(std::vector<std::vector<double>> in, std::vector<std::vector<double>>
siderialib::Disperse disperse;

float sampleRate = 44100.f;
float mix = 1.0f;
float timeMs = 100.0f;
float dispersion = 0.2f;
float mix = .2f;
float timeMs = 300.0f;
float dispersion = 0.5f;
float spread = 1.0f;
float feedback = 0.8f;
float tone = 0.8f;
float tone = 0.1f;
float modRateHz = 2.0f;
float modDepth = 0.3f;
float position = .323f;
float resampleFactor = 1.0;
float resampleFactor = .2;

siderialib::DisperseArrangement arrangement = siderialib::DisperseArrangement::FULL_PARALLEL;
disperse.initialize(sampleRate);
Expand All @@ -62,6 +59,7 @@ void apply(std::vector<std::vector<double>> in, std::vector<std::vector<double>>
disperse.setModDepth(modDepth);
disperse.setPosition(position);
disperse.setResampleFactor(resampleFactor);
disperse.setTone(tone);

disperse.setPingPongType(siderialib::DispersePingPong::OFF);

Expand Down

0 comments on commit bba034d

Please sign in to comment.