Sending OSC out of Tidal... Again - HELP!

Hi Everyone,

I'm having a very hard time sending osc messages outside of Tidal in order to change visual parameters in programs such as Processing and Hydra in real time. I've tried the following resources:

Olivia's official tidal/hydra example via github
Diego Dorado's tidal hydra tutorial via github
Official tidal osc documentation
Atsushi Tadokoro's processing/hydra example via github
tidal and processing blog post
p5dirt

sorry - new user - can only embed two links

I've also scanned the various Tidal/Hydra/Processing forums for more information as well - I haven't found anything I've been able to get up and running.

I'm more familiar with Processing, so I'd prefer instruction on sending messages from Tidal directly to Processing, however, it seems that once I can get messages out of Tidal, I can pretty much route them anywhere.

I've attempted to change the BootTidal.hs file, added osc routing inside SuperCollider, and reviewed the official documentation on the Tidal website - all to no avail.

Using OSCFunc.trace(true, true); in SuperCollider, I can see the osc messages are being received, I'm just having a hard time routing them outside of SuperCollider/Tidal.

I apologize for this screenshot, but I can only add one image and am hoping to give you all as much info as possible. Each screenshot is something different I've tried to get messages outside of Tidal and the various error messages I've encountered:

I'm very new to Tidal, and maybe I've made a very simple mistake that's preventing me form sending messages. Not sure, but any insight will be greatly appreciated. Thank You!!!

-Brittney

3 Likes

Welcome @brittneyjuliet,

First off, I've upped your "trust level" so you can should have an easier time adding links, images etc now. Sorry for this hassle!

It's a bit hard to read the screenshots, maybe you could paste your code directly into a post here, using the clicking the 'preformatted text' icon that looks like </>?

Otherwise a couple of thoughts:
It could be my eyes, but it looks like the processing sketch is listening on port 2020, and tidal is sending on port 5050, I guess they should be the same?

Are you editing the right BootTidal.hs ? Atom should give the location of the one it's loading when it starts up. (You can copy it into a friendlier location and configure atom to load that one in the settings of the tidalcycles package in the atom config).

In your screenshots it looks like you're editing a .tidal file rather than editing the BootTidal.hs file, which might be confusing things as you could be starting more than one tidal instance.

By the way, do you want to send the osc to superdirt as well as your visualiser?

Hi Yaxu,

Thanks so much for trying to help me figure this out! Also, thanks for upping my trust level - that'll make describing my problem so much easier!

Sorry about those screenshots! I know it looks like I've sent messages to the wrong port number, but I was going back and forth between applications and trying different number to see if I would have any success; by the time I wrote the initial forum post I just took a bunch of quick screenshots to get those error messages and didn't bother with changing the numbers... Lol

And yes, I'd like to send the osc request to superdirt as well as the visualizer. So I suppose here I'm trying to send osc data to another target similar to this post

When I add the osc-forwarding code to the BootTidal.hs file I get the following error:


(you'll see an image of the BootTidal.hs file next to the .tidal file in atom)

Here's the code I added in the BootTidal.hs file - just in case it's a bite easier to read here:

let target =
      Target {oName = "visualiser",   -- A friendly name for the target (only used in error messages)
              oAddress = "localhost", -- The target's network address, normally "localhost"
              oPort = 5050,           -- The network port the target is listening on
              oLatency = 0.2,         -- Additional delay, to smooth out network jitter/get things in sync
              oSchedule = Live,       -- The scheduling method - see below
              oWindow = Nothing,      -- Not yet used
              oHandshake = False,     -- SuperDirt specific
              oBusPort = Nothing      -- Also SuperDirt specific
             }
    oscplay = OSC "/play" $ ArgList [("s", Nothing),
                                     ("vowel", Just $ VS "a"),
                                     ("pan", Just $ VF 0.5),
                                     ("volume", Just $ VF 1),
                                     ("cut", Just $ VI 1),
                                     ("intensity", Just $ VI 0)
                                   ]
    intensity = pF "intensity"

let oscmap = [(target, [oscplay]),
              (superdirtTarget, [superdirtShape])
             ]

stream <- startStream defaultConfig oscmap

d = streamReplace stream

d 1 $ s "bd" 

And thanks fort the tip regarding moving the BootTidal file. I've kept it in the same place for now because I'm terrified if I move it I'll break Tidal... Lol but I'm glad I have the option!

Thanks Again :slight_smile:

-Brittney

1 Like

I think Line 16 and 25 should be indented to the same level, because Haskell uses indentation to describe blocks of code. Same indent = same block.

That's a classic Haskell footgun, happens to me all the time !

EDIT: also, looks like you are running Linux - the utility oscdump is really convenient to debug osc configs!

Hi @tgirod,

Thanks for popping in and giving me that tip regarding Haskell! I've literally never heard of Haskell until I installed Tidal and this indentation thing is def giving me the blues... Lol

I did a google search and found this reference regarding Haskell indentation. I've tried a few different ways of formatting that block of code and still receive the same error message for all:




And oscdump sounds perfect. I went ahead and installed the package - now to see if I can figure out how to get useful information out of it...

Thank You!!!

-Brittney

Here, you are using the keyword let to define three variables: target, oscplay and intensity. those three words should be at the same level, which is not the case in any of your screenshots.

It should be something like:

let target = Target{
        -- content goes here, at one indent level down `target`
        }
    oscplay = OSC -- define some stuff
    intensity = pF "intensity"

Be careful, haskell does not like it when your indentation is a mix of spaces and tabs. Decide for one and use it always.

Here is how I did it on another project:

let renoise = Target {
        oName="renoise",
        oAddress="127.0.0.1",
        oPort=8000,
        oLatency=0.2,
        oSchedule=Live,
        oWindow=Nothing,
        oBusPort=Nothing,
        oHandshake=False
        }
    formats = [
        -- send note_on event
        OSC "/renoise/trigger/note_on" $ ArgList [
            ("instrument", Just $ VI (-1)),
            ("track", Just $ VI (-1)),
            ("note", Nothing),
            ("velocity", Just $ VI 127)
            ],

        -- send note_off event (not very useful if you ask me)
        OSC "/renoise/trigger/note_off" $ ArgList [
            ("sound", Just $ VI (-1)),
            ("track", Just $ VI (-1)),
            ("noteOff", Nothing)
            ],

        -- instrument macro controls
        OSC "/renoise/song/instrument/{instrument}/macro1" $ ArgList [("m1", Nothing)],
        OSC "/renoise/song/instrument/{instrument}/macro2" $ ArgList [("m2", Nothing)],
        OSC "/renoise/song/instrument/{instrument}/macro3" $ ArgList [("m3", Nothing)],
        OSC "/renoise/song/instrument/{instrument}/macro4" $ ArgList [("m4", Nothing)],
        OSC "/renoise/song/instrument/{instrument}/macro5" $ ArgList [("m5", Nothing)],
        OSC "/renoise/song/instrument/{instrument}/macro6" $ ArgList [("m6", Nothing)],
        OSC "/renoise/song/instrument/{instrument}/macro7" $ ArgList [("m7", Nothing)],
        OSC "/renoise/song/instrument/{instrument}/macro8" $ ArgList [("m8", Nothing)],

        -- set device parameters (effects)
        OSC "/renoise/song/track/{track}/device/{device}/set_parameter_by_name" $ ArgList [
            ("param", Nothing),
            ("value", Nothing)
            ]
        ]
    -- use t1 .. t8 to select the track
    track = pI "track"
    -- sound to select an instrument
    sound = pI "instrument"
    s = sound
    -- triggers note_on event
    note = pI "note"
    n = note
    -- triggers note_off event
    noteOff = pI "noteOff"
    -- gain controls velocity, remapping from [0 1] to [0 127]
    -- gain = pF "velocity" . linlin 0 1 0 127
    -- instument macros
    m1 = pF "m1"
    m2 = pF "m2"
    m3 = pF "m3"
    m4 = pF "m4"
    m5 = pF "m5"
    m6 = pF "m6"
    m7 = pF "m7"
    m8 = pF "m8"
    -- device params
    device = pI "device"
    dev = device
    param = pS "param"
    par = param
    value = pF "value"
    val = value
    -- redefining octave. use it with operator |+ instead of #
    octave = \p -> note (p |* 12)
    oscmap = [(renoise, formats)]

Hope this helps!

1 Like

@tgirod's advice is all good but I think there is another issue or two here.

If you look at the BootTidal.hs file you can see :{ and :} around blocks of text. Because of the way that the editor sends the code to the haskell interpreter this is needed around any texts that go over more than one line.

So that's why it complains about line 15 there - it's trying to interpret one line at a time so it doesn't see the rest of the definition beyond let target =. I think what @tgirod says about indentation still stands and you'll need to get that right too. However the indentation actually looks correct in the code you pasted in (rather than the screenshots).

Another thing I've noticed is that you have this:

stream <- startStream defaultConfig oscmap`

I would replace this with

tidal <- startStream defaultConfig oscmap

... because tidal is what's used later to define hush, d1, d2 etc etc.

I would then delete these lines completely:

d = streamReplace stream

d 1 $ s "bd" 

I guess these two lines are intended just if you are running the commands from a tidal file in order to test it out, rather than putting it in your BootTidal.hs for automatic startup.

So then you'd be left with:

:{
let target =
      Target {oName = "visualiser",   -- A friendly name for the target (only used in error messages)
              oAddress = "localhost", -- The target's network address, normally "localhost"
              oPort = 5050,           -- The network port the target is listening on
              oLatency = 0.2,         -- Additional delay, to smooth out network jitter/get things in sync
              oSchedule = Live,       -- The scheduling method - see below
              oWindow = Nothing,      -- Not yet used
              oHandshake = False,     -- SuperDirt specific
              oBusPort = Nothing      -- Also SuperDirt specific
             }
    oscplay = OSC "/play" $ ArgList [("s", Nothing),
                                     ("vowel", Just $ VS "a"),
                                     ("pan", Just $ VF 0.5),
                                     ("volume", Just $ VF 1),
                                     ("cut", Just $ VI 1),
                                     ("intensity", Just $ VI 0)
                                   ]
    intensity = pF "intensity"
:}

:{
let oscmap = [(target, [oscplay]),
              (superdirtTarget, [superdirtShape])
             ]
:}

tidal <- startStream defaultConfig oscmap

Anyway clearly the instructions need some work!

3 Likes

@yaxu and @tgirod ,

Thanks so much for the insight :slight_smile:

Haskell is still very foreign to me but the two of you have demystified it a bit.

The code @yaxu provided works brilliantly and the oscdump utility provided by @tgirod made troubleshooting osc messages a breeze.

Thanks again for the help; I spent the last day playing around with some tidal-driven visuals in processing :grimacing:

-Brittney

2 Likes

That's great to hear @brittneyjuliet ! Glad to be of any help !

Hi, @tgirod @yaxu @brittneyjuliet

I tried an alternative approach sending OSC out of Tidalcycles.

I used SuperCollider to send the same OSC messages of SuperDirt using this script. (I wrote this script in the startup.scd file.)

a = NetAddr.new("localhost", 3333); //your osc port
OSCdef(\tidalplay, {
    arg msg;
    a.sendMsg(*msg);
}, '/dirt/play', n);

Next, I defined additional parameters of TidalCycles, adding this line in BootTidal.hs.

For example.

let td_s = pI "td_s"

("td_s" means TouchDesigner scene numbers.)

Then you can send extra parameters to other apps (Processing, openFrameworks, TouchDesigner, etc.)

d1
  $ s "bd cp bd hc"
  # td_s "0 1 2 3"

I like this simple method. You can try it if you like.

Best,
Atsushi Tadokoro

9 Likes

Wow this is actually super useful, getting the delta of each note as well as the cps really helps building visual interfaces in pd, I like this method is very simple as well.. thank you

3 Likes

Does anybody in here have experience with sending OSC to Blender with AddRoutes?
I am having a hard time sending "understandable" osc messages to blender...

Hi. Sorry in advance to revive this thread. Greetings from Argentina.

I’m fairly new to Tidal (perhaps this question is already answered. I would like to integrate Tidal and TouchDesigner via OSC.

Again, I’m asking since I’m also fairly new to live coding setups, so I have a very basic understanding about integration between these two tools, but I have a reasonable knowledge about Processing, Max/MSP, and recently TouchDesigner.

I’d like to expand my horizons. If you can provide me some online resources in order to get started I’d deeply appreciate it.

I have seen some recent live coding sets and they are amazing.

Many thanks!

Hello dario!

I am also interested in how to integrate TidalCycles with other applications.

I have previously posted information on the TidalCycles Blog!
https://tidalcycles.org/blog/tidal_profile_tadokoro

You might want to take a look at the section "Do you use Tidal with other tools / environments?"

Let's have fun together!

2 Likes

Hi! Thanks for your quick reply.

I have read you blog entry. I’ll give it a go.
In the meantime I also manage to integrate VSCode editor/Tidal with TouchDesigner so you can see in the performance the code and the visuals as well.

I followed this tutorial, courtesy of “moistplace”:

In the near future, I would like to integrate Tidal with Max as well, I guess for the audio part OSC will work just fine. For the visual part, I believe you can use Syphon/OBS in order to blend the editor layer with the visuals, instead of NDI/OBS as shown in the tutorial above.

Many thanks and happy coding!

2 Likes

I'm having issues with the NDI input and TouchDesigner.

The images that NDI feeds into TouchDesigner is OK, but then it get distorted in the output.

Perhaps its a silly question, but I can't figure it out...

Many thanks!

I suspect it is a resolution setting issue. Is the "noise1" resolution set very low?

1 Like

It was indeed the resolution of the noise TOP.

Ps: I'm using and non-commercial license of TD in this machine in order to test things out and not mess with my main machine. That's the warning sign on the NDI TOP. My OBS res is set to 1080p

Speaking of resolution. What do you consider to be an optimal resolution, for a better FPS performance, without compromising the stability of the project?

Many thanks in advance!

1 Like