From dc13195729897942b67e229d5c59c5ff811e169c Mon Sep 17 00:00:00 2001 From: sksum <55449862+sksum@users.noreply.github.com> Date: Sun, 7 Jun 2020 04:45:30 +0530 Subject: [PATCH 1/3] add doMIDI function map midi input data to the keys on virtual MusicKeyboard . handles cblk2 is null error decrement function will work even when cblk2 : null --- js/widgets/musickeyboard.js | 120 ++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/js/widgets/musickeyboard.js b/js/widgets/musickeyboard.js index 3782e0bdaa..20d7abe94f 100644 --- a/js/widgets/musickeyboard.js +++ b/js/widgets/musickeyboard.js @@ -453,6 +453,19 @@ function MusicKeyboard() { that._createAddRowPieSubmenu(); }; + let midiButton = widgetWindow.addButton( + null, + ICONSIZE, + _("MIDI") + ) + midiButton.onclick = function () { + if (navigator.requestMIDIAccess) { + that.doMIDI(); + } else { + logo.textMsg(' MIDI is not supported in this browser.'); + } + }; + // var cell = this._addButton(row1, 'table.svg', ICONSIZE, _('Table')); //that._createKeyboard(); @@ -2628,4 +2641,111 @@ function MusicKeyboard() { return cell; }; + this.doMIDI = () => { + + var duration = 0; + var startTime = 0; + + this.getElement = {}; + + for (let idx = 0; idx < this.layout.length; idx++) { + key = this.layout[idx]; + this.getElement[key.noteName.toString()+ key.noteOctave.toString()] = key.objId; + } + + let __startNote = (event, element) => { + if (!element) return; + startTime = event.timeStamp ; // Milliseconds(); + element.style.backgroundColor = platformColor.orange; + this._logo.synth.trigger( + 0, + this.noteMapper[element.id], + 1, + this.instrumentMapper[element.id], + null, + null + ); + }; + + let __endNote = (event, element) => { + if (!element) return; + + var id = element.id; + if (id.includes("blackRow")) { + element.style.backgroundColor = "black"; + } else { + element.style.backgroundColor = "white"; + } + + var now = event.timeStamp; + duration = now - startTime; + duration /= 1000; + this._logo.synth.stopSound( + 0, + this.instrumentMapper[element.id], + this.noteMapper[element.id] + ); + if (beginnerMode === "true") { + duration = parseFloat( + (Math.round(duration * 8) / 8).toFixed(3) + ); + } else { + duration = parseFloat( + (Math.round(duration * 16) / 16).toFixed(4) + ); + } + + if (duration === 0) { + duration = 0.125; + } else if (duration < 0) { + duration = -duration; + } + + this._notesPlayed.push({ + startTime: startTime, + noteOctave: this.noteMapper[element.id], + objId: element.id, + duration: duration, + voice: this.instrumentMapper[element.id], + blockNumber: this.blockNumberMapper[element.id] + }); + this._createTable(); + }; + + let numberToPitch = (num) => { + let offset = 4; + let octave = offset + Math.floor((num - 60) / 12); + let pitch = PITCHES[num % 12]; + return [pitch, octave]; + } + + //event attributes : timeStamp , data + //data : length -3 [0] : 144/128 : noteOn/NoteOff + // [1] : noteNumber : middle C always 60 + // [2] : velocity ,(currently not used). + + let onMIDIMessage = (event) => { + let pitch = numberToPitch(event.data[1] )[0]; + let octave = numberToPitch(event.data[1] )[1]; + console.debug(pitch, octave); + if (event.data[0] == 144 && event.data[2] != 0) { + __startNote(event, docById(this.getElement[pitch + "" + octave])); + + } + else { + __endNote(event, docById(this.getElement[pitch + "" + octave])); + } + } + + let onMIDISuccess = ( midiAccess) => { + midiAccess.inputs.forEach((input) => { input.onmidimessage = onMIDIMessage; }); + } + + if (this.midiON) return; + this.midiON = true; + + navigator.requestMIDIAccess() + .then(onMIDISuccess); + + } } From 58d044d6da5e6f03cb5110884e801d84fa7712f0 Mon Sep 17 00:00:00 2001 From: sksum <55449862+sksum@users.noreply.github.com> Date: Mon, 15 Jun 2020 22:33:37 +0530 Subject: [PATCH 2/3] improve midi allow solfege and sharps/flats in midi. --- js/widgets/musickeyboard.js | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/js/widgets/musickeyboard.js b/js/widgets/musickeyboard.js index 20d7abe94f..1d7d1b3046 100644 --- a/js/widgets/musickeyboard.js +++ b/js/widgets/musickeyboard.js @@ -2651,6 +2651,7 @@ function MusicKeyboard() { for (let idx = 0; idx < this.layout.length; idx++) { key = this.layout[idx]; this.getElement[key.noteName.toString()+ key.noteOctave.toString()] = key.objId; + this.getElement[FIXEDSOLFEGE1[key.noteName.toString()] + "" + key.noteOctave] = key.objId ; //convet solfege to alphabetic. } let __startNote = (event, element) => { @@ -2715,8 +2716,9 @@ function MusicKeyboard() { let numberToPitch = (num) => { let offset = 4; let octave = offset + Math.floor((num - 60) / 12); - let pitch = PITCHES[num % 12]; - return [pitch, octave]; + let pitch1 = NOTESSHARP[num % 12]; + let pitch2 = NOTESFLAT[num % 12]; + return [pitch1, pitch2, octave]; } //event attributes : timeStamp , data @@ -2725,15 +2727,18 @@ function MusicKeyboard() { // [2] : velocity ,(currently not used). let onMIDIMessage = (event) => { - let pitch = numberToPitch(event.data[1] )[0]; - let octave = numberToPitch(event.data[1] )[1]; - console.debug(pitch, octave); + let pitchOctave = numberToPitch(event.data[1]); + let pitch1 = pitchOctave[0]; + let pitch2 = pitchOctave[1]; + let octave = pitchOctave[2]; + let key = this.getElement[pitch1 +""+ octave] || this.getElement[pitch2 +"" + octave]; + console.debug(pitch1, octave); if (event.data[0] == 144 && event.data[2] != 0) { - __startNote(event, docById(this.getElement[pitch + "" + octave])); + __startNote(event, docById(key)); } else { - __endNote(event, docById(this.getElement[pitch + "" + octave])); + __endNote(event, docById(key)); } } From 147497f7f77c81334aa4ba2f663afc792f07e2bf Mon Sep 17 00:00:00 2001 From: sksum <55449862+sksum@users.noreply.github.com> Date: Fri, 19 Jun 2020 13:54:53 +0530 Subject: [PATCH 3/3] improve midi button better handling of midi access --- js/widgets/musickeyboard.js | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/js/widgets/musickeyboard.js b/js/widgets/musickeyboard.js index 1d7d1b3046..6b9632bf66 100644 --- a/js/widgets/musickeyboard.js +++ b/js/widgets/musickeyboard.js @@ -453,17 +453,13 @@ function MusicKeyboard() { that._createAddRowPieSubmenu(); }; - let midiButton = widgetWindow.addButton( + this.midiButton = widgetWindow.addButton( null, ICONSIZE, _("MIDI") ) - midiButton.onclick = function () { - if (navigator.requestMIDIAccess) { - that.doMIDI(); - } else { - logo.textMsg(' MIDI is not supported in this browser.'); - } + this.midiButton.onclick = function () { + that.doMIDI(); }; // var cell = this._addButton(row1, 'table.svg', ICONSIZE, _('Table')); @@ -2743,14 +2739,28 @@ function MusicKeyboard() { } let onMIDISuccess = ( midiAccess) => { + // re-init widget + if (this.midiON){ + this.midiButton.style.background = "#00FF00" ; + logo.textMsg("MIDI device present") + return ; + } midiAccess.inputs.forEach((input) => { input.onmidimessage = onMIDIMessage; }); + if (midiAccess.inputs.size) { + this.midiButton.style.background = "#00FF00" ; + logo.textMsg("MIDI device present") + this.midiON =true ; + } + else logo.textMsg("MIDI device not present"); } - if (this.midiON) return; - this.midiON = true; + let onMIDIFailure= () => { + logo.errorMsg( "Failed to get MIDI access in browser"); + this.midiON =false ; + } navigator.requestMIDIAccess() - .then(onMIDISuccess); + .then(onMIDISuccess,onMIDIFailure); } }