virtual_keyboard / keyboard.html
github-actions[bot]
Deploy to HF Spaces
2e0c2a7
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Virtual MIDI Keyboard</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<link rel="stylesheet" href="/file=static/styles.css" />
</head>
<body>
<div class="app-shell">
<div class="welcome-header">
<div class="welcome-header-inner">
<h1 class="synthia-logo">SYNTH<em>IA</em></h1>
<p class="welcome-intro">Start a jam with AI</p>
</div>
<button id="settingsToggleBtn" class="settings-toggle-btn" aria-label="Open settings">&#9881;</button>
</div>
<aside id="settingsPanel" class="settings-panel">
<div class="settings-panel-header">
<span class="settings-panel-title">&#9881; Settings</span>
<button id="settingsCloseBtn" class="settings-close-btn">&times;</button>
</div>
<div class="settings-panel-body">
<div class="settings-control-grid">
<label class="control-item" data-control-id="instrument">
Instrument
<select id="instrumentSelect" data-description="Choose the synth sound for your keyboard">
<option value="synth" data-tooltip="Bright, modern electronic sound">Synth</option>
<option value="piano" data-tooltip="Classic acoustic piano tone">Piano</option>
<option value="organ" selected data-tooltip="Rich, warm organ pipes">Organ</option>
<option value="bass" data-tooltip="Deep, resonant bass tones">Bass</option>
<option value="pluck" data-tooltip="Percussive plucked string sound">Pluck</option>
<option value="fm" data-tooltip="Complex, bell-like FM synthesis">FM Synth</option>
</select>
</label>
<label class="control-item" data-control-id="aiVoice">
AI Voice
<select id="aiInstrumentSelect" data-description="Select which instrument sound the AI uses when it responds">
<option value="synth" selected data-tooltip="Bright, modern electronic sound">Synth</option>
<option value="piano" data-tooltip="Classic acoustic piano tone">Piano</option>
<option value="organ" data-tooltip="Rich, warm organ pipes">Organ</option>
<option value="bass" data-tooltip="Deep, resonant bass tones">Bass</option>
<option value="pluck" data-tooltip="Percussive plucked string sound">Pluck</option>
<option value="fm" data-tooltip="Complex, bell-like FM synthesis">FM Synth</option>
</select>
</label>
<label class="control-item" data-control-id="userBars">
User Bars
<select id="userBarsSelect" data-description="Bars available for your call during game mode">
<option value="1" data-tooltip="One bar call window at 75 BPM">1 bar</option>
<option value="2" data-tooltip="Two bar call window at 75 BPM" selected>2 bars</option>
</select>
</label>
<label class="control-item" data-control-id="aiBars">
AI Bars
<select id="aiBarsSelect" data-description="Bars available for AI response during game mode">
<option value="1" data-tooltip="One bar AI response window at 75 BPM">1 bar</option>
<option value="2" data-tooltip="Two bar AI response window at 75 BPM" selected>2 bars</option>
</select>
</label>
<label class="control-item" data-control-id="engine">
Engine
<select id="engineSelect" data-description="Your generation model">
<option value="parrot" data-tooltip="Repeats your exact melody — useful for practicing or creating canon patterns">Parrot</option>
<option value="reverse_parrot" data-tooltip="Plays your melody backward — creates mirror images and harmonic inversions">Reverse Parrot</option>
<option value="godzilla_continue" data-tooltip="MIDI transformer that generates new musical continuations">Godzilla</option>
</select>
</label>
<label class="control-item" id="runtimeControl" data-control-id="runtime">
Runtime
<select id="runtimeSelect" data-description="Choose where the AI runs for faster or more reliable performance">
<option value="cpu" data-tooltip="Slower but always available, runs on CPU">CPU</option>
<option value="gpu" data-tooltip="Faster when available, uses ZeroGPU for inference">ZeroGPU</option>
<option value="auto" data-tooltip="Automatically prefers GPU if available, falls back to CPU" selected>Auto (GPU then CPU)</option>
</select>
</label>
<label class="control-item" data-control-id="aiStyle">
AI Style
<select id="responseStyleSelect" data-description="Applies post-processing styling to shape the AI's melodic character">
<option value="melodic" data-tooltip="Smooth, singable melodies with minimal pitch leaps">Melodic</option>
<option value="motif_echo" data-tooltip="Echoes the first couple notes from your input at the end of the response">Motif Echo</option>
<option value="playful" data-tooltip="Bouncy alternating pitch shifts for a whimsical, playful character">Playful</option>
</select>
</label>
<label class="control-item" data-control-id="responseMode">
Response Mode
<select id="responseModeSelect" data-description="Processing pipeline & creativity level">
<option value="raw_godzilla" data-tooltip="Pure AI output, maximum creativity (temperature=1.0, unpredictable)" selected>Raw Godzilla</option>
<option value="current_pipeline" data-tooltip="Balanced mode with AI Style applied, moderate creativity (temperature=0.9)">Current Pipeline</option>
<option value="musical_polish" data-tooltip="Refined with scale quantization and rhythm adjustment (temperature=0.85)">Musical Polish</option>
</select>
</label>
<label class="control-item" data-control-id="responseLength">
Response Length
<select id="responseLengthSelect" data-description="How many notes the AI generates in each response">
<option value="short" data-tooltip="8 notes - quick, snappy responses" selected>Short</option>
<option value="medium" data-tooltip="14 notes - balanced response length">Medium</option>
<option value="long" data-tooltip="20 notes - longer, more developed phrases">Long</option>
<option value="extended" data-tooltip="28 notes - extended musical conversations">Extended</option>
</select>
</label>
<label class="control-item" data-control-id="quantization">
AI Quantization
<select id="quantizationSelect" data-description="Quantization grid applied to AI notes during game mode playback">
<option value="sixteenth" data-tooltip="Quantize AI starts/ends to 16th-note timing">16th Notes</option>
<option value="eighth" data-tooltip="Quantize AI starts/ends to 8th-note timing">8th Notes</option>
<option value="none" selected data-tooltip="Keep AI timing unquantized (still clamped to bar length)">No Quantization</option>
</select>
</label>
</div>
</div>
</aside>
<div id="settingsBackdrop" class="settings-backdrop"></div>
<div id="mainContainer">
<div class="keyboard-section card">
<div id="keyboard"></div>
<!-- Required hidden elements (waitForKeyboardUIElements + bridge) -->
<button id="recordBtn" style="display:none">Record</button>
<button id="stopBtn" style="display:none" disabled>Stop</button>
<button id="playbackBtn" style="display:none" disabled>Playback</button>
<button id="saveBtn" style="display:none" disabled>Save MIDI</button>
<button id="panicBtn" style="display:none">Panic</button>
<input type="checkbox" id="keyboardToggle" style="display:none" checked>
<button id="gameStartBtn" style="display:none">Start Game</button>
<button id="gameStopBtn" style="display:none" disabled>Stop Game</button>
<span id="status" style="display:none">Idle</span>
<!-- Visible game toggle -->
<div class="game-btn-row">
<button id="gameToggleBtn" class="btn btn-game btn-game-toggle">Start</button>
</div>
</div>
<div class="turn-grid-section card">
<div class="turn-grid-header">
<h4>TURN GRID</h4>
<span id="gridPhaseBadge">Idle</span>
</div>
<div class="turn-grid-body">
<div class="turn-grid-lane user-lane">
<div class="turn-grid-lane-header">
<span class="lane-label">USER</span>
<span id="userGridMeta" class="lane-meta">2 bars</span>
</div>
<canvas id="userGridCanvas" class="turn-grid-canvas" aria-label="User turn note grid"></canvas>
</div>
<div class="turn-grid-lane ai-lane">
<div class="turn-grid-lane-header">
<span class="lane-label">AI</span>
<span id="aiGridMeta" class="lane-meta">2 bars</span>
</div>
<canvas id="aiGridCanvas" class="turn-grid-canvas" aria-label="AI turn note grid"></canvas>
</div>
</div>
</div>
<div class="monitor-section card">
<div class="terminal-header">
<h4>MIDI MONITOR</h4>
<div class="btn-tooltip-wrapper">
<button id="clearTerminal" class="btn btn-secondary">Clear</button>
<div class="btn-tooltip">Clear all MIDI events from the monitor.</div>
</div>
</div>
<div id="terminal"></div>
</div>
</div>
<div id="countdownOverlay" aria-live="polite" aria-atomic="true">
<div id="countdownText"></div>
</div>
</div>
<!-- External Dependencies -->
<script src="https://unpkg.com/tone@next/build/Tone.js"></script>
<!-- Application Logic -->
<script src="/file=static/keyboard.js"></script>
</body>
</html>