Skip to content

Commit

Permalink
midi input QoL
Browse files Browse the repository at this point in the history
  • Loading branch information
spessasus committed Jan 3, 2025
1 parent f4bfd4f commit 9002ccb
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 129 deletions.
168 changes: 87 additions & 81 deletions src/website/js/sequencer_ui/sequencer_ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,86 @@ class SequencerUI
enabled: false,
currentEncodedText: new Uint8Array(0)
};

// set up synth display event
let displayTimeoutId = null;
renderer.synth.eventHandler.addEvent("synthdisplay", "sequi-synth-display", data =>
{
if (data.displayType === 0 || data.displayType === 1)
{
// clear styles and apply monospace
this.mainTitleMessageDisplay.classList.add("sysex_display");
this.mainTitleMessageDisplay.classList.remove("xg_sysex_display");
let textData = data.displayData;
// remove "Display Letters" byte before decoding for XG display
if (data.displayType === 1)
{
textData = textData.slice(1);
}
// decode the text
let text = this.decodeTextFix(textData.buffer);

// XG is type 1, apply some fixes to it.
// XG Displays have a special behavior, we try to mimic it here
// reference video:
// https://www.youtube.com/watch?v=_mR7DV1E4KE
// first of all, extract the "Display Letters" byte
if (data.displayType === 1)
{
const displayLetters = data.displayData[0];
// XG Display Letters:
// the screen is monospace,
// two rows, 16 characters each (max)
// since this is XG data, apply the XG display style
this.mainTitleMessageDisplay.classList.add("xg_sysex_display");

// 0x0c where c are the amount of spaces prepended
const spaces = displayLetters & 0x0F;
for (let i = 0; i < spaces; i++)
{
text = " " + text;
}

// at 16 characters, add a newline
if (text.length >= 16)
{
text = text.slice(0, 16) + "\n" + text.slice(16);
}

// if type is 0x1x, add a newline
if ((displayLetters & 0x10) > 1)
{
text = "\n" + text;
}

}


if (text.trim().length === 0)
{
// set the text to invisible character to keep the height
this.mainTitleMessageDisplay.innerText = "‎ ";
}
else
{
// set the display to an invisible character to keep the height
this.mainTitleMessageDisplay.innerText = text;
}

this.synthDisplayMode.enabled = true;
this.synthDisplayMode.currentEncodedText = textData;
if (displayTimeoutId !== null)
{
clearTimeout(displayTimeoutId);
}
displayTimeoutId = setTimeout(() =>
{
this.synthDisplayMode.enabled = false;
this.restoreDisplay();
}, 5000);

}
});
}

toggleDarkMode()
Expand Down Expand Up @@ -265,94 +345,20 @@ class SequencerUI
}
// otherwise we're already dark
}

// set up synth display event
let displayTimeoutId = null;
this.seq.synth.eventHandler.addEvent("synthdisplay", "sequi-synth-display", data =>
{
if (data.displayType === 0 || data.displayType === 1)
{
// clear styles and apply monospace
this.mainTitleMessageDisplay.classList.add("sysex_display");
this.mainTitleMessageDisplay.classList.remove("xg_sysex_display");
let textData = data.displayData;
// remove "Display Letters" byte before decoding for XG display
if (data.displayType === 1)
{
textData = textData.slice(1);
}
// decode the text
let text = this.decodeTextFix(textData.buffer);

// XG is type 1, apply some fixes to it.
// XG Displays have a special behavior, we try to mimic it here
// reference video:
// https://www.youtube.com/watch?v=_mR7DV1E4KE
// first of all, extract the "Display Letters" byte
if (data.displayType === 1)
{
const displayLetters = data.displayData[0];
// XG Display Letters:
// the screen is monospace,
// two rows, 16 characters each (max)
// since this is XG data, apply the XG display style
this.mainTitleMessageDisplay.classList.add("xg_sysex_display");

// 0x0c where c are the amount of spaces prepended
const spaces = displayLetters & 0x0F;
for (let i = 0; i < spaces; i++)
{
text = " " + text;
}

// at 16 characters, add a newline
if (text.length >= 16)
{
text = text.slice(0, 16) + "\n" + text.slice(16);
}

// if type is 0x1x, add a newline
if ((displayLetters & 0x10) > 1)
{
text = "\n" + text;
}

}


if (text.trim().length === 0)
{
// set the text to invisible character to keep the height
this.mainTitleMessageDisplay.innerText = "‎ ";
}
else
{
// set the display to an invisible character to keep the height
this.mainTitleMessageDisplay.innerText = text;
}

this.synthDisplayMode.enabled = true;
this.synthDisplayMode.currentEncodedText = textData;
if (displayTimeoutId !== null)
{
clearTimeout(displayTimeoutId);
}
displayTimeoutId = setTimeout(() =>
{
this.synthDisplayMode.enabled = false;
this.restoreDisplay();
}, 5000);

}
});
}

/**
* Restores the display to the current song title and removes the SysEx display styles
*/
restoreDisplay()
{
this.mainTitleMessageDisplay.innerText = this.currentSongTitle;
let textToShow = this.currentSongTitle;
if (!this.seq)
{
// set to default title
textToShow = this.locale.getLocaleString("locale.titleMessage");
}
this.mainTitleMessageDisplay.innerText = textToShow;
this.mainTitleMessageDisplay.classList.remove("sysex_display");
this.mainTitleMessageDisplay.classList.remove("xg_sysex_display");
}
Expand Down
9 changes: 9 additions & 0 deletions src/website/js/settings_ui/handlers/midi_handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ export function _createMidiInputHandler(handler, synth)
}
this._saveSettings();
};
// try to connect the first input (if it exists)
if (handler.inputs.size > 0)
{
const firstInput = handler.inputs.entries().next().value;
handler.connectDeviceToSynth(firstInput[1], synth);
select.value = firstInput[0];
}
}

/**
Expand Down Expand Up @@ -105,6 +112,8 @@ export function _createMidiOutputHandler(handler, sequi)
{
if (!sequi.seq)
{
// set timeou to wait for sequencer to exist
setTimeout(select.onchange, 1000);
return;
}
if (select.value === "-1")
Expand Down
Loading

0 comments on commit 9002ccb

Please sign in to comment.