{"id":23982382,"url":"https://github.com/ut-proj/undermidi","last_synced_at":"2025-04-14T05:53:44.234Z","repository":{"id":45224148,"uuid":"389411323","full_name":"ut-proj/undermidi","owner":"ut-proj","description":"An Erlang/LFE MIDI soft real time server for live play of MIDI devices","archived":false,"fork":false,"pushed_at":"2025-01-16T16:24:11.000Z","size":1470,"stargazers_count":4,"open_issues_count":10,"forks_count":1,"subscribers_count":0,"default_branch":"release/0.3.x","last_synced_at":"2025-04-14T05:53:22.627Z","etag":null,"topics":["erlang","generative-music","hacktoberfest","lfe","lisp-flavoured-erlang","midi","music"],"latest_commit_sha":null,"homepage":"","language":"LFE","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ut-proj.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2021-07-25T18:06:29.000Z","updated_at":"2025-01-16T16:24:13.000Z","dependencies_parsed_at":"2024-10-22T21:24:48.580Z","dependency_job_id":null,"html_url":"https://github.com/ut-proj/undermidi","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ut-proj%2Fundermidi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ut-proj%2Fundermidi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ut-proj%2Fundermidi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ut-proj%2Fundermidi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ut-proj","download_url":"https://codeload.github.com/ut-proj/undermidi/tar.gz/refs/heads/release/0.3.x","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248830389,"owners_count":21168272,"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":["erlang","generative-music","hacktoberfest","lfe","lisp-flavoured-erlang","midi","music"],"created_at":"2025-01-07T11:16:52.392Z","updated_at":"2025-04-14T05:53:44.228Z","avatar_url":"https://github.com/ut-proj.png","language":"LFE","funding_links":[],"categories":[],"sub_categories":[],"readme":"# undermidi\n\n[![Build Status][gh-actions-badge]][gh-actions]\n[![LFE Versions][lfe badge]][lfe]\n[![Erlang Versions][erlang badge]][versions]\n[![Tags][github-tags-badge]][github-tags]\n[![Downloads][hex-downloads]][hex-package]\n\n*A set of OTP servers that faciliate live MIDI composition and performance*\n\n[![][logo]][logo-large]\n\n## About\n\nundermidi supports two use cases, both of which utilise the Erlang term MIDI message formats defined in [midilib](https://github.com/erlsci/midilib):\n\n* direct calls to MIDI devices, each call requiring the use of a device and MIDI channel\n* a MIDI device manager that allows calls to be made without explicitly passing the device and MIDI channel every time\n\nNote that the calls made to midilib use the `midibin` module for binary MIDI messages, which in turn uses the [Erlang MIDI NIF](https://github.com/sonic-pi-net/sonic-pi/tree/dev/app/external/sp_midi) provided by the [Sonic Pi project](https://github.com/sonic-pi-net/sonic-pi).\n\n**Update**: This use of an Erlang NIF is new in 0.3.0! As part of that change, we made _significant_ and **breaking** changes to the `undermidi` API.\n\n## Dependencies \u0026 Setup\n\nThis application assumes that the following are on your system:\n\n* `git`\n* `cmake`, GNU `make`, OS-specific dev libraries that support MIDI\n* A modern install of Erlang (v25+)\n* [rebar3](https://www.rebar3.org/) (Erlang build tool)\n\n## Build \u0026 Run\n\nThe required sources for buidling the Erlang NIF will be downloaded and compiled, and then the Erlang and LFE for undermidi will be compiled, all with the following:\n\n```shell\n$ rebar3 compile\n```\n\nThen start the LFE REPL with prefined options for undermidi:\n\n```shell\n$ rebar3 as undermidi repl\n```\n\n**IMPORTANT!!**: the command given above automatically starts undermidi. If you do not use that command, you will need to manually start undermidi. Not doing so will result in many commands causing a segmentation fault of the Erlang VM due to the MIDI NIF not being initialised!\n\nIf you find yourself tiring of typing the above command, you can use the simple bash script that does the same:\n\n``` shell\n$ ./priv/scripts/run.sh\n```\n\nOnce the LFE REPL is ready, you can start the app:\n\n```cl\n(undermidi@local)lfe\u003e (undermidi:start)\n```\n\nNote that, depending upon the configured log level, you may see a fair amount of output.\n\n## API\n\nThere are two ways to use this library:\n\n1. Stateless: Make direct calls to the undermidi wrappers for the MIDI Erlang NIF, passing device and channel with every call\n1. Stateful: Create a managed connection to the MIDI device, passing only the data you need to make music\n\nEach of these are demonstrated below. The stateful approach is preferred and encouraged, as it makes code easier to read and helps one organise workflows when coding for multiple MIDI devices at once.\n\nThe `midilib` code used by undermidi utilises the same means as the Erlang NIF for referencing MIDI devices: their system names. The full set known by the system can be displayed with the following:\n\n``` lisp\nlfe\u003e (undermidi:list-devices)\n\ninputs\n  1. network_session_1\n  2. core_midi_general\n  3. core_midi_keyboards\n  4. komplete_kontrol_s88_mk2_port_1\n  5. komplete_kontrol_s88_mk2_port_2\n  6. komplete_kontrol_daw_-_1\n  7. model_15\n  8. model_d\n\noutputs\n  1. network_session_1\n  2. core_midi_general\n  3. core_midi_keyboards\n  4. komplete_kontrol_s88_mk2_port_1\n  5. komplete_kontrol_s88_mk2_port_2\n  6. komplete_kontrol_daw_-_1\n  7. model_15\n  8. model_d\nok\n```\n\nThe output of this display function will vary, depending upon system and connected/configured MIDI devices.\n\nWe'll use one of these names in the examples below, Moog's `\"model_15\"`.\n\n### Stateful\n\nGet a managed MIDI device connection:\n\n``` lisp\nlfe\u003e (set `#(ok ,d) (undermidi.devices:new \"model_15\"))\n#(ok #Pid\u003c0.1140.0\u003e)\n```\n\nNote that the name may be passed as either an atom or a string (list), but that the name used by the NIF is a string, and as such, undermidi ensures a name passed as an atom is converted when calling `new`.\n\n#### Notes\n\nThe `undermidi` project represents notes as a data structure of pitch, velocity, and duration. However, it provides some defaults to make that a little easier to work with, as well as a means of easily referencing MIDI pitch values using note names.\n\nPlay a single note:\n\n``` lisp\nlfe\u003e (undermidi:play-note d 'C3)\n```\n\nPlay a series of notes:\n\n``` lisp\nlfe\u003e (undermidi:play-notes d '(C3 C3 Eb3 C3 C3 Bb3 C3 C4))\n```\n\nThe `play-notes` function also accepts optional arguments for changing the time between the notes as well as the ability to repeat the series.\n\n#### Chords\n\n#### Sequences\n\n### Stateless\n\nSome variables for the MIDI device and the MIDI channel we're going to use for most calls:\n\n``` lisp\nlfe\u003e (set device \"\")\nlfe\u003e (set channel 1)\n```\n\n#### Notes\n\n``` lisp\nlfe\u003e (um.note:play device channel 'C3)\nlfe\u003e (um.note:play device channel '(C3 C3 Eb3 C3 C3 Bb3 C3 C4))\n```\n\n#### Chords\n\n#### Sequences\n\n## Licenses\n\nundermidi: BSD 2-Clause\n\nSonic Pi's Erlang NIF: MIT\n\nRtMIDI: MIT-like (optional notification)\n\n[//]: ---Named-Links---\n\n[logo]: priv/images/project-logo.png\n[logo-large]: priv/images/project-logo-large.png\n[github]: https://github.com/ut-proj/undermidi\n[gh-actions-badge]: https://github.com/ut-proj/undermidi/workflows/ci%2Fcd/badge.svg\n[gh-actions]: https://github.com/ut-proj/undermidi/actions\n[lfe]: https://github.com/rvirding/lfe\n[lfe badge]: https://img.shields.io/badge/lfe-2.1-blue.svg\n[erlang badge]: https://img.shields.io/badge/erlang-25%20to%2027-blue.svg\n[versions]: https://github.com/ut-proj/undermidi/blob/master/.github/workflows/cicd.yml\n[github-tags]: https://github.com/ut-proj/undermidi/tags\n[github-tags-badge]: https://img.shields.io/github/tag/ut-proj/undermidi.svg\n[github-downloads]: https://img.shields.io/github/downloads/ut-proj/undermidi/total.svg\n[hex-badge]: https://img.shields.io/hexpm/v/undermidi.svg?maxAge=2592000\n[hex-package]: https://hex.pm/packages/undermidi\n[hex-downloads]: https://img.shields.io/hexpm/dt/undermidi.svg\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fut-proj%2Fundermidi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fut-proj%2Fundermidi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fut-proj%2Fundermidi/lists"}