---
title: "Keep only the codecs you use"
url: https://recursiveai.org/oneaudio/cookbook/trim-codecs/
description: "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."
version: "1.2.1"
---

# Keep only the codecs you use

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.

```csharp
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](https://github.com/recursive-ai-oss/oneaudio-csharp/blob/2ced4d52857c4a762b4a66e7da2885eb30f825c0/README.md#trimming-and-nativeaot).

When a managed library can replace FFmpeg, with ffmpeg commands mapped to C#: [Audio in .NET without FFmpeg](https://recursiveai.org/oneaudio/articles/audio-without-ffmpeg-dotnet/).
