Skip to content
This repository was archived by the owner on Jun 19, 2025. It is now read-only.
Open
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
483843b
begin supradough
felixroos Jun 1, 2025
5336569
proper lpf mapping + remove redundant worklet params,
felixroos Jun 1, 2025
5129fa6
fix click
daslyfe Jun 3, 2025
ff4b7ca
fix volume
daslyfe Jun 4, 2025
930dabe
dough as a singleton worklet with voice allocation
felixroos Jun 5, 2025
2cbd35f
refactor: make webaudio glue as minimal as possible
felixroos Jun 5, 2025
f0e6c54
handle invalid spawns + remove logs
felixroos Jun 5, 2025
ccec7e7
poc: render pattern audio with node script
felixroos Jun 5, 2025
87598e1
coarse
felixroos Jun 6, 2025
0cc18a6
crush (might be wrong)
felixroos Jun 6, 2025
623bf93
panning
felixroos Jun 6, 2025
9ed690c
pulse osc + velocity
felixroos Jun 6, 2025
794bf86
distort
felixroos Jun 6, 2025
6cf0b6f
hpf + bpf
felixroos Jun 6, 2025
e4cd5dc
rough filter envelope implementation
felixroos Jun 6, 2025
998a010
better filter envelopes
felixroos Jun 6, 2025
ccc90d5
ignore dough-export to fix checks
felixroos Jun 6, 2025
43c05cb
move supradough to separate package
felixroos Jun 6, 2025
49f38ae
remove log
felixroos Jun 6, 2025
1dac696
feedback delay (still hard coded feedback / time values)
felixroos Jun 7, 2025
d743570
set delay time and feedback from voice
felixroos Jun 7, 2025
e54449f
white brown pink noise + crackle alias for dust
felixroos Jun 7, 2025
77463a1
add square alias for pulse
felixroos Jun 7, 2025
b000f22
fm
felixroos Jun 7, 2025
2f2bf5b
fix: note2midi for notes without octave
felixroos Jun 7, 2025
5988e3d
fix: hot reloading for dough.mjs (see comment)
felixroos Jun 7, 2025
ab052ce
fix: polyblepped sawtooth + fm = death
felixroos Jun 7, 2025
ac7ee37
pitch envelope
felixroos Jun 7, 2025
0f2aa95
half working samples
felixroos Jun 8, 2025
356d436
fix: scheduling + sample playback
felixroos Jun 8, 2025
55aef18
buffers can now be repitched (still with aliasing)
felixroos Jun 8, 2025
ec9109d
exponential lerp
daslyfe Jun 8, 2025
1167fdb
Merge branch 'supradough' of https://github.com/tidalcycles/strudel i…
daslyfe Jun 8, 2025
181e51e
adjustable envelope curves
daslyfe Jun 8, 2025
73ef43d
move things around in init
felixroos Jun 8, 2025
1081fc6
refactor: stereo sample support + channelwise fx
felixroos Jun 9, 2025
d1b6b6b
fix: hpf
felixroos Jun 9, 2025
3ac0fdf
rudimentary sample map loading (doughsamples)
felixroos Jun 9, 2025
aeaed50
gaincurve
daslyfe Jun 9, 2025
3d30007
supersaw
daslyfe Jun 9, 2025
e825473
apply speed to synths and samples + add normalize flag (for fit)
felixroos Jun 9, 2025
c9f494d
fix: node export
felixroos Jun 9, 2025
e99adff
vibrato
felixroos Jun 9, 2025
3963b80
fix: calling doughsamples multiple times
felixroos Jun 9, 2025
7e8206d
pitched delay
daslyfe Jun 10, 2025
43504d1
add chorus
daslyfe Jun 10, 2025
bbd7ed0
lazy sample loading
felixroos Jun 12, 2025
5cbd38a
improve filter performance making it accept hz directly
felixroos Jun 12, 2025
3caf08e
up latency
felixroos Jun 12, 2025
14193ab
improve export: add stereo + measure performance + add bigger pattern…
felixroos Jun 12, 2025
30f7127
Merge remote-tracking branch 'origin/main' into supradough
felixroos Jun 12, 2025
8363ba5
format
felixroos Jun 12, 2025
239987a
snapshot
felixroos Jun 12, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 19 additions & 19 deletions packages/supradough/dough.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ export class ADSR {
this.state = 'off'
this.startTime = 0;
this.startVal = 0;
this.curve = props.curve ?? 1;
this.decayCurve = props.decayCurve ?? 1;
}

update(curTime, gate, attack, decay, susVal, release) {
Expand All @@ -234,11 +234,11 @@ export class ADSR {
this.startTime = curTime;
return 1;
}
return lerp(time / attack, this.startVal, 1, this.curve);
return lerp(time / attack, this.startVal, 1, 1);
}
case 'decay': {
let time = curTime - this.startTime;
let curVal = lerp(time / decay, 1, susVal, -this.curve);
let curVal = lerp(time / decay, 1, susVal, -this.decayCurve);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curious: why only decay and not attack / release ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be on the release and decay stage, the reason is that seems to be standard on most synthesizers so I played around with different curves and preferred the standard linear rate on attack, it was not scientific

if (gate <= 0) {
this.state = 'release';
this.startTime = curTime;
Expand Down Expand Up @@ -267,7 +267,7 @@ export class ADSR {
this.state = 'off';
return 0;
}
let curVal = lerp(time / release, this.startVal, 0, -this.curve);
let curVal = lerp(time / release, this.startVal, 0, -this.decayCurve);
if (gate > 0) {
this.state = 'attack';
this.startTime = curTime;
Expand Down Expand Up @@ -599,7 +599,7 @@ export class DoughVoice {
}

if (this.penv) {
this._penv = new ADSR();
this._penv = new ADSR({ decayCurve: 4 });
[this.pattack, this.pdecay, this.psustain, this.prelease] = getADSRValues([
this.pattack,
this.pdecay,
Expand All @@ -612,14 +612,14 @@ export class DoughVoice {
this._fm = new SineOsc();
this.fmh = this.fmh ?? getDefaultValue('fmh');
if (this.fmenv) {
this._fmenv = new ADSR();
this._fmenv = new ADSR({ decayCurve: 2 });
[this.fmattack, this.fmdecay, this.fmsustain, this.fmrelease] = getADSRValues([
this.fmattack,
this.fmdecay,
this.fmsustain,
this.fmrelease,
]);

}
}

Expand All @@ -628,8 +628,8 @@ export class DoughVoice {
this.resonance = this.resonance ?? getDefaultValue('resonance');
if (this.lpenv) {

this._lpenv = new ADSR({curve: 4});
this._lpenv = new ADSR({ decayCurve: 4 });

[this.lpattack, this.lpdecay, this.lpsustain, this.lprelease] = getADSRValues([
this.lpattack,
this.lpdecay,
Expand All @@ -641,8 +641,8 @@ export class DoughVoice {
this._hpf = this.hcutoff ? new TwoPoleFilter() : null;
this.hresonance = this.hresonance ?? getDefaultValue('hresonance');
if (this.hpenv) {
this._hpenv = new ADSR();
this._hpenv = new ADSR({ decayCurve: 4 });

[this.hpattack, this.hpdecay, this.hpsustain, this.hprelease] = getADSRValues([
this.hpattack,
this.hpdecay,
Expand All @@ -653,7 +653,7 @@ export class DoughVoice {
this._bpf = this.bandf ? new TwoPoleFilter() : null;
this.bandq = this.bandq ?? getDefaultValue('bandq');
if (this.bpenv) {
this._bpenv = new ADSR();
this._bpenv = new ADSR({ decayCurve: 4 });
[this.bpattack, this.bpdecay, this.bpsustain, this.bprelease] = getADSRValues([
this.bpattack,
this.bpdecay,
Expand All @@ -663,7 +663,7 @@ export class DoughVoice {
}

// gain envelope
this._adsr = new ADSR({curve: 2});
this._adsr = new ADSR({ decayCurve: 2 });

// fx setup
this._coarse = this.coarse ? new Coarse() : null;
Expand Down Expand Up @@ -695,7 +695,7 @@ export class DoughVoice {
if (this._fm) {
let fmi = this.fmi;
if (this._fmenv) {
const env = this._fmenv.update(t, gate, this.fmattack, this.fmdecay, this.fmsustain, this.fmrelease) ** 2;
const env = this._fmenv.update(t, gate, this.fmattack, this.fmdecay, this.fmsustain, this.fmrelease);
fmi = this.fmenv * env * fmi;
}
const modfreq = freq * this.fmh;
Expand All @@ -704,7 +704,7 @@ export class DoughVoice {
}

if (this._penv) {
const env = this._penv.update(t, gate, this.pattack, this.pdecay, this.psustain, this.prelease) ** 2;
const env = this._penv.update(t, gate, this.pattack, this.pdecay, this.psustain, this.prelease);
freq = freq + env * this.penv;
}

Expand All @@ -722,8 +722,8 @@ export class DoughVoice {
if (this._lpf) {
let cutoff = this.cutoff;
if (this._lpenv) {
const env = this._lpenv.update(t, gate, this.lpattack, this.lpdecay, this.lpsustain, this.lprelease) ** 2;
cutoff = 2 ** this.lpenv * env * cutoff + cutoff;
const env = this._lpenv.update(t, gate, this.lpattack, this.lpdecay, this.lpsustain, this.lprelease);
cutoff = this.lpenv * env * cutoff + cutoff;
}
cutoff = this.freq2cutoff(cutoff);
this._lpf.update(s, cutoff, this.resonance);
Expand All @@ -733,7 +733,7 @@ export class DoughVoice {
if (this._hpf) {
let cutoff = this.hcutoff;
if (this._hpenv) {
const env = this._hpenv.update(t, gate, this.hpattack, this.hpdecay, this.hpsustain, this.hprelease) ** 2;
const env = this._hpenv.update(t, gate, this.hpattack, this.hpdecay, this.hpsustain, this.hprelease);
cutoff = 2 ** this.hpenv * env * cutoff + cutoff;
}
cutoff = this.freq2cutoff(cutoff);
Expand All @@ -744,7 +744,7 @@ export class DoughVoice {
if (this._bpf) {
let cutoff = this.bandf;
if (this._bpenv) {
const env = this._bpenv.update(t, gate, this.bpattack, this.bpdecay, this.bpsustain, this.bprelease) ** 2;
const env = this._bpenv.update(t, gate, this.bpattack, this.bpdecay, this.bpsustain, this.bprelease);
cutoff = 2 ** this.bpenv * env * cutoff + cutoff;
}
cutoff = this.freq2cutoff(cutoff);
Expand Down
Loading