Procedural Music

by Ben Gillbanks

HTML

<script src="https://unpkg.com/[email protected]/build/Tone.js"></script>

JavaScript

// ๐ŸŽต Define a simple scale (C Major) to choose melody notes from
const scale = ["C4", "D4", "E4", "F4", "G4", "A4", "B4"]

// ๐ŸŽผ Define common chord progressions using Roman numeral notation
const chordProgressions = {
  simple: ["I", "IV", "V", "I"], // Classic pop progression
  jazz: ["ii", "V", "I"], // Jazz turnaround
  blues: ["I", "IV", "V", "IV"], // Basic blues progression
}

// ๐ŸŽน Map each chord symbol to its corresponding notes in the C Major scale
const chordsInC = {
  I: ["C4", "E4", "G4"], // C Major chord
  IV: ["F4", "A4", "C5"], // F Major chord
  V: ["G4", "B4", "D5"], // G Major chord
  ii: ["D4", "F4", "A4"], // D minor chord
}

// ๐ŸŽธ Define bass notes for each chord
const bassNotesInC = {
  I: "C2", // C bass note
  IV: "F2", // F bass note
  V: "G2", // G bass note
  ii: "D2", // D bass note
}

const arpeggioPatterns = [
  // ๐Ÿ”น Basic Patterns
  [0, 1, 2, 1], // Alternating (Classic chiptune arpeggio)
  [0, 1, 2, 3], // Ascending
  [3, 2, 1, 0], // Descending
  [0, 2, 1, 3], // Jumping pattern
  [0, 1, 0, 2], // NES-style triplet feel

  // ๐Ÿ”น Fast Repeats (Chiptune/NES Style)
  [0, 1, 2, 0], // Up and repeat
  [0, 2, 1, 2], // Midpoint bounce
  [0, 3, 2, 3], // Top bounce
  [3, 2, 1, 2], // Downward bounce
  [1, 0, 2, 3], // Shifted alternate

  // ๐Ÿ”น Sweep Patterns (Great for Game Soundtracks)
  [0, 1, 2, 1], // Gentle wave
  [0, 2, 3, 1], // Wide leap sweep
  [0, 3, 1, 2], // Broken wave
  [3, 0, 2, 1], // Inverted motion

  // ๐Ÿ”น Complex Patterns (More Unique Movement)
  [0, 1, 3, 2], // Wide stagger
  [3, 2, 0, 1], // Reverse stagger
  [0, 2, 1, 0], // Loop with anchor
  [1, 3, 0, 2], // Unusual movement

  // ๐Ÿ”น Random-Like Movement (But Still Structured)
  [0, 3, 1, 3], // Strong jumps
  [3, 1, 2, 0], // Reverse jumps
  [0, 2, 3, 0], // Spiral-like
  [1, 0, 3, 2], // Offset reverse

  // ๐Ÿ”น Patterns Starting at 1 (Second Note First)
  [1, 0, 2, 3], // Starts on the middle note, then moves around
  [1, 3, 2, 0], // Starts high, moves down
  [1,...