Giter VIP home page Giter VIP logo

jzz-midi-gm's Introduction

JZZ-midi-GM

npm npm build Coverage Status

General MIDI / GM2 / GS / XG instrument names: MIDI to string / string to MIDI

Install

npm install jzz-midi-gm
or yarn add jzz-midi-gm
or get the full development version and minified scripts from GitHub

Usage

Plain HTML
<script src="JZZ.js"></script>
<script src="JZZ.midi.GM.js"></script>
//...
CDN (jsdelivr)
<script src="https://cdn.jsdelivr.net/npm/jzz"></script>
<script src="https://cdn.jsdelivr.net/npm/jzz-midi-gm"></script>
//...
CDN (unpkg)
<script src="https://unpkg.com/jzz"></script>
<script src="https://unpkg.com/jzz-midi-gm"></script>
//...
CommonJS
var JZZ = require('jzz');
require('jzz-midi-gm')(JZZ);
//...
TypeScript / ES6
import { JZZ } from 'jzz';
import { GM } from 'jzz-midi-gm';
GM(JZZ);
//...
AMD
require(['JZZ', 'JZZ.midi.GM'], function(JZZ, gm) {
  // ...
});

API

MIDI to string

JZZ.MIDI.programName(midi) -
map MIDI program value to a General MIDI instrument name.

JZZ.MIDI.programName(midi, msb, lsb) -
map MIDI program value and bank msb/lsb to a GM2/GS/XG instrument name.

JZZ.MIDI.groupName(midi) -
map MIDI program value to a General MIDI group name.

JZZ.MIDI.percussionName(midi) -
map MIDI note value to General a MIDI percussion name.

console.log(JZZ.MIDI.programName(60));
// => 'French Horn'

console.log(JZZ.MIDI.programName(24, 0, 1));
// => 'Ukulele' (GM2)

console.log(JZZ.MIDI.groupName(60));
// => 'Brass'

console.log(JZZ.MIDI.percussionName(60));
// => 'Hi Bongo'

string to MIDI

JZZ.MIDI.programValue(str) -
map instrument name to a MIDI program (GM only); if there is no exact match, try the best guess.

JZZ.MIDI.noteValue(str) -
map percussion name to a MIDI note number; if there is no exact match, try the best guess.

JZZ.MIDI.guessValue(str) -
map program or percussion name (whatever matches best) to a MIDI value; if the return value is negative, it's the percussion note value with a minus sign, otherwise, it's the program value.

console.log(JZZ.MIDI.programName(JZZ.MIDI.programValue('piano')));
// => 'Acoustic Grand Piano'

console.log(JZZ.MIDI.percussionName(JZZ.MIDI.noteValue('snare')));
// => 'Acoustic Snare'

var n = JZZ.MIDI.guessValue('crash');
if (n < 0) console.log(JZZ.MIDI.percussionName(-n));
else console.log(JZZ.MIDI.programName(n));
// => 'Crash Cymbal 1'

list all instruments

allGM2() / allGS() / allXG() -
return a complete list of GM2/GS/XG programs as an array of of triplets [program-number, bank-msb, bank-lsb].

JZZ helpers

note(...) / noteOn(...) / noteOff(...) / aftertouch(...) / program(...) -
when the module is loaded, JZZ helper functions will understand the instrument names where appropriate.

JZZ().openMidiOut()
  .ch(0).program('accordion').noteOn('C#6', 100)
  .ch(9).noteOn('cowbell', 127);

More information

Please visit https://jazz-soft.net for more information.

jzz-midi-gm's People

Contributors

jazz-soft avatar nikolaivchr avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar  avatar

jzz-midi-gm's Issues

Can't generate midi drum sound

Hello. Thank you for great library. Convenient api makes me happy.
However I can't get drums work.
I added one more track to existing example and tried to setup bass drum and snare.
https://usermanuals.finalemusic.com/SongWriter2012Win/Content/PercussionMaps.htm
Generated file don't play drums sound(windows midi player) however midi notes exists in DAW(reaper).
Also when piano exists instead of vibraphone it doesn't produce sound. I tried using different channels but got stuck.
Please provide example how to make drums sound together with piano.

CODE:

<!DOCTYPE html>
<html>
<head>
<title>Write MIDI File</title>
<script src="https://cdn.jsdelivr.net/npm/jzz"></script>
<script src="https://cdn.jsdelivr.net/npm/jzz-midi-smf"></script>
<!-- https://github.com/jazz-soft/JZZ-midi-GM -->
<script src="https://cdn.jsdelivr.net/npm/jzz-midi-gm"></script>
<!-- <script src="./tracks.js"></script> -->
</head>

<body>
<h1>Write MIDI File</h1>

<div id=out></div>
<!-- <button onClick="playTrack()">Play</button> -->

<script type="module">

// Create a MIDI file. Type 1; 100 clocks per quarter note.
// Normally, it would rather be 96, but 100 makes it easier to count.
var smf = new JZZ.MIDI.SMF(1, 100);

// Add MIDI file tracks:
var trk0 = new JZZ.MIDI.SMF.MTrk(); smf.push(trk0); // First track in Type 1 MIDI file is normally used for tempo changes
var trk1 = new JZZ.MIDI.SMF.MTrk(); smf.push(trk1); // This one will be for the karaoke lyrics
var trk2 = new JZZ.MIDI.SMF.MTrk(); smf.push(trk2); // This one will be for the music
var trk3 = new JZZ.MIDI.SMF.MTrk(); smf.push(trk3); // This one will be for the music

trk0.smfSeqName('Little Lame') // The name of the first track serves as the file title
    .smfBPM(90); // Tempo. Normally set at clock 0, but can be also changed later

trk1.smfSeqName('Lyrics') // The names of other tracks don't have any particular meaning
    .smfText('@TMary Was A Little Lame') // Karaoke player will recognize this track by the "@T" tag
    .tick(100).smfText('\\Ma') // New verse starts with a backslash "\"
    .tick(75).smfText('ry ')
    .tick(25).smfText('was ')
    .tick(50).smfText('a ')
    .tick(50).smfText('lit')
    .tick(50).smfText('tle ')
    .tick(50).smfText('lame,')
    .tick(100).smfText('/Lit') // New line starts with a slash "/"
    .tick(50).smfText('tle ')
    .tick(50).smfText('lame,')
    .tick(100).smfText('/Lit')
    .tick(50).smfText('tle ')
    .tick(50).smfText('lame,')
    .tick(100).smfText('/Ma')
    .tick(75).smfText('ry ')
    .tick(25).smfText('was ')
    .tick(50).smfText('a ')
    .tick(50).smfText('lit')
    .tick(50).smfText('tle ')
    .tick(50).smfText('lame,')
    .tick(50).smfText('/A ')
    .tick(50).smfText('lit')
    .tick(50).smfText('tle ')
    .tick(50).smfText('lame ')
    .tick(50).smfText('was ')
    .tick(50).smfText('she!');
    

trk2.smfSeqName('Music')
    .ch(0) // all subsequent messahes will go to channel 0
    .program(0x0b) // set channel 0 program to vibraphone
    .tick(50).note('E5', 127, 5).note('E6', 127, 20)  // clock: 100, MIDI channel: 0, note: E5, velocity: 127, duration: 50 clocks
    .tick(50).note('D5', 127, 50)  // etc...
    .tick(50).note('C5', 127, 50)
    .tick(50).note('D5', 127, 50)
    .tick(50).note('E5',127, 25)
    .tick(50).note(64, 127, 50)   // can also use numerical values for the notes
    .tick(50).note(0x40, 127, 50)
    .tick(50).note('D5', 127, 50)
    .tick(50).note('D5', 127, 50)
    .tick(50).note('D5', 127, 50)
    .tick(100).note('E5', 127, 50)
    .tick(50).note('G5', 127, 50)
    .tick(50).note('G5', 127, 90)
    .tick(100).note('E5', 127, 75)
    .tick(75).note('D5', 127, 25)
    .tick(25).note('C5', 127, 50)
    .tick(50).note('D5', 127, 50)
    .tick(50).note('E5', 127, 50)
    .tick(50).note('E5', 127, 50)
    .tick(50).note('E5', 127, 50)
    .tick(75).note('E5', 127, 25)
    .tick(25).note('D5', 127, 50)
    .tick(50).note('D5', 127, 50)
    .tick(50).note('E5', 127, 50)
    .tick(50).note('D5', 127, 50)
    .tick(50).note('C5', 127, 190)
    .tick(100).note('E5', 100, 90).note('G5', 100, 90).note('C6', 127, 90)
    .tick(100).smfEndOfTrack(); // otherwise it will end on clock 1690
    
trk3.smfSeqName('drum')
    .ch(0) // all subsequent messahes will go to channel 0
    .program(JZZ.MIDI.programName(0, 127, 0))
    //.program('Standard Drum Kit') 
    .tick(50).note(0x51, 127, 5)  
    .tick(50).note(0x52, 127, 50)  
    .tick(50).note(0x53, 127, 50)
    .tick(50).note(0x54, 127, 50)
    .tick(50).note(36,127, 25)
    .tick(50).note(64, 127, 50)  
    .tick(50).note(0x40, 127, 50)
    .tick(50).note(36, 127, 50)
    .tick(50).note(20, 127, 50)
    .tick(50).note('C2', 127, 50)
    .tick(50).note('D2', 127, 50)
    .tick(50).note(0x50, 127, 50)
    .tick(50).note(0x60, 127, 50)
    .tick(50).note('C2', 127, 90)
    .tick(50).note(36, 127, 50)
    
    .tick(50).note(37, 127, 90)
    
    .tick(75).note(38, 127, 25)
    .tick(25).note(39, 127, 50)
    .tick(50).note('C2', 127, 50)
    .tick(50).note('D2', 127, 50)
    .tick(50).note(38, 127, 50)
    .tick(50).note('D2', 127, 50)
    .tick(75).note('D2', 127, 25)
    .tick(25).note('D2', 127, 50)
    .tick(50).note('D2', 127, 50)
    .tick(50).note('D2', 127, 50)
    .tick(50).note('C2', 127, 50)
    .tick(50).note('C2', 127, 190)
    .tick(50).note('D2', 100, 90)
    .tick(50).note('C2', 127, 190)
    .tick(50).note(40, 127, 50)
    .tick(50).note(41, 127, 50)
    .tick(50).note(42, 127, 190)
    .tick(50).note(43, 100, 90)
    .tick(50).note('C2', 127, 190)
    .tick(50).note('C2', 127, 190)
    .tick(50).note(50, 127, 190)
    .tick(50).note(50, 127, 190)
    
    .tick(100).smfEndOfTrack(); // otherwise it will end on clock 1690

var str = smf.dump(); // MIDI file dumped as a string
var b64 = JZZ.lib.toBase64(str); // convert to base-64 string
var uri = 'data:audio/midi;base64,' + b64; // data URI


// Finally, write it to the document as a link and as an embedded object:
document.getElementById('out').innerHTML = 'New file: <a download=lame.mid href=' + uri + '>DOWNLOAD</a> <embed src=' + uri + ' autostart=true>';
</script>

</body>
</html>

What are the asterisks and colons at the end of names?

There's an asterisk added to instrument names:

return _instr[n] + ' *';

What is this for?

Also, some instrument names include a colon, e.g. "Cello:"

{0:"Violin:",1:"Violin Attack:",8:"Slow Violin"},
{0:"Viola:",1:"Viola Attack:"},
{0:"Cello:",1:"Cello Attack:"},

Is from formatting the data into code?
Perhaps a regexp replace :"([},]) -> "$1 is in order.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.