Music Hard
Clausic — Free Compositions
10 original MIDI compositions across diverse moods and genres — Open Road, Emerald Canopy, Hollow Peak, Harbor Dawn, Starboard Waltz, Phantom Bells, Golden Savanna, Ember Coast, Iron Summit, Marble Hall.
Open in Lab
MCP
html-midi-player tone-js magenta
Targets: JS HTML
Code
:root {
--bg: #0f0f14;
--surface: #1a1a24;
--accent: #7c6af7;
--accent-dim: rgba(124, 106, 247, 0.15);
--text: #e0dff5;
--muted: #6b6a8a;
--radius: 10px;
}
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
background: var(--bg);
color: var(--text);
font-family: "Inter", system-ui, -apple-system, sans-serif;
max-width: 900px;
margin: 0 auto;
padding: 3rem 1.5rem 5rem;
min-height: 100vh;
}
header {
margin-bottom: 2rem;
}
header h1 {
font-size: 2.6rem;
font-weight: 700;
letter-spacing: -0.04em;
background: linear-gradient(135deg, var(--text), var(--accent));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
line-height: 1.1;
}
.subtitle {
color: var(--muted);
font-size: 0.95rem;
margin-top: 0.4rem;
}
.tabs {
display: flex;
gap: 0.4rem;
margin-bottom: 1.8rem;
flex-wrap: wrap;
}
.tab {
background: var(--surface);
border: 1px solid transparent;
color: var(--muted);
padding: 0.45rem 1.1rem;
border-radius: 999px;
cursor: pointer;
font-size: 0.88rem;
font-weight: 500;
font-family: inherit;
transition: background 0.15s, color 0.15s;
}
.tab:hover {
color: var(--text);
border-color: var(--accent-dim);
}
.tab.active {
background: var(--accent);
color: #fff;
border-color: var(--accent);
}
.piece {
display: none;
}
.piece.active {
display: block;
animation: fadeIn 0.22s ease;
}
.piece h2 {
font-size: 1.35rem;
font-weight: 600;
letter-spacing: -0.02em;
margin-bottom: 0.3rem;
display: flex;
align-items: center;
gap: 0.6rem;
}
.meta {
font-family: "SF Mono", "Fira Mono", "Consolas", monospace;
font-size: 0.8rem;
color: var(--muted);
margin-bottom: 1.4rem;
letter-spacing: 0.02em;
}
.gen-badge {
display: inline-flex;
align-items: center;
justify-content: center;
width: 2rem;
height: 2rem;
border-radius: 50%;
background: #e05252;
color: #fff;
font-size: 0.78rem;
font-weight: 700;
flex-shrink: 0;
}
midi-visualizer {
display: block;
width: 100%;
height: 280px;
background: var(--surface);
border-radius: var(--radius);
margin-bottom: 0.8rem;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.04);
}
midi-visualizer svg {
width: 100%;
height: 100%;
}
midi-player {
display: block;
width: 100%;
--player-background: var(--surface);
--player-color: var(--accent);
--player-playing-color: var(--accent);
border-radius: var(--radius);
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.04);
margin-bottom: 1.2rem;
}
/* Generation code details */
.gen-details {
margin-top: 0.4rem;
margin-bottom: 1.2rem;
}
.gen-details summary {
cursor: pointer;
font-size: 0.82rem;
font-weight: 500;
color: var(--accent);
padding: 0.4rem 0;
user-select: none;
display: inline-flex;
align-items: center;
gap: 0.4rem;
list-style: none;
}
.gen-details summary::-webkit-details-marker {
display: none;
}
.gen-details summary::before {
content: "\25B6";
font-size: 0.6rem;
transition: transform 0.2s ease;
display: inline-block;
}
.gen-details[open] summary::before {
transform: rotate(90deg);
}
.gen-details summary:hover {
color: var(--text);
}
.gen-code {
background: var(--surface);
border: 1px solid rgba(255, 255, 255, 0.06);
border-radius: var(--radius);
padding: 1rem 1.2rem;
margin-top: 0.5rem;
overflow-x: auto;
}
.gen-code pre {
font-family: "SF Mono", "Fira Mono", "Consolas", monospace;
font-size: 0.75rem;
line-height: 1.6;
color: var(--text);
white-space: pre-wrap;
word-wrap: break-word;
}
.gen-code .comment {
color: var(--muted);
}
.gen-code .key {
color: #7dd3fc;
}
.gen-code .val {
color: #a5f3c4;
}
.gen-code .str {
color: #fcd34d;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(7px);
}
to {
opacity: 1;
transform: translateY(0);
}
}/* ====================================================================
Clausic — Free Compositions
10 procedurally-generated NoteSequence compositions for html-midi-player
==================================================================== */
// --------------- Scale & Theory Helpers ---------------
const SCALES = {
major: [0, 2, 4, 5, 7, 9, 11],
minor: [0, 2, 3, 5, 7, 8, 10],
blues: [0, 3, 5, 6, 7, 10],
diminished: [0, 2, 3, 5, 6, 8, 9, 11],
};
const ROOTS = { C: 60, D: 62, E: 64, F: 65, G: 67, A: 69, B: 71 };
/** Map a scale degree (0-based, can exceed one octave) to a MIDI pitch */
function scaleNote(root, scale, degree) {
if (degree == null) return null;
const len = scale.length;
const octave = Math.floor(degree / len);
const idx = ((degree % len) + len) % len;
return root + scale[idx] + octave * 12;
}
/** Convert beat number to seconds */
function beatToSec(beat, bpm) {
return (beat * 60) / bpm;
}
// --------------- NoteSequence Generator ---------------
function generate(cfg) {
const { root, scale, bpm, bars, chords, melody, bass, drums, programs } = cfg;
const notes = [];
const sc = SCALES[scale];
const beatDur = 60 / bpm;
const eighthDur = beatDur / 2;
const beatsPerBar = 4;
const eighthsPerBar = 8;
const totalBeats = bars * beatsPerBar;
const totalTime = totalBeats * beatDur;
// ---- Chords / Pads ----
if (chords && chords.length > 0) {
for (let bar = 0; bar < bars; bar++) {
const chord = chords[bar % chords.length];
const startBeat = bar * beatsPerBar;
const start = beatToSec(startBeat, bpm);
const end = beatToSec(startBeat + beatsPerBar, bpm);
chord.forEach((deg) => {
const pitch = scaleNote(root, sc, deg);
if (pitch != null) {
notes.push({
pitch,
startTime: start,
endTime: end,
velocity: 45 + Math.floor(Math.random() * 15),
program: programs.pad,
});
}
});
}
}
// ---- Melody ----
if (melody && melody.length > 0) {
let melIdx = 0;
for (let bar = 0; bar < bars; bar++) {
for (let eighth = 0; eighth < eighthsPerBar; eighth++) {
const deg = melody[melIdx % melody.length];
melIdx++;
if (deg == null) continue;
const pitch = scaleNote(root, sc, deg);
if (pitch == null) continue;
const startBeat = bar * beatsPerBar + eighth * 0.5;
const start = beatToSec(startBeat, bpm);
const isLong = eighth % 2 === 0 && melody[melIdx % melody.length] == null;
const dur = isLong ? beatDur : eighthDur * 0.9;
notes.push({
pitch,
startTime: start,
endTime: start + dur,
velocity: 70 + Math.floor(Math.random() * 25),
program: programs.melody,
});
}
}
}
// ---- Counter-melody / harmony (optional) ----
if (cfg.counter && cfg.counter.length > 0) {
let cIdx = 0;
for (let bar = 0; bar < bars; bar++) {
for (let eighth = 0; eighth < eighthsPerBar; eighth++) {
const deg = cfg.counter[cIdx % cfg.counter.length];
cIdx++;
if (deg == null) continue;
const pitch = scaleNote(root, sc, deg);
if (pitch == null) continue;
const startBeat = bar * beatsPerBar + eighth * 0.5;
const start = beatToSec(startBeat, bpm);
const dur = eighthDur * 0.85;
notes.push({
pitch,
startTime: start,
endTime: start + dur,
velocity: 50 + Math.floor(Math.random() * 15),
program: programs.counter || programs.melody,
});
}
}
}
// ---- Bass ----
if (bass && bass.length > 0) {
let bassIdx = 0;
for (let bar = 0; bar < bars; bar++) {
for (let beat = 0; beat < beatsPerBar; beat++) {
const deg = bass[bassIdx % bass.length];
bassIdx++;
if (deg == null) continue;
const pitch = scaleNote(root - 24, sc, deg);
if (pitch == null) continue;
const startBeat = bar * beatsPerBar + beat;
const start = beatToSec(startBeat, bpm);
const dur = beatDur * 0.85;
notes.push({
pitch,
startTime: start,
endTime: start + dur,
velocity: 75 + Math.floor(Math.random() * 20),
program: programs.bass,
});
}
}
}
// ---- Drums ----
if (drums) {
const drumMap = { kick: 36, snare: 38, hat: 42, openHat: 46, crash: 49, ride: 51 };
for (const [name, pattern] of Object.entries(drums)) {
if (!pattern || pattern.length === 0) continue;
const drumPitch = drumMap[name] || 38;
let patIdx = 0;
for (let bar = 0; bar < bars; bar++) {
for (let eighth = 0; eighth < eighthsPerBar; eighth++) {
const hit = pattern[patIdx % pattern.length];
patIdx++;
if (!hit) continue;
const startBeat = bar * beatsPerBar + eighth * 0.5;
const start = beatToSec(startBeat, bpm);
const vel =
typeof hit === "number" && hit > 1 ? hit : 70 + Math.floor(Math.random() * 25);
notes.push({
pitch: drumPitch,
startTime: start,
endTime: start + 0.15,
velocity: vel,
isDrum: true,
});
}
}
}
}
return {
notes,
tempos: [{ time: 0, qpm: bpm }],
totalTime,
};
}
// --------------- Track Configurations ---------------
const tracks = [
// ── 0: Open Road — C major · 120 BPM · Adventure begins ──
{
root: ROOTS.C,
scale: "major",
bpm: 120,
bars: 16,
// C, F, G, C (I, IV, V, I) — classic adventure
chords: [
[0, 2, 4], // C (C E G)
[3, 5, 7], // F (F A C)
[4, 6, 8], // G (G B D)
[0, 2, 4], // C (C E G)
],
// Bright, bouncy, adventurous melody
melody: [
4,
5,
7,
null,
7,
9,
7,
5,
4,
null,
2,
4,
5,
null,
7,
null,
9,
7,
5,
4,
2,
null,
4,
5,
7,
null,
null,
5,
4,
2,
0,
null,
7,
9,
11,
null,
9,
7,
5,
null,
4,
5,
7,
9,
null,
11,
9,
7,
5,
null,
4,
2,
0,
null,
2,
4,
5,
7,
null,
5,
4,
null,
2,
null,
],
bass: [
0,
null,
0,
2,
3,
null,
3,
2,
4,
null,
4,
2,
0,
null,
2,
0,
0,
2,
0,
null,
3,
null,
2,
3,
4,
null,
2,
4,
0,
null,
2,
0,
],
// Upbeat, driving drums
drums: {
kick: [1, 0, 0, 1, 1, 0, 0, 0],
snare: [0, 0, 1, 0, 0, 0, 1, 0],
hat: [1, 1, 1, 1, 1, 1, 1, 1],
crash: [
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
],
},
programs: { melody: 0, bass: 33, pad: 48 }, // Piano, ElectricBass, Strings
},
// ── 1: Emerald Canopy — E minor · 68 BPM · Mystery ──
{
root: ROOTS.E,
scale: "minor",
bpm: 68,
bars: 16,
// Em, Am, Bm, Em (i, iv, v, i) — dark, mysterious
chords: [
[0, 2, 4], // Em
[3, 5, 7], // Am
[4, 6, 8], // Bm
[0, 2, 4], // Em
],
// Sparse, eerie melody with lots of rests — forest sounds
melody: [
4,
null,
null,
null,
5,
null,
null,
null,
3,
null,
2,
null,
null,
null,
null,
null,
null,
null,
4,
null,
null,
5,
null,
null,
3,
null,
null,
null,
2,
null,
0,
null,
null,
null,
null,
null,
7,
null,
null,
5,
4,
null,
null,
null,
null,
null,
3,
null,
null,
null,
2,
null,
null,
null,
null,
null,
4,
null,
null,
3,
null,
null,
2,
null,
],
counter: [
null,
null,
0,
null,
null,
null,
null,
null,
null,
null,
null,
null,
2,
null,
null,
null,
null,
null,
null,
null,
null,
null,
0,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
2,
null,
null,
null,
null,
null,
null,
null,
null,
null,
0,
null,
null,
null,
null,
null,
null,
null,
null,
2,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
],
bass: [0, null, null, null, 3, null, null, null, 4, null, null, null, 0, null, null, null],
// Very sparse drums — occasional soft kick, no snare
drums: {
kick: [1, 0, 0, 0, 0, 0, 0, 0],
hat: [0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
},
programs: { melody: 73, bass: 33, pad: 88, counter: 9 }, // Flute, ElectricBass, PadNewAge, Glockenspiel
},
// ── 2: Hollow Peak — D minor · 56 BPM · Dark caverns ──
{
root: ROOTS.D,
scale: "minor",
bpm: 56,
bars: 16,
// Dm, Gm, Bb, A (i, iv, bVI, V) — dark, cavernous
chords: [
[0, 2, 4], // Dm
[3, 5, 7], // Gm
[5, 7, 9], // Bb
[4, 6, 8], // A (borrowed V)
],
// Very slow, echoing, sparse — dripping cave melody
melody: [
7,
null,
null,
null,
null,
null,
null,
null,
null,
null,
5,
null,
null,
null,
null,
null,
4,
null,
null,
null,
null,
null,
3,
null,
null,
null,
null,
null,
2,
null,
null,
null,
null,
null,
null,
null,
null,
null,
5,
null,
null,
null,
null,
null,
7,
null,
null,
null,
null,
null,
4,
null,
null,
null,
null,
null,
3,
null,
null,
null,
null,
null,
2,
null,
],
counter: [
null,
null,
null,
null,
0,
null,
null,
null,
null,
null,
null,
null,
null,
null,
2,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
0,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
2,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
0,
null,
null,
null,
null,
null,
null,
null,
null,
null,
],
bass: [0, null, null, null, 3, null, null, null, 5, null, null, null, 4, null, null, null],
// NO drums — cave ambiance
drums: null,
programs: { melody: 11, bass: 33, pad: 89, counter: 9 }, // Vibraphone, ElectricBass, PadWarm, Glockenspiel
},
// ── 3: Harbor Dawn — A major · 92 BPM · Waterside calm ──
{
root: ROOTS.A,
scale: "major",
bpm: 92,
bars: 16,
// A, D, E, A (I, IV, V, I) — peaceful, flowing
chords: [
[0, 2, 4], // A
[3, 5, 7], // D
[4, 6, 8], // E
[0, 2, 4], // A
],
// Gentle, flowing melody like water
melody: [
4,
null,
5,
4,
2,
null,
null,
null,
0,
2,
4,
null,
5,
7,
null,
5,
4,
null,
2,
null,
4,
5,
7,
null,
9,
null,
7,
5,
4,
null,
null,
null,
7,
null,
9,
7,
5,
null,
4,
null,
2,
4,
null,
5,
7,
null,
9,
null,
7,
null,
5,
null,
4,
2,
null,
0,
2,
null,
4,
null,
null,
null,
null,
null,
],
bass: [
0,
null,
0,
2,
3,
null,
3,
2,
4,
null,
4,
2,
0,
null,
2,
0,
0,
null,
2,
0,
3,
null,
2,
3,
4,
null,
2,
4,
0,
null,
null,
null,
],
// Light drums — ride cymbal feel
drums: {
kick: [1, 0, 0, 0, 0, 0, 1, 0],
snare: [0, 0, 1, 0, 0, 0, 0, 0],
ride: [1, 0, 1, 0, 1, 0, 1, 0],
hat: [0, 1, 0, 1, 0, 1, 0, 1],
},
programs: { melody: 73, bass: 33, pad: 48 }, // Flute, ElectricBass, Strings
},
// ── 4: Starboard Waltz — F major · 100 BPM · Jazz cruise ──
{
root: ROOTS.F,
scale: "major",
bpm: 100,
bars: 16,
// Fmaj7, Gm7, Am7, Bbmaj7 (I7, ii7, iii7, IV7) — jazzy extensions
chords: [
[0, 2, 4, 6], // Fmaj7 (F A C E)
[1, 3, 5, 7], // Gm7
[2, 4, 6, 8], // Am7
[3, 5, 7, 9], // Bbmaj7
],
// Jazzy, swung melody with chromatic passing tones
melody: [
4,
null,
5,
6,
null,
5,
4,
null,
2,
4,
null,
5,
6,
null,
7,
null,
9,
null,
7,
6,
5,
null,
4,
2,
4,
null,
null,
null,
5,
6,
7,
null,
9,
11,
null,
9,
7,
null,
6,
5,
4,
null,
6,
null,
7,
9,
null,
7,
6,
null,
5,
4,
2,
null,
4,
null,
5,
null,
null,
4,
2,
null,
null,
null,
],
counter: [
null,
null,
null,
null,
2,
null,
null,
null,
null,
null,
4,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
2,
null,
null,
null,
4,
null,
null,
null,
null,
null,
null,
null,
6,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
4,
null,
null,
null,
null,
null,
null,
null,
null,
null,
2,
null,
null,
null,
null,
null,
4,
null,
],
bass: [
0,
null,
2,
4,
1,
null,
3,
1,
2,
null,
4,
2,
3,
null,
1,
3,
0,
2,
0,
null,
1,
null,
3,
1,
2,
null,
0,
2,
3,
null,
1,
null,
],
// Swung jazz drums — ride-driven, brushy
drums: {
kick: [1, 0, 0, 0, 0, 0, 1, 0],
snare: [0, 0, 0, 1, 0, 0, 0, 1],
ride: [1, 0, 1, 1, 1, 0, 1, 1],
hat: [0, 0, 0, 0, 0, 1, 0, 0],
},
programs: { melody: 4, bass: 33, pad: 0, counter: 11 }, // ElectricPiano, ElectricBass, Piano, Vibraphone
},
// ── 5: Phantom Bells — B diminished · 48 BPM · Haunting ──
{
root: ROOTS.B,
scale: "diminished",
bpm: 48,
bars: 16,
// Dissonant diminished clusters — eerie, unsettling
chords: [
[0, 2, 4], // Bdim cluster
[1, 3, 5], // C#dim cluster
[0, 3, 6], // tritone spacing
[1, 4, 7], // tritone spacing
],
// Haunting, sparse — ghost-like fragments
melody: [
4,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
5,
null,
null,
null,
null,
null,
3,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
2,
null,
null,
null,
null,
null,
null,
null,
null,
null,
6,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
4,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
3,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
5,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
2,
null,
null,
null,
null,
null,
],
counter: [
null,
null,
null,
null,
null,
null,
0,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
1,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
0,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
1,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
],
bass: [0, null, null, null, 1, null, null, null, 0, null, null, null, 1, null, null, null],
// NO drums — eerie silence
drums: null,
programs: { melody: 88, bass: 33, pad: 89, counter: 9 }, // PadNewAge, ElectricBass, PadWarm, Glockenspiel
},
// ── 6: Golden Savanna — G major · 104 BPM · Tropical ──
{
root: ROOTS.G,
scale: "major",
bpm: 104,
bars: 16,
// G, C, D, Em (I, IV, V, vi) — bright tropical
chords: [
[0, 2, 4], // G (G B D)
[3, 5, 7], // C (C E G)
[4, 6, 8], // D (D F# A)
[5, 7, 9], // Em (E G B)
],
// Bouncy, tropical marimba melody
melody: [
4,
5,
7,
null,
9,
7,
5,
4,
2,
4,
5,
7,
null,
9,
null,
7,
5,
4,
null,
2,
4,
5,
7,
9,
11,
null,
9,
7,
5,
null,
4,
null,
7,
9,
11,
null,
9,
7,
5,
null,
4,
5,
7,
null,
9,
11,
9,
7,
5,
null,
4,
2,
0,
2,
4,
null,
5,
7,
null,
9,
7,
5,
4,
null,
],
bass: [
0,
null,
0,
2,
3,
null,
3,
2,
4,
null,
4,
2,
5,
null,
4,
2,
0,
2,
0,
null,
3,
null,
2,
3,
4,
2,
4,
null,
5,
null,
4,
2,
],
// Lively tropical drums — lots of energy
drums: {
kick: [1, 0, 0, 1, 1, 0, 0, 1],
snare: [0, 0, 1, 0, 0, 0, 1, 0],
hat: [1, 1, 1, 1, 1, 1, 1, 1],
openHat: [0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
crash: [
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
],
},
programs: { melody: 12, bass: 33, pad: 25 }, // Marimba, ElectricBass, AcousticGuitar
},
// ── 7: Ember Coast — E blues · 88 BPM · Volcanic heat ──
{
root: ROOTS.E,
scale: "blues",
bpm: 88,
bars: 16,
// Blues shuffle: E7, A7, B7 (I7, IV7, V7)
chords: [
[0, 2, 4], // E blues tonic
[0, 2, 4], // E blues tonic
[2, 3, 5], // A7 area
[3, 4, 5], // B7 area
],
// Hot, bluesy melody — bends and licks
melody: [
4,
3,
2,
null,
0,
2,
3,
null,
4,
null,
5,
4,
3,
null,
2,
0,
2,
3,
4,
null,
5,
null,
4,
3,
2,
null,
null,
0,
2,
3,
4,
null,
5,
null,
4,
3,
2,
null,
3,
4,
5,
4,
3,
null,
2,
0,
null,
2,
3,
null,
4,
5,
null,
4,
3,
2,
0,
null,
null,
null,
2,
null,
3,
null,
],
bass: [
0,
null,
0,
2,
0,
null,
2,
0,
2,
null,
3,
2,
3,
null,
2,
0,
0,
2,
0,
null,
0,
null,
2,
0,
2,
null,
0,
2,
3,
null,
2,
null,
],
// Shuffling blues drums
drums: {
kick: [1, 0, 0, 1, 1, 0, 0, 0],
snare: [0, 0, 1, 0, 0, 0, 1, 0],
hat: [1, 0, 1, 1, 1, 0, 1, 1],
ride: [0, 1, 0, 0, 0, 1, 0, 0],
},
programs: { melody: 29, bass: 33, pad: 4 }, // OverdrivenGuitar, ElectricBass, ElectricPiano
},
// ── 8: Iron Summit — D minor · 112 BPM · Epic ascent ──
{
root: ROOTS.D,
scale: "minor",
bpm: 112,
bars: 16,
// Dm, Bb, C, Dm (i, bVI, bVII, i) — epic, driving
chords: [
[0, 2, 4], // Dm
[5, 7, 9], // Bb
[6, 8, 10], // C
[0, 2, 4], // Dm
],
// Intense, driving melody — ascending phrases
melody: [
0,
2,
4,
5,
7,
null,
5,
4,
2,
4,
5,
7,
9,
null,
7,
5,
4,
5,
7,
9,
10,
null,
9,
7,
5,
null,
4,
2,
0,
null,
null,
null,
7,
9,
10,
null,
12,
10,
9,
7,
5,
7,
9,
null,
10,
12,
10,
9,
7,
null,
5,
4,
2,
4,
5,
7,
9,
null,
7,
5,
4,
null,
2,
null,
],
counter: [
null,
null,
null,
null,
null,
null,
null,
null,
4,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
7,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
5,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
4,
null,
null,
null,
],
bass: [
0,
null,
0,
2,
5,
null,
5,
4,
6,
null,
6,
4,
0,
null,
2,
0,
0,
2,
0,
null,
5,
null,
4,
5,
6,
null,
4,
6,
0,
null,
2,
0,
],
// Intense, driving drums — double kick feel
drums: {
kick: [1, 0, 1, 0, 1, 0, 1, 0],
snare: [0, 0, 1, 0, 0, 0, 1, 0],
hat: [1, 1, 1, 1, 1, 1, 1, 1],
crash: [
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0,
],
},
programs: { melody: 56, bass: 38, pad: 48, counter: 80 }, // Trumpet, SynthBass, Strings, SynthLeadSquare
},
// ── 9: Marble Hall — A major · 96 BPM · Triumphant ──
{
root: ROOTS.A,
scale: "major",
bpm: 96,
bars: 16,
// A, D, E, F#m, D, E, A, A (I, IV, V, vi, IV, V, I, I) — regal, triumphant
chords: [
[0, 2, 4], // A
[3, 5, 7], // D
[4, 6, 8], // E
[5, 7, 9], // F#m
[3, 5, 7], // D
[4, 6, 8], // E
[0, 2, 4], // A
[0, 2, 4], // A
],
// Triumphant, regal melody — fanfare-like
melody: [
4,
null,
4,
5,
7,
null,
9,
null,
11,
null,
9,
7,
5,
null,
null,
null,
7,
null,
9,
11,
12,
null,
11,
9,
7,
null,
5,
null,
4,
null,
null,
null,
9,
null,
11,
12,
14,
null,
12,
11,
9,
null,
7,
null,
9,
11,
null,
9,
7,
null,
5,
4,
2,
null,
4,
5,
7,
null,
null,
null,
null,
null,
null,
null,
],
counter: [
null,
null,
null,
null,
2,
null,
null,
null,
null,
null,
null,
null,
null,
null,
4,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
2,
null,
null,
null,
null,
null,
4,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
null,
2,
null,
null,
null,
null,
null,
4,
null,
null,
null,
null,
null,
null,
null,
],
bass: [
0,
null,
0,
2,
3,
null,
3,
2,
4,
null,
4,
2,
5,
null,
4,
2,
3,
null,
3,
2,
4,
null,
4,
2,
0,
null,
2,
0,
0,
null,
0,
null,
],
// Full, majestic drums
drums: {
kick: [1, 0, 0, 1, 1, 0, 0, 0],
snare: [0, 0, 1, 0, 0, 0, 1, 0],
hat: [1, 1, 1, 1, 1, 1, 1, 1],
ride: [1, 0, 1, 0, 1, 0, 1, 0],
crash: [
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0,
],
},
programs: { melody: 56, bass: 33, pad: 48, counter: 0 }, // Trumpet, ElectricBass, Strings, Piano
},
];
// --------------- Visualization & Tab Helpers ---------------
function stopAllPlayers() {
document.querySelectorAll("midi-player").forEach((p) => {
try {
p.stop();
} catch (_) {}
});
}
function zoomVisualizer(viz) {
const svg = viz.querySelector("svg");
if (!svg) return;
const rects = svg.querySelectorAll("rect[data-note]");
if (!rects.length) return;
let minY = Infinity,
maxY = -Infinity;
rects.forEach((r) => {
const y = parseFloat(r.getAttribute("y") || 0),
h = parseFloat(r.getAttribute("height") || 0);
if (y < minY) minY = y;
if (y + h > maxY) maxY = y + h;
});
if (!isFinite(minY)) return;
const vb = svg.getAttribute("viewBox");
if (!vb) return;
const [vx, , vw, vh] = vb.split(" ").map(Number);
const m = vh * 0.05;
svg.setAttribute(
"viewBox",
`${vx} ${Math.max(0, minY - m)} ${vw} ${Math.min(vh, maxY - minY + m * 2)}`
);
svg.setAttribute("preserveAspectRatio", "xMidYMid meet");
}
function observeViz(viz) {
const obs = new MutationObserver(() => {
const svg = viz.querySelector("svg");
if (svg && svg.querySelectorAll("rect[data-note]").length > 0) {
zoomVisualizer(viz);
obs.disconnect();
}
});
obs.observe(viz, { childList: true, subtree: true, attributes: true });
zoomVisualizer(viz);
}
// --------------- Initialization ---------------
document.addEventListener("DOMContentLoaded", () => {
// Generate and assign NoteSequences to each player/visualizer
tracks.forEach((cfg, i) => {
const ns = generate(cfg);
const section = document.getElementById(`piece-p3-${i}`);
if (!section) return;
const player = section.querySelector("midi-player");
const viz = document.querySelector(`#viz-${i}`);
if (viz) {
viz.noteSequence = ns;
}
if (player) {
player.noteSequence = ns;
}
});
// Observe all visualizers for zoom
document.querySelectorAll("midi-visualizer").forEach(observeViz);
// Tab switching
document.querySelectorAll(".tabs").forEach((nav) => {
const tabs = nav.querySelectorAll(".tab");
tabs.forEach((tab) => {
tab.addEventListener("click", () => {
stopAllPlayers();
tabs.forEach((t) => t.classList.remove("active"));
tab.classList.add("active");
const parent = tab.closest(".collection") || document.body;
parent.querySelectorAll(".piece").forEach((p) => p.classList.remove("active"));
const target = document.getElementById(`piece-${tab.dataset.track}`);
if (target) {
target.classList.add("active");
target.querySelectorAll("midi-visualizer").forEach(observeViz);
}
});
});
});
});<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Clausic — Free Compositions</title>
<link rel="stylesheet" href="style.css">
<script src="https://cdn.jsdelivr.net/combine/npm/tone@14.7.58,npm/@magenta/music@1.23.1/es6/core.js,npm/html-midi-player@1.5.0"></script>
</head>
<body>
<header>
<h1>Clausic — Free Compositions</h1>
<p class="subtitle">10 original compositions across diverse moods and genres</p>
</header>
<nav class="tabs" role="tablist">
<button class="tab active" data-track="p3-0">Open Road</button>
<button class="tab" data-track="p3-1">Emerald Canopy</button>
<button class="tab" data-track="p3-2">Hollow Peak</button>
<button class="tab" data-track="p3-3">Harbor Dawn</button>
<button class="tab" data-track="p3-4">Starboard Waltz</button>
<button class="tab" data-track="p3-5">Phantom Bells</button>
<button class="tab" data-track="p3-6">Golden Savanna</button>
<button class="tab" data-track="p3-7">Ember Coast</button>
<button class="tab" data-track="p3-8">Iron Summit</button>
<button class="tab" data-track="p3-9">Marble Hall</button>
</nav>
<section class="piece active" id="piece-p3-0">
<h2>Open Road</h2>
<p class="meta">Adventure begins · C major · 120 BPM</p>
<details class="gen-details">
<summary>View generation code</summary>
<div class="gen-code"><pre><span class="comment">// Open Road — C major · 120 BPM · Adventure begins</span>
{
<span class="key">root</span>: <span class="str">"C"</span>, <span class="key">scale</span>: <span class="str">"major"</span>, <span class="key">bpm</span>: <span class="val">120</span>, <span class="key">bars</span>: <span class="val">16</span>,
<span class="comment">// C, F, G, C (I, IV, V, I) — classic adventure</span>
<span class="key">chords</span>: [[0,2,4], [3,5,7], [4,6,8], [0,2,4]],
<span class="comment">// Bright, bouncy, adventurous melody</span>
<span class="key">melody</span>: [4,5,7,null, 7,9,7,5, 4,null,2,4, 5,null,7,null, ...],
<span class="key">drums</span>: { <span class="key">kick</span>: [1,0,0,1,1,0,0,0], <span class="key">snare</span>: [0,0,1,0,0,0,1,0], <span class="key">hat</span>: [1,1,1,1,1,1,1,1] },
<span class="key">programs</span>: { <span class="key">melody</span>: <span class="val">0</span> <span class="comment">/* Piano */</span>, <span class="key">bass</span>: <span class="val">33</span> <span class="comment">/* ElectricBass */</span>, <span class="key">pad</span>: <span class="val">48</span> <span class="comment">/* Strings */</span> }
}</pre></div>
</details>
<midi-visualizer type="piano-roll" id="viz-0"></midi-visualizer>
<midi-player sound-font visualizer="#viz-0"></midi-player>
</section>
<section class="piece" id="piece-p3-1">
<h2>Emerald Canopy</h2>
<p class="meta">Mystery · E minor · 68 BPM</p>
<details class="gen-details">
<summary>View generation code</summary>
<div class="gen-code"><pre><span class="comment">// Emerald Canopy — E minor · 68 BPM · Mystery</span>
{
<span class="key">root</span>: <span class="str">"E"</span>, <span class="key">scale</span>: <span class="str">"minor"</span>, <span class="key">bpm</span>: <span class="val">68</span>, <span class="key">bars</span>: <span class="val">16</span>,
<span class="comment">// Em, Am, Bm, Em (i, iv, v, i) — dark, mysterious</span>
<span class="key">chords</span>: [[0,2,4], [3,5,7], [4,6,8], [0,2,4]],
<span class="comment">// Sparse, eerie melody with lots of rests — forest sounds</span>
<span class="key">melody</span>: [4,null,null,null, 5,null,null,null, 3,null,2,null, ...],
<span class="comment">// Counter-melody: glockenspiel — very sparse ghostly echoes</span>
<span class="key">counter</span>: [null,null,0,null, null,null,null,null, ...],
<span class="key">drums</span>: { <span class="key">kick</span>: [1,0,0,0,0,0,0,0], <span class="key">hat</span>: [sparse] },
<span class="key">programs</span>: { <span class="key">melody</span>: <span class="val">73</span> <span class="comment">/* Flute */</span>, <span class="key">bass</span>: <span class="val">33</span>, <span class="key">pad</span>: <span class="val">88</span> <span class="comment">/* PadNewAge */</span>, <span class="key">counter</span>: <span class="val">9</span> <span class="comment">/* Glockenspiel */</span> }
}</pre></div>
</details>
<midi-visualizer type="piano-roll" id="viz-1"></midi-visualizer>
<midi-player sound-font visualizer="#viz-1"></midi-player>
</section>
<section class="piece" id="piece-p3-2">
<h2>Hollow Peak</h2>
<p class="meta">Dark caverns · D minor · 56 BPM</p>
<details class="gen-details">
<summary>View generation code</summary>
<div class="gen-code"><pre><span class="comment">// Hollow Peak — D minor · 56 BPM · Dark caverns</span>
{
<span class="key">root</span>: <span class="str">"D"</span>, <span class="key">scale</span>: <span class="str">"minor"</span>, <span class="key">bpm</span>: <span class="val">56</span>, <span class="key">bars</span>: <span class="val">16</span>,
<span class="comment">// Dm, Gm, Bb, A (i, iv, bVI, V) — dark, cavernous</span>
<span class="key">chords</span>: [[0,2,4], [3,5,7], [5,7,9], [4,6,8]],
<span class="comment">// Very slow, echoing, sparse — dripping cave melody</span>
<span class="key">melody</span>: [7,null,null,null, null,null,null,null, null,null,5,null, ...],
<span class="key">counter</span>: [glockenspiel echoes],
<span class="key">drums</span>: <span class="val">null</span> <span class="comment">// NO drums — cave ambiance</span>,
<span class="key">programs</span>: { <span class="key">melody</span>: <span class="val">11</span> <span class="comment">/* Vibraphone */</span>, <span class="key">pad</span>: <span class="val">89</span> <span class="comment">/* PadWarm */</span>, <span class="key">counter</span>: <span class="val">9</span> <span class="comment">/* Glockenspiel */</span> }
}</pre></div>
</details>
<midi-visualizer type="piano-roll" id="viz-2"></midi-visualizer>
<midi-player sound-font visualizer="#viz-2"></midi-player>
</section>
<section class="piece" id="piece-p3-3">
<h2>Harbor Dawn</h2>
<p class="meta">Waterside calm · A major · 92 BPM</p>
<details class="gen-details">
<summary>View generation code</summary>
<div class="gen-code"><pre><span class="comment">// Harbor Dawn — A major · 92 BPM · Waterside calm</span>
{
<span class="key">root</span>: <span class="str">"A"</span>, <span class="key">scale</span>: <span class="str">"major"</span>, <span class="key">bpm</span>: <span class="val">92</span>, <span class="key">bars</span>: <span class="val">16</span>,
<span class="comment">// A, D, E, A (I, IV, V, I) — peaceful, flowing</span>
<span class="key">chords</span>: [[0,2,4], [3,5,7], [4,6,8], [0,2,4]],
<span class="comment">// Gentle, flowing melody like water</span>
<span class="key">melody</span>: [4,null,5,4, 2,null,null,null, 0,2,4,null, 5,7,null,5, ...],
<span class="key">drums</span>: { <span class="key">kick</span>: [1,0,0,0,0,0,1,0], <span class="key">snare</span>: [0,0,1,0,0,0,0,0], <span class="key">ride</span>: [1,0,1,0,1,0,1,0] },
<span class="key">programs</span>: { <span class="key">melody</span>: <span class="val">73</span> <span class="comment">/* Flute */</span>, <span class="key">bass</span>: <span class="val">33</span> <span class="comment">/* ElectricBass */</span>, <span class="key">pad</span>: <span class="val">48</span> <span class="comment">/* Strings */</span> }
}</pre></div>
</details>
<midi-visualizer type="piano-roll" id="viz-3"></midi-visualizer>
<midi-player sound-font visualizer="#viz-3"></midi-player>
</section>
<section class="piece" id="piece-p3-4">
<h2>Starboard Waltz</h2>
<p class="meta">Jazz cruise · F major · 100 BPM</p>
<details class="gen-details">
<summary>View generation code</summary>
<div class="gen-code"><pre><span class="comment">// Starboard Waltz — F major · 100 BPM · Jazz cruise</span>
{
<span class="key">root</span>: <span class="str">"F"</span>, <span class="key">scale</span>: <span class="str">"major"</span>, <span class="key">bpm</span>: <span class="val">100</span>, <span class="key">bars</span>: <span class="val">16</span>,
<span class="comment">// Fmaj7, Gm7, Am7, Bbmaj7 (I7, ii7, iii7, IV7) — jazzy extensions</span>
<span class="key">chords</span>: [[0,2,4,6], [1,3,5,7], [2,4,6,8], [3,5,7,9]],
<span class="comment">// Jazzy, swung melody with chromatic passing tones</span>
<span class="key">melody</span>: [4,null,5,6, null,5,4,null, 2,4,null,5, 6,null,7,null, ...],
<span class="key">counter</span>: [vibraphone],
<span class="key">drums</span>: { <span class="key">kick</span>: [1,0,0,0,0,0,1,0], <span class="key">snare</span>: [0,0,0,1,0,0,0,1], <span class="key">ride</span>: [1,0,1,1,1,0,1,1] },
<span class="key">programs</span>: { <span class="key">melody</span>: <span class="val">4</span> <span class="comment">/* ElectricPiano */</span>, <span class="key">pad</span>: <span class="val">0</span> <span class="comment">/* Piano */</span>, <span class="key">counter</span>: <span class="val">11</span> <span class="comment">/* Vibraphone */</span> }
}</pre></div>
</details>
<midi-visualizer type="piano-roll" id="viz-4"></midi-visualizer>
<midi-player sound-font visualizer="#viz-4"></midi-player>
</section>
<section class="piece" id="piece-p3-5">
<h2>Phantom Bells</h2>
<p class="meta">Haunting · B diminished · 48 BPM</p>
<details class="gen-details">
<summary>View generation code</summary>
<div class="gen-code"><pre><span class="comment">// Phantom Bells — B diminished · 48 BPM · Haunting</span>
{
<span class="key">root</span>: <span class="str">"B"</span>, <span class="key">scale</span>: <span class="str">"diminished"</span> <span class="val">[0,2,3,5,6,8,9,11]</span>, <span class="key">bpm</span>: <span class="val">48</span>, <span class="key">bars</span>: <span class="val">16</span>,
<span class="comment">// Dissonant diminished clusters — eerie, unsettling</span>
<span class="key">chords</span>: [[0,2,4], [1,3,5], [0,3,6], [1,4,7]],
<span class="comment">// Haunting, sparse — ghost-like fragments</span>
<span class="key">melody</span>: [4,null,null,null, null,null,null,null, null,null,null,null, 5,null,...],
<span class="key">drums</span>: <span class="val">null</span> <span class="comment">// NO drums — eerie silence</span>,
<span class="key">programs</span>: { <span class="key">melody</span>: <span class="val">88</span> <span class="comment">/* PadNewAge */</span>, <span class="key">pad</span>: <span class="val">89</span> <span class="comment">/* PadWarm */</span>, <span class="key">counter</span>: <span class="val">9</span> <span class="comment">/* Glockenspiel */</span> }
}</pre></div>
</details>
<midi-visualizer type="piano-roll" id="viz-5"></midi-visualizer>
<midi-player sound-font visualizer="#viz-5"></midi-player>
</section>
<section class="piece" id="piece-p3-6">
<h2>Golden Savanna</h2>
<p class="meta">Tropical · G major · 104 BPM</p>
<details class="gen-details">
<summary>View generation code</summary>
<div class="gen-code"><pre><span class="comment">// Golden Savanna — G major · 104 BPM · Tropical</span>
{
<span class="key">root</span>: <span class="str">"G"</span>, <span class="key">scale</span>: <span class="str">"major"</span>, <span class="key">bpm</span>: <span class="val">104</span>, <span class="key">bars</span>: <span class="val">16</span>,
<span class="comment">// G, C, D, Em (I, IV, V, vi) — bright tropical</span>
<span class="key">chords</span>: [[0,2,4], [3,5,7], [4,6,8], [5,7,9]],
<span class="comment">// Bouncy, tropical marimba melody</span>
<span class="key">melody</span>: [4,5,7,null, 9,7,5,4, 2,4,5,7, null,9,null,7, ...],
<span class="key">drums</span>: { <span class="key">kick</span>: [1,0,0,1,1,0,0,1], <span class="key">snare</span>: [0,0,1,0,0,0,1,0], <span class="key">hat</span>: [1,1,1,1,1,1,1,1] },
<span class="key">programs</span>: { <span class="key">melody</span>: <span class="val">12</span> <span class="comment">/* Marimba */</span>, <span class="key">bass</span>: <span class="val">33</span> <span class="comment">/* ElectricBass */</span>, <span class="key">pad</span>: <span class="val">25</span> <span class="comment">/* AcousticGuitar */</span> }
}</pre></div>
</details>
<midi-visualizer type="piano-roll" id="viz-6"></midi-visualizer>
<midi-player sound-font visualizer="#viz-6"></midi-player>
</section>
<section class="piece" id="piece-p3-7">
<h2>Ember Coast</h2>
<p class="meta">Volcanic heat · E blues · 88 BPM</p>
<details class="gen-details">
<summary>View generation code</summary>
<div class="gen-code"><pre><span class="comment">// Ember Coast — E blues · 88 BPM · Volcanic heat</span>
{
<span class="key">root</span>: <span class="str">"E"</span>, <span class="key">scale</span>: <span class="str">"blues"</span> <span class="val">[0,3,5,6,7,10]</span>, <span class="key">bpm</span>: <span class="val">88</span>, <span class="key">bars</span>: <span class="val">16</span>,
<span class="comment">// Blues shuffle: E7, A7, B7 (I7, IV7, V7)</span>
<span class="key">chords</span>: [[0,2,4], [0,2,4], [2,3,5], [3,4,5]],
<span class="comment">// Hot, bluesy melody — bends and licks</span>
<span class="key">melody</span>: [4,3,2,null, 0,2,3,null, 4,null,5,4, 3,null,2,0, ...],
<span class="key">drums</span>: { <span class="key">kick</span>: [1,0,0,1,1,0,0,0], <span class="key">snare</span>: [0,0,1,0,0,0,1,0], <span class="key">hat</span>: [1,0,1,1,1,0,1,1] },
<span class="key">programs</span>: { <span class="key">melody</span>: <span class="val">29</span> <span class="comment">/* OverdrivenGuitar */</span>, <span class="key">bass</span>: <span class="val">33</span>, <span class="key">pad</span>: <span class="val">4</span> <span class="comment">/* ElectricPiano */</span> }
}</pre></div>
</details>
<midi-visualizer type="piano-roll" id="viz-7"></midi-visualizer>
<midi-player sound-font visualizer="#viz-7"></midi-player>
</section>
<section class="piece" id="piece-p3-8">
<h2>Iron Summit</h2>
<p class="meta">Epic ascent · D minor · 112 BPM</p>
<details class="gen-details">
<summary>View generation code</summary>
<div class="gen-code"><pre><span class="comment">// Iron Summit — D minor · 112 BPM · Epic ascent</span>
{
<span class="key">root</span>: <span class="str">"D"</span>, <span class="key">scale</span>: <span class="str">"minor"</span>, <span class="key">bpm</span>: <span class="val">112</span>, <span class="key">bars</span>: <span class="val">16</span>,
<span class="comment">// Dm, Bb, C, Dm (i, bVI, bVII, i) — epic, driving</span>
<span class="key">chords</span>: [[0,2,4], [5,7,9], [6,8,10], [0,2,4]],
<span class="comment">// Intense, driving melody — ascending phrases</span>
<span class="key">melody</span>: [0,2,4,5, 7,null,5,4, 2,4,5,7, 9,null,7,5, ...],
<span class="key">counter</span>: [SynthLeadSquare accents],
<span class="key">drums</span>: { <span class="key">kick</span>: [1,0,1,0,1,0,1,0], <span class="key">snare</span>: [0,0,1,0,0,0,1,0], <span class="key">hat</span>: [1,1,1,1,1,1,1,1] },
<span class="key">programs</span>: { <span class="key">melody</span>: <span class="val">56</span> <span class="comment">/* Trumpet */</span>, <span class="key">bass</span>: <span class="val">38</span> <span class="comment">/* SynthBass */</span>, <span class="key">pad</span>: <span class="val">48</span> <span class="comment">/* Strings */</span>, <span class="key">counter</span>: <span class="val">80</span> }
}</pre></div>
</details>
<midi-visualizer type="piano-roll" id="viz-8"></midi-visualizer>
<midi-player sound-font visualizer="#viz-8"></midi-player>
</section>
<section class="piece" id="piece-p3-9">
<h2>Marble Hall</h2>
<p class="meta">Champion throne · A major · 96 BPM</p>
<details class="gen-details">
<summary>View generation code</summary>
<div class="gen-code"><pre><span class="comment">// Marble Hall — A major · 96 BPM · Triumphant</span>
{
<span class="key">root</span>: <span class="str">"A"</span>, <span class="key">scale</span>: <span class="str">"major"</span>, <span class="key">bpm</span>: <span class="val">96</span>, <span class="key">bars</span>: <span class="val">16</span>,
<span class="comment">// A, D, E, F#m, D, E, A, A (I, IV, V, vi, IV, V, I, I) — regal</span>
<span class="key">chords</span>: [[0,2,4], [3,5,7], [4,6,8], [5,7,9], [3,5,7], [4,6,8], [0,2,4], [0,2,4]],
<span class="comment">// Triumphant, regal melody — fanfare-like</span>
<span class="key">melody</span>: [4,null,4,5, 7,null,9,null, 11,null,9,7, 5,null,null,null, ...],
<span class="key">counter</span>: [Piano accents],
<span class="key">drums</span>: { <span class="key">kick</span>: [1,0,0,1,1,0,0,0], <span class="key">snare</span>: [0,0,1,0,0,0,1,0], <span class="key">hat</span>: [1,1,1,1,1,1,1,1], <span class="key">ride</span>: [1,0,1,0,1,0,1,0] },
<span class="key">programs</span>: { <span class="key">melody</span>: <span class="val">56</span> <span class="comment">/* Trumpet */</span>, <span class="key">bass</span>: <span class="val">33</span> <span class="comment">/* ElectricBass */</span>, <span class="key">pad</span>: <span class="val">48</span> <span class="comment">/* Strings */</span>, <span class="key">counter</span>: <span class="val">0</span> <span class="comment">/* Piano */</span> }
}</pre></div>
</details>
<midi-visualizer type="piano-roll" id="viz-9"></midi-visualizer>
<midi-player sound-font visualizer="#viz-9"></midi-player>
</section>
<script src="script.js"></script>
</body>
</html>Clausic — Free Compositions
10 original MIDI compositions across diverse moods and genres, from the bright Open Road to the triumphant Marble Hall.