From 39595806ff92bee3ad4faa173f1718387beb2bdf Mon Sep 17 00:00:00 2001 From: sandwich <299465+dskvr@users.noreply.github.com> Date: Tue, 13 Feb 2024 23:37:10 +0000 Subject: [PATCH] update music logic --- src/App.svelte | 13 +++--- src/tone.js | 115 ++++++++++++++++++++++++------------------------- 2 files changed, 65 insertions(+), 63 deletions(-) diff --git a/src/App.svelte b/src/App.svelte index 888c43b..cf2c2e9 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -21,6 +21,7 @@ const MONITOR = "cd18a5109bd5a3110e173331d873725dbf0c5bedc9357a3cc80ed7029b24e974"; + const ONLINE_THRESHOLD = Math.round(Date.now() / 1000) - 60 * 60 * 2.1; let currentRelayModal = null; let currentGenericModal = null; @@ -38,7 +39,7 @@ let loading = true; let masonry; let initialSyncComplete = false; - let since = Math.round(Date.now() / 1000) - 60 * 60 * 1.1; + let since = ONLINE_THRESHOLD const newEvents = []; @@ -96,9 +97,11 @@ const updateEvents = (processedEvent) => { if (processedEvent) { k30066.update((currentk30066) => { - return [processedEvent, ...currentk30066].filter( - (v, i, a) => a.findIndex((t) => t.dTag === v.dTag) === i, - ); + return [processedEvent, ...currentk30066] + .filter( + (v, i, a) => a.findIndex((t) => t.dTag === v.dTag) === i, + ) + .filter( ev => ev.created_at > Math.round(Date.now()/1000)-ONLINE_THRESHOLD ) }); } }; @@ -305,7 +308,7 @@ onMount(async () => { await initialSync(); - eventRunner = setInterval( populateNextEvent, 500 ) + eventRunner = setInterval( populateNextEvent, 250 ) await continuousSync(); return () => { clearInterval(eventRunner) diff --git a/src/tone.js b/src/tone.js index 1d50193..40b6090 100644 --- a/src/tone.js +++ b/src/tone.js @@ -2,23 +2,25 @@ import * as Tone from 'tone'; class ComplementaryToneGenerator { constructor() { - this.rootNote = 'C'; - this.currentOctave = 4; // Starting octave - this.octaveDirection = 1; // 1 for up, -1 for down - this.octaveMin = 3; // Minimum octave limit - this.octaveMax = 5; // Maximum octave limit + // Array of root notes designed to be melodic + + this.rootNotes = ['C', 'E', 'G', 'B', 'D', 'F', 'A']; + this.currentRootNoteIndex = 0; // Start with the first note in the array + this.rootNote = this.rootNotes[this.currentRootNoteIndex]; + this.currentOctave = 4; this.scalePatterns = { - major: [2, 2, 1, 2, 2, 2, 1], // W-W-H-W-W-W-H - minor: [2, 1, 2, 2, 1, 2, 2], // W-H-W-W-H-W-W - majorSeventh: [4, 3, 1], // Major 7th Chord (Root-Major 3rd-Perfect 5th-Major 7th) - pentatonic: [2, 2, 3, 2, 3], // Pentatonic Scale + major: [2, 2, 1, 2, 2, 2, 1], + minor: [2, 1, 2, 2, 1, 2, 2], + majorSeventh: [4, 3, 1], + pentatonic: [2, 2, 3, 2, 3], }; - this.scaleKeys = Object.keys(this.scalePatterns); - this.currentScalePatternIndex = 0; // Index to keep track of the current scale pattern - this.currentScalePattern = this.scaleKeys[this.currentScalePatternIndex]; + this.currentScalePatternIndex = 0; + this.currentScalePattern = Object.keys(this.scalePatterns)[this.currentScalePatternIndex]; this.currentScale = []; - this.scaleIndex = 0; - this.lastFrequency = null; + this.scaleIndex = -1; // Start before the first note to play the first note immediately + this.direction = 1; // Start ascending + this.notesSinceRootChange = 0 + this.randomRootChange = 0 this.synth = new Tone.Synth({ envelope: { @@ -32,65 +34,62 @@ class ComplementaryToneGenerator { this.initializeScale(); } - generateScale(rootNote, pattern) { - let scale = [`${rootNote}${this.currentOctave}`]; - let currentFrequency = Tone.Frequency(scale[0]).toFrequency(); - - pattern.forEach(interval => { - currentFrequency *= Tone.intervalToFrequencyRatio(interval); - scale.push(Tone.Frequency(currentFrequency).toNote()); - }); + generateScale() { + const pattern = this.scalePatterns[this.currentScalePattern]; + let scale = []; + let currentNote = `${this.rootNote}${this.currentOctave}`; + scale.push(currentNote); - return scale; - } + for (let i = 0; i < pattern.length; i++) { + currentNote = Tone.Frequency(currentNote).transpose(pattern[i]).toNote(); + scale.push(currentNote); + } + + this.currentScale = scale; +} initializeScale() { - this.currentScale = this.generateScale(this.rootNote, this.scalePatterns[this.currentScalePattern]); - this.scaleIndex = 0; // Reset scale index + this.reset() + this.generateScale(); + this.scaleIndex = 0; // Start from the first note } playNextNote() { - // Check if we've reached the end or start of the scale to change direction - if (this.scaleIndex >= this.currentScale.length - 1 || this.scaleIndex <= 0) { - this.adjustOctaveAndMaybeScale(); + this.notesSinceRootChange++ + if(this.notesSinceRootChange > this.randomRootChange){ + this.selectNextScaleAndRoot() + } + if (this.direction === 1 && this.scaleIndex >= this.currentScale.length - 1 || this.direction === -1 && this.scaleIndex <= 0) { + this.direction *= -1; // Change direction + } else { + this.scaleIndex += this.direction; + } + + if (this.scaleIndex < 0 || this.scaleIndex >= this.currentScale.length) { // Ensures index stays within bounds + return; } const nextNote = this.currentScale[this.scaleIndex]; - this.synth.triggerAttackRelease(nextNote, '8n', Tone.now()); - this.scaleIndex += this.octaveDirection; // Move index in the current direction - this.lastFrequency = Tone.Frequency(nextNote).toFrequency(); + + console.log(nextNote, this.currentRootNoteIndex, this.currentRootNoteIndex) + this.synth.triggerAttackRelease(nextNote, '8n'); } - adjustOctaveAndMaybeScale() { - // When changing direction at octave limits, also change the scale - if (this.currentOctave >= this.octaveMax || this.currentOctave <= this.octaveMin) { - this.octaveDirection *= -1; // Change direction - this.selectNextScaleAndRoot(); // Change scale and root note - } else if (this.scaleIndex === 0 || this.scaleIndex === this.currentScale.length - 1) { - // Regular octave direction change without hitting octave limits - this.octaveDirection *= -1; // Change direction - } + selectNextScaleAndRoot() { + this.reset() + this.currentRootNoteIndex = (this.currentRootNoteIndex + 1) % this.rootNotes.length; + this.rootNote = this.rootNotes[this.currentRootNoteIndex]; - // Adjust the octave within the limits - this.currentOctave += this.octaveDirection; - if (this.currentOctave > this.octaveMax) { - this.currentOctave = this.octaveMax; - } else if (this.currentOctave < this.octaveMin) { - this.currentOctave = this.octaveMin; - } + const max = Object.keys(this.scalePatterns).length + this.currentScalePatternIndex = Math.floor(Math.random() * (max - 0 + 1)) + 0; + this.currentScalePattern = Object.keys(this.scalePatterns)[this.currentScalePatternIndex]; - this.initializeScale(); // Re-initialize the scale with the new settings + this.initializeScale(); } - selectNextScaleAndRoot() { - // Move to the next scale pattern - this.currentScalePatternIndex = (this.currentScalePatternIndex + 1) % this.scaleKeys.length; - this.currentScalePattern = this.scaleKeys[this.currentScalePatternIndex]; - - const rootNotes = ['C', 'D', 'E', 'B', 'G', 'F', 'A']; - let currentRootIndex = rootNotes.indexOf(this.rootNote); - currentRootIndex = (currentRootIndex + 1) % rootNotes.length; - this.rootNote = rootNotes[currentRootIndex]; + reset(){ + this.randomRootChange = Math.floor(Math.random() * (12 - 3 + 1)) + 3 + this.notesSinceRootChange = 0 } }