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

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!

@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!

@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

1 Like

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