{"id":20796399,"url":"https://github.com/jazz-soft/jzz-midi-smf","last_synced_at":"2025-10-14T13:12:38.038Z","repository":{"id":57287848,"uuid":"130530513","full_name":"jazz-soft/JZZ-midi-SMF","owner":"jazz-soft","description":"Standard MIDI Files: read / write / play","archived":false,"fork":false,"pushed_at":"2025-04-13T00:09:33.000Z","size":457,"stargazers_count":44,"open_issues_count":3,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-07-06T19:53:13.761Z","etag":null,"topics":["midi","midi-clip","midi-file","midi-files","midi-player","midi2","smf","syx"],"latest_commit_sha":null,"homepage":"","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":"2018-04-22T03:04:19.000Z","updated_at":"2025-05-21T14:39:17.000Z","dependencies_parsed_at":"2023-12-23T07:22:40.556Z","dependency_job_id":"233e44b0-9074-4ba3-8e1a-6e1d5cfa8e09","html_url":"https://github.com/jazz-soft/JZZ-midi-SMF","commit_stats":{"total_commits":290,"total_committers":3,"mean_commits":96.66666666666667,"dds":0.4172413793103448,"last_synced_commit":"c83dfcd814042790b3796f873371461c2291a052"},"previous_names":[],"tags_count":113,"template":false,"template_full_name":null,"purl":"pkg:github/jazz-soft/JZZ-midi-SMF","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazz-soft%2FJZZ-midi-SMF","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazz-soft%2FJZZ-midi-SMF/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazz-soft%2FJZZ-midi-SMF/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazz-soft%2FJZZ-midi-SMF/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jazz-soft","download_url":"https://codeload.github.com/jazz-soft/JZZ-midi-SMF/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jazz-soft%2FJZZ-midi-SMF/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264320949,"owners_count":23590561,"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":["midi","midi-clip","midi-file","midi-files","midi-player","midi2","smf","syx"],"created_at":"2024-11-17T16:27:04.765Z","updated_at":"2025-10-14T13:12:38.033Z","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-SMF\n\nStandard MIDI Files: read / write / play  \n(MIDI 1.0 and MIDI 2.0)\n\n![Node.js](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![Internet Explorer](https://jazz-soft.github.io/img/msie.jpg)\n![Edge](https://jazz-soft.github.io/img/edgc.jpg)  \n[![npm](https://img.shields.io/npm/v/jzz-midi-smf.svg)](https://www.npmjs.com/package/jzz-midi-smf)\n[![npm](https://img.shields.io/npm/dt/jzz-midi-smf.svg)](https://www.npmjs.com/package/jzz-midi-smf)\n[![build](https://github.com/jazz-soft/JZZ-midi-SMF/actions/workflows/build.yml/badge.svg)](https://github.com/jazz-soft/JZZ-midi-SMF/actions)\n[![Coverage Status](https://coveralls.io/repos/github/jazz-soft/JZZ-midi-SMF/badge.svg?branch=master)](https://coveralls.io/github/jazz-soft/JZZ-midi-SMF?branch=master)\n\n## Install\n\n`npm install jzz-midi-smf --save`  \nor `yarn add jzz-midi-smf`  \nor get the full development version and minified scripts from [**GitHub**](https://github.com/jazz-soft/JZZ-midi-SMF)\n\n## Usage\n\n##### Plain HTML\n\n```html\n\u003cscript src=\"JZZ.js\"\u003e\u003c/script\u003e\n\u003cscript src=\"JZZ.midi.SMF.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\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/jzz-midi-smf\"\u003e\u003c/script\u003e\n//...\n```\n\n##### CDN (unpkg)\n\n```html\n\u003cscript src=\"https://unpkg.com/jzz\"\u003e\u003c/script\u003e\n\u003cscript src=\"https://unpkg.com/jzz-midi-smf\"\u003e\u003c/script\u003e\n//...\n```\n\n##### CommonJS\n\n```js\nvar JZZ = require('jzz');\nrequire('jzz-midi-smf')(JZZ);\n//...\n```\n\n##### TypeScript / ES6\n\n```ts\nimport { JZZ } from 'jzz';\nimport { SMF } from 'jzz-midi-smf';\nSMF(JZZ);\n//...\n```\n\n##### AMD\n\n```js\nrequire(['JZZ', 'JZZ.midi.SMF'], function(JZZ, dummy) {\n  // ...\n});\n```\n\n## MIDI files\nSupported file formats: `.mid`, `.kar`, `.rmi`\n\nPlease check the [**API Reference**](https://jazz-soft.net/doc/JZZ/midifile.html) !\n\n##### Playing MIDI file\n\n```js\nvar midiout = JZZ().openMidiOut();\nvar data = require('fs').readFileSync('file.mid', 'binary');\n// data can be String, Buffer, ArrayBuffer, Uint8Array or Int8Array\nvar smf = new JZZ.MIDI.SMF(data);\nvar player = smf.player();\nplayer.connect(midiout);\nplayer.play();\n//...\nplayer.speed(0.5); // play twice slower\n```\n\n##### Viewing the contents of MIDI file\n\n```js\nconsole.log(smf.toString());\n```\n\n##### Validating MIDI file\n\n```js\nvar warn = smf.validate();\nif (warn) console.log(warn);\n```\n\n##### Creating MIDI file from scratch\n\n```js\nvar smf = new JZZ.MIDI.SMF(0, 96); // type 0, 96 ticks per quarter note\nvar trk = new JZZ.MIDI.SMF.MTrk();\nsmf.push(trk);\n// add contents:\ntrk.add(0, JZZ.MIDI.smfSeqName('This is a sequence name'))\n   .add(0, JZZ.MIDI.smfBPM(90)) // tempo 90 bpm\n   .add(96, JZZ.MIDI.noteOn(0, 'C6', 127))\n   .add(96, JZZ.MIDI.noteOn(0, 'Eb6', 127))\n   .add(96, JZZ.MIDI.noteOn(0, 'G6', 127))\n   .add(192, JZZ.MIDI.noteOff(0, 'C6'))\n   .add(192, JZZ.MIDI.noteOff(0, 'Eb6'))\n   .add(192, JZZ.MIDI.noteOff(0, 'G6'))\n   .add(288, JZZ.MIDI.smfEndOfTrack());\n// or an alternative way:\ntrk.smfSeqName('This is a sequence name').smfBPM(90).tick(96)\n   .noteOn(0, 'C6', 127).noteOn(0, 'Eb6', 127).noteOn(0, 'G6', 127)\n   .tick(96).noteOff(0, 'C6').noteOff(0, 'Eb6').noteOff(0, 'G6')\n   .tick(96).smfEndOfTrack();\n// or even shorter:\ntrk.smfSeqName('This is a sequence name').smfBPM(90).tick(96)\n   .ch(0).note('C6', 127, 96).note('Eb6', 127, 96).note('G6', 127, 96)\n   .tick(192).smfEndOfTrack();\n```\n\n##### Exporting MIDI file data as JSON or any custom format\n\nOne easy thing to remember: `SMF` is an `Array` of `Track`s and `Track` is an `Array` of MIDI events:\n\n```js\nfor (var i = 0; i \u003c smf.length; i++) {\n  for (var j = 0; j \u003c smf[i].length; j++) {\n    console.log('track:', i, 'tick:', smf[i][j].tt, smf[i][j].toString());\n    // or do whatever else with the message\n  }\n}\n```\n\n##### Transposing MIDI file\n\n```js\nfor (var i = 0; i \u003c smf.length; i++) {\n  if (smf[i] instanceof JZZ.MIDI.SMF.MTrk) {\n    for (var j = 0; j \u003c smf[i].length; j++) {\n      var note = smf[i][j].getNote();\n      if (typeof note != 'undefined') {\n        if (smf[i][j].getChannel() != 9) { // skip the percussion channel\n          smf[i][j].setNote(note + 12);    // transpose one octave up\n        }\n      }\n    }\n  }\n}\n```\n\n##### Getting the info\n\n```js\nvar player = smf.player();\nvar dump = smf.dump();\nconsole.log('Type:', player.type());\nconsole.log('Number of tracks:', player.tracks());\nconsole.log('Size:', dump.length, 'bytes');\nconsole.log('Duration:', player.duration(), 'ticks');\nconsole.log('Total time:', player.durationMS(), 'milliseconds');\n```\n\n##### Saving MIDI file\n\n```js\nrequire('fs').writeFileSync('out.mid', smf.dump(), 'binary');\n```\n\n## SYX files\n\n##### All calls are almost identical to those for the SMF files:\n\n```js\nvar data = require('fs').readFileSync('file.syx', 'binary');\nvar syx = new JZZ.MIDI.SYX(data);\nsyx.send([0xf0, 0x7e, 0x7f, 0x06, 0x01, 0xf7]);\nsyx.sxMasterVolumeF(0.5);\nvar player = syx.player();\nplayer.connect(midiout);\nplayer.play();\nrequire('fs').writeFileSync('out.syx', syx.dump(), 'binary');\n```\n\n## MIDI 2.0 Clips\n\n##### Playing MIDI 2.0 clip\n\n```js\nvar midiout = JZZ().openMidiOut();\nvar data = require('fs').readFileSync('file.midi2', 'binary');\nvar clip = new JZZ.MIDI.Clip(data);\nvar player = clip.player();\n// since the majority of today's MIDI devices only support MIDI 1.0,\n// we can use a converter:\nvar conv = JZZ.M2M1();\nconv.connect(midiout);\nplayer.connect(conv);\nplayer.play();\n```\n\n##### Creating MIDI 2.0 clip from scratch\n\n```js\nvar clip = new JZZ.MIDI.Clip();\nclip.gr(0).ch(0).noteOn('C5').tick(96).noteOff('C5');\nrequire('fs').writeFileSync('out.midi2', clip.dump(), 'binary');\n```\n\n##### Most of other calls - same as above\n\n```js\nvar player = clip.player();\nvar dump = clip.dump();\nconsole.log(clip.toString());\nconsole.log('Size:', dump.length, 'bytes');\nconsole.log('Duration:', player.duration(), 'ticks');\nconsole.log('Total time:', player.durationMS(), 'milliseconds');\n```\n\n## Live DEMOs (source code included)\n\n[**Read MIDI file**](https://jazz-soft.net/demo/ReadMidiFile.html) - from file, URL, Base64  \n[**Write MIDI file**](https://jazz-soft.net/demo/WriteMidiFile.html) - create MIDI file from scratch  \n[**MIDI Player**](https://jazz-soft.net/demo/PlayMidiFile.html) - various ways to play MIDI file  \n[**Karaoke**](https://jazz-soft.net/demo/Karaoke.html) - playing MIDI files in *.kar* format\n\n## By popular demand\n##### Boilerplate code for bulk MIDI file editing\n```\nconst fs = require('fs');\nconst JZZ = require('jzz');\nrequire('jzz-midi-smf')(JZZ);\n\nif (process.argv.length != 4) {\n  console.log('Usage: node ' + process.argv[1] + ' \u003cinput.mid\u003e \u003coutput.mid\u003e');\n  process.exit(1);\n}\n\nvar old_midi = new JZZ.MIDI.SMF(fs.readFileSync(process.argv[2], 'binary'));\nvar new_midi = new JZZ.MIDI.SMF(old_midi); // copy all settings from the old file\nnew_midi.length = 0; // remove all tracks\n\nfor (var i = 0; i \u003c old_midi.length; i++) {\n  var old_track = old_midi[i];\n  if (!(old_track instanceof JZZ.MIDI.SMF.MTrk)) continue;\n  var new_track = new JZZ.MIDI.SMF.MTrk();\n  new_midi.push(new_track);\n  for (var j = 0; j \u003c old_track.length; j++) {\n    var old_msg = old_track[j];\n    var tick = old_msg.tt; // change it if you like, e.g. tick = old_msg.tt / 2;\n    if (true) { // add your own condition\n      new_track.add(tick, old_msg);\n    }\n    else if (false) { // add new messages or don't add anything\n      var new_msg = JZZ.MIDI.whatever(READ_THE_REFERENCE);\n      new_track.add(tick, new_msg);\n    }\n  }\n}\nfs.writeFileSync(process.argv[3], new_midi.dump(), 'binary');\n```\n\n## See also\n[**Test MIDI Files**](https://github.com/jazz-soft/test-midi-files) - these may be useful if you write a MIDI application...  \n\n## More information\n\nPlease visit [**https://jazz-soft.net**](https://jazz-soft.net) for more information.  \n\n## Thanks for your support!\n[![Stargazers for @jazz-soft/JZZ-midi-SMF](https://reporoster.com/stars/jazz-soft/JZZ-midi-SMF)](https://github.com/jazz-soft/JZZ-midi-SMF/stargazers)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjazz-soft%2Fjzz-midi-smf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjazz-soft%2Fjzz-midi-smf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjazz-soft%2Fjzz-midi-smf/lists"}