Recursive AI

Keep only the codecs you use

All oneaudio recipes

Make small NativeAOT and trimmed .NET apps with oneaudio: register only the formats you read with an AudioKit, so the other decoders are trimmed away.

C#
using OneAudio;
 
// Audio.* registers every codec, so an app that calls Audio.Load carries them
// all. An AudioKit over your own registry has the same methods and keeps only
// what you add.
var registry = new AudioCodecRegistry().AddWav().AddOgg().AddVorbis();
var kit = new AudioKit(registry);
 
AudioClip hit = kit.Load("hit.wav");
AudioClip music = kit.Load("music.ogg");
Console.WriteLine($"hit.wav {hit.Frames} frames, music.ogg {music.Frames} frames");
 
try
{
    kit.Load("music.mp3");
}
catch (UnsupportedAudioFormatException e)
{
    Console.WriteLine($"music.mp3: {e.Message}");
}
 
// These never touch a registry, so they add no codec.
AudioClip at48 = Audio.Resample(music, 48000);
double lufs = Audio.Measure(at48).IntegratedLufs;
Console.WriteLine($"resampled: {at48.Frames} frames, {lufs:F1} LUFS");
 
AudioMixer mixer = Audio.CreateMixer();
kit.Play(mixer, "hit.wav");
float[] block = new float[1024 * 2];
mixer.Render(block);
Console.WriteLine($"mixer: {mixer.ActiveVoices} voice playing");
Text
hit.wav 19200 frames, music.ogg 1411200 frames
music.mp3: No registered container format recognises this data.
resampled: 1536000 frames, -23.0 LUFS
mixer: 1 voice playing

Why

Audio.Load, Audio.Open, Audio.Transcode, Audio.Measure(path), Audio.Normalize(path, ...) and mixer.Play(path) use Audio.Kit, which registers every codec. Nothing is found by reflection, so a codec you never register is never referenced, and the trimmer removes it.

  • new AudioKit(registry) has the same methods with the same defaults, over the registry you give it. kit.Play(mixer, path) and kit.PlayStream(mixer, path) stand in for the mixer extensions.
  • The registry starts empty. Add containers and codecs: AddWav(), AddOgg(), AddVorbis(), AddOpus(), AddFlac(), AddMp3(). Ogg Vorbis and Ogg Opus need AddOgg() as well as the codec, and so does Ogg FLAC.
  • A file in a format you didn’t register throws UnsupportedAudioFormatException, as music.mp3 does above.
  • Audio.Resample, Audio.Measure(clip), Audio.Normalize on samples or clips, and Audio.CreateMixer never touch a registry.
  • The encoders are linked only into apps that write files with Transcode or Normalize, or use an encoder directly.

Measured

Published for linux-x64 with dotnet publish -c Release -r linux-x64 -p:PublishAot=true, this program built with no warnings, and the binary was 1,893,616 bytes. The same program with Audio.Kit in place of the three-codec kit was 2,136,096 bytes. The project’s own measurements, on a smaller app, are in the README.

When a managed library can replace FFmpeg, with ffmpeg commands mapped to C#: Audio in .NET without FFmpeg.