{"id":20796412,"url":"https://github.com/jazz-soft/jzz","last_synced_at":"2025-05-14T18:02:32.149Z","repository":{"id":43002536,"uuid":"38982462","full_name":"jazz-soft/JZZ","owner":"jazz-soft","description":" MIDI library for Node.js and web-browsers","archived":false,"fork":false,"pushed_at":"2025-05-06T01:01:59.000Z","size":1022,"stargazers_count":547,"open_issues_count":19,"forks_count":28,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-05-14T18:02:17.515Z","etag":null,"topics":["audio","javascript","midi","midi-file","midi-files","midi2","ump","web-audio","web-audio-api","web-midi","web-midi-api","webaudio","webaudioapi","webmidi","webmidiapi"],"latest_commit_sha":null,"homepage":"http://jazz-soft.net/doc/JZZ/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jazz-soft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","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,"zenodo":null},"funding":{"github":"jazz-soft","custom":"https://paypal.me/jazzsoft"}},"created_at":"2015-07-12T23:46:14.000Z","updated_at":"2025-05-06T01:02:03.000Z","dependencies_parsed_at":"2023-12-16T06:33:27.640Z","dependency_job_id":"1e922d75-9d46-4853-9159-5620f33a6e8a","html_url":"https://github.com/jazz-soft/JZZ","commit_stats":{"total_commits":488,"total_committers":7,"mean_commits":69.71428571428571,"dds":0.3770491803278688,"last_synced_commit":"8491ffa66c204744600e369138a4c0755328a9bb"},"previous_names":[],"tags_count":151,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazz-soft%2FJZZ","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazz-soft%2FJZZ/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazz-soft%2FJZZ/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazz-soft%2FJZZ/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jazz-soft","download_url":"https://codeload.github.com/jazz-soft/JZZ/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254198452,"owners_count":22030964,"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":["audio","javascript","midi","midi-file","midi-files","midi2","ump","web-audio","web-audio-api","web-midi","web-midi-api","webaudio","webaudioapi","webmidi","webmidiapi"],"created_at":"2024-11-17T16:27:08.779Z","updated_at":"2025-05-14T18:02:32.129Z","avatar_url":"https://github.com/jazz-soft.png","language":"JavaScript","funding_links":["https://github.com/sponsors/jazz-soft","https://paypal.me/jazzsoft"],"categories":[],"sub_categories":[],"readme":"# JZZ: MIDI library for Node.js and web-browsers\n![nodejs](https://jazz-soft.github.io/img/nodejs.jpg)\n![firefox](https://jazz-soft.github.io/img/firefox.jpg)\n![chrome](https://jazz-soft.github.io/img/chrome.jpg)\n![opera](https://jazz-soft.github.io/img/opera.jpg)\n![safari](https://jazz-soft.github.io/img/safari.jpg)\n![msie](https://jazz-soft.github.io/img/msie.jpg)\n![edge](https://jazz-soft.github.io/img/edgc.jpg)\n![windows](https://jazz-soft.github.io/img/windows.jpg)\n![macos](https://jazz-soft.github.io/img/macos.jpg)\n![linux](https://jazz-soft.github.io/img/linux.jpg)\n![raspberry pi](https://jazz-soft.github.io/img/rpi.jpg)\n![ios](https://jazz-soft.github.io/img/ios.jpg)\n![android](https://jazz-soft.github.io/img/android.jpg)  \n[![npm](https://img.shields.io/npm/v/jzz.svg)](https://www.npmjs.com/package/jzz)\n[![npm](https://img.shields.io/npm/dt/jzz.svg)](https://www.npmjs.com/package/jzz)\n[![jsDelivr](https://data.jsdelivr.com/v1/package/npm/jzz/badge)](https://www.jsdelivr.com/package/npm/jzz)\n[![build](https://github.com/jazz-soft/JZZ/actions/workflows/build.yml/badge.svg)](https://github.com/jazz-soft/JZZ/actions)\n[![Coverage](https://coveralls.io/repos/github/jazz-soft/JZZ/badge.svg?branch=master)](https://coveralls.io/github/jazz-soft/JZZ?branch=master)\n[![Try jzz on RunKit](https://badge.runkitcdn.com/jzz.svg)](https://npm.runkit.com/jzz)\n\n**JZZ.js** allows sending, receiving and playing MIDI messages\nin **Node.js** and **all major browsers**\nin **Linux**, **MacOS** and **Windows**.\nSome features are available on **iOS** and **Android** devices.\n\n**JZZ.js** enables [**Web MIDI API**](https://webaudio.github.io/web-midi-api/)\nin **Node.js** and those browsers that don't support it,\nand provides additional functionality to make developer's life easier.\n\nFor the best user experience, it's *highly RECOMMENDED (though not required)*\nto install the latest version of [**Jazz-Plugin**](https://jazz-soft.net)\nand browser extensions from [**Chrome Web Store**](https://chrome.google.com/webstore/detail/jazz-midi/jhdoobfdaejmldnpihidjemjcbpfmbkm)\nor [**Mozilla Add-ons**](https://addons.mozilla.org/en-US/firefox/addon/jazz-midi)\nor [**Apple App Store**](https://apps.apple.com/us/app/jazz-midi/id1506447231).\n\n## Features\n- MIDI In/Out\n- User-defined MIDI nodes\n- MIDI files\n- MPE\n- SMPTE\n- UMP (MIDI 2.0)\n- Additional modules\n\n## Install\n\n`npm install jzz --save`  \nor `yarn add jzz`  \nor get the full development version and minified scripts from [**Github**](https://github.com/jazz-soft/JZZ)\n\n*Note:* in the (unlikely) case you get into trouble installing the\n[**midi-test**](https://www.npmjs.com/package/midi-test) module,\nthat requires special system configuration,\nyou can safely remove it from the *devDependencies*\nby running `npm remove midi-test --save-dev`.\n\n## Usage\n\n##### Plain HTML\n\n```html\n\u003cscript src=\"JZZ.js\"\u003e\u003c/script\u003e\n//...\n```\n\n##### CDN (jsdelivr)\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/jzz\"\u003e\u003c/script\u003e       // the latest version, or\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/jzz@1.9.3\"\u003e\u003c/script\u003e // any particular version\n//...\n```\n\n##### CDN (unpkg)\n\n```html\n\u003cscript src=\"https://unpkg.com/jzz\"\u003e\u003c/script\u003e       // the latest version, or\n\u003cscript src=\"https://unpkg.com/jzz@1.9.3\"\u003e\u003c/script\u003e // any particular version\n//...\n```\n\n##### CommonJS\n\n```js\nvar JZZ = require('jzz');\n//...\n```\n\n##### TypeScript / ES6\n\n```ts\nimport { JZZ } from 'jzz';\n//...\n```\n\n##### AMD\n\n```js\nrequire(['JZZ'], function(JZZ) {\n  //...\n});\n```\n\n## Web MIDI API\n\n##### (Node.js example)\n\n```js\nvar navigator = require('jzz');\nnavigator.requestMIDIAccess().then(onSuccess, onFail);\n// ...\nnavigator.close(); // This will close MIDI inputs,\n                   // otherwise Node.js will wait for MIDI input forever.\n// In browsers the funcion is neither defined nor required.\n```\n\n## JZZ API\n\n##### MIDI Output/Input\n\n```js\nJZZ().or('Cannot start MIDI engine!')\n     .openMidiOut().or('Cannot open MIDI Out port!')\n     .wait(500).send([0x90,60,127]) // note on\n     .wait(500).send([0x80,60,0]);  // note off\nJZZ().openMidiIn().or('Cannot open MIDI In port!')\n     .and(function() { console.log('MIDI-In: ', this.name()); })\n     .connect(function(msg) { console.log(msg.toString()); })\n     .wait(10000).close();\n```\n\n##### Connecting MIDI nodes\n\n```js\nvar input = JZZ().openMidiIn();\nvar output = JZZ().openMidiOut();\nvar delay = JZZ.Widget({ _receive: function(msg) { this.wait(500).emit(msg); }});\ninput.connect(delay);\ndelay.connect(output);\n```\n\n##### Helpers and shortcuts\n\n```js\n// All calls below will do the same job:\nport.send([0x90, 61, 127]).wait(500).send([0x80, 61, 0]);   // arrays\nport.send(0x90, 61, 127).wait(500).send(0x80, 61, 0);       // comma-separated\nport.send(0x90, 'C#5', 127).wait(500).send(0x80, 'Db5', 0); // note names\nport.noteOn(0, 'C#5', 127).wait(500).noteOff(0, 'B##4');    // helper functions\nport.note(0, 'C#5', 127, 500);                              // another shortcut\nport.ch(0).noteOn('C#5').wait(500).noteOff('C#5');          // using channels\nport.ch(0).note('C#5', 127, 500);                           // using channels\n```\n\n##### Asynchronous calls\n\n```js\n// in the environments that support async/await:\nasync function playNote() {\n  var midi = await JZZ();\n  var port = await midi.openMidiOut();\n  await port.noteOn(0, 'C5', 127);\n  await port.wait(500);\n  await port.noteOff(0, 'C5');\n  await port.close();\n  console.log('done!');\n}\n// or:\nasync function playAnotherNote() {\n  var port = await JZZ().openMidiOut();\n  await port.noteOn(0, 'C5', 127).wait(500).noteOff(0, 'C5').close();\n  console.log('done!');\n}\n```\n\n##### Virtual MIDI ports\n\n```js\nvar logger = JZZ.Widget({ _receive: function(msg) { console.log(msg.toString()); }});\nJZZ.addMidiOut('Console Logger', logger);\n\n// now it can be used as a port:\nvar port = JZZ().openMidiOut('Console Logger');\n// ...\n\n// substitute the native MIDIAccess\n// to make virtual ports visible to the Web MIDI API code:\nnavigator.requestMIDIAccess = JZZ.requestMIDIAccess;\n```\n\n##### Frequency / MIDI conversion\n\n```js\nJZZ.MIDI.freq('A5'); // =\u003e 440\nJZZ.MIDI.freq(69);   // =\u003e 440\nJZZ.MIDI.freq(69.5); // =\u003e 452.8929841231365\n// from frequency:\nJZZ.MIDI.midi(440);  // =\u003e 69\nJZZ.MIDI.midi(450);  // =\u003e 69.38905773230853\n// or from name:\nJZZ.MIDI.midi('A5'); // =\u003e 69\n```\n\n## MIDI 2.0\n\n`MIDI2()` is an adapter that enables MIDI 2.0 in all subsequent chained calls.  \n`MIDI1()` returns the operation back to MIDI 1.0.  \nNote that the downstream MIDI nodes don't require any special actions to receive and transfer MIDI 2.0 messages:\n\n```js\nvar first = JZZ.Widget();\nvar second = JZZ.Widget();\nvar third = JZZ.Widget();\nfirst.connect(second);\nsecond.connect(third);\nthird.connect(function (msg) { console.log(msg.toString()); });\n\nfirst\n  .send([0x90, 0x3c, 0x7f])       // 90 3c 7f -- Note On\n  .MIDI2()                        // enable MIDI 2.0\n  .send([0x20, 0x90, 0x3c, 0x7f]) // 20903c7f -- Note On\n  .MIDI1()                        // reset to MIDI 1.0\n  .send([0x90, 0x3c, 0x7f])       // 90 3c 7f -- Note On\n```\n\nWhen used with MIDI 2.0, most of MIDI 1.0 helpers require `group` as an additional first parameter  \nand produce MIDI 1.0 messages wrapped into UMP packages.  \nMost of the new MIDI 2.0 helpers don't have corresponding MIDI 1.0 messages.  \nUse `gr()`, `ch()` and `sxId()` calls to set default `group`, `channel` and `SysEx ID` for the subsequent calls.  \n`MIDI2()` and `MIDI1()` clear off default `group`, `channel`, `SysEx ID` and `MPE` settings:\n\n```js\nfirst\n  .noteOn(5, 'C5', 127)           // 95 3c 7f -- Note On\n  .ch(5).noteOn('C5', 127)        // 95 3c 7f -- Note On\n  .MIDI2()\n  .noteOn(2, 5, 'C5', 127)        // 22953c7f -- Note On\n  .gr(2).noteOn(5, 'C5', 127)     // 22953c7f -- Note On\n  .ch(5).noteOn('C5', 127)        // 22953c7f -- Note On\n  .MIDI2()\n  .noteOn(2, 5, 'C5', 127)        // 22953c7f -- Note On\n  .ch(5).noteOn(2, 'C5', 127)     // 22953c7f -- Note On\n  .MIDI2()\n  .umpNoteOn(2, 5, 'C5', 127)     // 42953c00 007f0000 -- Note On\n  .gr(2).umpNoteOn(5, 'C5', 127)  // 42953c00 007f0000 -- Note On\n  .ch(5).umpNoteOn('C5', 127)     // 42953c00 007f0000 -- Note On\n```\n\nMore on [MIDI 2.0 support](https://jazz-soft.net/doc/JZZ/jzzmidi2.html)...\n\n## Additional modules\n- [**JZZ-midi-SMF**](https://github.com/jazz-soft/JZZ-midi-SMF) - Standard MIDI files: read / write / play\n- [**JZZ-midi-WS**](https://github.com/jazz-soft/JZZ-midi-WS) - MIDI via WebSockets\n- [**JZZ-midi-GM**](https://github.com/jazz-soft/JZZ-midi-GM) - General MIDI instrument names: MIDI to string / string to MIDI\n- [**JZZ-midi-Gear**](https://github.com/jazz-soft/JZZ-midi-Gear) - Retrieve your MIDI device model and manufacturer\n- [**JZZ-input-Kbd**](https://github.com/jazz-soft/JZZ-input-Kbd) - Virtual piano controls for your MIDI projects\n- [**JZZ-synth-Tiny**](https://github.com/jazz-soft/JZZ-synth-Tiny) - A tiny General MIDI synth implemented with the Web Audio API\n- [**JZZ-gui-Select**](https://github.com/jazz-soft/JZZ-gui-Select) - MIDI Input/Output pickers\n- [**JZZ-gui-Player**](https://github.com/jazz-soft/JZZ-gui-Player) - MIDI Player - ready for your page\n- [**JZZ-gui-Karaoke**](https://github.com/jazz-soft/JZZ-gui-Karaoke) - Karaoke :)\n- [**etc...**](https://github.com/jazz-soft/JZZ-modules) - Import third-party solutions into the JZZ framework\n\n## Testing your MIDI application\n- [**midi-test**](https://github.com/jazz-soft/midi-test) - Virtual MIDI ports for testing MIDI applications\n- [**web-midi-test**](https://github.com/jazz-soft/web-midi-test) - Fake Web MIDI API for testing Web MIDI applications\n- [**jazz-midi-headless**](https://github.com/jazz-soft/jazz-midi-headless) - MIDI for headless testing\n- [**test-midi-files**](https://github.com/jazz-soft/test-midi-files) - A framework for producing test MIDI files\n\n*Check the [**Getting Started**](https://jazz-soft.net/doc/JZZ) page\nand the [**API reference**](https://jazz-soft.net/doc/JZZ/reference.html)\nfor more information...*\n\n## Thanks for your support!\n[![Stargazers for @jazz-soft/JZZ](https://reporoster.com/stars/jazz-soft/JZZ)](https://github.com/jazz-soft/JZZ/stargazers)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjazz-soft%2Fjzz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjazz-soft%2Fjzz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjazz-soft%2Fjzz/lists"}