Recording controler input?

Hey. I was wondering if there is a way to turn a controler input such as cI into a pattern. Basically, the idea is to be able to record a knob "motion sequences" by simply turning it, and then it turns into a sequence.

So far I couldn't find anything on the subject, so here is an idea for a way to do it. What if cI and friends could take a pattern as a default value, instead of a single value?

let phrase = cI "0*16" "note"

Here, phrase would be 16 zeros by default, but sending /ctrl si note 3 to tidal would fill the current step with 3, and the pattern would play differently next time. Then the structure of the pattern dictates the resolution of the motion sequence.

this might fit better in the "innards" section.

I think if w're talking about user interfaces, that's not really about innards.. Maybe we need a new 'Tidal ideas' section? This could also be an issue on github.

It's a nice idea! I'm a bit unsure about how it would work

Say you had a structure like "0 [0 0]", and then received a control message at cycle position 0.1 with value 4, 0.4 with value 8 and 0.8 with value 200, how would they align?

It could be that the control messages change the events which come after, which in this example would result in "200 [8 8]" (4 gets lost). But then if you don't send any more control messages after that, you'd end up with "200 [200 200]" the next cycle, wouldn't everything come after the last message, which is 200? Or maybe one cycle's worth of messages since the last message 'sticks', so the "200 [8 8]" repeats until a new message comes along?


The way I see it, receiving a message would simply change the current event, nothing more. So, in your example, 0 [0 0] would turn into 4 [8 200], and would stay the same until a new message comes in - then, only the current step at the message's arrival would change.

But you are talking about the last message sticking, so maybe I'm missing something because I have no clue how this is coded under the hood.

I am just unsure about how to define what a 'current event' is. in "a b" we could say that 'a' is active during the first half of the cycle. But that means that if you change the control just before the start of the cycle, it wouldn't match with a, but b. I think that would be surprising.

I agree it could be surprising sometimes.

Just to clarify, this idea comes from some hardware sequencers that can do this - like the electribes, or more recently the digitakt. On those, I find this function really neat because you can quickly generate a semi-random melody just by twisting a knob. So the idea is not to have perfect control over what's gonna happen.

Now, recording a motion sequence is basically discretizing the motion into a sequence. With only two steps, your example is the most extreme discretization you could do, so it is bound to be weird. Now, if you do the same with the pattern "0*64", your message arriving just before the move to the next step would be less surprising, right?

It will already be discrete, though, so why not use the original incoming data (timestamped values) rather than do a sample-and-hold on top?

(Sorry to keep asking questions, just trying to scope out the problem..)

Storing every incoming message opens other possibilities, like creating a continuous control with a custom waveform - but I think it's an entirely different beast.

I think the big difference can be seen if you think about overdubbing. Let's say you record a motion sequence that span the whole cycle, and then later tweak the button during the first half of the cycle. How would you combine the previous data and the new?

If you store the events inside a pattern (sample and hold), it is trivial: the new event overwrites the old event at current step.

If you store all events based on their timestamp, it is trickier: should a new event replace an old one if it is close enough? If so, how close is close enough? Doesn't it start looking like sample and hold, then?

And I'm cool with questions, I actually enjoy that kind of exchange :wink:

Ok but what if you moved the dial, held it there for a quarter of a second, then moved it back. The controller wouldn't send any values while it was held in place. Then the previous values wouldn't get overwritten while the dial wasn't moving. Wouldn't that be a surprise?

If by surprise you mean expecting a certain behaviour and getting something else, well it depends on how the function is presented in the first place.

If you mean getting unexpected results, definitely. This is clearly not the best way to have fine control over the content of a pattern - if you want that, using cP (which I've just discovered on this forum) is probably better. But if you just want to smash buttons buttons and get something to work on, I think it could do the trick.

Hey, after lurking a bit on the Lines forum, it looks like this idea would do something similar to what is called a "shift register sequencer" in the modular world...