Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MIDI Program Change, SysEx, NRPN, PitchBend and AfterTouch Output #1244

Open
wants to merge 23 commits into
base: main
Choose a base branch
from

Conversation

nkymut
Copy link
Contributor

@nkymut nkymut commented Jan 18, 2025

This update adds support for sending MIDI Program Change and System Exclusive (SysEx) messages for @strudel/midi package. It builds upon the changes made in #1212; however, MIDI mapping and Hi-res CC have not been tested yet.

Examples:

Program Change:

// [obsolete]note("c a f e").pc("<0 1 2>").midichan(1).midi()
$: note("c a f e").progNum("<0 1 2>").midichan(1).midi()
$: "10 20 30".progNum().midichan(1).midi()

// midi/gm.mjs provides mapping of gm intrrument names and pg numbers. 
// [obsolete] note("c a f e").pc(gm['marimba']).midichan(2).midi()
note("c a f e").progNum(gm['marimba']).midichan(2).midi()
//use midicmd
$: note("c a f e").midicmd("progNum:10").midichan(1).midi()
$: "progNum:20 progNum:30".midicmd().midichan(1).midi()

SysEx Messages:

// Send a simple SysEx message
let id = 0x43; //Yamaha ID for Gakken(Yamaha) NSX-39
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();

//ID can be an array of numbers
//let id = "0x00:0x20:0x32"; //Behringer 

Test & ToDo

Bubobubobubobubo and others added 11 commits November 9, 2024 01:41
This commit adds a second argument to the midi() command: mapping.
This argument should be an object containing a key-value map of
MIDI controls used by an external synthesizer. If any control is
used that matches the mapping, a CC message is sent.
split sysex message into sysexid and sysexdata
sysexid is a device identification number or array
sysexdata is an array of data to be sent to the device
- add example sysex data for setting NSX-39(Pocket Miku) voice data.
@nkymut nkymut force-pushed the add-program-change branch from 37f826f to a880378 Compare January 18, 2025 18:33
@felixroos
Copy link
Collaborator

great stuff! would it make sense to add this to the existing midicmd ( #710 ) instead of the new pc function?

@felixroos
Copy link
Collaborator

wow also nice work on the docs

@nkymut
Copy link
Contributor Author

nkymut commented Jan 19, 2025

Thank you for bringing this to my attention (#710). I overlooked the existing midicmd control completely.
I should have also referenced Tidal's MIDI control conventions,
as I agree that the pc function (for program change) could be more descriptive.

Superdirt uses a 'midicmd' control to specify the different midi commands.
https://tidalcycles.org/docs/configuration/MIDIOSC/midi/#synchronising-midi-clock-via-tidal

This mirrors the supercollider midi api
https://doc.sccode.org/Tutorials/A-Practical-Guide/PG_08_Event_Types_and_Parameters.html#MIDI%20output

@nkymut
Copy link
Contributor Author

nkymut commented Jan 19, 2025

Regarding sysex (System Exclusive) messages,
I'm struggling with how to pass multiple pattern arguments (esp involving lists) to functions.

While ideally I'd want to structure it as:

sysex(id, data)

Currently, I've split it into:

sysexid(id).sysexdata(data)

This split approach largely follows webmidijs's sendSysex method specification,
which handles ID and data as separate parameters.
https://webmidijs.org/api/classes/Output#sendSysex

sendSysex([id],[data],[option])

If we adopt midicmd, it would be

midicmd("sysex:id:data")

here are some relevant topic on discord channel.
SysEx and lists
https://discordapp.com/channels/779427371270275082/1191429292744245250/1329202181055709226
Concatenate strings as a pattern
https://discordapp.com/channels/779427371270275082/1191429292744245250/1304375383268921397

Or

- MiniRepl for input-output.mdx
- addresses tidalcycles#789 tidalcycles#710
- add progNum keyword handler
- update midicmd handler to handle 'progNum' case
- sysex(id, data) and both arguments are patternable
@nkymut
Copy link
Contributor Author

nkymut commented Jan 23, 2025

I have managed to get sysex(id, data) working while keeping it chainable and the arguments are patternable Yay!
BTW, the idea that everything in Strudel/Tidal is a pattern is genuinely fascinating!

Here I have added a sysex method in controls.mjs using register from '@strudel/core' and pass args into 'sysexid' and 'sysexdata' controls to process furthur making the method to return a Pattern,.

export const sysex = register('sysex', (args, pat) => {
  if (!Array.isArray(args)) {
    throw new Error('sysex expects an array of [id, data]');
  }
  const [id, data] = args;
  return pat.sysexid(id).sysexdata(data); //return a chain of controls (which returns a Pattern)
});

@felixroos
Copy link
Collaborator

thanks! looking forward to testing this. i hope this can be part of the next release (happening soonish)

@felixroos felixroos added the v1.2 label Jan 24, 2025
@felixroos
Copy link
Collaborator

so i assume we have to merge #1212 first, right?

@nkymut
Copy link
Contributor Author

nkymut commented Jan 24, 2025

I tried adding API references, but it’s causing errors in the test code. I’ll fix it tomorrow morning by adding some dummy code for testing MIDI in and out.

- add mock 'midin' and 'sysex'
- typo in sysex example
@nkymut nkymut changed the title Add MIDI Program Change and SysEx Output Add MIDI Program Change and SysEx, NRPN, PitchBend, AfterTouch Output Jan 24, 2025
@nkymut nkymut changed the title Add MIDI Program Change and SysEx, NRPN, PitchBend, AfterTouch Output Add MIDI Program Change, SysEx, NRPN, PitchBend and AfterTouch Output Jan 24, 2025
@nkymut
Copy link
Contributor Author

nkymut commented Jan 24, 2025

Maybe I should have split them into seperate smaller PRs,
but I went ahead and added support for nprn #192 , midibend, and miditouch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants