Audio UI
Installation
pnpm dlx shadcn@latest add @audio-ui/export-dialog
Usage
import { useState } from "react";
import { ExportDialog } from "@/components/audio-ui/export-dialog";
import { downloadFile } from "@/lib/audio-encode";
import { DEFAULT_EXPORT_SETTINGS, type ExportSettings, exportSound } from "@/lib/audio-export";
const [open, setOpen] = useState(false);
const [settings, setSettings] = useState(DEFAULT_EXPORT_SETTINGS);
async function exportMix(picked: ExportSettings) {
const rendered = await renderMix(); // an AudioBuffer, from your engine
const channels = [rendered.getChannelData(0), rendered.getChannelData(1)];
const { file, loudness } = await exportSound(channels, rendered.sampleRate, picked, showProgress);
downloadFile(file, `mix.${picked.format}`);
}
<ExportDialog
onExport={exportMix}
onOpenChange={setOpen}
onSettingsChange={setSettings}
open={open}
range="Bars 1 to 9"
settings={settings}
/>;The dialog picks the settings and renders nothing itself: Export closes it and hands onExport the settings. Render the sound your own way (an OfflineAudioContext, renderArrangement, an engine of your own), then exportSound from audio-export turns the channels into the file. settings and onSettingsChange keep the choice wherever you want it remembered.
- Format: WAV or FLAC, at 16 or 24 bits (a WAV also at 32-bit float, which keeps what goes past full scale), or MP3, at 128 to 320 kbps.
- Normalize: off, the file holds the render as it is; peak, the loudest sample reaches 0 dBFS; or a loudness target, -14 LUFS for streaming, -16 for podcasts, -23 for broadcast, reached as far as the true peak stays at or under -1 dBTP. A sound that would pass the ceiling lands under its target, and nothing is limited.
exportSound says how far it is through its last argument, (stage, done): "measuring", then "encoding" from 0 to 1. Measuring reads every sample at once, and the page waits about half a second a minute of stereo, after it has painted the stage, so show it. The result's loudness is how loud the file came out, in LUFS and dBTP, and gain the dB it was brought by. The loudness and file libs it is built on work on their own too.
API reference
ExportDialog
Props · 5
exportSound
Props · 4
format, bitDepth, bitrate and normalize ("off", "peak" or a target in LUFS)."measuring", then "encoding" from 0 to 1.It resolves to { file, gain, loudness }: the file as a Blob, the gain in dB, and how loud the file is (lufs, peak, truePeak).