-
-
Notifications
You must be signed in to change notification settings - Fork 260
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
Support for control bus changes #762
Comments
Actually using the current 'context' wouldn't work, because that would be applied to the whole value, which for controlpatterns is the whole dictionary. Bah. |
I think some of the confusion is trying to represent two things at once:
That is both setting the
Then if
Or maybe just leave pan as it is, and use another parameter to 'send' it places:
Then the scheduler could just look for Then
It's a bit annoying having parameter names as barewords for function names and as quoted strings as parameters though.. |
Again though there could be shorthand:
|
This is nice because it doesn't require any changes to the underlying types.. But this means that it's "stringly typed", in particular that the type of a bus value comes from its name in a controlpattern hash being prefixed by an |
Ah actually it's much simpler than all this! Just set the parameter to the string value of
Then all the scheduler has to do is redirect parameters starting with Then to only receive from (and not send to) that bus it'd simply be:
|
Well that would break e.g.
and then the scheduler swapped things around. |
This sounds like something that almost logically occurs with this kind of bus mapping. You normally have numbers, which support all kind of math, then you allow the same system to use bus mappings to pass signals. But then the backend would theoretically have to replicate all the math on numbers on the bus system. Of course superdirt/sc-server does support math on signals, but to implement something that would make this work is almost like designing an intermediate language that sends and maintains synthessis graphs on the engine. In sclang, these operations of bus symbols are usually just ignored. |
I think it's no problem to do all the maths on the tidal side. |
I meant continuous audio signals (the values on a control bus). For example, you read some bus value written by some pattern from some other pattern. As long as you just use that value for sending the OSC message, that's fine. But if you want to multiply it with some value first, it gets tricky. That can't be done in tidal, and doing it in superdirt is complicated because of the potential complexity of calculations. |
Hm maybe we are talking about different things. I was thinking about this sort of thing:
This is working now - I just had to make sure all the pan patterns had the same name, and the bus id (actually also a pattern) is kept separately and dealt with by the scheduler while constructing OSC messages to sclang (/dirt/play) and scsynth (/c_set). A remaining problem is that querying a tidal pattern can cut events into parts. As tidal queries at a rate of 20Hz that's the minimum number of /c_set messages sent per second. I'll implement something so that it only sends a value to a bus if it's changed from the previous value, but feel that's a workaround and this should really be fixed in the representation. E.g.
The event represents one 0.5 event per cycle.
The above represents one event but in two parts, one of which has value 0.75 and the other 0.625. The problem is that these look the same:
The caller can't tell that the latter represents a changed value. They both return This is one of those problems where I really don't know whether there is a very simple solution or whether it's actually impossible to solve. |
yes, we were.
On the sc-synth side, this kind of load is not a problem, I think. So one could first try and then optimise afterwards? |
Ok! |
This means that if someone did:
The sine would be sampled at 20Hz. They could increase that by being explicit
That would be sent at e.g. 100Hz if the cps was set at 1. Well it would be sent more often than that unless the underlying 20Hz framerate was perfectly in phase with the 100Hz segmentation.. Still with 100 new values per second, but some repeated. This all seems fine. |
It would be good to aggregate messages from several parallel running patterns. The OSC spec of sc-synth supports this, you can send to many busses at once: |
Ok, this shouldn't be very difficult to implement. In the end there is only really one running pattern, they all get combined into one for scheduling. |
This is a lot of fun! It does get in the way of patterning things though For example this doesn't really work:
Because the cutoff control goes via a single bus, the two layers are in conflict and it sounds like the cutoff isn't reversed. There is a workaround:
Adding a cutoffbus of 1 with a value of 0 adds 1 to the bus id, and nothing to the cutoff value, so the cutoff goes via a different bus and you can hear it descending properly. A bit strange but works! |
ah yes, that's why I thought the busses would need to get allocated implicitly – but of course that is complictaed. |
Yes definitely complicated. This'll do for now! |
I've been a bit stalled on implementing the tidal side of this: musikinformatik/SuperDirt#190
We need a way to label values that are not sent with the trigger message, but with later control messages direct to scsynth. The value needs to be associated with a bus identifier (probably an integer), which gets sent in place of the value in the trigger message, so that superdirt reads from that bus, and tidal later sends control changes to that bus.
I've tried a couple of approaches.
One is to add a
vbus
field to everyValue
constructor (VS, VF, VB etc). This kind of worked and is how things are in the main branch. One disadvantage is that it changes the interface for describing OSC 'targets', adding an extra, generally unused parameter to every control.. But we could add some helper functions with an improved interface.https://github.com/tidalcycles/Tidal/blob/main/src/Sound/Tidal/Pattern.hs#L279
Then I tried removing
vbus
and instead making a newVBus
constructor for theValue
datatype:00d5a2f#diff-c7cfc09d6380f2dbbc46f6f2d9cba755924358f0429a782c7c746ff7c409007fR293
That seemed to be a bit tidier, but I realised a bit late that this makes manipulating and combining patterns more complicated, e.g. adding together controlpatterns.
Then the current thing I'm trying is adding a
Control
datatype, composed of theValue
andMeta
types:I guess I was thinking this would be more extensible, if we needed to add more metadata. But implementing this is a bit of a pain, with the extra stage of misdirection.. Maybe a case for 'arrows' but I've not managed to get my head around those.
Thinking about it though we already have metadata stored at the event level - the 'context', where source code positions are kept. So perhaps it would make more sense for the bus id to be stored there..? I think that would be better as it means that values could be associated with bus ids either before or after they get associated with control names.
It seems I'm mainly rubberducking here but thoughts very welcome!
The text was updated successfully, but these errors were encountered: