How to connect Tidal to MaxMSP

Normally, when you open up Tidal and start live coding you are connected to the SuperCollider based synthesizer SuperDirt.

The way the two communicate is through an Open Sound Control (OSC) connection – a handy protocol designed for sending sound-related data over a network (in this instance locally, within your computer).

This means that every time you “play a note” in Tidal you are sending off a bundle of parameter data – note values, duration, current cycle number, etc. – as a neatly organized data package containing all the information necessary for SuperCollider to setup and play a sound.

One of the many fantastic things about this relationship – where Tidal is in charge of the composition process and SuperCollider is in charge of the sound synthesis – is its modularity (and as such: hackability).

Practically, what this means is you can simply unplug Tidal from SuperCollider and plug it in to other environments – any environment, actually, that is able to receive data over OSC. One such environment is the very popular Max MSP.

Hello Max

Connecting Tidal Cycles and Max MSP is a very rewarding way of harnessing the power of Tidal’s pattern system to explore the immense possibilities of Max MSP. Using this method, you can set up Tidal patterns to control visuals made in Jitter, manipulate a Max MSP based synthesis engine / instrument or funnel the data to Max4Live (which I will show to do later on).

To get up and running, I have made a simple setup which can be downloaded from Github. It consists of three things:
1. A Haskell module (called MaxMspOsc) that defines the OSC connection to Max MSP
2. A very simple tidal example ( tidal-maxmsp-example.tidal ) that sends off a pattern of data
3. Max MSP project ( tidal-maxmsp.maxproj ) with a simple patch receiving the data from Tidal.

Inside the max patch

Once everything is installed, you should open up the tidal-maxmsp.maxproj. This is where you will receive the OSC data. Any of the standard tidal parameters are available as well as a few extra parameters defined in the MaxMspOsc module (see the dropdown on the right side of the patch which contains all of these custom parameters which are all float values of 0.0 to 1.0 for consistency’s sake).

At the top of the patch is a udpreceive object which is the network object that will receive the OSC data from tidal. It has one parameter defined, the port number, which is set to 8020 both here and in Tidal (you can change it another integer number as long as both Max MSP and Tidal are using the same port number).

Below it is an OSC-route object which looks for any OSC bundles with a url starting with /fromTidal and passes it on to the tidal-osc-parse abstraction.

If you double click the tidal-osc-parse abstraction you will see a small patch which has three inlets. The first is for the raw osc data from the OSC-route object. Inlet 2 receives the stream number (defined in Tidal) and inlet 3 takes the parameter name to look for. It breaks down the OSC message into pairs of parameters / values and looks for the one defined in inlet 3 and spits it out of it’s left outlet (and the raw message without any url at it’s right outlet).

Now, head back to Tidal and open up tidal-maxmsp-example.tidal. At the top of this file you’ll see an import statement for the Haskell module. Evaluate this line – if you don’t get an error, you most probably installed it correctly. Now evaluate max1 <- maxmspStream “” 8020 1 and the last line to start sending OSC data.

If you head back to Max you should now see the values of the velocity pattern defined in Tidal now showing up in the float box in the bottom of the patch and all of the raw bundle in the message box.

That’s it!

Try connecting the float box to whatever Max MSP project you have, or if you want: Get more Tidal parameters by copying and pasting everything inside of the purple panel and changing the dropdown or message at the rightmost inlet of the tidal-osc-parse abstraction (and changing the tidal code accordingly).

Now, this is just a basic example which is not super precise in terms of timing. To get more precision we need to add time stamps/tags to make sure everything is played on time but this basic patch should get you started.

8 thoughts on “How to connect Tidal to MaxMSP”

  1. Hi. New to TidalCycles. When following instructions to connect with Max, encountering the following error:

    Could not find module ‘Sound.Tidal.MaxMspOsc’ It is not a module in the current program, or in any known package.

    Any guidance would be appreciated.

    Kind Regards,


    1. Hi Daniel. Sorry, I didn’t see your message until now. It sounds like the module isn’t installed. Did you follow point 2 on the install instructions on github? Make sure to be in the folder tidal/MaxMspOsc of the github files you downloaded.

      1. Thank you, Mads, for your reply. I really appreciate it.
        I am on a Mac running 10.12.6.
        To complete Step 2 of the directions on Git, I do the following:
        1. Open the Terminal on my computer
        2. Type “cd” followed by the directory path ending tidal/MaxMspOsc
        3. Type “cabal install”

        Terminal reports back:

        Warning: –root-cmd is no longer supported, see (if you didn’t type –root-cmd,
        comment out root-cmd in your ~/.cabal/config file)
        Resolving dependencies…
        Configuring MaxMspOsc-…
        Building MaxMspOsc-…
        Installed MaxMspOsc-
        Updating documentation index

        I do not know what this means. But if I proceed to Step 4, and evaluate the import line “Shift Return,” I get the same error:

        : error:tidal>
        Could not find module ‘Sound.Tidal.MaxMspOsc’ It is not a module in the current program, or in any known package.

        Lastly, it may not be related. But although Tidal works, and I really like it, I do get the following error message whenever I start it:

        Warning: No local targets specified, so ghci will not use any options from your package.yaml / *.cabal files.
        Potential ways to resolve this: * If you want to use the package.yaml / *.cabal package in the current directory, use stack init to create a new stack.yaml. * Add to the ‘packages’ field of /Users/MaxPhoton/.stack/global-project/stack.yaml Configuring GHCi with the following packages:

        Thank you for any guidance or insight you are able to provide.



  2. I have it working.

    Ultimately, I wiped a laptop clean, reinstalled OSX 10.13.3, and reinstalled Haskell and Atom. Also, I installed Homebrew (per a recommendation in SuperCollider documentation; so this may be totally irrelevant as SuperCollider is not a part of the equation).

    So it is hard to say where the error was (probably a misstep of mine during prior installation).

    In any event, it is now running, and I am excited to explore creative possibilities at the intersection Tidal and Max.

    Thank you for putting this package together.



  3. Hey, Mads, I have another question.

    Is it viable for me, as someone unfamiliar with Haskell, to rename the parameters?–to replace “velocity” and “param1” etc. with parameters of my own designation?

    I want to name the parameters to align with those pertinent to a particular Max patch.

    Along the same lines, can I change max1 to m1–for the sake of speed when coding.

    Thank you for any guidance you are able to provide, and thank you again for creating and sharing this tool.


    1. Hey Daniel. You can change max1 to m1 during setup by writing `m1 <- maxmspStream "" 8020 1`

      If you want to change it after having set it up: evaluate `m1 = max1` on a line of it's own.

      After making max1 synonymous with m1 you can use the two interchangeably. The same goes for parameters. You make one thing synonymous with some other thing by declaring this in a line of it's own (as an example): `someNewParam = param1`. After this, when you write someNewParam in your tidal pattern it points to param1 behind the scenes (although it's still called param1 in max).

      If you want to take it even further, in Max you can unlock the patcher, mark the dropdown and open inspector. Then, under the `range/enum` parameter you will see the entire list of parameters. You can change this however you want. If you for example want to add `someNewParam` you just double click the list of parameters in the inspector, add a space and write `someNewParam`.

      Let me know if this makes sense.


      1. Hey Mads:

        Creating equivalency in Tidal (someNewParam = param1) does not alter data Tidal sends to Max (as I am seeing it).

        In other words, although I may type in Tidal , Tidal will still send “param1” to Max.

        Consequently, inputting “someNewParam” into the object in Max will not work, since Tidal is not actually sending “someNewParam” as data, but sending its equivalent, “param1.”

        Does that make sense?

        I am guessing that to send “someNewParam” to Max for recognition in the requires deeper changes–perhaps to MaxMspOsc.hs?

        Or am I missing something?


Leave a Reply

Your email address will not be published. Required fields are marked *