add midibend, miditouch

This commit is contained in:
nkymut 2025-01-25 02:28:56 +08:00
parent 393d17a41b
commit b8b999eab5
2 changed files with 72 additions and 15 deletions

View File

@ -1651,18 +1651,33 @@ export const { ccv } = registerControl('ccv');
export const { ctlNum } = registerControl('ctlNum');
// TODO: ctlVal?
/**
* MIDI NRPN non-registered parameter number: Sends a MIDI NRPN non-registered parameter number message.
* @name nrpnn
* @param {number | Pattern} nrpnn MIDI NRPN non-registered parameter number (0-127)
* @example
* note("c4").nrpnn("1:8").nrpv("123").midichan(1).midi()
*/
export const { nrpnn } = registerControl('nrpnn');
/**
* MIDI NRPN non-registered parameter value: Sends a MIDI NRPN non-registered parameter value message.
* @name nrpv
* @param {number | Pattern} nrpv MIDI NRPN non-registered parameter value (0-127)
* @example
* note("c4").nrpnn("1:8").nrpv("123").midichan(1).midi()
*/
export const { nrpv } = registerControl('nrpv');
/**
* MIDI program number: Sends a MIDI program change message.
*
* @name progNum
* @param {number | Pattern} program MIDI program number (0-127)
* @example
* note("c4").progNum(10).midichan(1).midi()
*/
export const { progNum } = registerControl('progNum');
export const { polyTouch } = registerControl('polyTouch');
export const { midibend } = registerControl('midibend');
export const { miditouch } = registerControl('miditouch');
/**
* MIDI sysex: Sends a MIDI sysex message.
* @name sysex
@ -1694,3 +1709,24 @@ export const { sysexid } = registerControl('sysexid');
* note("c4").sysexid("0x77").sysexdata("0x01:0x02:0x03:0x04").midichan(1).midi()
*/
export const { sysexdata } = registerControl('sysexdata');
/**
* MIDI pitch bend: Sends a MIDI pitch bend message.
* @name midibend
* @param {number | Pattern} midibend MIDI pitch bend (-1 - 1)
* @example
* note("c4").midibend(sine.slow(4).range(-0.4,0.4)).midi()
*/
export const { midibend } = registerControl('midibend');
/**
* MIDI key after touch: Sends a MIDI key after touch message.
* @name miditouch
* @param {number | Pattern} miditouch MIDI key after touch (0-1)
* @example
* note("c4").miditouch(sine.slow(4).range(0,1)).midi()
*/
export const { miditouch } = registerControl('miditouch');
// TODO: what is this?
export const { polyTouch } = registerControl('polyTouch');

View File

@ -153,6 +153,9 @@ Pattern.prototype.midi = function (output) {
ccv,
midichan = 1,
midicmd,
midibend,
miditouch,
polyTouch, //??
gain = 1,
velocity = 0.9,
progNum,
@ -217,18 +220,7 @@ Pattern.prototype.midi = function (output) {
// list of manufacturer ids can be found here : https://midi.org/sysexidtable
// if sysexid is an array the first byte is 0x00
// if (sysex !== undefined) {
// console.log('sysex', sysex);
// if (Array.isArray(sysex)) {
// if (Array.isArray(sysex[0])) {
// //device.sendSysex(sysex[0], sysex[1], { time: timeOffsetString });
// } else {
// //device.sendSysex(sysex[0], sysex[1], { time: timeOffsetString });
// }
// }
// }
if (sysexid !== undefined && sysexdata !== undefined) {
//console.log('sysex', sysexid, sysexdata);
if (Array.isArray(sysexid)) {
if (!sysexid.every((byte) => Number.isInteger(byte) && byte >= 0 && byte <= 255)) {
throw new Error('all sysexid bytes must be integers between 0 and 255');
@ -260,6 +252,35 @@ Pattern.prototype.midi = function (output) {
device.sendControlChange(ccn, scaled, midichan, { time: timeOffsetString });
}
// Handle NRPN non-registered parameter number
if (nrpnn !== undefined && nrpv !== undefined) {
if (Array.isArray(nrpnn)) {
if (!nrpnn.every((byte) => Number.isInteger(byte) && byte >= 0 && byte <= 255)) {
throw new Error('all nrpnn bytes must be integers between 0 and 255');
}
} else if (!Number.isInteger(nrpv) || nrpv < 0 || nrpv > 255) {
throw new Error('A:sysexid must be an number between 0 and 255 or an array of such integers');
}
device.sendNRPN(nrpnn, nrpv, midichan, { time: timeOffsetString });
}
// Handle midibend
if (midibend !== undefined) {
if (typeof midibend !== 'number' || midibend < 1 || midibend > -1) {
throw new Error('expected midibend to be a number between 1 and -1');
}
device.sendPitchBend(midibend, midichan, { time: timeOffsetString });
}
// Handle miditouch
if (miditouch !== undefined) {
if (typeof miditouch !== 'number' || miditouch < 1 || miditouch > 0) {
throw new Error('expected miditouch to be a number between 1 and 0');
}
device.sendKeyAfterTouch(miditouch, midichan, { time: timeOffsetString });
}
// Handle midicmd
if (hap.whole.begin + 0 === 0) {
// we need to start here because we have the timing info