oneshotlm
Compare all models on this prompt →

Drum machine · qwen3-coder-flash

Build a 16-step drum machine with a clickable grid for kick, snare, hi-hat, and clap, all sounds synthesized with the Web Audio API, plus play/stop and an adjustable BPM.

⚠ no runnable output

This one-shot run produced no runnable artifact.

agent produced no index.html

The transcript below shows what the model did — read it to see why the one shot fell short.

transcript · 2 messages
user

Build a 16-step drum machine with a clickable grid for kick, snare, hi-hat, and clap, all sounds synthesized with the Web Audio API, plus play/stop and an adjustable BPM.

assistant

```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>16-Step Drum Machine</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background: linear-gradient(135deg, #1a1a2e, #16213e); min-height: 100vh; display: flex; justify-content: center; align-items: center; padding: 20px; color: #fff; } .container { background: rgba(0, 0, 0, 0.7); border-radius: 20px; padding: 30px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5); width: 100%; max-width: 800px; backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.1); } h1 { text-align: center; margin-bottom: 25px; font-size: 2.5rem; color: #4cc9f0; text-shadow: 0 0 10px rgba(76, 201, 240, 0.5); } .controls { display: flex; justify-content: space-between; align-items: center; margin-bottom: 30px; background: rgba(30, 30, 46, 0.8); padding: 20px; border-radius: 15px; } .bpm-control { display: flex; flex-direction: column; align-items: center; } .bpm-label { margin-bottom: 10px; font-size: 1.1rem; } .bpm-slider { width: 200px; height: 10px; -webkit-appearance: none; background: #3a3a5a; border-radius: 5px; outline: none; } .bpm-slider::-webkit-slider-thumb { -webkit-appearance: none; width: 25px; height: 25px; border-radius: 50%; background: #4cc9f0; cursor: pointer; box-shadow: 0 0 10px rgba(76, 201, 240, 0.7); } .bpm-value { margin-top: 5px; font-size: 1.2rem; font-weight: bold; color: #f72585; } .playback-controls { display: flex; gap: 15px; } button { padding: 12px 25px; font-size: 1.1rem; border: none; border-radius: 50px; cursor: pointer; transition: all 0.3s ease; font-weight: bold; background: #4361ee; color: white; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3); } button:hover { transform: translateY(-3px); box-shadow: 0 6px 15px rgba(0, 0, 0, 0.4); } button:active { transform: translateY(1px); } #stopBtn { background: #f72585; } #stopBtn:hover { background: #d1186c; } .drum-machine { display: grid; grid-template-columns: 150px repeat(16, 1fr); gap: 5px; margin-bottom: 30px; } .drum-name { display: flex; align-items: center; justify-content: center; background: rgba(30, 30, 46, 0.8); padding: 15px; border-radius: 10px; font-weight: bold; font-size: 1.1rem; } .step { aspect-ratio: 1; background: rgba(30, 30, 46, 0.8); border-radius: 8px; cursor: pointer; transition: all 0.2s ease; display: flex; align-items: center; justify-content: center; font-size: 1.5rem; box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.5); } .step.active { background: rgba(76, 201, 240, 0.7); box-shadow: 0 0 15px rgba(76, 201, 240, 0.7); } .step.kick.active { background: rgba(247, 37, 133, 0.7); box-shadow: 0 0 15px rgba(247, 37, 133, 0.7); } .step.snare.active { background: rgba(76, 201, 240, 0.7); box-shadow: 0 0 15px rgba(76, 201, 240, 0.7); } .step.hihat.active { background: rgba(110, 231, 183, 0.7); box-shadow: 0 0 15px rgba(110, 231, 183, 0.7); } .step.clap.active { background: rgba(255, 193, 7, 0.7); box-shadow: 0 0 15px rgba(255, 193, 7, 0.7); } .step:hover { transform: scale(1.05); } .step.active:hover { transform: scale(1.05); } .step-labels { display: grid; grid-template-columns: repeat(16, 1fr); gap: 5px; margin-top: 10px; } .step-number { display: flex; align-items: center; justify-content: center; font-size: 0.8rem; color: #aaa; } .visualizer { height: 100px; background: rgba(30, 30, 46, 0.8); border-radius: 10px; margin-top: 20px; overflow: hidden; position: relative; } .bar { position: absolute; bottom: 0; width: 8px; background: linear-gradient(to top, #4cc9f0, #4361ee); border-radius: 4px 4px 0 0; transition: height 0.1s ease; } .status { text-align: center; margin-top: 20px; font-size: 1.2rem; color: #4cc9f0; height: 30px; } @media (max-width: 768px) { .container { padding: 15px; } .drum-machine { grid-template-columns: 100px repeat(16, 1fr); } .controls { flex-direction: column; gap: 20px; } .bpm-slider { width: 150px; } } </style> </head> <body> <div class="container"> <h1>16-Step Drum Machine</h1> <div class="controls"> <div class="bpm-control"> <div class="bpm-label">BPM: <span id="bpmValue" class="bpm-value">120</span></div> <input type="range" min="60" max="180" value="120" class="bpm-slider" id="bpmSlider"> </div> <div class="playback-controls"> <button id="playBtn">Play</button> <button id="stopBtn">Stop</button> </div> </div> <div class="drum-machine"> <div class="drum-name">Kick</div> <div class="step kick" data-drum="kick" data-step="0"></div> <div class="step kick" data-drum="kick" data-step="1"></div> <div class="step kick" data-drum="kick" data-step="2"></div> <div class="step kick" data-drum="kick" data-step="3"></div> <div class="step kick" data-drum="kick" data-step="4"></div> <div class="step kick" data-drum="kick" data-step="5"></div> <div class="step kick" data-drum="kick" data-step="6"></div> <div class="step kick" data-drum="kick" data-step="7"></div> <div class="step kick" data-drum="kick" data-step="8"></div> <div class="step kick" data-drum="kick" data-step="9"></div> <div class="step kick" data-drum="kick" data-step="10"></div> <div class="step kick" data-drum="kick" data-step="11"></div> <div class="step kick" data-drum="kick" data-step="12"></div> <div class="step kick" data-drum="kick" data-step="13"></div> <div class="step kick" data-drum="kick" data-step="14"></div> <div class="step kick" data-drum="kick" data-step="15"></div> <div class="drum-name">Snare</div> <div class="step snare" data-drum="snare" data-step="0"></div> <div class="step snare" data-drum="snare" data-step="1"></div> <div class="step snare" data-drum="snare" data-step="2"></div> <div class="step snare" data-drum="snare" data-step="3"></div> <div class="step snare" data-drum="snare" data-step="4"></div> <div class="step snare" data-drum="snare" data-step="5"></div> <div class="step snare" data-drum="snare" data-step="6"></div> <div class="step snare" data-drum="snare" data-step="7"></div> <div class="step snare" data-drum="snare" data-step="8"></div> <div class="step snare" data-drum="snare" data-step="9"></div> <div class="step snare" data-drum="snare" data-step="10"></div> <div class="step snare" data-drum="snare" data-step="11"></div> <div class="step snare" data-drum="snare" data-step="12"></div> <div class="step snare" data-drum="snare" data-step="13"></div> <div class="step snare" data-drum="snare" data-step="14"></div> <div class="step snare" data-drum="snare" data-step="15"></div> <div class="drum-name">Hi-Hat</div> <div class="step hihat" data-drum="hihat" data-step="0"></div> <div class="step hihat" data-drum="hihat" data-step="1"></div> <div class="step hihat" data-drum="hihat" data-step="2"></div> <div class="step hihat" data-drum="hihat" data-step="3"></div> <div class="step hihat" data-drum="hihat" data-step="4"></div> <div class="step hihat" data-drum="hihat" data-step="5"></div> <div class="step hihat" data-drum="hihat" data-step="6"></div> <div class="step hihat" data-drum="hihat" data-step="7"></div> <div class="step hihat" data-drum="hihat" data-step="8"></div> <div class="step hihat" data-drum="hihat" data-step="9"></div> <div class="step hihat" data-drum="hihat" data-step="10"></div> <div class="step hihat" data-drum="hihat" data-step="11"></div> <div class="step hihat" data-drum="hihat" data-step="12"></div> <div class="step hihat" data-drum="hihat" data-step="13"></div> <div class="step hihat" data-drum="hihat" data-step="14"></div> <div class="step hihat" data-drum="hihat" data-step="15"></div> <div class="drum-name">Clap</div> <div class="step clap" data-drum="clap" data-step="0"></div> <div class="step clap" data-drum="clap" data-step="1"></div> <div class="step clap" data-drum="clap" data-step="2"></div> <div class="step clap" data-drum="clap" data-step="3"></div> <div class="step clap" data-drum="clap" data-step="4"></div> <div class="step clap" data-drum="clap" data-step="5"></div> <div class="step clap" data-drum="clap" data-step="6"></div> <div class="step clap" data-drum="clap" data-step="7"></div> <div class="step clap" data-drum="clap" data-step="8"></div> <div class="step clap" data-drum="clap" data-step="9"></div> <div class="step clap" data-drum="clap" data-step="10"></div> <div class="step clap" data-drum="clap" data-step="11"></div> <div class="step clap" data-drum="clap" data-step="12"></div> <div class="step clap" data-drum="clap" data-step="13"></div> <div class="step clap" data-drum="clap" data-step="14"></div> <div class="step clap" data-drum="clap" data-step="15"></div> </div> <div class="step-labels"> <!-- Step numbers will be generated by JavaScript --> </div> <div class="visualizer" id="visualizer"></div> <div class="status" id="status">Ready</div> </div> <script> document.addEventListener('DOMContentLoaded', () => { // Audio context initialization const AudioContext = window.AudioContext || window.webkitAudioContext; const audioCtx = new AudioContext(); // DOM elements const playBtn = document.getElementById('playBtn'); const stopBtn = document.getElementById('stopBtn'); const bpmSlider = document.getElementById('bpmSlider'); const bpmValue = document.getElementById('bpmValue'); const visualizer = document.getElementById('visualizer'); const statusElement = document.getElementById('status'); // State variables let isPlaying = false; let stepInterval = null; let currentStep = 0; let bpm = 120; let sequence = { kick: Array(16).fill(false), snare: Array(16).fill(false), hihat: Array(16).fill(false), clap: Array(16).fill(false) }; // Create step labels const stepLabelsContainer = document.querySelector('.step-labels'); for (let i = 0; i < 16; i++) { const label = document.createElement('div'); label.className = 'step-number'; label.textContent = i + 1; stepLabelsContainer.appendChild(label); } // Create visualizer bars const bars = []; for (let i = 0; i < 32; i++) { const bar = document.createElement('div'); bar.className = 'bar'; bar.style.left = `${i * 12}px`; bar.style.height = '0px'; visualizer.appendChild(bar); bars.push(bar); } // Update BPM display bpmSlider.addEventListener('input', () => { bpm = parseInt(bpmSlider.value); bpmValue.textContent = bpm; }); // Play button handler playBtn.addEventListener('click', () => { if (!isPlaying) { startPlayback(); } }); // Stop button handler stopBtn.addEventListener('click', () => { stopPlayback(); }); // Toggle step activation document.querySelectorAll('.step').forEach(step => { step.addEventListener('click', () => { const drum = step.dataset.drum; const stepIndex = parseInt(step.dataset.step); // Toggle the step state sequence[drum][stepIndex] = !sequence[drum][stepIndex]; // Update UI if (sequence[drum][stepIndex]) { step.classList.add('active'); } else { step.classList.remove('active'); } }); }); // Start playback function startPlayback() { if (isPlaying) return; isPlaying = true; playBtn.disabled = true; stopBtn.disabled = false; statusElement.textContent = `Playing at ${bpm} BPM`; // Calculate interval in milliseconds const interval = (60 / bpm) * 1000 / 4; // 16th notes // Clear previous interval if (stepInterval) { clearInterval(stepInterval); } // Start new interval stepInterval = setInterval(() => { playStep(); updateVisualizer(); }, interval); } // Stop playback function stopPlayback() { isPlaying = false; clearInterval(stepInterval); stepInterval = null; playBtn.disabled = false; stopBtn.disabled = true; statusElement.textContent = 'Stopped'; resetStepIndicator(); } // Play a step function playStep() { // Reset previous step indicator resetStepIndicator(); // Update current step indicator const steps = document.querySelectorAll('.step'); steps.forEach(step => { if (parseInt(step.dataset.step) === currentStep) { step.classList.add('active'); } }); // Play sounds for active steps if (sequence.kick[currentStep]) { playKick(); } if (sequence.snare[currentStep]) { playSnare(); } if (sequence.hihat[currentStep]) { playHiHat(); } if (sequence.clap[currentStep]) { playClap(); } // Move to next step currentStep = (currentStep + 1) % 16; } // Reset step indicator function resetStepIndicator() { const steps = document.querySelectorAll('.step'); steps.forEach(step => { step.classList.remove('active'); }); } // Update visualizer function updateVisualizer() { // Shift bars left for (let i = 0; i < bars.length - 1; i++) { bars[i].style.height = bars[i + 1].style.height; } // Set random height for new bar (0-100px) const height = Math.floor(Math.random() * 100) + 1; bars[bars.length - 1].style.height = `${height}px`; } // Synthesize sounds using Web Audio API // Kick drum sound function playKick() { const oscillator = audioCtx.createOscillator(); const gainNode = audioCtx.createGain(); oscillator.connect(gainNode); gainNode.connect(audioCtx.destination); oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(150, audioCtx.currentTime); oscillator.frequency.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.5); gainNode.gain.setValueAtTime(1, audioCtx.currentTime); gainNode.gain.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.5); oscillator.start(audioCtx.currentTime); oscillator.stop(audioCtx.currentTime + 0.5); } // Snare drum sound function playSnare() { const noise = audioCtx.createBuffer(1, audioCtx.sampleRate * 0.5, audioCtx.sampleRate); const data = noise.getChannelData(0); for (let i = 0; i < noise.length; i++) { data[i] = Math.random() * 2 - 1; } const noiseBufferSource = audioCtx.createBufferSource(); noiseBufferSource.buffer = noise; const noiseFilter = audioCtx.createBiquadFilter(); noiseFilter.type = 'highpass'; noiseFilter.frequency.value = 10000; const noiseGain = audioCtx.createGain(); noiseGain.gain.setValueAtTime(1, audioCtx.currentTime); noiseGain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.5); noiseBufferSource.connect(noiseFilter); noiseFilter.connect(noiseGain); noiseGain.connect(audioCtx.destination); noiseBufferSource.start(audioCtx.currentTime); noiseBufferSource.stop(audioCtx.currentTime + 0.5); // Add a quick sine wave for the snare tone const oscillator = audioCtx.createOscillator(); const oscGain = audioCtx.createGain(); oscillator.connect(oscGain); oscGain.connect(audioCtx.destination); oscillator.type = 'triangle'; oscillator.frequency.setValueAtTime(100, audioCtx.currentTime); oscillator.frequency.exponentialRampToValueAtTime(0.001, audioCtx.currentTime + 0.1); oscGain.gain.setValueAtTime(0.7, audioCtx.currentTime); oscGain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.1); oscillator.start(audioCtx.currentTime); oscillator.stop(audioCtx.currentTime + 0.1); } // Hi-hat sound function playHiHat() { const noise = audioCtx.createBuffer(1, audioCtx.sampleRate * 0.1, audioCtx.sampleRate); const data = noise.getChannelData(0); for (let i = 0; i < noise.length; i++) { data[i] = Math.random() * 2 - 1; } const noiseBufferSource = audioCtx.createBufferSource(); noiseBufferSource.buffer = noise; const noiseFilter = audioCtx.createBiquadFilter(); noiseFilter.type = 'highpass'; noiseFilter.frequency.value = 10000; const noiseGain = audioCtx.createGain(); noiseGain.gain.setValueAtTime(0.5, audioCtx.currentTime); noiseGain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.1); noiseBufferSource.connect(noiseFilter); noiseFilter.connect(noiseGain); noiseGain.connect(audioCtx.destination); noiseBufferSource.start(audioCtx.currentTime); noiseBufferSource.stop(audioCtx.currentTime + 0.1); } // Clap sound function playClap() { const noise = audioCtx.createBuffer(1, audioCtx.sampleRate * 0.3, audioCtx.sampleRate); const data = noise.getChannelData(0); for (let i = 0; i < noise.length; i++) { data[i] = Math.random() * 2 - 1; } const noiseBufferSource = audioCtx.createBufferSource(); noiseBufferSource.buffer = noise; const noiseFilter = audioCtx.createBiquadFilter(); noiseFilter.type = 'highpass'; noiseFilter.frequency.value = 5000; const noiseGain = audioCtx.createGain(); noiseGain.gain.setValueAtTime(0.8, audioCtx.currentTime); noiseGain.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.3); noiseBufferSource.connect(noiseFilter); noiseFilter.connect(noiseGain); noiseGain.connect(audioCtx.destination); noiseBufferSource.start(audioCtx.currentTime); noiseBufferSource.stop(audioCtx.currentTime + 0.3); } // Initialize with some default patterns sequence.kick = [true, false, false, false, true, false, false, false, true, false, false, false, true, false, false, false]; sequence.snare = [false, false, true, false, false, false, true, false, false, false, true, false, false, false, true, false]; sequence.hihat = [true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true]; sequence.clap = [false, false, false, true, false, false, false, true, false, false, false, true, false, false, false, true]; // Update UI based on initial sequence document.querySelectorAll('.step').forEach(step => { const drum = step.dataset.drum; const stepIndex = parseInt(step.dataset.step); if (sequence[drum][stepIndex]) { step.classList.add('active'); } }); }); </script> </body> </html> ```

TAKE IT TO CODE

This run produced no artifact — reuse the prompt with a different model or your own pi-agent run.

RUN

modelqwen3-coder-flash
vendorQwen
harnesspi-agent
generated2026-08-01

METRICS

runtime55.2s
tokens in139
tokens out6.1k
cached1.5k
cost / run$0.0060