Lab

Export dialog

The settings of an export: the file's format, its bit depth or bitrate, and its level, left as it is, brought to its peak or to a loudness target.

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

It resolves to { file, gain, loudness }: the file as a Blob, the gain in dB, and how loud the file is (lufs, peak, truePeak).

Built by Ouest Labs, the source code is available on GitHub.
RSS