Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add swing parameter to clock #276

Open
eethann opened this issue Apr 22, 2022 · 6 comments
Open

Add swing parameter to clock #276

eethann opened this issue Apr 22, 2022 · 6 comments

Comments

@eethann
Copy link

eethann commented Apr 22, 2022

Opening a feature request here, following up on the conversation at llllllllines. I'm an Orca newcomer but have implemented swing and alternate feels in a few other frameworks and would like to help how I can.

For background on approaches to adding "shuffle" the manual for the 4MS Shuffling Clock Multiplier module has a clear description and some nice illustrations. It mirrors Roger Linn's summary of the swing parameter he uses (more detail in the article):

My implementation of swing has always been very simple: I merely delay the second 16th note within each 8th note. In other words, I delay all the even-numbered 16th notes within the beat (2, 4, 6, 8, etc.) In my products I describe the swing amount in terms of the ratio of time duration between the first and second 16th notes within each 8th note.

Looking over the clock code, I think this might be fairly straightforward to implement: in essence you have two overlaid 1/8th note clocks, each regular divisions of the beat - we might call one the "odd tick" clock (downbeats and upbeats - pulses 0 and 2 within a 4 division cycle), and the other the "even tick" clock (the 16th notes just after and just before the downbeat). The shuffle parameter then controls the delay between the odd clock and the even clock. At 50% the delay of the even clock is exactly 1/16th note, at smaller values it shifts forwards, at greater values it shifts backward. I think this can be implemented with two timers, each just sending a clock tick when they fire, each triggered every 8th note ((60000/bpm)/2 instead of the current /4).

I'm not 100% clear how to best precisely delay the even tick clock relative to the odd one, and I have a sense there are likely some edge cases when the clock is paused and restarted that would need to be checked for (e.g. if paused just after an odd tick, you don't want to restart the odd tick first, or your shuffle will be inverted).

There are more complex approaches to humanizing timing, for sure, and those are likely best handled at via external syncing to a MIDI clock where the clock itself is swung. This could be a great standalone utility at some point (create a simple DSL for describing clock modifications).

I don't have as much free time to implement and test this as I'd like, but I'll try to pull together at least a proof of concept PR that can be built off of.

Thanks for making this awesome open source software!

@eethann
Copy link
Author

eethann commented Apr 24, 2022

I've got an implementation proposal: specify "groove" as an array of division ratios. The current clock callback gets run every grooveArray.length ticks and schedules the next length-1 ticks based on the ratios in the array. If there's only one groove ratio, this behaves like standard shuffle, but it also allows for more than one ratio. Thoughts?

@eethann
Copy link
Author

eethann commented Apr 26, 2022

Proof of concept PR here: #277

I ditched the nested timers and went with a loop using setTimeout in the worker process. May need to check for jitter and adjust timings, but seemed the cleanest approach.

@eethann
Copy link
Author

eethann commented May 11, 2022

Just following up on this ticket that the PR should be fully functional now. I'm sure some of the code could be tightened up a bit, but should be okay to merge.

@eethann
Copy link
Author

eethann commented May 11, 2022

Just found one potential issue in the swing code: the MIDI note length might not figure in swing.

@eethann
Copy link
Author

eethann commented May 11, 2022

Looked at the code, this shouldn't be an issue.

@neauoire
Copy link
Member

I haven't been able to review this one just yet, I'll check it out soon. Sorry about the delay.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants