tidalcycles / strudel

Web-based environment for live coding algorithmic patterns, incorporating a faithful port of TidalCycles to JavaScript
https://strudel.cc/
GNU Affero General Public License v3.0
586 stars 105 forks source link

supersaw oscillator #978

Closed daslyfe closed 3 months ago

daslyfe commented 4 months ago

uses detune, spread, and unison params can easily stack up to 100 oscillators supports modulators. FM sounds like a weird wall of horror for some reason I have not figured out but I kinda love it

daslyfe commented 4 months ago

This should be ready to go now :)

felixroos commented 3 months ago

duping idea from chat: " sounds amazing! the only thing I've noticed is that the detune value doesn't seem to be in cents. It might also make sense to change detune to have a usable range inside 0-1. maybe just like foxdot is doing it: https://www.youtube.com/watch?v=lZ9Tbv9kY8E

it looks like the detune there is in semitones having it in semitones makes it easily automated with signals without needing to set a range "

felixroos commented 3 months ago

btw the synth code refactoring looks very reasonable!

daslyfe commented 3 months ago

duping idea from chat: " sounds amazing! the only thing I've noticed is that the detune value doesn't seem to be in cents. It might also make sense to change detune to have a usable range inside 0-1. maybe just like foxdot is doing it: https://www.youtube.com/watch?v=lZ9Tbv9kY8E

it looks like the detune there is in semitones having it in semitones makes it easily automated with signals without needing to set a range "

I updated the detune to use the lerp function, and changed it so that the detune is in semitones

daslyfe commented 3 months ago

I think the hyperpop test just generates a different slightly output sometimes. can we delete it?

felixroos commented 3 months ago

I think the hyperpop test just generates a different slightly output sometimes. can we delete it?

yup, it's too large anyway

daslyfe commented 3 months ago

I think the hyperpop test just generates a different slightly output sometimes. can we delete it?

yup, it's too large anyway

cool i removed it

felixroos commented 3 months ago

added a fix that pans to center for unison(1)

freq("110").s("supersaw")
.unison(2)
.detune(1) // getting whole tone instead of semitone
.detune(1.5) // minor third 
.detune(2) // major third instead of whole tone
.detune(3.5) // fifth, would be nicer if it was 7

could be fixed by doing getUnisonDetune(voices, freqspread/2, n). What do you think?

edit: i know this is not how you normally use a supersaw...

daslyfe commented 3 months ago

Sure, maybe multiply by .5 instead so the math is faster

daslyfe commented 3 months ago

added a fix that pans to center for unison(1)

* after some testing I realized it might actually be more usable if the detune value is halved, because rn the actual difference between bottom and top voice is detune*2, so the commonly memorized semitone values work differently:
freq("110").s("supersaw")
.unison(2)
.detune(1) // getting whole tone instead of semitone
.detune(1.5) // minor third 
.detune(2) // major third instead of whole tone
.detune(3.5) // fifth, would be nicer if it was 7

could be fixed by doing getUnisonDetune(voices, freqspread/2, n). What do you think?

edit: i know this is not how you normally use a supersaw...

I tried this and I think it makes the behavior more convusing tbh, it works when you have two oscillators, but they will be out of tune with everything else. I think detune(12) with unison(3) giving octaves makes more sense

daslyfe commented 3 months ago

If the intent is to get musical sounding intervals with two oscillators with the detune param, then the original detune behavior where the first oscillator is always at the fundamental is probably more desirable because detune(7) would give [0, 7]