This is a working performance model

This commit is contained in:
joe 2025-04-25 09:03:54 +01:00
parent 0e31c0ea1d
commit e5eacbba0d
5 changed files with 62 additions and 38 deletions

View File

@ -10,7 +10,8 @@
"midi-channel-name": "conductorOrchestralBass", "midi-channel-name": "conductorOrchestralBass",
"image": { "image": {
"filename": "bass.svg", "filename": "bass.svg",
"yPos": "13%", "yPos": "2.5%",
"width": "100", "width": "100",
"height": "100" "height": "100"
} }
@ -24,7 +25,7 @@
"midi-channel-name": "conductorSnare", "midi-channel-name": "conductorSnare",
"image": { "image": {
"filename": "snare.svg", "filename": "snare.svg",
"yPos": "26%", "yPos": "7%",
"width": "100", "width": "100",
"height": "100" "height": "100"
} }
@ -32,10 +33,10 @@
"Surdo": { "Surdo": {
"directory": "/assets/instruments/surdo", "directory": "/assets/instruments/surdo",
"filenames": ["surdo-5.mp3", "surdo-6.mp3", "surdo-7.mp3"], "filenames": ["surdo-5.mp3", "surdo-6.mp3", "surdo-7.mp3"],
"midi-channel-name": "conductorSnare", "midi-channel-name": "conductorSurdo",
"image": { "image": {
"filename": "surdo.svg", "filename": "surdo.svg",
"yPos": "39%", "yPos": "10.5%",
"width": "100", "width": "100",
"height": "100" "height": "100"
} }
@ -46,7 +47,7 @@
"midi-channel-name": "conductorSurdoNapa", "midi-channel-name": "conductorSurdoNapa",
"image": { "image": {
"filename": "surdo-napa.svg", "filename": "surdo-napa.svg",
"yPos": "42%", "yPos": "12%",
"width": "100", "width": "100",
"height": "100" "height": "100"
} }
@ -62,7 +63,7 @@
"midi-channel-name": "conductorTimpaniLarge", "midi-channel-name": "conductorTimpaniLarge",
"image": { "image": {
"filename": "timpani-large.svg", "filename": "timpani-large.svg",
"yPos": "55%", "yPos": "14%",
"width": "100", "width": "100",
"height": "100" "height": "100"
} }
@ -77,7 +78,7 @@
"midi-channel-name": "conductorTimpaniSmall", "midi-channel-name": "conductorTimpaniSmall",
"image": { "image": {
"filename": "timpani-small.svg", "filename": "timpani-small.svg",
"yPos": "68%", "yPos": "18%",
"width": "100", "width": "100",
"height": "100" "height": "100"
} }
@ -92,7 +93,7 @@
"midi-channel-name": "conductorToms", "midi-channel-name": "conductorToms",
"image": { "image": {
"filename": "toms.svg", "filename": "toms.svg",
"yPos": "62%", "yPos": "42%",
"width": "100", "width": "100",
"height": "100" "height": "100"
} }

View File

@ -1,5 +1,6 @@
export async function sendMidiMessage(midiChannelName, sampleNumber) { export async function sendMidiMessage(midiChannelName, sampleNumber, midiAccess) {
try { try {
console.log(midiChannelName, sampleNumber);
const availableMidiOutputs = midiAccess.outputs.values(); const availableMidiOutputs = midiAccess.outputs.values();
let midiOut; let midiOut;
@ -16,11 +17,11 @@ export async function sendMidiMessage(midiChannelName, sampleNumber) {
} }
// MIDI Note On (Play Note) // MIDI Note On (Play Note)
midiOut.send([0x90, 36 + sampleNumber, 127]); midiOut.send([0x90, 35 + sampleNumber, 127]);
// MIDI Note Off after 500ms // MIDI Note Off after 500ms
setTimeout(() => { setTimeout(() => {
midiOut.send([0x80, 36 + sampleNumber, 0]); // Stop Note midiOut.send([0x80, 35 + sampleNumber, 0]); // Stop Note
}, 500); }, 500);
} catch (error) { } catch (error) {
console.error("Failed to get MIDI access:", error); console.error("Failed to get MIDI access:", error);

View File

@ -7,7 +7,7 @@ export class Renderer {
sheetWindow; sheetWindow;
canvases = []; canvases = [];
iconCache = []; iconCache = [];
iconScale = 0.25; iconScale = 0.20;
constructor() { constructor() {
this.numStaves = 6; this.numStaves = 6;
@ -29,31 +29,44 @@ export class Renderer {
for (let i = 1; i <= this.numStaves; i++) { for (let i = 1; i <= this.numStaves; i++) {
const staveWrapper = document.createElement("div"); const staveWrapper = document.createElement("div");
staveWrapper.classList.add("stave-wrapper"); staveWrapper.classList.add("stave-wrapper");
staveWrapper.setAttribute("id", `stave-wrapper-${i}`); staveWrapper.setAttribute("id", `stave-wrapper-${i}`);
staveWrapper.style.position = "relative"; staveWrapper.style.position = "relative";
const staveObject = document.createElement("object"); const staveObject = document.createElement("object");
staveObject.type = "image/svg+xml"; staveObject.type = "image/svg+xml";
staveObject.data = "assets/svg/stave.svg"; staveObject.data = "assets/svg/stave.svg";
staveObject.class = "stave-svg"; staveObject.className = "stave-svg"; // Fixed className
this.sheetWindow.appendChild(staveWrapper);
const canvas = document.createElement("canvas"); const canvas = document.createElement("canvas");
canvas.id = `canvas-${i}`; canvas.id = `canvas-${i}`;
canvas.className = "event-canvas"; canvas.className = "event-canvas";
const ctx = canvas.getContext("2d"); const ctx = canvas.getContext("2d");
this.canvases.push({ canvas, ctx }); this.canvases.push({ canvas, ctx });
staveWrapper.appendChild(staveObject); staveWrapper.appendChild(staveObject);
staveWrapper.appendChild(canvas); staveWrapper.appendChild(canvas);
this.sheetWindow.appendChild(staveWrapper);
// Your exact sizing method + minimal DPR adjustment
requestAnimationFrame(() => { requestAnimationFrame(() => {
canvas.width = canvas.offsetWidth; const dpr = window.devicePixelRatio || 1;
canvas.height = canvas.offsetHeight;
// Keep your offset measurements
const displayWidth = canvas.offsetWidth;
const displayHeight = canvas.offsetHeight;
// Apply to actual canvas buffer
canvas.width = Math.round(displayWidth * dpr);
canvas.height = Math.round(displayHeight * dpr);
// Maintain your display size
canvas.style.width = `${displayWidth}px`;
canvas.style.height = `${displayHeight}px`;
// Scale context to compensate
ctx.scale(dpr , dpr);
}); });
} }
} }

View File

@ -10,21 +10,30 @@ document.addEventListener("DOMContentLoaded", async () => {
await conductor.init(); await conductor.init();
const dataStream = new DataStream(); const dataStream = new DataStream();
const instruments = await conductor.instruments; const instruments = await conductor.instruments;
let strikes = 0;
const strikeEvery = 2;
const renderer = new Renderer(); const renderer = new Renderer();
dataStream.addEventListener("strike", () => { dataStream.addEventListener("strike", () => {
console.log(strikes);
//** select instrument */ //** select instrument */
const keys = Object.keys(instruments); if (strikes === strikeEvery){
const randomIndex = Math.floor(Math.random() * keys.length);
const selectedInstrument = instruments[keys[randomIndex]];
//** select sample */ const keys = Object.keys(instruments);
const numSamples = selectedInstrument.numSamples; const randomIndex = Math.floor(Math.random() * keys.length);
const randomSampleNumber = Math.floor(Math.random() * numSamples); const selectedInstrument = instruments[keys[randomIndex]];
renderer.placeIcon(selectedInstrument); //** select sample */
sendMidiMessage(selectedInstrument.midiChannelName, randomSampleNumber + 1, midiAccess); const numSamples = selectedInstrument.numSamples;
const randomSampleNumber = Math.floor(Math.random() * numSamples);
renderer.placeIcon(selectedInstrument);
sendMidiMessage(selectedInstrument.midiChannelName, randomSampleNumber + 1, midiAccess);
strikes = 0;
}
strikes++;
}); });
dataStream.init(); dataStream.init();

View File

@ -2,7 +2,7 @@ body {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
background-color: rgb(24, 24, 24); background-color: rgb(0,0,0);
height: 100vh; height: 100vh;
overflow: hidden; overflow: hidden;
@ -91,11 +91,11 @@ html {
display: block; display: block;
width: 100%; width: 100%;
height: 12vh; height: 12vh;
background-color: rgb(24,24,24); background-color: rgb(0,0,0);
padding-top: 30px; padding-top: 30px;
padding-bottom: 20px; padding-bottom: 20px;
overflow: visible; overflow: visible;
z-index: 100; z-index: 9995;
} }
.logo { .logo {
@ -140,7 +140,7 @@ html {
max-width: 700px; max-width: 700px;
height: 70%; height: 70%;
margin: 0; margin: 0;
background-color: rgb(24,24,24); background-color: rgb(0,0,0);
margin-bottom: 100px; margin-bottom: 100px;
overflow: visible; overflow: visible;
} }
@ -181,7 +181,7 @@ html {
margin-bottom: 80px; margin-bottom: 80px;
text-align: center; text-align: center;
color: white; color: white;
background-color: rgb(24,24,24); background-color: rgb(0,0,0);
/* height: 20vh; */ /* height: 20vh; */
font-family: Helvetica; font-family: Helvetica;
font-size: clamp(14px,1.1vw, 18px); font-size: clamp(14px,1.1vw, 18px);
@ -216,7 +216,7 @@ html {
bottom: 0; bottom: 0;
width: 2px; width: 2px;
height: 92%; height: 92%;
background-color: red; background-color: rgb(0, 0, 0);
z-index: 0; z-index: 0;
animation: moveRight 10s linear infinite; animation: moveRight 10s linear infinite;
will-change: transform; will-change: transform;