Synchronising Multi Stream OSC

Hi,

I'm trying to send tidal data simultaneously to both SuperDirt and another OSC target. The code in my BootTidal.hs currently looks like:

`

:set -XOverloadedStrings
:set prompt ""
:set prompt-cont ""

import Sound.Tidal.Context


tidal <- startTidal (superdirtTarget {oLatency = 0.1, oAddress = "127.0.0.1", oPort = 57120}) (defaultConfig {cFrameTimespan = 1/20})

:{
let atomTarget = Target {oName = "atom",
            oAddress = "127.0.0.1",
            oPort = 20202,
            oLatency = 0,
            oWindow = Nothing,
            oSchedule = Live }
:}

:{
let oscplay = OSC {path = "/cps",
           args = ArgList [("cps", Nothing), ("cycle", Nothing), ("vowel", Just $ VS "a"),
                                      ("pan", Just $ VF 0.5)]
          }
:}


-- multiple osc mappings
:{
let oscmap = [(atomTarget, [oscplay]),
              (superdirtTarget, [superdirtShape])
             ]
:}


atomStream <- startStream (defaultConfig {cCtrlListen = False}) oscmap

streamReplace atomStream 0 $ s "dummy"

-- for use in tidal code..
let z = streamReplace atomStream

`

This current set up means I can send data like this

d1 $ s "bd(3,8) #cps "0.8"

to the SuperDirt target and

z 1 $ s "bd(3,8)" # cps "0.8"

to the other target. But is there a way to send out from d1 to both targets?

2 Likes

Hmm, as far as I can tell, z 1 should already be sending to both targets, as you have superdirt and atomtarget in the oscmap for the atomStream. So you could just d1 = z 1 to use the d1 alias for this.

I have a similar question so I figured I'd post it here.

I'm looking for a way to send a duplicate OSC output to another port (that I'll receive using MaxMSP). So I'd like the exact same OSC messages going to SuperDirt to also go to this new location. I'd like to use Tidal exactly as I have been if possible, with d1, d2, etc, but have the OSC go to two places simultaneously. I'm guessing this is trivial once fully understood?

I've found the custom OSC documentation page, and I've been trying to hack a new BootTidal file together but my limited understanding is stopping me from getting this exactly right.

In the custom OSC docs example, I understand that this is where we 'enable' the multiple outputs:
let oscmap = [(target, [oscplay]), (superdirtTarget, [superdirtShape]) ]

but the part in the default BootTidal file about starting the stream gets confusing because it also has the port assignments in it, so it's a bit hard to parse the differences.

tidal <- startTidal (superdirtTarget {oLatency = 0.1, oAddress = "127.0.0.1", oPort = 57120}) (defaultConfig {cFrameTimespan = 1/20})

Is there a way to just modify that line to send the same outputs to another port? Or another simple way?
Thanks so much. I hope this is clear.

B

Here's a simple version, which replaces the startTidal call, assuming max is listening on port 7070:

tidal <- startStream defaultConfig [(superdirtTarget, [superdirtShape]),
                                    (superdirtTarget {oPort = 7070}, [superdirtShape])
                                   ]

You will probably find they're a bit out of sync, in which case you can configure oLatency to delay one or the other:

tidal <- startStream defaultConfig [(superdirtTarget {oLatency = 0.11}, [superdirtShape]),
                                    (superdirtTarget {oPort = 7070, oLatency = 0.1}, [superdirtShape])
                                   ]

This assumes that you schedule the incoming messages in max/msp - the osc messages will be sent in timestamped osc bundles in batches. If you'd rather tidal scheduled outgoing messages then you can do that like this:

tidal <- startStream defaultConfig [(superdirtTarget {oLatency = 0.11}, [superdirtShape]),
                                    (superdirtTarget {oPort = 7070, oLatency = 0.1, oSchedule = Live}, [superdirtShape])
                                   ]

Thanks @yaxu
I'm getting errors however.

I should replace this whole line:
tidal <- startTidal (superdirtTarget {oLatency = 0.1, oAddress = "127.0.0.1", oPort = 57120}) (defaultConfig {cFrameTimespan = 1/20})

With this one (for example), yes?

tidal <- startStream defaultConfig [(superdirtTarget {oLatency = 0.11}, [superdirtShape]),
                                    (superdirtTarget {oPort = 7070, oLatency = 0.1, oSchedule = Live}, [superdirtShape])
                                ]

Maybe I'm getting errors because I replaced the original IP and port addresses with the new code that leaves out that info?

EDIT: I tried this:

tidal <- startStream defaultConfig [(superdirtTarget {oLatency = 0.1, oAddress = "127.0.0.1", oPort = 57120}, [superdirtShape]),
                                    (superdirtTarget {oPort = 7070}, [superdirtShape])
                                   ]

but I'm still getting the error:
Warning: GHCi | <interactive>:38:30: error: Variable not in scope: tidal :: Stream

Hm try putting it all in one line:

tidal <- startStream defaultConfig [(superdirtTarget {oLatency = 0.11}, [superdirtShape]), (superdirtTarget {oPort = 7070, oLatency = 0.1, oSchedule = Live}, [superdirtShape])]

(Or otherwise wrapping it in :{and :} as you see with other multi-line things in the BootTidal.hs file.)

2 Likes

Ahhhh, that did it thank you!!

1 Like