// AllNotesOffAU3.js
// Version 1.0
// Helper script to work around a bug in LPX AU3
// multiport regarding hanging notes when the transport is stopped
var NeedsTimingInfo = true; //only needed to detect play state
var usedChannelPorts = new Array(17);
for(var i=0;i<17;i++) {
usedChannelPorts[i] = new Array(9);
for(var j=1;j<=8;j++) {
usedChannelPorts[i][j] = false;
}
}
//=============================================================
// Actual HandleMIDI function
//=============================================================
function HandleMIDI(event) {
//=================================================================
// If all Notes Off for channel, handle specially,
// forward to all ports, received from double click transport
//=================================================================
if (event instanceof ControlChange
&& event.number == 123
&& event.value == 0) {
AllNotesOffByChannel(event.channel, true);
return;
}
// All other Events
usedChannelPorts[event.channel][event.port] = true;
event.send();
}
function Reset() {
for(var i=0;i<17;i++) {
for(var j=1;j<=8;j++) {
usedChannelPorts[i][j] = false;
}
}
}
//===================================================
// Prcoess MIDI is used to detact transport STOP
// in order to send AllNotesOff to all ports/channels
// todo, sometimes this happens before handleMIDI has
// processed everything. Need to figure out something
//===================================================
var playState = false;
function ProcessMIDI() {
var ctx = GetTimingInfo();
if (ctx.playing) {
playState = true;
}
else {
if (playState == true) {
// stop recently happened
AllNotesOff();
playState = false;
}
}
}
//=======================================
// Propagate AllNotesOff to all ports
// for a given midi channel
//=======================================
var ccOff = new ControlChange;
ccOff.number = 123;
ccOff.value = 0;
// forceFlg is used for double clicking transport PANIC to make sure
// all 768 channel/ports receive the CC123 message for all notes off.
// But actually do we really need that? TODO, think it through more.
function AllNotesOffByChannel(channel, forceFlg) {
ccOff.channel = channel;
for (var port = 1; port <= 8; port++) {
if(forceFlg || (!forceFlg && usedChannelPorts[channel][port])) {
ccOff.port = port;
ccOff.send();
usedChannelPorts[channel][port] = false;
}
}
}
//====================================
// AllNotesOff all Channels
//====================================
function AllNotesOff() {
for (var chan = 1; chan <= 16; chan++) {
AllNotesOffByChannel(chan, false);
}
}