{
  "schemaVersion": 1,
  "slug": "note-frequency-calculator",
  "category": "music",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "7e1283278c67300cc0adef2cbfb84cc4e0c442d78317ccf296930429e335f772",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/note-frequency-calculator.json",
    "src/engine.js"
  ],
  "runtimeSource": "/sources/engine.txt",
  "runtimeHash": "5c888d8898afbdee36267bb9977829e1e2ac568f6677c8ee87469c139864645c",
  "scope": "The compute function records implemented equations, constants, lookup tables and custom rules. Inputs record defaults and allowed values; outputs record precision and units. Defaults are examples, not recommendations. General background references are not evidence for this specific algorithm.",
  "publishedFormula": {
    "formula": "f = A × 2^(((O+1)×12 + s − 69)/12)",
    "vars": [
      [
        "f",
        "frequency, Hz"
      ],
      [
        "A",
        "reference frequency A4, Hz"
      ],
      [
        "O",
        "octave number"
      ],
      [
        "s",
        "semitone index, C = 0"
      ]
    ],
    "note": "MIDI number = (O+1)×12+s; wavelength = 343/f×100 cm (speed of sound 343 m/s); cents from A4 = (MIDI−69)×100; octave above = 2f."
  },
  "externalEvidence": null,
  "contract": {
    "compute": "const names = ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B']; const enh = { 'C#': 'Db', 'D#': 'Eb', 'F#': 'Gb', 'G#': 'Ab', 'A#': 'Bb' }; const semi = names.indexOf(note); const midi = (Math.round(octave) + 1)*12 + (semi < 0 ? 0 : semi); const freq = reference*Math.pow(2, (midi - 69)/12); const fromA4 = midi - 69; const speed = 343; return { frequency: freq, midiNumber: midi, wavelengthCm: freq > 0 ? speed/freq*100 : 0, centsFromA4: Math.round(fromA4*100), semitonesFromA4: fromA4, isSameAs: enh[note] ? note + ' = ' + enh[note] : note + ' has no common enharmonic name', octaveAbove: freq*2 };",
    "inputs": [
      {
        "name": "note",
        "type": "select",
        "default": "A",
        "options": [
          {
            "value": "C"
          },
          {
            "value": "C#"
          },
          {
            "value": "D"
          },
          {
            "value": "D#"
          },
          {
            "value": "E"
          },
          {
            "value": "F"
          },
          {
            "value": "F#"
          },
          {
            "value": "G"
          },
          {
            "value": "G#"
          },
          {
            "value": "A"
          },
          {
            "value": "A#"
          },
          {
            "value": "B"
          }
        ]
      },
      {
        "name": "octave",
        "type": "number",
        "default": 4,
        "min": -1,
        "max": 9,
        "step": 1,
        "slider": true
      },
      {
        "name": "reference",
        "type": "number",
        "default": 440,
        "min": 380,
        "max": 500,
        "step": 1,
        "slider": true
      }
    ],
    "outputs": [
      {
        "name": "frequency",
        "precision": 2,
        "unit": "Hz"
      },
      {
        "name": "midiNumber",
        "precision": 0,
        "unit": ""
      },
      {
        "name": "wavelengthCm",
        "precision": 1,
        "unit": "cm"
      },
      {
        "name": "centsFromA4",
        "precision": 0,
        "unit": ""
      },
      {
        "name": "semitonesFromA4",
        "precision": 0,
        "unit": ""
      },
      {
        "name": "isSameAs",
        "precision": 0,
        "unit": "",
        "type": "text"
      },
      {
        "name": "octaveAbove",
        "precision": 2,
        "unit": "Hz"
      }
    ],
    "interpret": null
  }
}
