From 7fe72de979ca940bae0867be02dde86f4b7f2584 Mon Sep 17 00:00:00 2001 From: Brackets-Coder <142950368+Brackets-Coder@users.noreply.github.com> Date: Tue, 15 Oct 2024 17:59:24 -0400 Subject: [PATCH 1/9] Create midi.js --- extensions/MasterMath/midi.js | 211 ++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 extensions/MasterMath/midi.js diff --git a/extensions/MasterMath/midi.js b/extensions/MasterMath/midi.js new file mode 100644 index 0000000000..e8424672bc --- /dev/null +++ b/extensions/MasterMath/midi.js @@ -0,0 +1,211 @@ +// Name: MIDI +// ID: midi +// Description: An extension that retrieves input from MIDI devices. +// By: -MasterMath- +// License: MPL-2.0 + +(function (Scratch) { + "use strict"; + + if (!Scratch.extensions.unsandboxed) { + alert("This MIDI extension must run unsandboxed!"); + throw new Error("This MIDI extension must run unsandboxed!"); + } + + let midiInputDevices = []; + let midiDeviceInfo = []; + let notesOn = []; + let noteVelocities = []; + let lastNotePressed = 0; + let lastNoteReleased = 0; + + if (navigator.requestMIDIAccess) { + navigator.requestMIDIAccess().then(onSuccess, onError); + + function onSuccess(midiAccess) { + midiAccess.onstatechange = (event) => { + if (event.port.state == "connected") { + midiInputDevices.push([ + `[id: "${event.port.id}"` + ` name: "${event.port.name}"]`, + ]); + midiDeviceInfo.push([event.port.id, event.port.name]); + } else if (event.port.state == "disconnected") { + midiInputDevices.splice( + [`[id: "${event.port.id}"` + ` name: "${event.port.name}"]`], + 1, + ); + midiDeviceInfo.splice([event.port.id, event.port.name]); + } + }; + + function onMIDIMessage(event) { + const [status, note, velocity] = event.data; + const command = status & 0xf0; + if (command === 0x90 && velocity > 0) { + notesOn.push(note); + noteVelocities.push([note, velocity]); + lastNotePressed = note; + Scratch.vm.runtime.startHats("midi_whenNotePressed"); + } else if (command === 0x80 || (command === 0x90 && velocity === 0)) { + lastNoteReleased = note; + notesOn.splice(notesOn.indexOf(note), 1); + noteVelocities.splice( + noteVelocities.findIndex((subArray) => subArray[0] === note), + 1, + ); + Scratch.vm.runtime.startHats("midi_whenNoteReleased"); + } else { + console.log( + `Other MIDI Message: Status=${status}, Note=${note}, Velocity=${velocity}, Timestamp ${event.timeStamp}`, + ); + } + } + + midiAccess.inputs.forEach((entry) => { + entry.onmidimessage = onMIDIMessage; + }); + } + + function onError(err) { + alert("MIDI Access Error:", err); + throw new Error("MIDI Access Error:", err); + } + } else { + alert("MIDI is not supported on this browser."); + throw new Error("MIDI is not supported on this browser."); + } + + class MIDI { + getInfo() { + return { + id: "midi", + name: "MIDI", + blocks: [ + { + opcode: "MIDIinputDevices", + blockType: Scratch.BlockType.REPORTER, + text: "connected MIDI input devices", + disableMonitor: true, + }, + { + opcode: "midiDeviceInfo", + blockType: Scratch.BlockType.REPORTER, + text: "[info] of MIDI device [number]", + arguments: { + info: { + type: Scratch.ArgumentType.STRING, + defaultValue: "name", + menu: "infoMenu", + }, + number: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: 0, + }, + }, + }, + "---", + { + opcode: "whenNotePressed", + blockType: Scratch.BlockType.EVENT, + text: "when any note pressed", + isEdgeActivated: false, + shouldRestartExistingThreads: true, + }, + { + opcode: "whenNoteReleased", + blockType: Scratch.BlockType.EVENT, + text: "when any note released", + isEdgeActivated: false, + shouldRestartExistingThreads: true, + }, + { + opcode: "noteOn", + blockType: Scratch.BlockType.BOOLEAN, + text: "is note [note] on?", + arguments: { + note: { + type: Scratch.ArgumentType.NOTE, + defaultValue: 60, + }, + }, + }, + { + opcode: "noteVelocity", + blockType: Scratch.BlockType.REPORTER, + text: "velocity of note [note]", + arguments: { + note: { + type: Scratch.ArgumentType.NOTE, + defaultValue: 60, + }, + }, + }, + { + opcode: "activeNotes", + blockType: Scratch.BlockType.REPORTER, + text: "all active notes", + disableMonitor: true, + }, + { + opcode: "lastNotePressed", + blockType: Scratch.BlockType.REPORTER, + text: "last note pressed", + disableMonitor: true, + }, + { + opcode: "lastNoteReleased", + blockType: Scratch.BlockType.REPORTER, + text: "last note released", + disableMonitor: true, + }, + ], + menus: { + infoMenu: { + acceptReporters: false, + items: ["name", "id"], + }, + }, + }; + } + + MIDIinputDevices() { + return midiInputDevices; + } + + midiDeviceInfo(args) { + if (midiInputDevices[args.number] != null) { + return midiDeviceInfo[args.number][args.info == "id" ? 0 : 1]; + } else { + return; + } + } + + noteOn(args) { + return notesOn.includes(Number(args.note)); + } + + noteVelocity(args) { + if ( + notesOn.includes(args.note) && + noteVelocities.find((subArray) => subArray[0] === args.note)[1] !== + undefined + ) { + return noteVelocities.find((subArray) => subArray[0] === args.note)[1]; + } + } + + activeNotes() { + return notesOn; + } + + lastNotePressed() { + return lastNotePressed; + } + + lastNoteReleased() { + return lastNoteReleased; + } + } + + Scratch.extensions.register(new MIDI()); +})(Scratch); From c4f995498d31f07388cbf4a517dfefb6f914c808 Mon Sep 17 00:00:00 2001 From: Brackets-Coder <142950368+Brackets-Coder@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:08:19 -0400 Subject: [PATCH 2/9] Update extensions.json I didn't know where to put the MIDI extension. Please move it if you disagree. --- extensions/extensions.json | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions/extensions.json b/extensions/extensions.json index 9027c00ac9..7c63ed11e5 100644 --- a/extensions/extensions.json +++ b/extensions/extensions.json @@ -37,6 +37,7 @@ "veggiecan/browserfullscreen", "shreder95ua/resolution", "XmerOriginals/closecontrol", + "MasterMath/midi", "navigator", "battery", "PwLDev/vibration", From 6cc1d31992f64f155724bd043e9d4e115a140e0d Mon Sep 17 00:00:00 2001 From: Brackets-Coder <142950368+Brackets-Coder@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:10:15 -0400 Subject: [PATCH 3/9] Create midi.png --- images/MasterMath/midi.png | 1 + 1 file changed, 1 insertion(+) create mode 100644 images/MasterMath/midi.png diff --git a/images/MasterMath/midi.png b/images/MasterMath/midi.png new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/images/MasterMath/midi.png @@ -0,0 +1 @@ + From 4261daa04da7b7449927d562bc55bffe61ebf301 Mon Sep 17 00:00:00 2001 From: Brackets-Coder <142950368+Brackets-Coder@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:10:36 -0400 Subject: [PATCH 4/9] Delete images/MasterMath/midi.png --- images/MasterMath/midi.png | 1 - 1 file changed, 1 deletion(-) delete mode 100644 images/MasterMath/midi.png diff --git a/images/MasterMath/midi.png b/images/MasterMath/midi.png deleted file mode 100644 index 8b13789179..0000000000 --- a/images/MasterMath/midi.png +++ /dev/null @@ -1 +0,0 @@ - From a61a1df56ff5c5cf5ddae9a75bbd20bca18ee9c7 Mon Sep 17 00:00:00 2001 From: Brackets-Coder <142950368+Brackets-Coder@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:11:11 -0400 Subject: [PATCH 5/9] Create midi.png --- images/MasterMath/midi.png | 1 + 1 file changed, 1 insertion(+) create mode 100644 images/MasterMath/midi.png diff --git a/images/MasterMath/midi.png b/images/MasterMath/midi.png new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/images/MasterMath/midi.png @@ -0,0 +1 @@ + From cb7da194795f8aabdc2166609a4169c6d529b931 Mon Sep 17 00:00:00 2001 From: Brackets-Coder <142950368+Brackets-Coder@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:11:30 -0400 Subject: [PATCH 6/9] Add midi.png --- images/MasterMath/midi.png | Bin 1 -> 13976 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/images/MasterMath/midi.png b/images/MasterMath/midi.png index 8b137891791fe96927ad78e64b0aad7bded08bdc..f2f610e632abdf41cd19caddfe673c3616f0bc06 100644 GIT binary patch literal 13976 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 literal 1 Icmd-A000XB3jhEB From d67eb86d0b4b86920d99bc3c4e35cf99c4bb2c17 Mon Sep 17 00:00:00 2001 From: Brackets-Coder <142950368+Brackets-Coder@users.noreply.github.com> Date: Wed, 16 Oct 2024 15:27:39 -0400 Subject: [PATCH 7/9] Attempt to fix midi.js prettier I've ran prettier like a few dozen times with the same version and settings as the repo. If this fails I have no idea why --- extensions/MasterMath/midi.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/MasterMath/midi.js b/extensions/MasterMath/midi.js index e8424672bc..5de0195b63 100644 --- a/extensions/MasterMath/midi.js +++ b/extensions/MasterMath/midi.js @@ -32,7 +32,7 @@ } else if (event.port.state == "disconnected") { midiInputDevices.splice( [`[id: "${event.port.id}"` + ` name: "${event.port.name}"]`], - 1, + 1 ); midiDeviceInfo.splice([event.port.id, event.port.name]); } @@ -51,12 +51,12 @@ notesOn.splice(notesOn.indexOf(note), 1); noteVelocities.splice( noteVelocities.findIndex((subArray) => subArray[0] === note), - 1, + 1 ); Scratch.vm.runtime.startHats("midi_whenNoteReleased"); } else { console.log( - `Other MIDI Message: Status=${status}, Note=${note}, Velocity=${velocity}, Timestamp ${event.timeStamp}`, + `Other MIDI Message: Status=${status}, Note=${note}, Velocity=${velocity}, Timestamp ${event.timeStamp}` ); } } From 2cc79efb238f7f7a12574140fc56bb82bbde4bf0 Mon Sep 17 00:00:00 2001 From: Brackets-Coder Date: Wed, 16 Oct 2024 21:32:03 -0400 Subject: [PATCH 8/9] Add new block and improve efficiency --- extensions/MasterMath/midi.js | 75 +++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 20 deletions(-) diff --git a/extensions/MasterMath/midi.js b/extensions/MasterMath/midi.js index 5de0195b63..16a9c252fb 100644 --- a/extensions/MasterMath/midi.js +++ b/extensions/MasterMath/midi.js @@ -45,7 +45,13 @@ notesOn.push(note); noteVelocities.push([note, velocity]); lastNotePressed = note; - Scratch.vm.runtime.startHats("midi_whenNotePressed"); + Scratch.vm.runtime.startHats("midi_whenAnyNote", { + pressedReleased: "pressed", + }); + Scratch.vm.runtime.startHats("midi_whenNote", { + note: note, + pressedReleased: "pressed", + }); } else if (command === 0x80 || (command === 0x90 && velocity === 0)) { lastNoteReleased = note; notesOn.splice(notesOn.indexOf(note), 1); @@ -53,7 +59,13 @@ noteVelocities.findIndex((subArray) => subArray[0] === note), 1 ); - Scratch.vm.runtime.startHats("midi_whenNoteReleased"); + Scratch.vm.runtime.startHats("midi_whenAnyNote", { + pressedReleased: "released", + }); + Scratch.vm.runtime.startHats("midi_whenNote", { + note: note, + pressedReleased: "released", + }); } else { console.log( `Other MIDI Message: Status=${status}, Note=${note}, Velocity=${velocity}, Timestamp ${event.timeStamp}` @@ -105,18 +117,36 @@ }, "---", { - opcode: "whenNotePressed", + opcode: "whenAnyNote", blockType: Scratch.BlockType.EVENT, - text: "when any note pressed", + text: "when any note [pressedReleased]", isEdgeActivated: false, shouldRestartExistingThreads: true, + arguments: { + pressedReleased: { + type: Scratch.ArgumentType.STRING, + defaultValue: "pressed", + menu: "pressedReleased", + }, + }, }, { - opcode: "whenNoteReleased", + opcode: "whenNote", blockType: Scratch.BlockType.EVENT, - text: "when any note released", + text: "when note [note] [pressedReleased]", isEdgeActivated: false, shouldRestartExistingThreads: true, + arguments: { + note: { + type: Scratch.ArgumentType.NOTE, + defaultValue: 60, + }, + pressedReleased: { + type: Scratch.ArgumentType.STRING, + defaultValue: "pressed", + menu: "pressedReleased", + }, + }, }, { opcode: "noteOn", @@ -147,16 +177,17 @@ disableMonitor: true, }, { - opcode: "lastNotePressed", - blockType: Scratch.BlockType.REPORTER, - text: "last note pressed", - disableMonitor: true, - }, - { - opcode: "lastNoteReleased", + opcode: "lastNote", blockType: Scratch.BlockType.REPORTER, - text: "last note released", + text: "last note [pressedReleased]", disableMonitor: true, + arguments: { + pressedReleased: { + type: Scratch.ArgumentType.STRING, + defaultValue: "pressed", + menu: "pressedReleased", + }, + }, }, ], menus: { @@ -164,6 +195,10 @@ acceptReporters: false, items: ["name", "id"], }, + pressedReleased: { + acceptReporters: false, + items: ["pressed", "released"], + }, }, }; } @@ -198,12 +233,12 @@ return notesOn; } - lastNotePressed() { - return lastNotePressed; - } - - lastNoteReleased() { - return lastNoteReleased; + lastNote({ pressedReleased }) { + if (pressedReleased == "pressed") { + return lastNotePressed; + } else { + return lastNoteReleased; + } } } From 90142971038c83c6d578862e5d60b2c1e3a4c9d2 Mon Sep 17 00:00:00 2001 From: Brackets-Coder Date: Wed, 30 Oct 2024 08:20:33 -0400 Subject: [PATCH 9/9] Fix connection splice() --- extensions/MasterMath/midi.js | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/extensions/MasterMath/midi.js b/extensions/MasterMath/midi.js index 16a9c252fb..f18510088b 100644 --- a/extensions/MasterMath/midi.js +++ b/extensions/MasterMath/midi.js @@ -25,16 +25,23 @@ function onSuccess(midiAccess) { midiAccess.onstatechange = (event) => { if (event.port.state == "connected") { - midiInputDevices.push([ - `[id: "${event.port.id}"` + ` name: "${event.port.name}"]`, - ]); + midiInputDevices.push( + `[id: "${event.port.id}" name: "${event.port.name}"]` + ); midiDeviceInfo.push([event.port.id, event.port.name]); } else if (event.port.state == "disconnected") { - midiInputDevices.splice( - [`[id: "${event.port.id}"` + ` name: "${event.port.name}"]`], - 1 + // Find and remove from midiInputDevices + const inputIndex = midiInputDevices.findIndex( + (item) => + item === `[id: "${event.port.id}" name: "${event.port.name}"]` + ); + if (inputIndex !== -1) midiInputDevices.splice(inputIndex, 1); + + // Find and remove from midiDeviceInfo + const infoIndex = midiDeviceInfo.findIndex( + (item) => item[0] === event.port.id ); - midiDeviceInfo.splice([event.port.id, event.port.name]); + if (infoIndex !== -1) midiDeviceInfo.splice(infoIndex, 1); } };