Added default midi in port and routing to scripts
This commit is contained in:
12
index.html
12
index.html
@ -261,6 +261,18 @@
|
|||||||
<label for="default-checkbox" class="ml-2 text-sm font-medium text-dark">Send MIDI Clock</label>
|
<label for="default-checkbox" class="ml-2 text-sm font-medium text-dark">Send MIDI Clock</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex flex-row">
|
||||||
|
<div class="flex items-center mb-4 ml-6">
|
||||||
|
<label for="default-checkbox" class="ml-2 text-sm font-medium text-dark">MIDI input: </label>
|
||||||
|
<select id="default-midi-input" class="w-32 h-8 text-sm font-medium text-black bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2">
|
||||||
|
<option value="-1">Keystep</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center mb-4 ml-20">
|
||||||
|
<input id="midi-channels-scripts" type="checkbox" value="" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
|
||||||
|
<label for="default-checkbox" class="ml-2 text-sm font-medium text-dark">Channels to scripts</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Information card -->
|
<!-- Information card -->
|
||||||
<div class="flex lg:flex-row space-y-2 lg:space-y-0 flex-col w-auto min-w-screen px-4 lg:space-x-8 space-x-0">
|
<div class="flex lg:flex-row space-y-2 lg:space-y-0 flex-col w-auto min-w-screen px-4 lg:space-x-8 space-x-0">
|
||||||
|
|||||||
@ -45,8 +45,10 @@ export interface Settings {
|
|||||||
* @param time_position - Whether or not to show time position
|
* @param time_position - Whether or not to show time position
|
||||||
* @param tips - Whether or not to show tips
|
* @param tips - Whether or not to show tips
|
||||||
* @param send_clock - Whether or not to send midi clock
|
* @param send_clock - Whether or not to send midi clock
|
||||||
|
* @param midi_channels_scripts - Whether midi input channels fires scripts
|
||||||
* @param midi_clock_input - The name of the midi clock input
|
* @param midi_clock_input - The name of the midi clock input
|
||||||
* @param midi_clock_ppqn - The pulses per quarter note for midi clock
|
* @param midi_clock_ppqn - The pulses per quarter note for midi clock
|
||||||
|
* @param default_midi_input - The default midi input for incoming messages
|
||||||
*/
|
*/
|
||||||
vimMode: boolean;
|
vimMode: boolean;
|
||||||
theme: string;
|
theme: string;
|
||||||
@ -59,8 +61,10 @@ export interface Settings {
|
|||||||
load_demo_songs: boolean;
|
load_demo_songs: boolean;
|
||||||
tips: boolean;
|
tips: boolean;
|
||||||
send_clock: boolean;
|
send_clock: boolean;
|
||||||
|
midi_channels_scripts: boolean;
|
||||||
midi_clock_input: string|undefined;
|
midi_clock_input: string|undefined;
|
||||||
midi_clock_ppqn: number;
|
midi_clock_ppqn: number;
|
||||||
|
default_midi_input: string|undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const template_universe = {
|
export const template_universe = {
|
||||||
@ -118,9 +122,10 @@ export class AppSettings {
|
|||||||
* @param time_position - Whether or not to show time position
|
* @param time_position - Whether or not to show time position
|
||||||
* @param tips - Whether or not to show tips
|
* @param tips - Whether or not to show tips
|
||||||
* @param send_clock - Whether or not to send midi clock
|
* @param send_clock - Whether or not to send midi clock
|
||||||
|
* @param midi_channels_scripts - Whether midi input channels fires scripts
|
||||||
* @param midi_clock_input - The name of the midi clock input
|
* @param midi_clock_input - The name of the midi clock input
|
||||||
* @param midi_clock_ppqn - The pulses per quarter note for midi clock
|
* @param midi_clock_ppqn - The pulses per quarter note for midi clock
|
||||||
|
* @param default_midi_input - The default midi input for incoming messages
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public vimMode: boolean = false;
|
public vimMode: boolean = false;
|
||||||
@ -133,7 +138,9 @@ export class AppSettings {
|
|||||||
public time_position: boolean = true;
|
public time_position: boolean = true;
|
||||||
public tips: boolean = true;
|
public tips: boolean = true;
|
||||||
public send_clock: boolean = false;
|
public send_clock: boolean = false;
|
||||||
|
public midi_channels_scripts: boolean = true;
|
||||||
public midi_clock_input: string|undefined = undefined;
|
public midi_clock_input: string|undefined = undefined;
|
||||||
|
public default_midi_input: string|undefined = undefined;
|
||||||
public midi_clock_ppqn: number = 24;
|
public midi_clock_ppqn: number = 24;
|
||||||
public load_demo_songs: boolean = true;
|
public load_demo_songs: boolean = true;
|
||||||
|
|
||||||
@ -154,8 +161,10 @@ export class AppSettings {
|
|||||||
this.time_position = settingsFromStorage.time_position;
|
this.time_position = settingsFromStorage.time_position;
|
||||||
this.tips = settingsFromStorage.tips;
|
this.tips = settingsFromStorage.tips;
|
||||||
this.send_clock = settingsFromStorage.send_clock;
|
this.send_clock = settingsFromStorage.send_clock;
|
||||||
|
this.midi_channels_scripts = settingsFromStorage.midi_channels_scripts;
|
||||||
this.midi_clock_input = settingsFromStorage.midi_clock_input;
|
this.midi_clock_input = settingsFromStorage.midi_clock_input;
|
||||||
this.midi_clock_ppqn = settingsFromStorage.midi_clock_ppqn || 24;
|
this.midi_clock_ppqn = settingsFromStorage.midi_clock_ppqn || 24;
|
||||||
|
this.default_midi_input = settingsFromStorage.default_midi_input;
|
||||||
this.load_demo_songs = settingsFromStorage.load_demo_songs;
|
this.load_demo_songs = settingsFromStorage.load_demo_songs;
|
||||||
} else {
|
} else {
|
||||||
this.universes = template_universes;
|
this.universes = template_universes;
|
||||||
@ -181,8 +190,10 @@ export class AppSettings {
|
|||||||
time_position: this.time_position,
|
time_position: this.time_position,
|
||||||
tips: this.tips,
|
tips: this.tips,
|
||||||
send_clock: this.send_clock,
|
send_clock: this.send_clock,
|
||||||
|
midi_channels_scripts: this.midi_channels_scripts,
|
||||||
midi_clock_input: this.midi_clock_input,
|
midi_clock_input: this.midi_clock_input,
|
||||||
midi_clock_ppqn: this.midi_clock_ppqn,
|
midi_clock_ppqn: this.midi_clock_ppqn,
|
||||||
|
default_midi_input: this.default_midi_input,
|
||||||
load_demo_songs: this.load_demo_songs,
|
load_demo_songs: this.load_demo_songs,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -206,8 +217,10 @@ export class AppSettings {
|
|||||||
this.time_position = settings.time_position;
|
this.time_position = settings.time_position;
|
||||||
this.tips = settings.tips;
|
this.tips = settings.tips;
|
||||||
this.send_clock = settings.send_clock;
|
this.send_clock = settings.send_clock;
|
||||||
|
this.midi_channels_scripts = settings.midi_channels_scripts;
|
||||||
this.midi_clock_input = settings.midi_clock_input;
|
this.midi_clock_input = settings.midi_clock_input;
|
||||||
this.midi_clock_ppqn = settings.midi_clock_ppqn;
|
this.midi_clock_ppqn = settings.midi_clock_ppqn;
|
||||||
|
this.default_midi_input = settings.default_midi_input;
|
||||||
this.load_demo_songs = settings.load_demo_songs;
|
this.load_demo_songs = settings.load_demo_songs;
|
||||||
localStorage.setItem("topos", JSON.stringify(this.data));
|
localStorage.setItem("topos", JSON.stringify(this.data));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -146,45 +146,76 @@ export class MidiConnection {
|
|||||||
* Updates the MIDI clock input select element with the available MIDI inputs.
|
* Updates the MIDI clock input select element with the available MIDI inputs.
|
||||||
*/
|
*/
|
||||||
if(this.midiInputs.length > 0) {
|
if(this.midiInputs.length > 0) {
|
||||||
const select = document.getElementById("midi-clock-input") as HTMLSelectElement;
|
const midiClockSelect = document.getElementById("midi-clock-input") as HTMLSelectElement;
|
||||||
select.innerHTML = "";
|
const midiInputSelect = document.getElementById("default-midi-input") as HTMLSelectElement;
|
||||||
|
|
||||||
|
midiClockSelect.innerHTML = "";
|
||||||
|
midiInputSelect.innerHTML = "";
|
||||||
|
|
||||||
// Defaults to internal clock
|
// Defaults to internal clock
|
||||||
const defaultOption = document.createElement("option");
|
const defaultOption = document.createElement("option");
|
||||||
defaultOption.value = "-1";
|
defaultOption.value = "-1";
|
||||||
defaultOption.text = "Internal";
|
defaultOption.text = "Internal";
|
||||||
select.appendChild(defaultOption);
|
midiClockSelect.appendChild(defaultOption);
|
||||||
// Add MIDI inputs to clock select input
|
|
||||||
|
// Add MIDI inputs to clock select input and default midi input
|
||||||
this.midiInputs.forEach((input, index) => {
|
this.midiInputs.forEach((input, index) => {
|
||||||
const option = document.createElement("option");
|
const option = document.createElement("option");
|
||||||
option.value = index.toString();
|
option.value = index.toString();
|
||||||
option.text = input.name || index.toString();
|
option.text = input.name || index.toString();
|
||||||
select.appendChild(option);
|
midiClockSelect.appendChild(option);
|
||||||
|
midiInputSelect.appendChild(option.cloneNode(true));
|
||||||
});
|
});
|
||||||
|
|
||||||
if(this.settings.midi_clock_input) {
|
if(this.settings.midi_clock_input) {
|
||||||
const clockMidiInputIndex = this.getMidiInputIndex(this.settings.midi_clock_input);
|
const clockMidiInputIndex = this.getMidiInputIndex(this.settings.midi_clock_input);
|
||||||
select.value = clockMidiInputIndex.toString();
|
midiClockSelect.value = clockMidiInputIndex.toString();
|
||||||
if(clockMidiInputIndex > 0) {
|
if(clockMidiInputIndex > 0) {
|
||||||
this.midiClockInput = this.midiInputs[clockMidiInputIndex];
|
this.midiClockInput = this.midiInputs[clockMidiInputIndex];
|
||||||
this.registerMidiClockListener();
|
this.registerMidiClockListener();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
select.value = "-1";
|
midiClockSelect.value = "-1";
|
||||||
}
|
}
|
||||||
// Add listener
|
|
||||||
select.addEventListener("change", (event) => {
|
if(this.settings.default_midi_input) {
|
||||||
|
const defaultMidiInputIndex = this.getMidiInputIndex(this.settings.default_midi_input);
|
||||||
|
midiInputSelect.value = defaultMidiInputIndex.toString();
|
||||||
|
if(defaultMidiInputIndex > 0) {
|
||||||
|
this.currentInputIndex = defaultMidiInputIndex;
|
||||||
|
this.registerMidiInputListener();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
midiInputSelect.value = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add midi clock listener
|
||||||
|
midiClockSelect.addEventListener("change", (event) => {
|
||||||
const value = (event.target as HTMLSelectElement).value;
|
const value = (event.target as HTMLSelectElement).value;
|
||||||
if(value === "-1") {
|
if(value === "-1") {
|
||||||
if(this.midiClockInput) this.midiClockInput.onmidimessage = null;
|
if(this.midiClockInput) this.midiClockInput.onmidimessage = null;
|
||||||
this.midiClockInput = undefined;
|
this.midiClockInput = undefined;
|
||||||
this.settings.midi_clock_input = undefined;
|
this.settings.midi_clock_input = undefined;
|
||||||
} else {
|
} else {
|
||||||
this.currentInputIndex = parseInt(value);
|
const clockInputIndex = parseInt(value);
|
||||||
if(this.midiClockInput) this.midiClockInput.onmidimessage = null;
|
if(this.midiClockInput) this.midiClockInput.onmidimessage = null;
|
||||||
this.midiClockInput = this.midiInputs[this.currentInputIndex];
|
this.midiClockInput = this.midiInputs[clockInputIndex];
|
||||||
this.registerMidiClockListener();
|
this.registerMidiClockListener();
|
||||||
this.settings.midi_clock_input = this.midiClockInput.name || undefined;
|
this.settings.midi_clock_input = this.midiClockInput.name || undefined;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Add mini input listener
|
||||||
|
midiInputSelect.addEventListener("change", (event) => {
|
||||||
|
const value = (event.target as HTMLSelectElement).value;
|
||||||
|
if(value) {
|
||||||
|
this.unregisterMidiInputListener();
|
||||||
|
this.currentInputIndex = parseInt(value);
|
||||||
|
this.registerMidiInputListener();
|
||||||
|
this.settings.default_midi_input = this.midiInputs[this.currentInputIndex].name || undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,6 +252,45 @@ export class MidiConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public registerMidiInputListener(): void {
|
||||||
|
/**
|
||||||
|
* Register midi input listener and store last value as global parameter named channel_{number}
|
||||||
|
*/
|
||||||
|
if(this.currentInputIndex !== undefined) {
|
||||||
|
const input = this.midiInputs[this.currentInputIndex];
|
||||||
|
if(input) {
|
||||||
|
input.onmidimessage = (event: Event) => {
|
||||||
|
const message = event as MIDIMessageEvent;
|
||||||
|
|
||||||
|
// List of all note_on messages from channels 1-16
|
||||||
|
const all_note_ons = [0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D,0x9E, 0x9F];
|
||||||
|
// If message is one of note ons
|
||||||
|
if(all_note_ons.indexOf(message.data[0]) !== -1) {
|
||||||
|
const channel = all_note_ons.indexOf(message.data[0])+1;
|
||||||
|
const note = message.data[1];
|
||||||
|
const velocity = message.data[2];
|
||||||
|
this.api.variable(`channel_${channel}_note`, note);
|
||||||
|
this.api.variable(`channel_${channel}_velocity`, velocity);
|
||||||
|
if(this.settings.midi_channels_scripts) this.api.script(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public unregisterMidiInputListener(): void {
|
||||||
|
/**
|
||||||
|
* Unregister midi input listener
|
||||||
|
*/
|
||||||
|
if(this.currentInputIndex !== undefined) {
|
||||||
|
const input = this.midiInputs[this.currentInputIndex];
|
||||||
|
if(input) {
|
||||||
|
input.onmidimessage = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public onMidiClock(timestamp: number): void {
|
public onMidiClock(timestamp: number): void {
|
||||||
/**
|
/**
|
||||||
* Called when a MIDI clock message is received.
|
* Called when a MIDI clock message is received.
|
||||||
|
|||||||
11
src/main.ts
11
src/main.ts
@ -212,6 +212,10 @@ export class Editor {
|
|||||||
"send-midi-clock"
|
"send-midi-clock"
|
||||||
) as HTMLInputElement;
|
) as HTMLInputElement;
|
||||||
|
|
||||||
|
midi_channels_scripts: HTMLInputElement = document.getElementById(
|
||||||
|
"midi-channels-scripts"
|
||||||
|
) as HTMLInputElement;
|
||||||
|
|
||||||
midi_clock_ppqn: HTMLSelectElement = document.getElementById(
|
midi_clock_ppqn: HTMLSelectElement = document.getElementById(
|
||||||
"midi-clock-ppqn-input"
|
"midi-clock-ppqn-input"
|
||||||
) as HTMLSelectElement;
|
) as HTMLSelectElement;
|
||||||
@ -262,6 +266,7 @@ export class Editor {
|
|||||||
this.time_position_checkbox.checked = this.settings.time_position;
|
this.time_position_checkbox.checked = this.settings.time_position;
|
||||||
this.tips_checkbox.checked = this.settings.tips;
|
this.tips_checkbox.checked = this.settings.tips;
|
||||||
this.midi_clock_checkbox.checked = this.settings.send_clock;
|
this.midi_clock_checkbox.checked = this.settings.send_clock;
|
||||||
|
this.midi_channels_scripts.checked = this.settings.midi_channels_scripts;
|
||||||
this.midi_clock_ppqn.value = this.settings.midi_clock_ppqn.toString();
|
this.midi_clock_ppqn.value = this.settings.midi_clock_ppqn.toString();
|
||||||
if (!this.settings.time_position) {
|
if (!this.settings.time_position) {
|
||||||
document.getElementById("timeviewer")!.classList.add("hidden");
|
document.getElementById("timeviewer")!.classList.add("hidden");
|
||||||
@ -605,6 +610,7 @@ export class Editor {
|
|||||||
this.time_position_checkbox.checked = this.settings.time_position;
|
this.time_position_checkbox.checked = this.settings.time_position;
|
||||||
this.tips_checkbox.checked = this.settings.tips;
|
this.tips_checkbox.checked = this.settings.tips;
|
||||||
this.midi_clock_checkbox.checked = this.settings.send_clock;
|
this.midi_clock_checkbox.checked = this.settings.send_clock;
|
||||||
|
this.midi_channels_scripts.checked = this.settings.midi_channels_scripts;
|
||||||
this.midi_clock_ppqn.value = this.settings.midi_clock_ppqn.toString();
|
this.midi_clock_ppqn.value = this.settings.midi_clock_ppqn.toString();
|
||||||
this.load_demo_songs.checked = this.settings.load_demo_songs;
|
this.load_demo_songs.checked = this.settings.load_demo_songs;
|
||||||
|
|
||||||
@ -707,6 +713,11 @@ export class Editor {
|
|||||||
this.settings.send_clock = checked;
|
this.settings.send_clock = checked;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.midi_channels_scripts.addEventListener("change", () => {
|
||||||
|
let checked = this.midi_channels_scripts.checked ? true : false;
|
||||||
|
this.settings.midi_channels_scripts = checked;
|
||||||
|
});
|
||||||
|
|
||||||
this.midi_clock_ppqn.addEventListener("change", () => {
|
this.midi_clock_ppqn.addEventListener("change", () => {
|
||||||
let value = parseInt(this.midi_clock_ppqn.value);
|
let value = parseInt(this.midi_clock_ppqn.value);
|
||||||
this.settings.midi_clock_ppqn = value;
|
this.settings.midi_clock_ppqn = value;
|
||||||
|
|||||||
Reference in New Issue
Block a user