{"id":16887882,"url":"https://github.com/jswrenn/midiplex","last_synced_at":"2025-10-29T01:10:27.410Z","repository":{"id":68404076,"uuid":"129158799","full_name":"jswrenn/midiplex","owner":"jswrenn","description":"Volume-aware splitting of a polyphonic MIDI stream into multiple, monophonic streams.","archived":false,"fork":false,"pushed_at":"2018-07-12T19:45:00.000Z","size":30,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-14T18:59:20.549Z","etag":null,"topics":["alsa","midi","rust"],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jswrenn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-04-11T21:55:59.000Z","updated_at":"2020-08-26T01:24:53.000Z","dependencies_parsed_at":"2023-04-27T22:31:55.005Z","dependency_job_id":null,"html_url":"https://github.com/jswrenn/midiplex","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jswrenn%2Fmidiplex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jswrenn%2Fmidiplex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jswrenn%2Fmidiplex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jswrenn%2Fmidiplex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jswrenn","download_url":"https://codeload.github.com/jswrenn/midiplex/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244566926,"owners_count":20473451,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["alsa","midi","rust"],"created_at":"2024-10-13T16:47:26.764Z","updated_at":"2025-10-29T01:10:22.393Z","avatar_url":"https://github.com/jswrenn.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"MIDIplex is a utility for volume-aware distributing a _polyphonic_ MIDI stream into multiple output streams. The output streams are guaranteed to be monophonic. Output streams are allocated to a note in proportion to that note's velocity, relative to the velocity of other notes being played.\n\n## Why MIDIplex?\nMusic is often _polyphonic_, i.e., at times, there are multiple notes playing simultaneously. However, some synthesizers are _monophonic_, i.e., they can only voice one sound at a time. MIDIplex consumes a MIDI stream and automagically distributes it across a set number of output channels in such a way that it is guaranteed that no output will be expected to play two notes or more notes simultaneously. You can use MIDIplex to render a polyphonic MIDI across a given number of monophonic synthesizers, be it a [choir of musical floppy disks](https://www.youtube.com/watch?v=C3dU5u4xXaY), or (as I am) across a [lab of computers with `beep` installed](https://www.youtube.com/watch?v=ehpZ2GfWKe8).\n\nFor a visual depiction of how MIDIplex distributes notes, watch [this demonstration video](https://www.youtube.com/watch?v=leyjsN-FpUo), in which events from an input keyboard (top) are distributed across three output channels.\n\n## System Requirements\nMIDIplex integrates with the _Advanced Linux Sound Architecture_. MIDIplex therefore is only supported on systems running Linux.\n\n## Usage\n### Overview\n\n```\nUSAGE:\n    midiplex [OPTIONS] \u003cOUTPUT MODE\u003e\n\nOPTIONS:\n    -i, --input-pool-size \u003cI\u003e   sets the ALSA input pool size\n    -m, --max-allocation \u003cN\u003e    sets the maximum number of outputs allocated to any note\n\nOUTPUT MODES:\n    alsa                        ALSA output mode\n    udp                         UDP output mode\n```\n\n### Input\nMIDIplex consumes input as a virtual ALSA MIDI device named ‘midiplex’ with a writable port named ‘input’. You can verify that MIDIplex is running with `aconnect`:\n```\n$ aconnect -l\nclient 0: 'System' [type=kernel]\n    0 'Timer           '\n    1 'Announce        '\nclient 14: 'Midi Through' [type=kernel]\n    0 'Midi Through Port-0'\nclient 128: 'midiplex' [type=user,pid=6496]\n    0 'input \n```\n\n### Output\nMIDIplex supports two output modes. For most users, the ALSA output mode offers the most flexibility.\n\n#### ALSA Output\nIn the ALSA output mode, midiplex creates a specified list of readable ports to which it distributes notes. You can then patch those notes to other MIDI devices using the `aconnect` utility from `alsa-utils`, or a visual connection manager such as [patchage](http://drobilla.net/software/patchage).\n\n##### Overview:\n```\nUSAGE:\n    midiplex alsa [OPTIONS] \u003cNAMES\u003e...\n\nOPTIONS:\n    -o, --output-pool-size \u003cO\u003e  sets output pool size\n\nARGS:\n    \u003cNAMES\u003e...                  space-delimited names of output ports\n```\n\n##### Example:\n```\n$ midiplex alsa melete mneme aoide \u0026 aconnect -l\n[1] 10337\nclient 0: 'System' [type=kernel]\n    0 'Timer           '\n    1 'Announce        '\nclient 14: 'Midi Through' [type=kernel]\n    0 'Midi Through Port-0'\nclient 128: 'midiplex' [type=user,pid=10337]\n    0 'input           '\n    1 'melete          '\n    2 'mneme           '\n    3 'aoide           '\n```\n\n##### “Help! I’m getting `ENOSPC`”:\nThe ALSA output mode is resource-intensive. For 𝘯 outputs, each input note _on_ and _off_ event must be copied 𝘯 times. If those 𝘯 output ports are then patched to 𝘯 synthesizers, that entails additional copying of the event. These issues can be somewhat assuaged with `--input-pool-size` and `--output-pool-size`, but for large values of 𝘯, intensive pieces may nonetheless cause MIDIplex to terminate with `ENOSPC`.\n\n#### UDP Output\nFor cases where ALSA output mode is unsuitable, MIDIplex can write its output directly to a UDP socket. Note _on_ and _off_ events are encoded as three-byte datagrams, [as described by the MIDI specification](https://www.midi.org/specifications/item/table-1-summary-of-midi-message). You can receive these messages using a utility such as [MIDInet](https://github.com/jswrenn/midinet) or [qmidinet](https://qmidinet.sourceforge.io/).\n\n##### Overview:\n```\nUSAGE:\n    midiplex udp [HOSTS]...\n\nARGS:\n    \u003cHOSTS\u003e...                  space-delimited socket addresses\n```\n\n##### Example:\nAssuming three reachable hosts, _melete_, _mneme_ and _aoide_:\n```\n$ midiplex udp melete:8336 mneme:8336 aoide:8336 \u0026 aconnect -l\n[1] 13114\nclient 0: 'System' [type=kernel]\n    0 'Timer           '\n    1 'Announce        '\nclient 14: 'Midi Through' [type=kernel]\n    0 'Midi Through Port-0'\nclient 128: 'midiplex' [type=user,pid=13114]\n    0 'input           '\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjswrenn%2Fmidiplex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjswrenn%2Fmidiplex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjswrenn%2Fmidiplex/lists"}