{
  "schemaVersion": 1,
  "slug": "speaker-box-calculator",
  "category": "music",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "4074d6faedf4cfd951f198e5968ad4e0333edbe813da2aebbfd4e265331f7786",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/speaker-box-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": "Vb₁ = Vas ÷ ((Qtc÷Qts)² − 1); Vb₂ = 15×Vas×Qts^2.87; L = 23562.5D²Np ÷ (F²Vb₂) − 0.732D",
    "vars": [
      [
        "Vas",
        "Equivalent compliance volume (L)"
      ],
      [
        "Qts",
        "Driver total Q"
      ],
      [
        "Qtc",
        "Target system Q"
      ],
      [
        "F",
        "Tuning frequency (Hz)"
      ],
      [
        "D",
        "Port diameter (cm)"
      ],
      [
        "Np",
        "Number of ports"
      ]
    ],
    "note": "Sealed volume uses Vas divided by (Qtc/Qts)^2−1 and requires Qtc > Qts. Ported volume is a simplified empirical estimate; port length uses the standard cylindrical-port relationship with input dimensions. Driver displacement, port area/velocity and other design constraints are not modeled. Nonpositive calculated port lengths are left blank."
  },
  "externalEvidence": null,
  "contract": {
    "compute": "const qtsV = Math.max(0.05, qts); const alpha = Math.pow(qtc/qtsV, 2) - 1; if (boxType === 'sealed' && alpha <= 0.01) return { boxVolume:null, boxVolumeCuFt:null, portLength:null, portLengthIn:null, __error:'inputError' }; const sealedV = vas/alpha; const portedV = 15*vas*Math.pow(qtsV,2.87); const Vb = boxType === 'sealed' ? sealedV : portedV; const Dv=portDiameter; const Np=Math.max(1,Math.round(portCount)); const rawLv=boxType==='ported'&&Vb>0&&tuningFreq>0 ? (23562.5*Dv*Dv*Np)/(tuningFreq*tuningFreq*Vb)-0.732*Dv : null; const Lv=rawLv>0?rawLv:null; return { boxVolume:Vb, boxVolumeCuFt:Vb/28.3168, portLength:Lv, portLengthIn:Lv===null?null:Lv/2.54 };",
    "inputs": [
      {
        "name": "boxType",
        "type": "select",
        "default": "ported",
        "options": [
          {
            "value": "sealed"
          },
          {
            "value": "ported"
          }
        ]
      },
      {
        "name": "vas",
        "type": "number",
        "default": 60,
        "min": 0.1,
        "max": 2000,
        "step": 0.1
      },
      {
        "name": "qts",
        "type": "number",
        "default": 0.4,
        "min": 0.05,
        "max": 2,
        "step": 0.01,
        "slider": true
      },
      {
        "name": "qtc",
        "type": "number",
        "default": 0.707,
        "min": 0.3,
        "max": 1.5,
        "step": 0.001,
        "slider": true
      },
      {
        "name": "tuningFreq",
        "type": "number",
        "default": 35,
        "min": 5,
        "max": 200,
        "step": 0.5,
        "slider": true
      },
      {
        "name": "portDiameter",
        "type": "number",
        "default": 10,
        "min": 1,
        "max": 50,
        "step": 0.5,
        "slider": true
      },
      {
        "name": "portCount",
        "type": "number",
        "default": 1,
        "min": 1,
        "max": 8,
        "step": 1
      }
    ],
    "outputs": [
      {
        "name": "boxVolume",
        "precision": 2,
        "unit": "L"
      },
      {
        "name": "boxVolumeCuFt",
        "precision": 3,
        "unit": "cu ft"
      },
      {
        "name": "portLength",
        "precision": 2,
        "unit": "cm",
        "optional": true
      },
      {
        "name": "portLengthIn",
        "precision": 2,
        "unit": "in",
        "optional": true
      }
    ],
    "interpret": null
  }
}
