diff --git a/app.css b/app.css index 808246a..ea05169 100644 --- a/app.css +++ b/app.css @@ -2,6 +2,32 @@ * { margin: 0; font-family: sans-serif; + font-weight: lighter; +} + +html { + color: white; + background-color: rgb(11, 8, 20); +} + +button { + border: 1px solid white; + color: inherit; + background-color: inherit; + border-radius: 25rem; + padding: 0.2rem 0.7rem; +} + +button:active { + background-color: darkgreen; +} + +#start-tone { + width: 12vw; + height: 5vh; + position: absolute; + left: 45vw; + top: 50%; } /* javascript utilities */ @@ -9,36 +35,115 @@ display: none; } -/* document styles */ +/* header styles */ header { display: block; - position: fixed; + position: sticky; + background-color: black; + border-bottom: 1px solid white; + max-height: 25vh; width: 100%; text-align: center; - min-height: 12rem; - top: 0; padding: 2rem; + top: 0; + z-index: 9; } +header h2 { + margin: 1rem 1rem 1.5rem; +} + +header button { + margin-top: 0.75rem; +} + +header p { + padding: 0.4rem; +} + +#navbar-tools { + display: flex; +} + +#info-button { + position: absolute; + text-align: center; + top: 1rem; + left: 1.5rem; +} + +/* main section style */ main { display: flex; flex-direction: column; width: 100%; + margin-top: 4rem; align-items: center; position: relative; - top: 15rem; + z-index: 8; } -.audio-controls { - display: flex; - width: 80%; +/* styling for animated visuals */ +.visuals { + display: inline-flex; + flex-direction: row; + justify-content: space-between; + height: 18rem; +} + +.voice { + display: inline-block; + background-color: rgb(5, 5, 75); + width: 20vw; + height: 100%; + margin: 0 1rem; +} + +#visuals-border { + display: block; + width: 85vw; + height: 1rem; + background-color: white; + margin: 3rem 0; + border-radius: 15rem; +} + +/* styling for synth control panel */ +.control-row { + display: inline-flex; + flex-direction: row; + align-items: center; + margin: 1rem 0; +} + +.button-row button { + margin: 0 0.4rem; } .controls { display: inline-flex; flex-direction: column; - border: 1px solid black; align-items: center; + justify-content: center; + border: 1px solid white; + width: 18vw; + height: 25vh; + margin: 1rem; +} + +.controls h3 { + margin-bottom: 1rem; + text-transform: uppercase; + letter-spacing: 0.2em; +} + +.controls label { + display: inline-flex; + flex-direction: row; +} + +.controls label, input { + margin: 0.2rem 0; } #synth-button { diff --git a/app.js b/app.js new file mode 100644 index 0000000..096770a --- /dev/null +++ b/app.js @@ -0,0 +1,70 @@ +import { sopranoTones, altoTones, tenorTones, bassTones, evaluateHarmony } from "./js/toneGeneration.js"; + +const pitchsets = [sopranoTones, altoTones, tenorTones, bassTones]; + +// initialize four synth voices +const soprano = new Tone.Synth().toDestination(); +const alto = new Tone.Synth().toDestination(); +const tenor = new Tone.Synth().toDestination(); +const bass = new Tone.Synth().toDestination(); + +// test function for audio is armed +export const audioTest = () => { + soprano.triggerAttackRelease("C5", "16n"); + alto.triggerAttackRelease("F4", "16n"); + tenor.triggerAttackRelease("E4", "16n"); + bass.triggerAttackRelease("G3", "16n"); +} + +// allows a chord to be generated with input from another function +export const soundChord = (pitches) => { + const [s,a,t,b] = pitches; + soprano.triggerAttackRelease(s, "8n"); + alto.triggerAttackRelease(a, "8n"); + tenor.triggerAttackRelease(t, "8n"); + bass.triggerAttackRelease(b, "8n"); +} + +// initial test: generate a single, random chord +export const fullRandomChord = () => { + let pitches = []; + for (let voice of pitchsets) { + // finds a random index, excluding any which may already exist in the array + let index; + + do { + index = Math.floor(Math.random() * 100) % voice.length; + } while (pitches.includes(voice[index])); + + pitches.push(voice[index]); + console.log(voice[index]); + } + + for (let i = 0; i < pitches.length; i++) { + if (pitches[i] === pitches[i+1]) { + console.log("CAUGHT"); + } + } + + soundChord(pitches); + evaluateHarmony(pitches); +} + +// set up transport +let clock = 0; +let slowClock = 0; + +const transportStart = document.getElementById('transport-start'); + +let transport; + +const loop = new Tone.Loop((time) => { + audioTest(); +}, "8n").start(0); + +loop.probability = 0.8; + +transportStart.onclick = () => { + Tone.Transport.start(); +} + diff --git a/index.html b/index.html index c9e1881..bb9cd11 100644 --- a/index.html +++ b/index.html @@ -6,92 +6,121 @@