Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changed interpolateNoteX to be a bit faster #3

Merged
merged 2 commits into from
Jul 5, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 28 additions & 12 deletions src/core/PianoRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const outOfRangeNoteSize = 10;

let whiteKeyWidth: number;
let blackKeyWidth: number;
let rangeBase = 0;
let rangeOffset = 0;

export function init() {
pianoCanvas = document.getElementById("pianoCanvas") as HTMLCanvasElement;
Expand Down Expand Up @@ -81,6 +83,14 @@ export function drawKeys(from: Audio.Note, to: Audio.Note) {
notePositions.set(note, { x, y });
}
}

// For InterpolateNoteX
rangeBase = from;
rangeOffset =
Math.floor((1 / 12) * from + 1) + Math.floor((1 / 12) * (from - 5));
if (!isWhiteKey(from)) {
rangeOffset += 1;
}
}

export function drawNote(
Expand Down Expand Up @@ -162,21 +172,27 @@ export function isWhiteKey(note: Audio.Note) {
}

export function interpolateNoteX(note: Audio.Note) {
// TODO: Think of a better way to do this
const lowerNote = Math.floor(note);
const noteMod1 = note - lowerNote;

const lowerPos = notePositions.get(lowerNote);
const upperPos = notePositions.get(lowerNote + 1);
if (!lowerPos || !upperPos) {
return Infinity;
}
// Piano Key is the index of the key on the Piano, pretending there are no gap in the black keys
const pianoKey = calculateNoteX(note) - rangeBase;

return lerp(lowerPos.x, upperPos.x, noteMod1);
return ((pianoKey - rangeOffset) * whiteKeyWidth) / 2;
}

function lerp(a: number, b: number, t: number) {
return a + (b - a) * t;
function calculateNoteX(note: Audio.Note) {
// Desmos View and a bit of explaination: https://www.desmos.com/calculator/40j3sx9jsq
const noteFloor = Math.floor(note);
// Instead of working with floors like the Desmos view, we instead take the mod 12 of note and adjust the multiplier from that
const noteMod12 = noteFloor % 12;
const mul1 = noteMod12 == 4 ? 1 : 0;
const mul2 = noteMod12 == 11 ? 1 : 0;
const multiplier = 1 + mul1 + mul2;

const offsetBase =
Math.floor((1 / 12) * note + 1) + Math.floor((1 / 12) * (note - 5));
const offsetBetween = -(multiplier - 1) * noteFloor;
const offset = offsetBase + offsetBetween;

return multiplier * note + offset + 1;
}

export function resize(yPos: number, width: number, height: number) {
Expand Down