diff --git a/packages/core/controls.mjs b/packages/core/controls.mjs index 967c0904..82330bb8 100644 --- a/packages/core/controls.mjs +++ b/packages/core/controls.mjs @@ -1629,6 +1629,8 @@ export const { midimap } = registerControl('midimap'); * * @name midiport * @param {number | Pattern} port MIDI port + * @example + * note("c a f e").midiport("<0 1 2 3>").midi() */ export const { midiport } = registerControl('midiport'); diff --git a/packages/midi/README.md b/packages/midi/README.md index cefe40ab..aa90992d 100644 --- a/packages/midi/README.md +++ b/packages/midi/README.md @@ -41,7 +41,7 @@ Additional controls can be mapped using the mapping object passed to `.midi()`: ## Examples -### midi(outputName?) +### midi(outputName?, options?) 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. @@ -52,6 +52,42 @@ $: chord("").voicing().midi('IAC Driver') 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".` +### Options + +The `.midi()` function accepts an options object with the following properties: + +```javascript +$: note("c a f e").midi('IAC Driver', { isController: true, midimap: 'default'}) +``` + +
+Available Options + +| Option | Type | Default | Description | +|--------|------|---------|-------------| +| isController | boolean | false | When true, disables sending note messages. Useful for MIDI controllers | +| latencyMs | number | 34 | Latency in milliseconds to align MIDI with audio engine | +| noteOffsetMs | number | 10 | Offset in milliseconds for note-off messages to prevent glitching | +| midichannel | number | 1 | Default MIDI channel (1-16) | +| velocity | number | 0.9 | Default note velocity (0-1) | +| gain | number | 1 | Default gain multiplier for velocity (0-1) | +| midimap | string | 'default' | Name of MIDI mapping to use for control changes | +| midiport | string/number | - | MIDI device name or index | + +
+ + + + +### midiport(outputName) + +Selects the MIDI output device to use, pattern can be used to switch between devices. + +```javascript +$: midiport('IAC Driver') +$: note("c a f e").midiport("<0 1 2 3>").midi() +``` + ### midichan(number) Selects the MIDI channel to use. If not used, `.midi` will use channel 1 by default. diff --git a/test/__snapshots__/examples.test.mjs.snap b/test/__snapshots__/examples.test.mjs.snap index 2920a7a4..ebd1c209 100644 --- a/test/__snapshots__/examples.test.mjs.snap +++ b/test/__snapshots__/examples.test.mjs.snap @@ -5215,6 +5215,15 @@ exports[`runs examples > example "midi" example index 0 1`] = ` ] `; +exports[`runs examples > example "midi" example index 1 1`] = ` +[ + "[ 0/1 → 1/1 | note:c4 midichan:1 ]", + "[ 1/1 → 2/1 | note:c4 midichan:1 ]", + "[ 2/1 → 3/1 | note:c4 midichan:1 ]", + "[ 3/1 → 4/1 | note:c4 midichan:1 ]", +] +`; + exports[`runs examples > example "midibend" example index 0 1`] = ` [ "[ 0/1 → 1/1 | note:c4 midibend:0 ]", @@ -5453,6 +5462,27 @@ exports[`runs examples > example "midin" example index 0 1`] = ` ] `; +exports[`runs examples > example "midiport" example index 0 1`] = ` +[ + "[ 0/1 → 1/4 | note:c midiport:0 ]", + "[ 1/4 → 1/2 | note:a midiport:0 ]", + "[ 1/2 → 3/4 | note:f midiport:0 ]", + "[ 3/4 → 1/1 | note:e midiport:0 ]", + "[ 1/1 → 5/4 | note:c midiport:1 ]", + "[ 5/4 → 3/2 | note:a midiport:1 ]", + "[ 3/2 → 7/4 | note:f midiport:1 ]", + "[ 7/4 → 2/1 | note:e midiport:1 ]", + "[ 2/1 → 9/4 | note:c midiport:2 ]", + "[ 9/4 → 5/2 | note:a midiport:2 ]", + "[ 5/2 → 11/4 | note:f midiport:2 ]", + "[ 11/4 → 3/1 | note:e midiport:2 ]", + "[ 3/1 → 13/4 | note:c midiport:3 ]", + "[ 13/4 → 7/2 | note:a midiport:3 ]", + "[ 7/2 → 15/4 | note:f midiport:3 ]", + "[ 15/4 → 4/1 | note:e midiport:3 ]", +] +`; + exports[`runs examples > example "miditouch" example index 0 1`] = ` [ "[ 0/1 → 1/1 | note:c4 miditouch:0.5 ]", diff --git a/website/src/pages/learn/input-output.mdx b/website/src/pages/learn/input-output.mdx index 15d31f2a..92379aa6 100644 --- a/website/src/pages/learn/input-output.mdx +++ b/website/src/pages/learn/input-output.mdx @@ -16,14 +16,63 @@ It is also possible to pattern other things with Strudel, such as software and h Strudel supports MIDI without any additional software (thanks to [webmidi](https://npmjs.com/package/webmidi)), just by adding methods to your pattern: -## midi(outputName?) +## midiin(inputName?) + + + +## midi(outputName?,options?) 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. -").voicing().midi()`} /> +").voicing().midi('IAC Driver') +`} +/> -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".` +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".` +``` + +The `.midi()` function accepts an options object with the following properties: + + + +
+Available Options + +| Option | Type | Default | Description | +| ------------ | ------------- | --------- | ---------------------------------------------------------------------- | +| isController | boolean | false | When true, disables sending note messages. Useful for MIDI controllers | +| latencyMs | number | 34 | Latency in milliseconds to align MIDI with audio engine | +| noteOffsetMs | number | 10 | Offset in milliseconds for note-off messages to prevent glitching | +| midichannel | number | 1 | Default MIDI channel (1-16) | +| velocity | number | 0.9 | Default note velocity (0-1) | +| gain | number | 1 | Default gain multiplier for velocity (0-1) | +| midimap | string | 'default' | Name of MIDI mapping to use for control changes | +| midiport | string/number | - | MIDI device name or index | + +
+ +### midiport(outputName) + +Selects the MIDI output device to use, pattern can be used to switch between devices. + +```javascript +$: midiport('IAC Driver'); +$: note('c a f e').midiport('<0 1 2 3>').midi(); +``` + + ## midichan(number) @@ -106,8 +155,8 @@ The value should be an array of numbers between 0-255 representing the SysEx dat let id = 0x43; //Yamaha //let id = "0x00:0x20:0x32"; //Behringer ID can be an array of numbers let data = "0x79:0x09:0x11:0x0A:0x00:0x00"; // Set NSX-39 voice to say "Aa" -$: note("c d e f e d c").sysex(id, data).midi(); -$: note("c d e f e d c").sysexid(id).sysexdata(data).midi();`} +$: note("c a f e").sysex(id, data).midi(); +$: note("c a f e").sysexid(id).sysexdata(data).midi();`} /> The exact format of SysEx messages depends on your MIDI device's specification. @@ -118,9 +167,9 @@ Consult your device's MIDI implementation guide for details on supported SysEx m `midibend` sets MIDI pitch bend (-1 - 1) `miditouch` sets MIDI key after touch (0-1) - + - + # OSC/SuperDirt/StrudelDirt