Recursive AI

Decode Ogg Vorbis in C#

All oneaudio recipes

Decode Ogg Vorbis files in C# with oneaudio: load or stream the samples, read the comment tags, and play chained Ogg files as one stream.

C#
using OneAudio;
using OneAudio.Vorbis;
 
AudioClip clip = Audio.Load("music.ogg");
Console.WriteLine($"music.ogg: {clip.Format.SampleRate} Hz, " +
                  $"{clip.Format.Channels} ch, {clip.Frames} frames");
 
// The concrete decoder carries the comment header.
using (var vorbis = (VorbisDecoder)Audio.Open("music.ogg"))
{
    Console.WriteLine($"vendor: {vorbis.Vendor}");
    foreach (string comment in vorbis.Comments)     // NAME=value
        Console.WriteLine($"  {comment}");
}
 
// A chained file: two Ogg streams one after the other, music and then an
// announcement.
using (var chained = (VorbisDecoder)Audio.Open("chained.ogg"))
{
    Console.WriteLine($"chained.ogg: {chained.LinkCount} links, " +
                      $"{chained.LengthFrames} frames in all");
    float[] buffer = new float[4096 * chained.Format.Channels];
    long total = 0;
    int read;
    while ((read = chained.Read(buffer)) > 0)
        total += read;
    Console.WriteLine($"read {total} frames");
    Console.WriteLine($"comments of the last link: {string.Join(", ", chained.Comments)}");
}
Text
music.ogg: 44100 Hz, 2 ch, 1411200 frames
vendor: Lavf62.3.100
  encoder=Lavc62.11.100 libvorbis
  ARTIST=Test signal
  TITLE=Four chords
chained.ogg: 2 links, 1676903 frames in all
read 1676903 frames
comments of the last link: encoder=Lavc62.11.100 libvorbis, TITLE=Announcement

Chained files

An Ogg file can hold several streams one after another, such as a radio recording or tracks joined with cat. Consecutive links in the same format decode as one stream. LengthFrames covers every link, and seeking works across them. LinkCount says how many links there are, and GetLinkFormat(link) returns the format of each one. Vendor and Comments belong to the link being decoded, which is why the sample prints the announcement’s title after reading to the end.

Good to know

  • Audio.Open returns a VorbisDecoder for Ogg Vorbis. Cast to it for Vendor, Comments and the link members. The same file through Audio.Load or the mixer needs no cast.
  • Comments are NAME=value strings exactly as the file stores them. Names come in any case (ffmpeg writes encoder in lowercase), so compare them without regard to case. See Read audio metadata.
  • The decoder was checked against libvorbis 1.3.7 on the Xiph test vectors: the same frame counts, and floor-1 streams within 2e-6.
  • oneaudio doesn’t write Vorbis. An .ogg output path in Audio.Transcode writes Ogg Opus.

Streaming, exact seeking and chained files, compared with NVorbis: Decode Ogg Vorbis in C#.