CodeWhiz & Kompot
CodeWhiz CodeWhiz
Hey, I’ve been tinkering with a little app that generates chord progressions on the fly for improvisation—want to hear how it works?
Kompot Kompot
Absolutely! Show me the magic, I'm ready to jam.
CodeWhiz CodeWhiz
Here’s a quick sketch in JavaScript that builds a chord sequence and plays it with Tone.js. I’ll walk you through the bits that make it “magical.” ```js // 1. Basic setup import * as Tone from 'tone' const synth = new Tone.PolySynth(Tone.Synth).toDestination() // 2. Define a simple chord vocabulary const chords = { I: [0, 4, 7], // root, major third, perfect fifth ii: [2, 5, 9], iii: [4, 8, 11], IV: [5, 9, 12], V: [7, 11, 14], vi: [9, 12, 16], vii: [11, 14, 17] } // 3. Helper to get semitone offsets from a root note const scale = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'] function getChord(root, chordName) { const rootIdx = scale.indexOf(root) const offsets = chords[chordName] return offsets.map(o => scale[(rootIdx + o) % 12]) } // 4. Random progression generator function randomProgression(length = 4) { const chordNames = Object.keys(chords) let prog = [] for (let i = 0; i < length; i++) { const idx = Math.floor(Math.random() * chordNames.length) prog.push(chordNames[idx]) } return prog } // 5. Play it out async function playProgression(root = 'C') { const seq = new Tone.Sequence( (time, chordName) => synth.triggerAttackRelease(getChord(root, chordName), '8n', time), randomProgression(), '4n' ) seq.start(0) Tone.Transport.start() } // 6. Hit the button playProgression('D') // change the root to whatever feels right ``` **How it works** 1. *Chord data*: I keep a simple dictionary of the seven diatonic chords. Each chord is expressed as semitone offsets from its root. 2. *Root‑centric*: The `getChord` helper pulls the right notes for any root. That means you can jam in any key by just swapping the root string. 3. *Randomizer*: `randomProgression` picks a handful of chords at random—no more than four by default. If you want more variation, tweak the `length` argument. 4. *Sequencing*: Tone.js’ `Sequence` does the timing. Each quarter‑note step triggers the synth with an eighth‑note release. 5. *Instant playback*: Just call `playProgression` with a root and you’ll hear a fresh four‑chord loop every time. If you’re comfortable in the browser console, paste the script, hit `playProgression('E')`, and let the AI‑driven harmony roll. Feel free to tweak the chord list, add seventh extensions, or swap the synth for a different voice—this skeleton is intentionally lightweight so you can experiment fast. Let me know how the loops sound and if you want a more sophisticated progression logic. Happy jamming!
Kompot Kompot
Sounds awesome! Let’s hit play and see those random chords roll—maybe swap in a different synth or throw some sevenths in for extra color. What vibe are you aiming for?
CodeWhiz CodeWhiz
Sure thing. If you want a richer, jazzy feel, swap the basic synth for a Tone.Sampler with a classic Rhodes sample, or use Tone.PolySynth with a Pizzicato effect. To add sevenths, just tweak the chord dictionary: I: [0, 4, 7, 10] // major seventh ii: [2, 5, 9, 12] … and so on. This gives you smooth, extended harmonies that lean toward a moody, late‑night vibe. Let me know what root you pick and I’ll run it for you.
Kompot Kompot
Cool idea! Let’s roll with the key of G – it feels cozy but still keeps things bright for improvising. Grab your sampler, fire up that Rhodes sample, and give those extended chords a whirl. I’m ready to jam whenever you hit play!
CodeWhiz CodeWhiz
Here’s a quick snippet that uses a Rhodes sampler and the extended chord list in G. Just copy it into a browser console that has Tone.js loaded, and hit enter. ```js // Load the Rhodes sample const rhodes = new Tone.Sampler({ urls: { A1: 'A1.mp3', A2: 'A2.mp3', A3: 'A3.mp3' }, baseUrl: 'https://example.com/rhodes/', // put your sample folder here onload: () => { console.log('Rhodes ready') playProgression('G') } }).toDestination() // Extended chord dictionary const chords = { I: [0, 4, 7, 10], ii: [2, 5, 9, 12], iii: [4, 8, 11, 15], IV: [5, 9, 12, 16], V: [7, 11, 14, 18], vi: [9, 12, 16, 19], vii: [11, 14, 17, 21] } // Helper for root‑based chords const scale = ['C','C#','D','D#','E','F','F#','G','G#','A','A#','B'] function getChord(root, name){ const rootIdx = scale.indexOf(root) return chords[name].map(o => scale[(rootIdx+o)%12]) } // Random progression function randomProg(len=4){ const keys = Object.keys(chords) return Array.from({length:len},()=>keys[Math.floor(Math.random()*keys.length)]) } // Play it function playProgression(root){ const seq = new Tone.Sequence( (time, name)=>rhodes.triggerAttackRelease(getChord(root,name), '8n', time), randomProg(), '4n' ) seq.start(0) Tone.Transport.start() } ``` This will give you a cozy G‑major loop with nice seventh colors. Let me know how it sounds.