AAC Decoder
Contents
AAC Decoder#
This article explains how you can use Transcoder.Pull to decode an AAC ADTS elementary stream.
Source Audio#
For source we use the Hydrate-Kenny_Beltrey.aac
file from the AVBlocks Assets repository. After downloading and unzipping you will find Hydrate-Kenny_Beltrey.aac
in the aud
subdirectory.
Code#
This code takes an AAC ADTS stream and decodes it to uncompressed LPCM samples.
Initialize AVBlocks#
static void DecodeAACStream()
{
Library.Initialize();
DecodeAACStream("Hydrate-Kenny_Beltrey.aac");
Library.Shutdown();
}
Configure Transcoder#
static void DecodeAACStream(string inputFile)
{
// Create an input socket from file
var inSocket = new MediaSocket()
{
File = inputFile
};
// Create an output socket with one YUV 4:2:0 video pin
var outSocket = new MediaSocket()
{
StreamType = StreamType.LPCM
};
outSocket.Pins.Add(new MediaPin()
{
StreamInfo = new AudioStreamInfo()
{
StreamType = StreamType.LPCM,
SampleRate = 44100,
Channels = 2,
BitsPerSample = 16
}
});
// Create Transcoder
using (var transcoder = new Transcoder())
{
transcoder.Inputs.Add(inSocket);
transcoder.Outputs.Add(outSocket);
if (transcoder.Open())
{
DecodeAACStream(transcoder);
transcoder.Close();
}
}
}
Call Transcoder.Pull#
static void DecodeAACStream(Transcoder transcoder)
{
int outputIndex = 0;
var audioSample = new MediaSample();
while (transcoder.Pull(out outputIndex, audioSample))
{
// Each call to Transcoder::pull returns one audio frame.
// One audio frame typically contains 512 audio samples.
ProcessAudioFrame(audioSample);
}
}
Complete Program#
using PrimoSoftware.AVBlocks;
namespace AACDecoder
{
class Program
{
static int sampleIndex = 0;
static void ProcessAudioFrame(MediaSample sample)
{
// The samples of multi-channel audio (such as stereo and surround) are stored by
// cycling through the samples for each channel before advancing to the next sample time
// sample.Buffer contains 512 interleaved samples.
// In this example each sample is 16 bit signed integer (so 1024 bytes total)
Console.WriteLine("Sample Index : {0} StartTime : {1} Buffer.Start : {2} Buffer.DataSize : {3}", sampleIndex, sample.StartTime, sample.Buffer.Start, sample.Buffer.DataSize);
sampleIndex++;
}
static void DecodeAACStream(Transcoder transcoder)
{
int outputIndex = 0;
var audioSample = new MediaSample();
while (transcoder.Pull(out outputIndex, audioSample))
{
// Each call to Transcoder::pull returns one audio frame.
// One audio frame typically contains 512 audio samples.
ProcessAudioFrame(audioSample);
}
}
static void DecodeAACStream(string inputFile)
{
// Create an input socket from file
var inSocket = new MediaSocket()
{
File = inputFile
};
// Create an output socket with one YUV 4:2:0 video pin
var outSocket = new MediaSocket()
{
StreamType = StreamType.LPCM
};
outSocket.Pins.Add(new MediaPin()
{
StreamInfo = new AudioStreamInfo()
{
StreamType = StreamType.LPCM,
SampleRate = 44100,
Channels = 2,
BitsPerSample = 16
}
});
// Create Transcoder
using (var transcoder = new Transcoder())
{
transcoder.Inputs.Add(inSocket);
transcoder.Outputs.Add(outSocket);
if (transcoder.Open())
{
DecodeAACStream(transcoder);
transcoder.Close();
}
}
}
static void DecodeAACStream()
{
Library.Initialize();
DecodeAACStream("Hydrate-Kenny_Beltrey.aac");
Library.Shutdown();
}
static void Main(string[] args)
{
DecodeAACStream();
}
}
}
How to run#
Follow the steps to create a C# console application in Visual Studio but in Program.cs
use the code from this article.
Copy the Hydrate-Kenny_Beltrey.aac
file from the assets archive to bin/x64/Debug/net6.0
under the project’s directory.
Run the application in Visual Studio.