Tidal futures

Work has started on a bit of a rewrite/refactor of Tidal, I thought I’d write a quick post about how things are progressing. There’s a github project here if you’d like more info or want to get involved.

Structure comes from where you want

In current Tidal, “the structure comes from the left” has become a bit of a mantra. In the next version, it’ll come from where you want.

For example "1 2 3" + "4 5" used to give you "4 6 7", because the structure comes from the first part, and  that2 in the middle starts in the first half of the cycle, so matches with 4.

In the rewrite, by default, structure comes from both sides, so in the above example, you end up with the equivalent of "1 [6 7] 8" — the 2 gets split in two, to match with both 4 and 5.

To get the old behaviour, of structure coming from the left, you’d use |+, i.e. "1 2 3" |+ "4 5". To get structure from the right, you’d do "1 2 3" +| "4 5", which would give you "5 7".. Then |+| does exactly the same as +, i.e. it gets structure from both sides.

Unified pattern operators

|+|, |+ and +| all work on patterns of parameters (now known as control patterns) as well as patterns of numbers. So these two are the same: n ("1 2" + "3 4 5") + s "bass" and n "1 2" + n "3 4 5" + s "bass".

Of course there are also *, /, % and - versions of the above.

There is also |>| and |<| and friends; the arrow there points at where the values come from. So you could do "[1 2] [3 5 6]" |> "5 2" to take the structure from the left, and the values from the right, giving you "[5 5] [2 2 2". Aha!

|> basically does what # does now, we’ll likely keep that as an alias..

On the way.. Stateful patterns

Patterns can now respond to state, the idea being that you can do things like note "c a f e" # sound "bass" # speed (scale 1 1.6 $ control "knob1") where knob1 somehow maps to an external controller. Latency might be an issue.. It’s all in bits at the moment though, the new version doesn’t actually make sound yet.. Will update this post as things develop.

Internals

The most exciting thing for me is that the code is a bit cleaner on the inside, with fewer bugs and edge cases, and things generally make more sense. There’s even some tests, a start at creating a more complete definition of what patterns are and how they should behave. Patterns are flagged as being either continuous or discrete, which clears up a lot of ambiguity that was around before.

Keep an eye on the project for updates!

Function of the Month #0 – preamble

Welcome to a new series of “Function of the month” (FotM) blog posts. We hope to build up a comprehensive picture of TidalCycles by periodically making a post with a short video. We plan to be true to the name, and do this every month, with a focus on a particular function. However allow us to deviate from this plan immediately by first taking some time to describe how the different parts of a standard Tidal system works. Take this as a hopefully illuminating preamble for this series.. We’ll get onto specific Tidal functions in FotM #1!

0. Introduction

A video accompanying the below will go here, once we’ve made it. In the meantime please feed back with comments and questions on the below, which we’ll then be able to respond to in the video itself.

A complete TidalCycles system has a few components which we’ll tour around, the TidalCycles language for generating pattern from code, the SuperCollider synthesis system which hosts SuperDirt for turning those patterns into sound, and an editor such as Atom which acts as a text editor for writing those Tidal patterns.  but lets start our tour with the TidalCycles language itself.

1) TidalCycles

TidalCycles is a computer language for generating pattern from code. It consists of an expressive mini-language for describing polyrhythmic sequences, and a wide range of pattern operators and functions for patterning such sequences in a variety of ways. For example, by rotating them, mirroring them, shifting them in time, combining them into weird interference patterns, and ‘glitching’ the sequence with random numbers.

You’ll have noticed that we often call TidalCycles by its shorter name Tidal. That’s actually what it was originally called, until someone started up a music streaming service with the same name, and we felt the need to differentiate..

Tidal is written in a programming language called Haskell. Strictly speaking, when you’re making patterns in Tidal you’re mostly writing Haskell code, but in practice you don’t need to learn Haskell in order to be a top Tidal coder. This is because Tidal is what is called a “Domain Specific Language”, embedded in Haskell, which supplies its own model of computation, operators, function and mini-language for sequences, all centred around pattern generation. That said, are some things about the underlying Haskell language that take a bit of getting used to though, like what that mysterious $ is doing, we’ll confront this in a later episode.

It’s important to note that the Tidal language does not make sound by itself, it only makes patterns. It talks to other software or hardware to make sound (using e.g. the OSC or MIDI protocol),  usually SuperDirt running in SuperCollider. However, quite a few people have plugged Tidal into custom software in order to generate patterned visuals, lights or even choreography. For now lets focus on the common case – SuperCollider and SuperDirt.

2. SuperCollider

SuperCollider is the synth behind most desktop live coding systems, and by default, Tidal is no exception. As we said above, Tidal is made for generating patterns, but doesn’t itself make any sound, that’s why you need SuperCollider installed. SuperCollider is a very well developed programming language that is designed for sound synthesis (and digital signal processing in general) that can itself be live coded. By default though, you’ll just use it in order to host SuperDirt.

2a) SuperDirt

SuperDirt is a sound synthesis framework designed especially for TidalCycles, and written in SuperCollider. You don’t need to know anything about SuperCollider in order to run SuperDirt, you just have to start it up, and Tidal will by default send messages to it in order to trigger sounds. SuperDirt comes with a fairly large library of sound samples, as well as a range of synthesisers.

With the latest version it is also possible to register MIDI devices with SuperDirt, so that you can trigger external sounds on soft/hardware synthesisers. This will be the topic of a FotM post later on.

If you run some Tidal code like this:

You’re sending two trigger messages to SuperDirt per cycle, first for the cp sound, and then the supermandolin sound. In the case of cp, SuperDirt will play a short sound sample, which it will find inside a folder called cp on your computer. You can find it from SuperCollider – from the menus select ‘open user support directory’, and then open ‘downloaded-quarks’ and then ‘Dirt-Samples’. You’ll see a bunch of ‘.wav’ files inside the cp folder, because cp isn’t a single sound but a set of them known as a ‘soundbank’. By default SuperDirt will play the first one – to play the second, you can specify cp:1 in your pattern instead (it starts counting at 0).

You won’t find a folder in Dirt-Samples called supermandolin, because that is a synthesiser rather than sample-based soundbank. You can play notes as numbers like this:

or as note names like this:

(If supermandolin isn’t working for you, it’s almost definitely because sc3-plugins isn’t installed properly, which is required by most synths.)

3. Atom

Your main interface to all this is probably Atom, or otherwise one of the other supported text editors. Atom is where you type in and run your Tidal patterns, although strictly speaking, Tidal itself doesn’t run inside Atom but in its own process. You’ll have installed a ‘tidalcycles’ extension inside Atom, but this isn’t tidal itself, but an interface to it. Clear? Hopefully!

Summary

Ok, that was a brief tour of the different components of a standard Tidal system. There’s a text editor Atom, sending code to a Tidal process to run, which in turn sends messages to SuperDirt to make sound, which in turn runs inside SuperCollider. Hopefully that’s straightened out some confusions, but feel free to ask some questions below!

TidalCycles Extension 0.5.6 for VS Code

The TidalCycles extension for VS Code has a fresh update. A couple of improvements have been made around configuration setting errors and custom boot file path errors.

Config Setting Errors

The new update now removes errors telling you that the TidalCycles config settings were “unknown”. Now it’s just a clean config:

Neat!

Boot File Path Errors

A few minor versions ago, we introduced the ability to configure a path to a custom Tidal boot file. With that, you can now configure Tidal to load up all of your custom stuff in a seamless bootup sequence. However, if VS Code could not locate your custom bootup file it wouldn’t tell you.

Now, the Tidal console output and a VS Code message will notify you that you boot file was not found:

What’s more is that you can fix your boot file config settings and try to reboot Tidal without restarting VS Code. Fancy!

Oh Hey One More Thing!

VS Code recently released a new feature where you can dock the terminal to the right-hand side of the IDE:

So now you can put the Tidal output to the side instead of below your Tidal code, if you so desire:

TidalCycles 0.9.8

TidalCycles 0.9.8 newly out! It replaces 0.9.7 which didn’t work well with many haskell versions. Here’s a quick run through the changes since 0.9.6. Any problems or questions, join us on the #tidal channel on talk.lurk.org, or the tidal list on we.lurk.org.

How to update

If you use cabal (rather than stack) to install, it’s just a matter of running cabal update then cabal install tidal from the commandline. I’m not clear on the best way to update using stack (as tidal hasn’t yet updated on stackage LTS), if you know please leave a comment!

New Bjorklund (aka Euclidean) functions

New function einv, which fills the “blanks” left by e. For example, e 3 8 "x" gives "x ~ ~ x ~ ~ x ~", whereas einv 3 8 "x" gives "~ x x ~ x x ~ x".

Another new function efull which takes two patterns rather than one, combining e n k on the first with einv n k on the second. For example, efull 3 8 "2" "1" gives "2 1 1 2 1 1 2 1"

Yet another function distrib, which is similar to e, but takes a list of numbers. distrib [5,8] "x" is the same as e 5 8 "x", but distrib [2,5,8] will  do something rather freaky.. It will take the (5,8) pattern as a starting point (which is "x ~ x x ~ x x ~") and then attempt to distribute two events evenly over those five xs as though they were contiguous,  creating "x ~ ~ x ~ ~ ~ ~"). Basically, give it a list of numbers which increase in value and you’ll find some interesting off-kilter rhythms.

d1 $ distrib [5,7,16] $ sound "bd:7"

Sequence parser

Now you can give * and / subpatterns in the parser. For example "[a b]*[2 3]" would be the same as "[a b] [b a b]" (i.e. the first half of "a b a b", which is the pattern at twice the speed, and the second half of "a b a b b a b", which is the pattern at three times the speed).

Floating point notes

Now notes are floating point. This means that you can do things like d1 $ s "drum*8" # n (sine * 8). It also means that for some synthesised sounds you can play between the notes (microtones?), e.g. d1 $ sound "supermandolin*8" # n sine. There have been other adjustments in this area, so previously where you had to do fiddly conversions between integers and floats, you no longer have to.

ghc support

Tidal now supports the latest version of ghc (8.4.1). You should probably be running at least 7.10.3 by now but older versions may still work.

SuperDirt

Exciting SuperDirt update to follow soonish, including new MIDI support.

Enjoy!

TidalBot

TidalBot is back! You can tweet tidal patterns to @tidalbot on twitter, and it will give you back an mp3 of the pattern, as well as a PDF with a visualisation of it.. Here’s a couple of examples:

As a bonus, the latest pattern is currently being projected into the shop window of Access Space Labs on Fitzalan Square in Sheffield.

Atom package v0.12.1: current directory boot file

The latest version (0.12.1) of the TidalCycles package for Atom has a new option to use a bootup file in your current project directory:

What this means is that you can now have a custom bootup file for each “project” you may be working on (e.g. compositions, MIDI modules, custom OSC setups, live sets, etc).

All you need to do for this to work is to create a BootTidal.hs file at the root of your Atom project folder:

If you’re not sure where to start with a custom boot file, you can reference a sample default one on the TidalCycles Atom package page, or use this code:

With these configuration options, you can now have complete control over your own custom Tidal boot code rather than modifying the source code of the package’s boot file.

For more information check out this video that explores all of the boot options in the Atom Tidalcycles package:

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 “127.0.0.1” 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.

Elastic Tempo Flux

I just published a new tutorial video on how to achieve continuous, elastic tempo changes in TidalCycles.

The video covers techniques with two different functions: nudge and spaceOut.

nudge

You can use nudge to move the timing of events into the future. Here, we schedule each of the four cp samples with future times of 0, 0.7, 0.2, and 0.4 seconds, respectively:

The above example isn’t very interesting. However, when you apply a sine function to nudge, you can make time appear to stretch in a smooth way:

Different pattern densities, scaling, and sine speeds interact with each other to create different results:

spaceOut

The spaceOut function lets you specify a list of cycle speed multipliers, and then plays the pattern exactly once at each speed:

The above code will play the cp*4 cp*2 pattern at 1, then 0.5, 1.33, 0.1, and 2 times the normal cycle speed.

Where spaceOut gets a little more interesting is when you use Haskell’s list syntax to build longer lists of linear (or non-linear) values. Consider this spaceOut pattern that plays at speeds ranging from 1 to 3, incrementing by 0.1:

The above pattern has 30 different speeds (!) but with very little code.

You can achieve speed “oscillations” that resemble a triangle wave by adding two lists together with the ++ operator:

You can use many different Haskell features to build lists. Here is a different method that constructs lists of fractional values using map:

TidalCycles and Processing

TidalCycles is close friends with SuperDirt but can be configured to send trigger messages to anything that accepts Open Sound Control network messages (or MIDI).

A while back I made a quick example of how to live code Processing sketch from Tidal. You can find an example sketch and tidal file on github. See what can be done with this sort of approach here:

Atsushi Tadokoro is doing similar things in Tokyo, I think with openframeworks.

Yecto has been working on this sort of thing for a while too, check out his spine-tingling sh2hs2 system.

Atom Package v0.11.0: custom Tidal boot path

A new release (version 0.11.0) of the TidalCycles package for Atom is available today. With this version you can now specify a path to your own boot file in the package settings:

This means that you no longer need to modify the provided BootTidal.hs file in the package with your own custom logic (e.g. custom functions, additional modules, etc).

If you want to create your own boot file:

  1. Create a copy of the original (available here)
  2. Save it anywhere on your computer
  3. Modify the TidalCycles package settings to point to where you saved the new file