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

Render notes with fake time for now

parent 6c4f0154
......@@ -9,12 +9,9 @@ window.addEventListener('load', async _ => {
const fileReader = new FileReader();
fileReader.addEventListener('load', _ => {
// TODO: Do this in a Web Worker and report progress to the UI.
const data = new SmfParser().parse(fileReader.result);
// Deadmau5 - Strobe from tilt1981 uses 2 channels
//console.log('channels[0]', data.channels[0]);
//console.log('channels[1]', data.channels[1]);
// TODO: What is this?
//console.log('systems', data.systems); // timeSignature & endOfTracks & setTempo's
//^ same as tracks[0] and tracks[1]
......@@ -25,31 +22,59 @@ window.addEventListener('load', async _ => {
//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
// TODO: User channels to generate objects in this format:
// { note: number, startPosition: number, endPosition: number }
const boxes = [];
const notes = data.channels[0].filter(note => note.subtype === 'noteOn' || note.subtype === 'noteOff');
let time = 0;
let pressed = [];
for (const note of notes) {
switch (note.subtype) {
case 'noteOn': {
// TODO: Check if unpressed - should never happen if pressed
pressed.push(note.noteNumber);
break;
}
case 'noteOff': {
// TODO: Make box with timeFrom, timeTo and noteNo
break;
}
}
}
console.log(notes);
// 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);
// https://www.youtube.com/watch?v=ppLnKRObtM0
renderChannelNotes(channel0Notes, length);
renderChannelNotes(channel1Notes, length);
});
fileReader.readAsBinaryString(file);
});
});
function* getNotes(channel) {
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;
break;
}
case 'noteOff': {
yield ({ on: notes[event.noteNumber], off: time, no: event.noteNumber });
delete notes[event.noteNumber];
break;
}
}
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.
// TODO: Do not use `100` for padding, use non-absolute positioning instead.
const limit = length * height * 2 + 100;
for (const note of notes) {
const boxDiv = document.createElement('div');
boxDiv.style.position = 'absolute';
boxDiv.style.background = `rgb(255, 255, ${note.no})`;
boxDiv.style.border = '1px solid black';
boxDiv.style.borderRadius = '10%';
boxDiv.style.top = `${limit - (note.on * height)}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