diff --git a/Logo.svg b/Logo.svg new file mode 100644 index 0000000..e1b2adf --- /dev/null +++ b/Logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/sounds/Bass.mp3 b/assets/sounds/Bass.mp3 new file mode 100644 index 0000000..7773c94 Binary files /dev/null and b/assets/sounds/Bass.mp3 differ diff --git a/assets/sounds/Gong.mp3 b/assets/sounds/Gong.mp3 new file mode 100644 index 0000000..365e71e Binary files /dev/null and b/assets/sounds/Gong.mp3 differ diff --git a/assets/sounds/Snare.mp3 b/assets/sounds/Snare.mp3 new file mode 100644 index 0000000..de42807 Binary files /dev/null and b/assets/sounds/Snare.mp3 differ diff --git a/assets/sounds/Surdo.mp3 b/assets/sounds/Surdo.mp3 new file mode 100644 index 0000000..d321b9b Binary files /dev/null and b/assets/sounds/Surdo.mp3 differ diff --git a/assets/sounds/Timpani.wav b/assets/sounds/Timpani.wav new file mode 100644 index 0000000..277def8 Binary files /dev/null and b/assets/sounds/Timpani.wav differ diff --git a/assets/sounds/Toms.mp3 b/assets/sounds/Toms.mp3 new file mode 100644 index 0000000..6e4211e Binary files /dev/null and b/assets/sounds/Toms.mp3 differ diff --git a/assets/sounds/Tubular-Bells.wav b/assets/sounds/Tubular-Bells.wav new file mode 100644 index 0000000..b72dd0e Binary files /dev/null and b/assets/sounds/Tubular-Bells.wav differ diff --git a/assets/svg/Orchestral Bass.svg b/assets/svg/Bass.svg similarity index 100% rename from assets/svg/Orchestral Bass.svg rename to assets/svg/Bass.svg diff --git a/assets/svg/Tubular Bells.svg b/assets/svg/Tubular-Bells.svg similarity index 100% rename from assets/svg/Tubular Bells.svg rename to assets/svg/Tubular-Bells.svg diff --git a/index.html b/index.html index 0664941..146bdf4 100644 --- a/index.html +++ b/index.html @@ -4,6 +4,7 @@ Mishka Henner - Conductor + diff --git a/src/script.js b/src/script.js index fd8f83a..f272cbd 100644 --- a/src/script.js +++ b/src/script.js @@ -1,89 +1,143 @@ -import { Client, BrowserSocketFactory } from './blitz.js'; +import { Client, BrowserSocketFactory } from "./blitz.js"; -document.addEventListener('DOMContentLoaded', () => { - - const socketFactory = new BrowserSocketFactory(); - const client = new Client(socketFactory); +document.addEventListener("DOMContentLoaded", () => { + const audioContext = new (window.AudioContext || window.webkitAudioContext)(); + const socketFactory = new BrowserSocketFactory(); + const client = new Client(socketFactory); + client.connect(); - const svgFiles = [ - { fileName: 'Gong.svg', yPos: '20%' }, - { fileName: 'Orchestral Bass.svg', yPos: '10%' }, - { fileName: 'Snare.svg', yPos: '20%' }, - { fileName: 'Surdo Napa.svg', yPos: '30%' }, - { fileName: 'Surdo.svg', yPos: '25%' }, - { fileName: 'Timpani Large.svg', yPos: '40%' }, - { fileName: 'Timpani Small.svg', yPos: '30%' }, - { fileName: 'Toms.svg', yPos: '25%' }, - { fileName: 'Tubular Bells.svg', yPos: '0%' } - ]; - const numStaves = 6; - const numFiles = svgFiles.length; - const sheetWindow = document.getElementById("music-window"); + const instruments = [ + { image: "Gong.svg", yPos: "20%", sample: "Gong.mp3" }, + { + image: "Bass.svg", + yPos: "10%", + sample: "Bass.mp3", + }, + { + image: "Snare.svg", + yPos: "20%", + sample: "Snare.mp3", + }, + { image: "Surdo Napa.svg", yPos: "30%", sample: "Surdo.mp3" }, + { + image: "Surdo.svg", + yPos: "25%", + sample: "Surdo.mp3", + }, + { + image: "Timpani Large.svg", + yPos: "40%", + sample: "Timpani.wav", + }, + { + image: "Timpani Small.svg", + yPos: "30%", + sample: "Timpani.wav", + }, + { + image: "Toms.svg", + yPos: "25%", + sample: "Toms.mp3", + }, + { + image: "Tubular-Bells.svg", + yPos: "0%", + sample: "Tubular-Bells.wav", + }, + ]; - for (let i = 1; i <= numStaves; i++) { - const staveWrapper = document.createElement('div'); - staveWrapper.classList.add(`stave-wrapper`); - staveWrapper.setAttribute("id", `stave-wrapper-${i}`); - staveWrapper.style.position = 'relative'; - const staveObject = document.createElement('object'); - staveObject.type = 'image/svg+xml'; - staveObject.data = 'assets/svg/Stave.svg'; - staveObject.classList.add('stave-svg'); - - staveWrapper.appendChild(staveObject); - sheetWindow.appendChild(staveWrapper); + (async () => { + for (let i = 0; i < instruments.length; i++) { + try { + const response = await fetch(`/assets/sounds/${instruments[i].sample}`); + const arrayBuffer = await response.arrayBuffer(); + const audioBuffer = await audioContext.decodeAudioData(arrayBuffer); + instruments[i][`soundBuffer`] = audioBuffer; + console.log(`Loaded ${i}`); + console.log(instruments[i][`soundBuffer`]); + } catch (error) { + console.error(`Failed to load ${i}: ${error.message}`); + } } + })(); - const timeIndicator = document.querySelector('#time-indicator'); + const numStaves = 6; + const numFiles = instruments.length; + const sheetWindow = document.getElementById("music-window"); - // Debugging log to ensure the element is found - if (timeIndicator) { - console.log('timeIndicator element found'); - } else { - console.log('timeIndicator element not found'); - } + for (let i = 1; i <= numStaves; i++) { + const staveWrapper = document.createElement("div"); + staveWrapper.classList.add(`stave-wrapper`); + staveWrapper.setAttribute("id", `stave-wrapper-${i}`); + staveWrapper.style.position = "relative"; + const staveObject = document.createElement("object"); + staveObject.type = "image/svg+xml"; + staveObject.data = "assets/svg/Stave.svg"; + staveObject.classList.add("stave-svg"); - timeIndicator.addEventListener("animationiteration", () => { - const icons = document.querySelectorAll('.event-icon'); + staveWrapper.appendChild(staveObject); + sheetWindow.appendChild(staveWrapper); + } - icons.forEach((icon) => { - icon.classList.add('fade-out'); - icon.addEventListener('transitionend', () => { - icon.remove(); - }); - }); + const timeIndicator = document.querySelector("#time-indicator"); + + timeIndicator.addEventListener("animationiteration", () => { + const icons = document.querySelectorAll(".event-icon"); + + icons.forEach((icon) => { + icon.classList.add("fade-out"); + icon.addEventListener("transitionend", () => { + icon.remove(); + }); }); + }); - client.on('data', (strike) => { + const playSound = (num) => { + const source = audioContext.createBufferSource(); + const rando = Math.floor(Math.random() * instruments.length); + source.buffer = instruments[num].soundBuffer; // Example: Play the 'Gong' sound + source.connect(audioContext.destination); + source.start(); + }; - if (strike){ + const placeIcon = (region) => { + // create random numbers + const randomStaveNumber = Math.floor((region % 6) + 1); + const randomFileNumber = Math.floor(region); - const randomStaveNumber = Math.floor(Math.random() * numStaves + 1); - const randomFileNumber = Math.floor(Math.random() * numFiles + 1); - const rect = timeIndicator.getBoundingClientRect(); - const sheetLeft = sheetWindow.getBoundingClientRect().left; - const xPosition = rect.left + window.scrollX - sheetLeft; - - - const newObject = document.createElement('div'); - newObject.classList.add('event-icon'); - newObject.style.position = 'absolute'; - newObject.style.left = `${xPosition}px`; - newObject.style.top = `${svgFiles[randomFileNumber].yPos}`; - const eventIcon = document.createElement('object'); - eventIcon.type = 'image/svg+xml'; - eventIcon.data = `assets/svg/${svgFiles[randomFileNumber].fileName}`; - eventIcon.style.width = '35px'; - eventIcon.style.height = '35px'; - - newObject.appendChild(eventIcon); - - const staveWrapper = document.getElementById(`stave-wrapper-${strike.region + 1 % 6}`); - console.log(strike.region); - staveWrapper.appendChild(newObject); - } - }); + // Determine the position of the time indicator + const rect = timeIndicator.getBoundingClientRect(); + const sheetLeft = sheetWindow.getBoundingClientRect().left; + const xPosition = rect.left + window.scrollX - sheetLeft; - client.connect(); + // Create the icon div and give it its location data + const newObject = document.createElement("div"); + newObject.classList.add("event-icon"); + newObject.style.position = "absolute"; + newObject.style.left = `${xPosition}px`; + newObject.style.top = `${instruments[randomFileNumber].yPos}`; -}) \ No newline at end of file + // create the icon + const eventIcon = document.createElement("object"); + eventIcon.type = "image/svg+xml"; + eventIcon.data = `assets/svg/${instruments[randomFileNumber].image}`; + eventIcon.style.width = "35px"; + eventIcon.style.height = "35px"; + + // append icon to div + newObject.appendChild(eventIcon); + + // select the staveWrapper in which to place the div + const staveWrapper = document.getElementById( + `stave-wrapper-${randomStaveNumber}` + ); + + // append the div to the staveWrapper + staveWrapper.appendChild(newObject); + }; + + client.on("data", (strike) => { + placeIcon(strike.region % 9); + playSound(strike.region % 9); + }); +});