Snippet

Frequency piano

Full page view

Description

A crude piano which hits frequencies in intervals of 50 Hz.

Created on 27 Oct 2025

Code

<style>
  input {
    display: block;
  }
</style>

<label>
  Select the input, then type numbers or the top row of letters on your keyboard. Press any other key for a random frequency:
  <input id='in' autofocus='autofocus'/>
</label>
<output for='in'>Frequency: <span>-</span></output>

<script>
  function getRandomIntInclusive(min, max) {
    const minCeiled = Math.ceil(min);
    const maxFloored = Math.floor(max);
    return Math.floor(Math.random() * (maxFloored - minCeiled + 1) + minCeiled);
  }

  const frequencies = {
    Digit1: 50,
    Digit2: 100,
    Digit3: 150,
    Digit4: 200,
    Digit5: 250,
    Digit6: 300,
    Digit7: 350,
    Digit8: 400,
    Digit9: 450,
    Digit0: 500,
    KeyQ: 550,
    KeyW: 600,
    KeyE: 650,
    KeyR: 700,
    KeyT: 750,
    KeyY: 800,
    KeyU: 850,
    KeyI: 900,
    KeyO: 950,
    KeyP: 1000
  }

  window.addEventListener('keydown', (ev) => {
    const context = new AudioContext(),
      oscillator = context.createOscillator(),
      gainNode = context.createGain();
    oscillator.connect(gainNode);
    gainNode.connect(context.destination);
    document.querySelector('span').textContent = (oscillator.frequency.value = frequencies[ev.code] || getRandomIntInclusive(50, 1000)) + ' Hz';
    oscillator.start();
    window.addEventListener('keyup', (ev) => {
      setTimeout(() => gainNode.gain.setTargetAtTime(0, context.currentTime, .5), 100)
    }, { once: true });
  });
</script>

Site info

Canonical URL https://miro.boats/snippets/snippet/frequency-piano/
Static site generator Astro v6.3.1
Last build 2026-05-16T07:59:28.197
Web hosting Netlify
Deployment status Netlify deploy status
Git hosting Codeberg
DNS Namecheap