Commit e626f0a1 authored by Tomáš Hübelbauer's avatar Tomáš Hübelbauer

Improve note absolute time calculation

parent 0f1ea0bf
......@@ -4,7 +4,7 @@ window.addEventListener('load', async _ => {
fileInput.addEventListener('change', _ => {
const file = fileInput.files[0];
nameH1.textContent = file.name;
//nameH1.textContent = file.name;
const fileReader = new FileReader();
......@@ -17,15 +17,11 @@ window.addEventListener('load', async _ => {
//^ same as tracks[0] and tracks[1]
// Deadmau5 - Strobe from tilt1981 uses 4 tracks
//console.log('tracks[0]', data.tracks[0]); // timeSignature & endOfTracks
//console.log('tracks[1]', data.tracks[1]); // setTempo's
//console.log('tracks[2]', data.tracks[2]); // same as channels[0] + author meta & endOfTracks
//console.log('tracks[3]', data.tracks[3]); // same as channels[1] + author meta & endOfTracks
console.log('tracks[0]', data.tracks[0]); // timeSignature & endOfTracks
console.log('tracks[1]', data.tracks[1]); // setTempo's
// Deadmau5 - Strobe from tilt1981 uses 2 channels
const channel0Notes = [ ...getNotes(data.channels[0]) ];
const channel1Notes = [ ...getNotes(data.channels[1]) ];
const length = Math.max(channel0Notes.length, channel1Notes.length);
const channel0Notes = [ ...getNotes(data.tracks[2]) ];
const channel1Notes = [ ...getNotes(data.tracks[3]) ];
// https://www.youtube.com/watch?v=ppLnKRObtM0
renderChannelNotes(channel0Notes, length);
......@@ -36,32 +32,51 @@ window.addEventListener('load', async _ => {
});
});
function* getNotes(channel) {
// https://stackoverflow.com/a/23071105/2715716
// TODO: Accept tempo changes and reflect that in time
function* getNotes(track) {
let time = 0;
let notes = {};
for (const event of channel.filter(event => event.subtype === 'noteOn' || event.subtype === 'noteOff')) {
switch (event.subtype) {
case 'noteOn': {
notes[event.noteNumber] = time;
for (const event of track) {
time += event.deltaTime;
switch (event.type) {
case 'channel': {
switch (event.subtype) {
case 'noteOn': {
notes[event.noteNumber] = time;
break;
}
case 'noteOff': {
yield ({ onTime: notes[event.noteNumber], offTime: time, no: event.noteNumber });
delete notes[event.noteNumber];
break;
}
case 'controller': break;
case 'pitchBend': break;
case 'programChange': break;
default: console.log(event);
}
break;
}
case 'noteOff': {
yield ({ on: notes[event.noteNumber], off: time, no: event.noteNumber });
delete notes[event.noteNumber];
case 'meta': {
switch (event.subtype) {
case 'trackName': break;
case 'endOfTrack': break;
default: console.log(event);
}
break;
}
default: console.log(event);
}
time++; // TODO: Do this using `setTempo`.
}
}
const width = 10;
const height = 10;
function renderChannelNotes(notes, length) {
// TODO: Fix bug with note sized space between notes.
function renderChannelNotes(notes) {
// TODO: Do not use `100` for padding, use non-absolute positioning instead.
const limit = length * height * 2 + 100;
const limit = notes.slice(-1)[0].offTime + 100;
for (const note of notes) {
const boxDiv = document.createElement('div');
boxDiv.style.position = 'absolute';
......@@ -69,11 +84,13 @@ function renderChannelNotes(notes, length) {
boxDiv.style.border = '1px solid black';
boxDiv.style.borderRadius = '10%';
boxDiv.style.top = `${limit - (note.on * height)}px`;
boxDiv.style.top = `${limit - note.offTime}px`;
boxDiv.style.bottom = `${limit - note.onTime}px`;
boxDiv.style.left = `${note.no * width}px`;
boxDiv.style.width = `${width}px`;
boxDiv.style.height = `${(note.off - note.on) * height}px`;
boxDiv.textContent = note.no;
document.body.appendChild(boxDiv);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment