diff options
author | Matthew Hodgson <matthew@matrix.org> | 2014-10-19 07:52:59 +0100 |
---|---|---|
committer | Matthew Hodgson <matthew@matrix.org> | 2014-10-19 07:52:59 +0100 |
commit | 4f58d41c156784348a78c1caffa3b58193916e4d (patch) | |
tree | 0a0e33a179b323e86f445f07bd9564c39fda0ce8 | |
parent | Added MIDI.js and VexFlow libs (diff) | |
download | synapse-4f58d41c156784348a78c1caffa3b58193916e4d.tar.xz |
support for chords & rests
-rw-r--r-- | webclient/components/matrix/midi-event-handler.js | 161 |
1 files changed, 103 insertions, 58 deletions
diff --git a/webclient/components/matrix/midi-event-handler.js b/webclient/components/matrix/midi-event-handler.js index 2c6b654765..606b2fcd5b 100644 --- a/webclient/components/matrix/midi-event-handler.js +++ b/webclient/components/matrix/midi-event-handler.js @@ -25,6 +25,12 @@ var MidiEventHandler = { vexTabString: "", + chord: { + start_midi_ts: 0, + end_midi_ts: 0, + notes: {}, + }, + currentMeasureTime: 0, perLine: -1, @@ -79,6 +85,77 @@ notes C-D-E/4 #0# =:: C-D-E-F/4 =|="); this.render(); }, + getLogDuration: function(duration) { + var fraction = duration / this.beat; + console.log(fraction); + var musicFraction; + var duration = Math.floor(Math.log2(1 / fraction)) - 1; + }, + + renderChord: function(duration, rest) { + var logDuration = this.getLogDuration(duration); + var trashIt = false; // Flag to ignore artefact(???) + switch (logDuration) { + case 4: + musicFraction = "w"; + break; + case 2: + musicFraction = "h"; + break; + case 1: + musicFraction = "q"; + break; + case 0: + musicFraction = "8"; + break; + case -1: + musicFraction = "16"; + break; + case -2: + musicFraction = "32"; + break; + default: + console.log("## Ignored note"); + // Too short, ignore it + trashIt = true; + break; + } + + // Matthew is about to fix it + if (trashIt) return; + + } + this.currentMeasureTime += duration; + + var s = ":" + musicFraction + " "; + + if (rest) { + s += "##"; + } + else { + var notes = []; + for (var note in chord.notes) { + if (chord.notes.hasOwnProperty(note)) { + notes.push(note); + } + } + + if (notes.length > 1) { + s += "("; + for (int i = 0; i < notes.length; i++) { + s += notes[i]; + if (i < notes.length - 1) s+= "."; + } + s += ")"; + } + else { + s += vexNote; + } + } + + this.addNote(s); + }, + handleEvent: function(event, isLiveEvent) { if(!isLiveEvent) { @@ -105,73 +182,41 @@ notes C-D-E/4 #0# =:: C-D-E-F/4 =|="); return; } - var vexNote = this.getVexNote( this.getMidiNote(event.content.note) ); if ("on" === event.content.state) { - this.notesON[vexNote] = parseInt(event.content.midi_ts); - } - else if (this.notesON[vexNote]) - { - // How long the note last - var duration = parseInt(event.content.midi_ts) - this.notesON[vexNote]; - delete this.notesON[vexNote]; - - var fraction = duration / this.beat; - - console.log(fraction); + var midi_ts = parseInt(event.content.midi_ts); + this.notesON[vexNote] = midi_ts; - var musicFraction; - - // Flag to ignore artefact(???) - var trashIt = false; - - var duration = Math.floor(Math.log2(1 / fraction)) - 1; - switch (duration) { - case 4: - musicFraction = "w"; - break; - case 2: - musicFraction = "h"; - break; - case 1: - musicFraction = "q"; - break; - case 0: - musicFraction = "8"; - break; - case -1: - musicFraction = "16"; - break; - case -2: - musicFraction = "32"; - break; - - default : - - console.log("## Ignored note"); - // Too short, ignore it - trashIt = true; - break; - + if (event.content.midi_ts - this.chord.start_midi_ts < 300) { // empirically + // just add it to the current chord we're building up. + this.chord.note[vexNote]++; } - - // Matthew is about to fix it - if (trashIt) return; - - this.currentMeasureTime += duration; + else { + // render the last note/chord + this.renderChord(this.chord.end_midi_ts - this.chord.start_midi_ts, false); + // check if it's been so long since the last note that we should do a rest. + var logDuration = this.getLogDuration(midi_ts - this.chord.end_midi_ts); + if (logDuration >= -2) { + this.renderChord(midi_ts - this.chord.end_midi_ts, true); + } + + // start a new chord + this.chord.notes = { vexNote }; + this.chord.start_midi_ts = midi_ts; + this.chord.end_midi_ts = 0; + } + } + else if (this.notesON[vexNote]) // note is turning off. + { + // How long the note lasts + this.chord.end_midi_ts = parseInt(event.content.midi_ts); + delete this.notesON[vexNote]; - vexNote = ":" + musicFraction + " " + vexNote; - - this.addNote(vexNote); + // TODO: optimisation: we could render this note now if we know there are no others sounding... } }, - - c: function(fraction) { - return Math.floor(Math.log2(1 / fraction)) - 1; - - }, addNote: function (vexNote) { |