Store Midi clock stuff to localstorage
This commit is contained in:
@ -60,7 +60,7 @@ export class UserAPI {
|
||||
load: samples;
|
||||
|
||||
constructor(public app: Editor) {
|
||||
this.MidiConnection = new MidiConnection(this);
|
||||
this.MidiConnection = new MidiConnection(this, app.settings);
|
||||
}
|
||||
|
||||
_loadUniverseFromInterface = (universe: string) => {
|
||||
|
||||
@ -45,6 +45,8 @@ export interface Settings {
|
||||
* @param time_position - Whether or not to show time position
|
||||
* @param tips - Whether or not to show tips
|
||||
* @param send_clock - Whether or not to send midi clock
|
||||
* @param midi_clock_input - The name of the midi clock input
|
||||
* @param midi_clock_ppqn - The pulses per quarter note for midi clock
|
||||
*/
|
||||
vimMode: boolean;
|
||||
theme: string;
|
||||
@ -56,6 +58,8 @@ export interface Settings {
|
||||
time_position: boolean;
|
||||
tips: boolean;
|
||||
send_clock: boolean;
|
||||
midi_clock_input: string|undefined;
|
||||
midi_clock_ppqn: number;
|
||||
}
|
||||
|
||||
export const template_universe = {
|
||||
@ -113,6 +117,8 @@ export class AppSettings {
|
||||
* @param time_position - Whether or not to show time position
|
||||
* @param tips - Whether or not to show tips
|
||||
* @param send_clock - Whether or not to send midi clock
|
||||
* @param midi_clock_input - The name of the midi clock input
|
||||
* @param midi_clock_ppqn - The pulses per quarter note for midi clock
|
||||
|
||||
*/
|
||||
|
||||
@ -126,6 +132,8 @@ export class AppSettings {
|
||||
public time_position: boolean = true;
|
||||
public tips: boolean = true;
|
||||
public send_clock: boolean = false;
|
||||
public midi_clock_input: string|undefined = undefined;
|
||||
public midi_clock_ppqn: number = 24;
|
||||
|
||||
constructor() {
|
||||
const settingsFromStorage = JSON.parse(
|
||||
@ -144,6 +152,8 @@ export class AppSettings {
|
||||
this.time_position = settingsFromStorage.time_position;
|
||||
this.tips = settingsFromStorage.tips;
|
||||
this.send_clock = settingsFromStorage.send_clock;
|
||||
this.midi_clock_input = settingsFromStorage.midi_clock_input;
|
||||
this.midi_clock_ppqn = settingsFromStorage.midi_clock_ppqn || 24;
|
||||
} else {
|
||||
this.universes = template_universes;
|
||||
}
|
||||
@ -168,6 +178,8 @@ export class AppSettings {
|
||||
time_position: this.time_position,
|
||||
tips: this.tips,
|
||||
send_clock: this.send_clock,
|
||||
midi_clock_input: this.midi_clock_input,
|
||||
midi_clock_ppqn: this.midi_clock_ppqn,
|
||||
};
|
||||
}
|
||||
|
||||
@ -190,6 +202,8 @@ export class AppSettings {
|
||||
this.time_position = settings.time_position;
|
||||
this.tips = settings.tips;
|
||||
this.send_clock = settings.send_clock;
|
||||
this.midi_clock_input = settings.midi_clock_input;
|
||||
this.midi_clock_ppqn = settings.midi_clock_ppqn;
|
||||
localStorage.setItem("topos", JSON.stringify(this.data));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { UserAPI } from "../API";
|
||||
import { AppSettings } from "../AppSettings";
|
||||
|
||||
export class MidiConnection {
|
||||
/**
|
||||
@ -12,6 +13,7 @@ export class MidiConnection {
|
||||
*/
|
||||
|
||||
private api: UserAPI;
|
||||
private settings: AppSettings;
|
||||
private midiAccess: MIDIAccess | null = null;
|
||||
public midiOutputs: MIDIOutput[] = [];
|
||||
public midiInputs: MIDIInput[] = [];
|
||||
@ -28,13 +30,13 @@ export class MidiConnection {
|
||||
private clockBuffer: number[] = [];
|
||||
private deltaBuffer: number[] = [];
|
||||
private clockBufferLength = 24;
|
||||
private clockPPQN = 24;
|
||||
private clockTicks = 0;
|
||||
private clockErrorCount = 0;
|
||||
private skipOnError = 0;
|
||||
|
||||
constructor(api: UserAPI) {
|
||||
constructor(api: UserAPI, settings: AppSettings) {
|
||||
this.api = api;
|
||||
this.settings = settings;
|
||||
this.lastBPM = api.bpm();
|
||||
this.roundedBPM = this.lastBPM;
|
||||
this.initializeMidiAccess();
|
||||
@ -58,7 +60,6 @@ export class MidiConnection {
|
||||
console.warn("No MIDI inputs available.");
|
||||
} else {
|
||||
this.updateMidiClockSelect();
|
||||
this.clockPPQNSelect();
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to initialize MIDI:", error);
|
||||
@ -156,34 +157,37 @@ export class MidiConnection {
|
||||
this.midiInputs.forEach((input, index) => {
|
||||
const option = document.createElement("option");
|
||||
option.value = index.toString();
|
||||
option.text = input.name || "No name input";
|
||||
option.text = input.name || index.toString();
|
||||
select.appendChild(option);
|
||||
});
|
||||
select.value = this.currentInputIndex ? this.currentInputIndex.toString() : "-1";
|
||||
if(this.settings.midi_clock_input) {
|
||||
const clockMidiInputIndex = this.getMidiInputIndex(this.settings.midi_clock_input);
|
||||
select.value = clockMidiInputIndex.toString();
|
||||
if(clockMidiInputIndex > 0) {
|
||||
this.midiClockInput = this.midiInputs[clockMidiInputIndex];
|
||||
this.registerMidiClockListener();
|
||||
}
|
||||
} else {
|
||||
select.value = "-1";
|
||||
}
|
||||
// Add listener
|
||||
select.addEventListener("change", (event) => {
|
||||
const value = (event.target as HTMLSelectElement).value;
|
||||
if(value === "-1") {
|
||||
if(this.midiClockInput) this.midiClockInput.onmidimessage = null;
|
||||
this.midiClockInput = undefined;
|
||||
this.settings.midi_clock_input = undefined;
|
||||
} else {
|
||||
this.currentInputIndex = parseInt(value);
|
||||
if(this.midiClockInput) this.midiClockInput.onmidimessage = null;
|
||||
this.midiClockInput = this.midiInputs[this.currentInputIndex];
|
||||
this.registerMidiClockListener();
|
||||
this.settings.midi_clock_input = this.midiClockInput.name || undefined;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
clockPPQNSelect(): void {
|
||||
const select = document.getElementById("midi-clock-ppqn-input") as HTMLSelectElement;
|
||||
select.addEventListener("change", (event) => {
|
||||
const value = (event.target as HTMLSelectElement).value;
|
||||
this.clockPPQN = parseInt(value);
|
||||
});
|
||||
}
|
||||
|
||||
public registerMidiClockListener(): void {
|
||||
/**
|
||||
* Registers a listener for MIDI clock messages on the currently selected MIDI input.
|
||||
@ -241,12 +245,12 @@ export class MidiConnection {
|
||||
this.clockErrorCount = 0;
|
||||
/* I dont know why this happens. But when it does, deltas for the following messages are off.
|
||||
So skipping ~ quarted of clock resolution usually helps */
|
||||
this.skipOnError = this.clockPPQN/4;
|
||||
this.skipOnError = this.settings.midi_clock_ppqn/4;
|
||||
timestamp = 0; // timestamp 0 == lastTimestamp 0
|
||||
} else {
|
||||
|
||||
this.midiClockDelta = timestamp - this.lastTimestamp;
|
||||
this.lastBPM = 60 * (1000 / this.midiClockDelta / 24);
|
||||
this.lastBPM = 60 * (1000 / this.midiClockDelta / this.settings.midi_clock_ppqn);
|
||||
|
||||
this.clockBuffer.push(this.lastBPM);
|
||||
if(this.clockBuffer.length>this.clockBufferLength) this.clockBuffer.shift();
|
||||
|
||||
11
src/main.ts
11
src/main.ts
@ -197,6 +197,10 @@ export class Editor {
|
||||
"send-midi-clock"
|
||||
) as HTMLInputElement;
|
||||
|
||||
midi_clock_ppqn: HTMLSelectElement = document.getElementById(
|
||||
"midi-clock-ppqn-input"
|
||||
) as HTMLSelectElement;
|
||||
|
||||
// Editor mode selection
|
||||
normal_mode_button: HTMLButtonElement = document.getElementById(
|
||||
"normal-mode"
|
||||
@ -246,6 +250,7 @@ export class Editor {
|
||||
this.time_position_checkbox.checked = this.settings.time_position;
|
||||
this.tips_checkbox.checked = this.settings.tips;
|
||||
this.midi_clock_checkbox.checked = this.settings.send_clock;
|
||||
this.midi_clock_ppqn.value = this.settings.midi_clock_ppqn.toString();
|
||||
if (!this.settings.time_position) {
|
||||
document.getElementById("timeviewer")!.classList.add("hidden");
|
||||
}
|
||||
@ -565,6 +570,7 @@ export class Editor {
|
||||
this.time_position_checkbox.checked = this.settings.time_position;
|
||||
this.tips_checkbox.checked = this.settings.tips;
|
||||
this.midi_clock_checkbox.checked = this.settings.send_clock;
|
||||
this.midi_clock_ppqn.value = this.settings.midi_clock_ppqn.toString();
|
||||
|
||||
if (this.settings.vimMode) {
|
||||
let vim = document.getElementById("vim-mode-radio") as HTMLInputElement;
|
||||
@ -665,6 +671,11 @@ export class Editor {
|
||||
this.settings.send_clock = checked;
|
||||
});
|
||||
|
||||
this.midi_clock_ppqn.addEventListener("change", () => {
|
||||
let value = parseInt(this.midi_clock_ppqn.value);
|
||||
this.settings.midi_clock_ppqn = value;
|
||||
});
|
||||
|
||||
this.vim_mode_button.addEventListener("click", () => {
|
||||
this.settings.vimMode = true;
|
||||
this.view.dispatch({
|
||||
|
||||
Reference in New Issue
Block a user