Lab

files

Files from @audio-ui/engine: an audio file decoded into samples at a context's rate, sound written to WAV, FLAC or MP3, notes read from and written to a MIDI file, and a score read from and written to MusicXML.

pnpm add @audio-ui/engine
import { decodeAudioChannels, decodeAudioSamples, downloadFile, encodeAudio, downloadMidiFile, /* … */ } from "@audio-ui/engine/files";
Used byaudio-export
audio.js@audio/decode-aiff, @audio/decode-caf, @audio/decode-mp4, @audio/encode, @audio/midi-parse, @audio/midi-write, @audio/musicxml, @audio/resample-sinc
ExportKindWhat it is
decodeAudioChannelsfunctionDecodes raw audio bytes, such as file.arrayBuffer(), into every channel's PCM samples at the context's sample rate, ready for computePeaks.
decodeAudioSamplesfunctionDecodes raw audio bytes into one channel's PCM samples, ready for downsampleWaveform: decodeAudioChannels, then the channel asked for, or the last there is.
AudioFileFormattypeThe formats encodeAudio writes.
downloadFilefunctionSaves a file through the browser's downloads, named name.
EncodeAudioOptionsinterfaceWhat encodeAudio writes: the format, its bit depth or bitrate, the channels' sample rate, and a callback for its progress.
encodeAudiofunctionEncodes channels of samples, from -1 to 1, as a file.
downloadMidiFilefunctionSaves the notes as a .mid file, named filename.
MIDI_FILE_ACCEPTconstWhat a file input or a drop zone accepts as a MIDI file.
MidiFileGridinterfaceThe grid notes are read onto: steps a quarter note, the clip's length in steps, and the pitch and tempo ranges it takes.
readMidiFilefunctionReads a MIDI file's notes onto a grid of steps, with the file's own tempo (clamped to the BPM range).
readMidiFilePartsfunctionReads a MIDI file as parts, for a host that lays each on a track of its own: a part per track and channel, named after its track (and its channel, when a track holds several), its notes in beats as they were written, not quantized and not cut, at least a tick long, and the first program its channel plays.
ScoreNoteinterfaceA note of a score in beats: where it starts and how long it lasts, in quarter notes.
ScorePartinterfaceOne part of a score: its name, whether it is drums, and its notes in beats.
writeMidiFilefunctionThe notes as a Standard MIDI File, the inverse of readMidiFile.
downloadMusicXmlFilefunctionSaves the notes as a .musicxml file, named filename.
MUSICXML_FILE_ACCEPTconstWhat a file input or a drop zone accepts as a MusicXML file: a score, or one compressed as .mxl.
MusicXmlFileGridinterfaceThe grid notes are read onto: steps a quarter note, the clip's length in steps, and the pitch and tempo ranges it takes.
readMusicXmlFilefunctionReads a MusicXML score's notes onto a grid of steps, with its first tempo (clamped to the BPM range), every part into the one clip.
readMusicXmlFilePartsfunctionReads a MusicXML score as parts, for a host that lays each on a track of its own: a part each, by its name, its notes in beats as they were written, through changes of tempo, not quantized and not cut.
writeMusicXmlFilefunctionThe notes as a MusicXML score, the inverse of readMusicXmlFile, for a notation app to open: on the grid they sit on, so nothing moves.

Audio files

A file's audio as samples at the context's rate, one array per channel: what the browser decodes, and AIFF, CAF or Apple Lossless where it cannot (Chrome does not), with audio.js decoders.

import { decodeAudioChannels } from "@audio-ui/engine/files";

const channels = await decodeAudioChannels(ctx, await file.arrayBuffer());

The samples are at the context's sample rate, so they play as they are and computePeaks (from @audio-ui/engine/analysis) draws them. The waveform player and the arrangement decode dropped files this way.

Writing a file

Sound saved as a file: WAV (16 or 24-bit, or 32-bit float), FLAC or MP3 at a bitrate, encoded in chunks with its progress, from what an OfflineAudioContext rendered or a recording kept.

import { downloadFile, encodeAudio } from "@audio-ui/engine/files";

const file = await encodeAudio(channels, { bitDepth: 24, format: "wav", sampleRate, onProgress: (done) => setProgress(done) });
downloadFile(file, "mix.wav");

audio-export adds loudness normalization on top of it.

MIDI files

Audio UI

The midi-file library reads a .mid file onto the roll's steps and writes one back.

import { downloadMidiFile, MIDI_FILE_ACCEPT, readMidiFile } from "@audio-ui/engine/files";

<input
  accept={MIDI_FILE_ACCEPT}
  onChange={async (event) => {
    const file = event.target.files?.[0];
    if (file) {
      const { bpm, notes } = await readMidiFile(file, {
        duration: 64,
        maxPitch: 84,
        minPitch: 36,
      });
      setNotes(notes);
      setBpm(bpm);
    }
  }}
  type="file"
/>
<Button onClick={() => downloadMidiFile(notes, { bpm, filename: "clip.mid" })}>
  Export
</Button>

readMidiFile puts each note on the nearest step, at least one step long, drops the notes starting past duration, keeps the pitches between minPitch and maxPitch and returns the file's tempo, kept between minBpm and maxBpm (20 and 200 by default). It takes any File or Blob, so a drop works the same as an input. writeMidiFile goes the other way, at 480 ticks a quarter note, and leaves deactivated notes out; downloadMidiFile writes the file and saves it. A step is a sixteenth note: set stepsPerQuarter on both sides for another grid.

For a host that lays each part on a track of its own, such as a DAW, readMidiFileParts(file) reads a file as parts instead: one per track and channel, named after its track, with the General MIDI program it asks for and whether it is the drums of channel 10, its notes in beats as they were written, not quantized. The file is parsed by @audio/midi-parse.

MusicXML files

A MusicXML score onto a roll's steps, a part at a time, and notes back out as a score: what notation software reads and writes.

import { downloadMusicXmlFile, readMusicXmlFile } from "@audio-ui/engine/files";

const { bpm, notes } = await readMusicXmlFile(file, { duration: 64, maxPitch: 84, minPitch: 36 });
downloadMusicXmlFile(notes, { bpm, filename: "clip.musicxml" });

readMusicXmlFileParts gives each part on its own; writeMusicXmlFile the score as a string. For a .mid file, see midi-file.

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