---
title: MIDI, OSC & MQTT
layout: ../../layouts/MainLayout.astro
---

import { MiniRepl } from '../../docs/MiniRepl';
import { JsDoc } from '../../docs/JsDoc';

# MIDI, OSC and MQTT

Normally, Strudel is used to pattern sound, using its own '[web audio](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API)'-based synthesiser called [SuperDough](https://github.com/tidalcycles/strudel/tree/main/packages/superdough).

It is also possible to pattern other things with Strudel, such as software and hardware synthesisers with MIDI, other software using Open Sound Control/OSC (including the [SuperDirt](https://github.com/musikinformatik/SuperDirt/) synthesiser commonly used with Strudel's sibling [TidalCycles](https://tidalcycles.org/)), or the MQTT 'internet of things' protocol.

# MIDI

Strudel supports MIDI without any additional software (thanks to [webmidi](https://npmjs.com/package/webmidi)), just by adding methods to your pattern:

## midi(outputName?)

Either connect a midi device or use the IAC Driver (Mac) or Midi Through Port (Linux) for internal midi messages.
If no outputName is given, it uses the first midi output it finds.

<MiniRepl client:idle tune={`chord("<C^7 A7 Dm7 G7>").voicing().midi()`} />

In the console, you will see a log of the available MIDI devices as soon as you run the code, e.g. `Midi connected! Using "Midi Through Port-0".`

## midichan(number)

Selects the MIDI channel to use. If not used, `.midi` will use channel 1 by default.

## ccn && ccv

- `ccn` sets the cc number. Depends on your synths midi mapping
- `ccv` sets the cc value. normalized from 0 to 1.

<MiniRepl client:idle tune={`note("c a f e").ccn(74).ccv(sine.slow(4)).midi()`} />

In the above snippet, `ccn` is set to 74, which is the filter cutoff for many synths. `ccv` is controlled by a saw pattern.
Having everything in one pattern, the `ccv` pattern will be aligned to the note pattern, because the structure comes from the left by default.
But you can also control cc messages separately like this:

<MiniRepl
  client:idle
  tune={`$: note("c a f e").midi()
$: ccv(sine.segment(16).slow(4)).ccn(74).midi()`}
/>

Instead of setting `ccn` and `ccv` directly, you can also create mappings with `midimaps`:

## midimaps

<JsDoc client:idle name="midimaps" h={0} />

## defaultmidimap

<JsDoc client:idle name="defaultmidimap" h={0} />

# OSC/SuperDirt/StrudelDirt

In TidalCycles, sound is usually generated using [SuperDirt](https://github.com/musikinformatik/SuperDirt/), which runs inside SuperCollider. Strudel also supports using SuperDirt, although it requires installing some additional software.

There is also [StrudelDirt](https://github.com/daslyfe/StrudelDirt) which is SuperDirt with some optimisations for working with Strudel. (A longer term aim is to merge these optimisations back into mainline SuperDirt)

## Prequisites

To get SuperDirt to work with Strudel, you need to

1. install SuperCollider + sc3 plugins, see [Tidal Docs](https://tidalcycles.org/docs/) (Install Tidal) for more info.
2. install SuperDirt, or the [StrudelDirt](https://github.com/daslyfe/StrudelDirt) fork which is optimised for use with Strudel
3. install [node.js](https://nodejs.org/en/)
4. download [Strudel Repo](https://github.com/tidalcycles/strudel/) (or git clone, if you have git installed)
5. run `pnpm i` in the strudel directory
6. run `pnpm run osc` to start the osc server, which forwards OSC messages from Strudel REPL to SuperCollider

Now you're all set!

## Usage

1. Start SuperCollider, either using SuperCollider IDE or by running `sclang` in a terminal
2. Open the [Strudel REPL](https://strudel.cc/#cygiYmQgc2QiKS5vc2MoKQ%3D%3D)

...or test it here:

<MiniRepl client:only="react" tune={`s("bd sd").osc()`} />

If you now hear sound, congratulations! If not, you can get help on the [#strudel channel in the TidalCycles discord](https://discord.com/invite/HGEdXmRkzT).

Note: if you have the 'Audio Engine Target' in settings set to 'OSC', you do not need to add .osc() to the end of your pattern.

### Pattern.osc

<JsDoc client:idle name="Pattern.osc" h={0} />

## SuperDirt Params

Please refer to [Tidal Docs](https://tidalcycles.org/) for more info.

<br />

But can we use Strudel [offline](/learn/pwa)?

# MQTT

MQTT is a lightweight network protocol, designed for 'internet of things' devices. For use with strudel, you will
need access to an MQTT server known as a 'broker' configured to accept secure 'websocket' connections. You could
run one yourself (e.g. by running [mosquitto](https://mosquitto.org/)), although getting an SSL certificate that
your web browser will trust might be a bit tricky for those without systems administration experience.
Alternatively, you can use [a public broker](https://www.hivemq.com/mqtt/public-mqtt-broker/).

Strudel does not yet support receiving messages over MQTT, only sending them.

## Usage

The following example shows how to send a pattern to an MQTT broker:

<MiniRepl
  client:only="react"
  tune={`"hello world"
    .mqtt(undefined, // username (undefined for open/public servers)
          undefined, // password 
          '/strudel-pattern', // mqtt 'topic' 
          'wss://mqtt.eclipseprojects.io:443/mqtt', // MQTT server address
          'mystrudel', // MQTT client id - randomly generated if not supplied
          0 // latency / delay before sending messages (0 = no delay)
         )`}

/>

Other software can then receive the messages. For example using the [mosquitto](https://mosquitto.org/) commandline client tools:

```
> mosquitto_sub  -h mqtt.eclipseprojects.io -p 1883  -t "/strudel-pattern"
hello
world
hello
world
...
```

Control patterns will be encoded as JSON, for example:

<MiniRepl
  client:only="react"
  tune={`sound("sax(3,8)").speed("2 3")
  .mqtt(undefined, // username (undefined for open/public servers)
        undefined, // password
        '/strudel-pattern', // mqtt 'topic'
        'wss://mqtt.eclipseprojects.io:443/mqtt', // MQTT server address
        'mystrudel', // MQTT client id - randomly generated if not supplied
        0 // latency / delay before sending messages (0 = no delay)
       )`}
/>

Will send messages like the following:

```
{"s":"sax","speed":2}
{"s":"sax","speed":2}
{"s":"sax","speed":3}
{"s":"sax","speed":2}
...
```

Libraries for receiving MQTT are available for many programming languages.
