strudel icon indicating copy to clipboard operation
strudel copied to clipboard

Patternable tempo changes via `cps`

Open yaxu opened this issue 3 years ago • 16 comments

There is cpm in core but it assumes a scheduler running at 1 cps.

It would be great if cps could be patternable, e.g.

cps(saw.range(0.9,1.8).slow(16))

or

sound("bd [bd bd]").cps(1,1.5)

yaxu avatar Apr 12 '22 12:04 yaxu

I wonder if the assumption of 1 cycle / second has any disadvantage? If not, we could implement cps like cpm

felixroos avatar Apr 18 '22 20:04 felixroos

Hm, I think having a global cycle rate that can be changed is pretty important. Personally I don't really like 1cps, the default in tidal is 0.5625.

yaxu avatar Apr 18 '22 20:04 yaxu

But anything against implementing it with slow, assuming a hard coded cps? I kind of like 1s because it's normalized

felixroos avatar Apr 18 '22 20:04 felixroos

slow doesn't hold state, so slow (saw.segment(8).range(1,2)) would miss a lot of events.

With something like: "a b".cps(1.5).every(3,rev)

The rev would not work on cycle boundaries.

More generally, when it comes to syncing between systems, it would be difficult to do that without a global clock.

yaxu avatar Apr 18 '22 21:04 yaxu

makes sense. so we need a global clock that dictates how fast the scheduler will run. also thought syncing would be great. .cps would then have a side effect to talk to the scheduler.

felixroos avatar Apr 18 '22 21:04 felixroos

SuperDirt likes to have some metadata - the current cps, the duration (as delta) of the event in seconds, and the event onset (wholeorpart.begin) in cycles (as cycle). So it could be good for the scheduler to provide this info (or a way to get it) to the callback.

yaxu avatar May 08 '22 14:05 yaxu

i made some improvements to the scheduler + sketched cps option DEMO

I am not sure if the behavior is right when I change the tempo: when pressing minus, the scheduling might repeat notes, if pressing plus, the scheduler might jump over notes. it feels like the scheduler has to use a time phase? is this how tidal does it too? this is the code: https://github.com/tidalcycles/strudel/blob/ea1ffca4ae430cc64a0be08dfc062204021c351a/packages/webaudio/scheduler.mjs

felixroos avatar Aug 11 '22 23:08 felixroos

tempo changes are now working smoothly (the above link will still show the old behavior). Updated demo

Interestingly, the implementation is quite similar to a digital oscillator, which also requires keeping the phase in state to avoid phase jumps / cracks when repitching: https://github.com/tidalcycles/strudel/blob/optimize-scheduler/packages/webaudio/scheduler.mjs#L17

The next step is changing cps from a hap. I think it will only be possible to change the cps once per slice (in the above example it's 10Hz)

felixroos avatar Aug 12 '22 20:08 felixroos

The next step is changing cps from a hap. I think it will only be possible to change the cps once per slice (in the above example it's 10Hz)

That's also working now not sure if this is similar how it works in tidal though

felixroos avatar Aug 12 '22 20:08 felixroos

This got lost along the way..

yaxu avatar Feb 21 '23 15:02 yaxu

moved from https://github.com/tidalcycles/strudel/issues/494:

global clock https://github.com/tidalcycles/strudel/issues/470 is now implemented in https://github.com/tidalcycles/strudel/pull/493 . example: https://strudel.tidalcycles.org/?9xvgxvOjkBR1

now the next step is making it work with patterns

felixroos avatar Mar 01 '23 09:03 felixroos

Good stuff. FWIW I needed to do a hard refresh for that to work.

yaxu avatar Mar 01 '23 09:03 yaxu

Good stuff. FWIW I needed to do a hard refresh for that to work.

sometimes the old version may be stuck in the cache.. ideally, the pwa service worker will update itself and reload the page when it's ready

felixroos avatar Mar 01 '23 09:03 felixroos

small request: once this is fixed, if possible find a way to make a separate function that does what the current behaviour does, because it's quite cool!

jarmitage avatar Oct 27 '23 19:10 jarmitage

I noticed that passing a pattern to setcps("0.6") stops all sound and needs a hard refresh. No errors/warnings are printed to console.

yaxu avatar Nov 21 '23 11:11 yaxu