Jazz-Soft.net

We make it sound!

Home » Documentation » JZZ.js » JZZ.MIDI

JZZ.MIDI

All midi messages are internally handled as JZZ.MIDI objects. This type inherits from the JavaScript Array, and therefore allows all array operations on it.

Construction

JZZ.MIDI() works with or without the new keyword.

It accepts an array or a comma-separated list of the message bytes or another JZZ.MIDI object.

String names for the notes are allowed where appropriate (in the note on / note off / aftertouch messages).

Note name consists of the pitch class (from A to G), accidentals (#, ##, b, bb, or none), and the octave (from 0 to 10), and is case-insensitive.

German notation fans can use H and Bb for Si and Si-flat.

e.g. C#5, c#5, Db5, db5, DB5, dB5, B##4, b##4, H##4, h##4 will all have value of 61.

MIDI note range spans from C0 (0) to G10 (127), and the Middle-C is C5 (60).

Example

All following statements will produce the same result:

msg = new JZZ.MIDI([0x90, 63, 127]);
msg = new JZZ.MIDI(0x90, 63, 127);
msg = JZZ.MIDI(0x90, 63, 127);
msg = JZZ.MIDI([0x90, 'Eb5', 127]);
msg = JZZ.MIDI.noteOn(0, 'D#5', 127);                    // see below...

Timestamp

Timestamps will be available in the future releases.

toString()

toString() convert MIDI message to human-readable string.

NOTE: in most JavaScript realizations, console.log() does not automatically call this function.

Example

console.log(JZZ.MIDI.noteOn(0, 'D#5', 127).toString());  // or
console.log('Playing note: ' + JZZ.MIDI.noteOn(0, 'D#5', 127));

Helpers

It is not uncommon for JavaScript developer to forget which MIDI message stands for Dumper piano pedal off.

Therefore, some helper functions might be helpful.

In the following list c will stand for the channel, nn - for the note, vv - for velocity, mm - for the most significant byte (MSB), ll - for the least significant byte (LSB), b - for the boolean On/Off, xx and yy for other paraneters.

Functions that require two 7-bit numbers for MSB and LSB can also accept a single 14-bit number kk = (mm << 7) + ll as argument.

If the function produces multiple MIDI messages, those are returned as an Array.

noteOn(c, nn, vv) - note on; returns 9c nn vv. If omitted, default velocity value is 7F (127).

noteOff(c, nn, vv) - note off; returns 8c nn vv. In most cases, velocity can be omitted.

aftertouch(c, nn, xx) - aftertouch; returns Ac nn xx.

program(c, xx) - program change; returns Cc xx.

pressure(c, xx) - pressure (channel aftertouch); returns Dc xx.

pitchBend(c, kk), pitchBend(c, mm, ll) - pitch bender; returns Ec ll mm.

pitchBendF(c, xx) - same as above, but converts the floating point number -1 <= xx <= 1 to a 14-bit value.

control(c, xx, yy) - other control; returns Bc xx yy; some controls have their own dedicated helpers below.

bankMSB(c, mm) - bank select, MSB; returns Bc 00 mm.

bankLSB(c, ll) - bank select, LSB; returns Bc 20 ll.

bank(c, kk), bank(c, mm, ll) - bank select; returns [Bc 00 mm, Bc 20 ll].

modMSB(c, mm) - modulation wheel, MSB; returns Bc 01 mm.

modLSB(c, ll) - modulation wheel, LSB; returns Bc 21 ll.

mod(c, kk), mod(c, mm, ll) - modulation wheel; returns [Bc 01 mm, Bc 21 ll].

modF(c, xx) - same as above, but converts the floating point number 0 <= xx <= 1 to a 14-bit value.

breathMSB(c, mm) - breath controller, MSB; returns Bc 02 mm.

breathLSB(c, ll) - breath controller, LSB; returns Bc 22 ll.

breath(c, kk), breath(c, mm, ll) - breath controller; returns [Bc 02 mm Bc 22 ll].

breathF(c, xx) - same as above, but converts the floating point number 0 <= xx <= 1 to a 14-bit value.

footMSB(c, mm) - foot controller, MSB; returns Bc 04 mm.

footLSB(c, ll) - foot controller, LSB; returns Bc 24 ll.

footF(c, xx) - same as above, but converts the floating point number 0 <= xx <= 1 to a 14-bit value.

portamentoMSB(c, mm) - portamento time, MSB; returns Bc 05 mm.

portamentoLSB(c, ll) - portamento time, LSB; returns Bc 25 ll.

portamentoTime(c, kk), portamentoTime(c, mm, ll) - portamento time; returns [Bc 05 mm, Bc 25 ll].

portamentoTimeF(c, xx) - same as above, but converts the floating point number 0 <= xx <= 1 to a 14-bit value.

volumeMSB(c, mm) - channel volume, MSB; returns Bc 07 mm.

volumeLSB(c, ll) - channel volume, LSB; returns Bc 27 ll.

volume(c, kk), volume(c, mm, ll) - channel volume; returns [Bc 07 mm, Bc 27 ll].

volumeF(c, xx) - same as above, but converts the floating point number 0 <= xx <= 1 to a 14-bit value.

balanceMSB(c, mm) - stereo balance, MSB; returns Bc 08 mm.

balanceLSB(c, ll) - stereo balance, LSB; returns Bc 28 ll.

balance(c, kk), balance(c, mm, ll) - stereo balance; returns [Bc 08 mm, Bc 28 ll].

balance(c, xx) - same as above, but converts the floating point number -1 <= xx <= 1 to a 14-bit value.

panMSB(c, mm) - stereo pan, MSB; returns Bc 0A mm.

panLSB(c, ll) - stereo pan, LSB; returns Bc 2A mm.

pan(c, kk), pan(c, mm, ll) - stereo pan; returns [Bc 2A mm, Bc 2A mm].

panF(c, xx) - same as above, but converts the floating point number -1 <= xx <= 1 to a 14-bit value.

expressionMSB(c, mm) - expression controller, MSB; returns Bc 0B mm.

expressionLSB(c, ll) - expression controller, LSB; returns Bc 2B mm.

expression(c, kk), expression(c, mm, ll) - expression controller; returns [Bc 2B mm, Bc 2B mm].

expressionF(c, xx) - same as above, but converts the floating point number 0 <= xx <= 1 to a 14-bit value.

damper(c, b) - damper pedal on/off; default: b = true; returns Bc 40 7f/00.

portamento(c, b) - portamento on/off; default: b = true; returns Bc 41 7f/00.

sostenuto(c, b) - sostenuto pedal on/off; default: b = true; returns Bc 42 7f/00.

soft(c, b) - soft pedal on/off; default: b = true; returns Bc 43 7f/00.

legato(c, b) - legato on/off; default: b = true; returns Bc 44 7f/00.

hold2(c, b) - hold 2 on/off; default: b = true; returns Bc 45 7f/00.

ptc(c, nn) - portamento control; returns Bc 54 nn.

dataMSB(c, mm) - data entry, MSB; returns Bc 06 mm.

dataLSB(c, ll) - data entry, LSB; returns Bc 26 ll.

data(c, kk), data(c, mm, ll) - data entry; returns [Bc 06 mm, Bc 26 ll].

dataIncr(c) - data increment; returns Bc 60 00.

dataDecr(c) - data decrement; returns Bc 61 00.

nrpnLSB(c, ll) - non-registered parameter number, LSB; returns Bc 62 ll.

nrpnMSB(c, mm) - non-registered parameter number, MSB; returns Bc 63 mm.

nrpn(c, kk), nrpn(c, mm, ll) - non-registered parameter number; returns [Bc 63 mm, Bc 62 ll].

rpnLSB(c, ll) - registered parameter number, LSB; returns Bc 64 ll.

rpnMSB(c, mm) - registered parameter number, MSB; returns Bc 65 mm.

rpn(c, kk), rpn(c, mm, ll) - registered parameter number; returns [Bc 65 mm, Bc 64 ll].

allSoundOff(c) - all sound off; returns Bc 78 00.

resetAllControllers(c) - reset all controllers; returns Bc 79 00.

localControl(c, b) - local control on/off; default: b = true; returns Bc 7A 7f/00.

allNotesOff(c) - all notes off; returns Bc 7B 00.

omni(c, b) - Omni Mode On/Off; default: b = true; returns Bc 7D/7C 00.

mono(c, xx) - Mono Mode On; xx - number of channels, default: xx = 1; returns Bc 7E xx.

poly(c) - Poly Mode On; returns Bc 7F 00.

mtc(smpte) - MIDI time code (SMPTE quarter-frame); returns F1 xx.

songPosition(xx) - song position pointer; returns F2 ll mm.

songSelect(xx) - song select; returns F3 xx.

tune() - tune request; returns F6.

clock() - timing clock; returns F8.

start() - start; returns FA.

continue() - continue; returns FB.

stop() - stop; returns FC.

active() - active sensing; returns FE.

reset() - reset; returns FF.

Some RPN messages:

rpnPitchBendRange(c, kk), rpnPitchBendRange(c, mm, ll) - channel pitch bend range; returns [Bc 65 00, Bc 64 00, Bc 06 mm, Bc 26 ll].

rpnPitchBendRangeF(c, xx) - same as above; converts the floating point pitch bend range of +/- xx semitones to a 14-bit MIDI value.

rpnFineTuning(c, kk), rpnFineTuning(c, mm, ll) - channel fine tuning; returns [Bc 65 00, Bc 64 01, Bc 06 mm, Bc 26 ll].

rpnFineTuningF(c, xx) - same as above; converts the fractional part of xx (frequency shift in semitones) to a 14-bit MIDI value.

rpnCoarseTuning(c, mm) - channel coarse tuning; returns [Bc 65 00, Bc 64 02, Bc 06 mm].

rpnCoarseTuningF(c, xx) - same as above; converts the integer part of xx (frequency shift in semitones) to a 7-bit MIDI value.

rpnTuning(c, nn, kk), rpnTuning(c, nn, mm, ll) - channel coarse and fine tuning; returns [Bc 65 00, Bc 64 02, Bc 06 nn, Bc 65 00, Bc 64 01, Bc 06 mm, Bc 26 ll].

rpnTuningF(c, xx) - same as above; splits xx (frequency shift in semitones) into the corresponding MIDI values.

rpnTuningA(c, f) - channel A tuning; f - frequency of the note A in Hz (originally 440); returns rpnTuning messages with the calculated parameters.

rpnSelectTuningProgram(c, xx) - select tuning program; returns [Bc 65 00, Bc 64 03, Bc 06 xx].

rpnSelectTuningBank(c, xx) - select tuning bank; returns [Bc 65 00, Bc 64 04, Bc 06 xx].

rpnSelectTuning(c, xx, yy), rpnSelectTuning(c, xx) - select tuning bank and program;

combines rpnSelectTuningBank(c, xx) and rpnSelectTuningProgram(c, yy) or returns rpnSelectTuningProgram(c, xx) if yy is undefined.

rpnModulationDepthRange(c, kk), rpnModulationDepthRange(c, mm, ll) - channel modulation bend (modulation wheel) range; returns [Bc 65 00, Bc 64 05, Bc 06 mm, Bc 26 ll].

rpnModulationDepthRangeF(c, xx) - same as above; converts the floating point modulation bend range of xx semitones to a 14-bit MIDI value.

rpnNull(c) - RPN reset; returns [Bc 65 7F, Bc 64 7F].

Some common SysEx messages:

sxIdRequest() - device ID request; returns F0 7E 7F 06 01 F7. (see also: gearInfo())

sxFullFrame(smpte) - SMPTE full-frame; returns F0 7F 7F 01 01 xx xx xx xx F7.

sxMasterVolume(kk), sxMasterVolume(mm, ll) - master volume; returns F0 7F 7F 01 04 01 ll mm F7.

sxMasterVolumeF(xx) - same as above; converts the volume 0 <= xx <= 1 to a 14-bit MIDI value.

sxMasterFineTuning(kk), sxMasterFineTuning(mm, ll) - master fine tuning; returns F0 7F 7F 01 04 03 ll mm F7.

sxMasterFineTuningF(xx) - same as above; converts the fractional part of x (frequency shift in semitones) to a 14-bit MIDI value.

sxMasterCoarseTuning(mm) - master coarse tuning; returns F0 7F 7F 01 04 04 00 mm F7.

sxMasterCoarseTuningF(xx) - same as above; converts the integer part of xx (frequency shift in semitones) to a 7-bit MIDI value.

sxMasterTuning(nn, kk), sxMasterTuning(nn, mm, ll) - master coarse and fine tuning; returns [F0 7F 7F 01 04 04 00 nn F7, F0 7F 7F 01 04 03 ll mm F7].

sxMasterTuningF(xx) - same as above; splits xx (frequency shift in semitones) into the corresponding MIDI values.

sxMasterTuningA(f) - master A tuning; f - frequency of the note A in Hz (originally 440); returns the sxMasterTuning messages with calculated parameters.

sxTuningDumpRequest(xx), sxTuningDumpRequest(xx, yy) - tuning dump request with/without bank; returns F0 7E 7F 08 00 xx F7 or F0 7E 7F 08 03 xx yy F7.

sxNoteTuning(xx, data) - program note tuning; returns F0 7F 7F 08 02 xx ... F7. xx is the program number.

sxNoteTuning(xx, yy, data), sxNoteTuning(xx, yy, data, rt) - bank and program note tuning; returns F0 7F/7E 7F 08 07 xx yy ... F7;

xx, yy are the bank and program numbers. If rt is undefined or true, the second byte in the message is 7F, otherwise, 7E;

data is a map (can also be an array) of the key: tuning pairs, where key is the name or integer MIDI value of the key, and tuning is the 21-bit-encoded frequency (see the MIDI specs).

sxNoteTuningF(xx, data), sxNoteTuningF(xx, yy, data), sxNoteTuningF(xx, yy, data, rt) - same as above, except that tunings are floating point MIDI values or note names. e.g. { 'A5': 'A#5', 'A#5': 70.5 }.

sxNoteTuningHZ(xx, data), sxNoteTuningHZ(xx, yy, data), sxNoteTuningHZ(xx, yy, data, rt) - same as above, except that tunings are frequencies in HZ.

sxScaleTuning1(data), sxScaleTuning1(mask, data), sxScaleTuning1(data, rt), sxScaleTuning1(mask, data, rt) - scale tuning, 1-byte; returns F0 7F/7E 7F 08 08 ... F7;

mask is the channel mask, default: 0xffff; If rt is undefined or true, the second byte in the message is 7F, otherwise, 7E;

data is an array of 12 7-bit tuning values (see the MIDI specs).

sxScaleTuning1F(data), sxScaleTuning1F(mask, data), sxScaleTuning1F(data, rt), sxScaleTuning1F(mask, data, rt) - same as above, except that data is an array of floating point shifts in semitones from -0.64 to 0.63.

sxScaleTuning2(data), sxScaleTuning2(mask, data), sxScaleTuning2(data, rt), sxScaleTuning2(mask, data, rt) - scale tuning, 2-byte; returns F0 7F/7E 7F 08 09 ... F7;

mask, rt - same as above; data is an array of 12 14-bit tuning values (see the MIDI specs).

sxScaleTuning2F(data), sxScaleTuning2F(mask, data), sxScaleTuning2F(data, rt), sxScaleTuning2F(mask, data, rt) - same as above, except that data is an array of floating point shifts in semitones from -1 to 1.

sxScaleTuning(...) - an alias for sxScaleTuning2(...).

sxScaleTuningF(...) - an alias for sxScaleTuning2F(...).

Channel and SysEx ID modifiers:

ch(c) - default channel; e.g. JZZ.MIDI.ch(5).noteOn('C5', 127) is equialent to JZZ.MIDI.noteOn(5, 'C5', 127).

sxId(n) - default SysEx ID; e.g. JZZ.MIDI.sxId(5).sxMasterCoarseTuning(1) returns F0 7F 05 01 04 04 00 41 F7 instead of F0 7F 7F 01 04 04 00 41 F7.

All helpers above (and some more) can be directly used with the MIDI-Out port and MTrk objects.

SMF helpers

Strictly speaking, Standard MIDI File Meta Event is NOT a MIDI message.
However, these can pass through regular JZZ MIDI pipelines, and be used in MIDI files.

In the following list len is the length of the subsequent data, data - the string of bytes, str and text - a (possibly, wide character-) String and its representation as the sequence of bytes.

smf(xx, data) - meta event of an arbitrary type xx; returns FFxx len data.

smfSeqNumber(ssss) - sequence number; returns FF00 02 ssss, where ssss is a 16-bit integer.

smfText(str) - text event; returns FF01 len text. This is the event used in karaoke files.

smfCopyright(str) - copyright notice; returns FF02 len text.

smfSeqName(str) - sequence/track name; returns FF03 len text.

smfInstrName(str) - instrument name; returns FF04 len text.

smfLyric(str) - lyric; returns FF05 len text.

smfMarker(str) - marker; returns FF06 len text.

smfCuePoint(str) - cue point; returns FF07 len text.

smfProgName(str) - program name; returns FF08 len text.

smfDevName(str) - device name; returns FF09 len text.

smfChannelPrefix(cc) - channel prefix; returns FF20 01 cc.

smfMidiPort(pp) - MIDI port; returns FF21 01 pp.

smfEndOfTrack() - end of track; returns FF2F 00.

smfTempo(tttttt) - set tempo in microseconds per quarter note; returns FF51 03 tttttt, where tttttt is a 24-bit integer.

smfBPM(bpm) - set tempo in beats per minute; calculates tttttt and returns smfTempo(tttttt).

smfSMPTE(smpte) or smfSMPTE([hh, mm, ss, fr, ff]) or smfSMPTE(hh, mm, ss, fr, ff) - SMPTE offset; returns FF54 05 hh mm ss fr ff, where hh / mm / ss / fr are hours / minutes / seconds / frames, and ff is the frame fraction, in hundredth's of a frame.

smfTimeSignature(tss, cc, bb), smfTimeSignature(nn, dd, cc, bb) - time signature; returns FF58 04 nn xx cc bb;
where tss = nn + '/' + dd is a time signature string, e.g. '6/8', nn - time signature numerator, and dd = 2xx - time signature denominator (must be a power of 2).
Optional parameters: cc - number of MIDI clocks per metronome click (default: 24), bb - number of 1/32 notes per 24 MIDI clocks (default: 8) - most of the existing software ignores these.

smfKeySignature(key) - key signature; returns FF59 02 sf mi, where key is a key signature (e.g. 'Bb', 'F#m'), sf - a sharp/flat count (e.g. -7 for 7 flats, 7 for 7 sharps, 0 for C major / A minor), mi = 0/1 for major / minor.

smfSequencer(data) - sequencer specific meta event; returns FF7F len data.

All helpers above can be directly used with the MIDI-Out port and MTrk objects.

Data access

isNoteOn() - return true for the Note On message (9x nn vv; vv > 0), or false otherwise.

isNoteOff() - return true for the Note Off message (8x nn vv or 9x nn 00), or false otherwise.

isSysEx() - return true if the message starts with F0, or false otherwise.

isFullSysEx() - return true if the message starts with F0 and ends with F7, or false otherwise.

isSMF() - return true if the message is an SMF Meta Event, or false otherwise.

isTempo() - return true if the message is an SMF Tempo meta event, or false otherwise.

isTimeSignature() - return true if the message is an SMF Time Signature meta event, or false otherwise.

isKeySignature() - return true if the message is an SMF Key Signature meta mvent, or false otherwise.

isEOT() - return true if the message is an SMF End of Track meta event, or false otherwise.

getChannel() - return the channel number if the message is channel-related, or undefined otherwise.

setChannel(cc) - set the channel number to cc where it makes sense.

getNote() - return the note MIDI value for Note On / Note Off / Aftertouch messages, or undefined for others.

setNote(nn) - set the note to nn where it makes sense; nn can be a MIDI value or a note name.

getVelocity() - return the velocity for Note On / Note Off messages, or undefined for others.

setVelocity(vv) - set velocity for Note On / Note Off messages.

getSysExId() - return the SysEx ID if the message is a SysEx, or undefined otherwise.

setSysExId(cc) - set the SysEx ID in the SysEx message.

The following functions are applied to SMF messages:

getData() - return a String containing the message binary data.

setData(data) - set the string of bytes as the message binary data.

getText() - return the message text. If the message data is valid UTF8, it is converted to a wide character string.

setText(str) - set the message text. The input may be converted to UTF8. If you don't want UTF8 conversion, use setData() instead.

getTempo() - extract the tempo in microseconds per quarter note from an SMF Tempo message.

getBPM() - extract the tempo in beats per minute from an SMF Tempo message.

getTimeSignature() - extract the time signature from an SMF Time Signature message as [ numerator, denominator ], e.g. [ 3, 4 ] for "3/4".

getKeySignature() - extract the key signature from an SMF Key Signature message as [ sharps, base, min ], e.g. [ -5, 'Bb', true ] for "B♭-minor".

All the above getters return undefined for the wrong messages.

Example

// transpose msg an octave up:
var note = msg.getNote();
if (note !== undefined) msg.setNote(note + 12);

freq()

JZZ.MIDI.freq(nn) or JZZ.MIDI.freq(nn, a5) - return the note frequency in HZ.

nn - note name or numerical MIDI value (can be a floating point number to denote partial semitones).

a5 - frequency of the A5 note, default value is 440.

midi()

JZZ.MIDI.midi(f) or JZZ.MIDI.midi(f, a5) - return the MIDI value for given frequency (can return a floating point number).

a5 - frequency of the A5 note, default value is 440.

This is the reverse of the previous function: JZZ.MIDI.freq(JZZ.MIDI.midi(x)) = x; JZZ.MIDI.midi(JZZ.MIDI.freq(x)) = x.

shift()

JZZ.MIDI.shift(f, f0) or JZZ.MIDI.shift(f) - return the shift in semitones between two frequencies f and f0 (default: 440).

It is closely related to the previous function: JZZ.MIDI.midi(x) = JZZ.MIDI.shift(x) + 69.

to14b()

JZZ.MIDI.to14b(x) - map floating point number x between 0.0 and 1.0 to a 14-bit value from 0 to 0x3fff; 0 for x < 0; 0x3fff for x > 1.

to21b()

JZZ.MIDI.to21b(x) - map floating point number x between 0.0 and 128.0 to a 21-bit value from 0 to 0x1ffffe; 0 for x <= 0; 0x1ffffe for x >= 128.

First 7 bits encode the integer part of the number. A special value 0x1fffff is returned for x = undrfined.

See also