{"id":13768079,"url":"https://github.com/AndrejHronco/midi-ports","last_synced_at":"2025-05-10T23:31:02.323Z","repository":{"id":57296860,"uuid":"55096212","full_name":"andrejhronco/midi-ports","owner":"andrejhronco","description":"Returns an object of attached midi ports with inputID, outputID, name, and manufacturer for more semantic MIDI port access.","archived":false,"fork":false,"pushed_at":"2017-10-30T18:23:41.000Z","size":13,"stargazers_count":16,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-11-17T03:31:12.755Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/andrejhronco.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}},"created_at":"2016-03-30T20:41:51.000Z","updated_at":"2023-02-01T23:25:19.000Z","dependencies_parsed_at":"2022-09-04T08:00:43.081Z","dependency_job_id":null,"html_url":"https://github.com/andrejhronco/midi-ports","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/andrejhronco%2Fmidi-ports","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrejhronco%2Fmidi-ports/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrejhronco%2Fmidi-ports/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrejhronco%2Fmidi-ports/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andrejhronco","download_url":"https://codeload.github.com/andrejhronco/midi-ports/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253497296,"owners_count":21917683,"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":[],"created_at":"2024-08-03T16:01:16.291Z","updated_at":"2025-05-10T23:31:02.069Z","avatar_url":"https://github.com/andrejhronco.png","language":"JavaScript","funding_links":[],"categories":["Libraries: Web MIDI API","Obsolete"],"sub_categories":["Web MIDI API","Community"],"readme":"#midi-ports\n\nWraps the MIDIAccess object and builds an object of midi devices with name, inputID, outputID, and manufacturer allowing a more semantic way of interacting with midi devices in the browser.\n\nFor use with the Web MIDI API, check browser support here: http://caniuse.com/#feat=midi\n\n##install\n```javascript\nnpm install midi-ports --save\n```\n##usage\n```javascript\nimport midiPorts from 'midi-ports'\n\nlet midi, ports;\n\nnavigator.requestmidiAccess({sysex: true}) // set to true if you need to send sysex messages\n\t.then((midiAccess) =\u003e {\n\t\tmidi = midiAccess\n\t\tports = midiPorts(midi [,options])\n\t})\n\n//internally builds a ports object:\nports('ports') \n/* =\u003e\n{\n\t'k-mix-audio-control': {\n\t\tname: 'K-Mix Audio Control',\n\t\tinputID: '-543473823',\n\t\toutputID: '586923498',\n\t\tmanufacturer: 'keith-mcmillen-instruments'\n\t},\n\t'k-mix-control-surface': {\n\t\tname: 'K-Mix Control Surface',\n\t\tinputID: '-543345892',\n\t\toutputID: '654298746',\n\t\tmanufacturer: 'keith-mcmillen-instruments'\n\t}\n}\n*/\n```\nWhich enables port access by name:\n\n```javascript\n// get an input and listen for messages\nlet kmixInput = ports('k-mix-control-surface').get('input')\nkmixInput.onmidimessage = (e) =\u003e console.log('data', e.data)\n\n// or, get an output and send messages\nlet kmixOutput = ports('k-mix-control-surface').get('output')\nkmixOutput.send([176, 1, 64])\n```\n\n##Grouped Devices\nIf you want to group ports by device, you can pass in an object as the second param which allows you to get a device:port by name.\n\nThe grouped devices object should be formatted:\n\n```javascript\nlet grouped = {\n\t'device': {\n\t\t'port-name': { }, // empty object which gets populated with name, inputID, outputID, and manufacturer\n\t\t'other-info': 'this can be any info you want to reference'\n\t}\n}\n```\n\n*Port names must be lowercase and hyphen-separated.\n\n```javascript\nlet grouped = {\n\t'k-mix': {\n\t\t'k-mix-audio-control': { },\n\t\t'k-mix-control-surface': { },\n\t\t'icon': 'https://files.keithmcmillen.com/products/k-mix/icons/k-mix.svg',\n\t\t'manufacturer': 'Keith McMillen Instruments'\n\t},\n\t'k-board':{\n\t\t'k-board': { },\n\t\t'icon': 'https://files.keithmcmillen.com/products/k-board/icons/k-board.svg',\n\t\t'manufacturer': 'Keith McMillen Instruments'\n\t}\n}\n//...\nlet devices = midiPorts(midi, grouped)\n/*\ninternally builds a devices.ports object:\n\ndevices('devices') =\u003e \n {\n\t'k-mix': {\n\t\t'k-mix-audio-control': {\n\t\t\tname: 'K-Mix Audio Control',\n\t\t\tinputID: '-543473823',\n\t\t\toutputID: '586923498',\n\t\t\tmanufacturer: 'keith-mcmillen-instruments'\n\t\t},\n\t\t'k-mix-control-surface': {\n\t\t\t'name': 'K-Mix Control Surface',\n\t\t\tinputID: '-543345892',\n\t\t\toutputID: '654298746',\n\t\t\tmanufacturer: 'keith-mcmillen-instruments'\n\t\t},\n\t\t'icon': 'https://files.keithmcmillen.com/products/k-mix/icons/k-mix.svg',\n\t\t'manufacturer': 'Keith McMillen Instruments'\n\t},\n\t'k-board':{\n\t\t'k-board': {\n\t\t\tname:'K-Board',\n\t\t\tinputID:'1852960744',\n\t\t\toutputID:'-162522465',\n\t\t\tmanufacturer:'kesumo-llc'\n\t\t},\n\t\t'icon': 'https://files.keithmcmillen.com/products/k-board/icons/k-board.svg',\n\t\t'manufacturer': 'Keith McMillen Instruments'\n\t}\n}\n*/\n```\nTo access grouped devices, use the 'device:port-name' format \n\n```javascript\nlet kmixOutput = devices('k-mix:k-mix-audio-control').get('output')\n\nkmixOutput.send([240, 126, 127, 6, 1, 247])\n```\nIf you want to group a device:port with only one port and its name is the same as the device, you can use a shorthand for getting that port.\n\n```javascript\n\t// you can use either\n\tdevices('k-board:k-board').get('input') // =\u003e midiInput\n\t\n\t// or, the shorter\n\tdevices('k-board').get('input') // =\u003e midiInput\n```\n\n##Accessing midiAccess The Ports Object, and the Devices Object\nYou can get direct access to the midiAccess object from within midi-ports, for example, to set a statechange handler, or loop over the 'ports' or 'devices' objects.\n\nIf you're not passing in an grouped devices object, 'ports' and 'devices' reference the same object, otherwise, 'devices' is in the format of grouped devices, 'device.port-name'. \n\nThe 'ports' object is always available and includes *_ALL_* attached ports.\n\n```javascript\nlet devices = midiPorts(midi, grouped)\n\n// get ports object, a la midi-ports v.1.x\ndevices('ports') // =\u003e {'port-name': { ... }}\n\n// get device object, a la midi-ports v.1.x\ndevices('devices') // =\u003e {'device': {'port-name': { ... }}}\n\n// get midiAccess object\ndevices('access') // =\u003e midiAccess\n\n// get midiAccess inputs / outputs iterator\n// ** when getting inputs / outputs from the midi Access object you must use the 'midi' param\ndevices('midi').get('inputs') // =\u003e midiInputMap\n\n// if using grouped devices object and a device isn't found ** see Error Handling below\ndevices('notfound') // =\u003e array of notfound ports ['k-mix-audio-control','k-mix-control-surface']\n// otherwise returns false\n```\n\n##Setting / Getting data\nYou can also set arbitrary port-specific data using the set method. Set and Get can be chained.\n\n```javascript\nlet devices = midiPorts(midi)\ndevices('k-board').set('quality', 'great!')\n\n// get custom data\ndevices('k-board').get('quality') // =\u003e great!\n\n// chain set and get\ndevices('k-board').set('price', '$99').set('review', 'awesome!').get('review') // =\u003e 'awesome!'\n```\n\n##Error Handling\n\nIf you're passing in an 'grouped devices' object and that device is not connected/found, midi-ports will add a each not-found port to an internal list, allowing for easier error handling. Fallback ports can be setup by using the 'ports' object if desired. For example, you could loop over 'ports' and build a select menu to allow the user to choose an alternate port.\n\nIn the case above, if 'k-mix' is not connected/found, querying 'notfound' will return a list like this:\n\n```javascript\ndevices('notfound') // =\u003e ['k-mix-audio-control','k-mix-control-surface']\n\ndevices('devices') \n/* =\u003e {\n\t'k-board': {\n \t\t'k-board': {\n   \t \t\tname: \"K-Board\",\n    \t\tinputID: \"1852960744\",\n    \t\toutputID: \"-162522465\",\n    \t\tmanufacturer: \"kesumo-llc\"\n\t\t}\n\t}\n}\n*/\ndevices('ports') \n/* =\u003e {\n\t'k-board': {\n\t\tname: \"K-Board\",\n\t\tinputID: \"1852960744\",\n\t\toutputID: \"-162522465\",\n\t\tmanufacturer: \"kesumo-llc\"\n}\n*/\n```\nWhich makes it easy to use alternative ports if your desired port isn't connected/found:\n\n```javascript\nif(!!ports('notfound')){\n\tconsole.warn('device ' + ...devices('notfound') + ' not found')\n\t\n\t// use an alternate port from devices('ports')\n\t// map devices('ports') keys to build select menu\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAndrejHronco%2Fmidi-ports","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAndrejHronco%2Fmidi-ports","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAndrejHronco%2Fmidi-ports/lists"}