Vorbis Decoder (Run)¶
This article explains how you can use {transcoder-run-net} to decode a Vorbis OGG file to a WAV file.
The code snippets in this article are from the dec_vorbis_file .NET sample.
Source Audio¶
For source we use the Hydrate-Kenny_Beltrey.ogg file from the AVBlocks Assets repository. After downloading and unzipping you will find Hydrate-Kenny_Beltrey.ogg in the aud subdirectory.
Code¶
This code takes a Vorbis OGG file and decodes it to uncompressed WAV output.
Initialize AVBlocks¶
The first step in any AVBlocks application is to initialize the library. This must be done before using any other AVBlocks functionality. Always call Library.Shutdown() at the end of the program to clean up resources.
static int Main(string[] args)
{
var opt = new Options();
if (!opt.Prepare(args))
return opt.Error ? (int)ExitCodes.OptionsError : (int)ExitCodes.Success;
Library.Initialize();
bool decodeResult = Decode(opt);
Library.Shutdown();
return decodeResult ? (int)ExitCodes.Success : (int)ExitCodes.DecodingError;
}
Configure Input Socket¶
The input socket points directly to the Vorbis OGG input file.
// create input socket
MediaSocket inSocket = new MediaSocket();
inSocket.File = opt.InputFile;
Configure Output Socket¶
The output socket writes a WAV file. The sample configures the output socket as Wave and uses an LPCM audio stream pin.
static MediaSocket CreateOutputSocket(Options opt)
{
MediaSocket socket = new MediaSocket();
socket.File = opt.OutputFile;
socket.StreamType = StreamType.Wave;
MediaPin pin = new MediaPin();
socket.Pins.Add(pin);
AudioStreamInfo asi = new AudioStreamInfo();
pin.StreamInfo = asi;
asi.StreamType = StreamType.LPCM;
// You can change the number of the channels
// asi.Channels = 1;
// or the sampling rate and
// asi.SampleRate = 44100;
return socket;
}
Configure and Run Transcoder¶
After creating the input and output sockets, the sample creates a transcoder, enables demo mode, adds the sockets, removes any existing output file, opens the transcoder, runs the decode, and closes it.
static bool Decode(Options opt)
{
// transcoder will fail if output exists (by design)
DeleteFile(opt.OutputFile);
// Create output directory if needed
string outputDir = System.IO.Path.GetDirectoryName(opt.OutputFile);
if (!string.IsNullOrEmpty(outputDir))
System.IO.Directory.CreateDirectory(outputDir);
// create input socket
MediaSocket inSocket = new MediaSocket();
inSocket.File = opt.InputFile;
// create output socket
MediaSocket outSocket = CreateOutputSocket(opt);
// create Transcoder
using (Transcoder transcoder = new Transcoder())
{
transcoder.AllowDemoMode = true;
transcoder.Inputs.Add(inSocket);
transcoder.Outputs.Add(outSocket);
bool res = transcoder.Open();
PrintError("Transcoder open", transcoder.Error);
if (!res)
return false;
res = transcoder.Run();
PrintError("Transcoder run", transcoder.Error);
if (!res)
return false;
transcoder.Close();
}
return true;
}
Complete Code¶
Here’s the complete working example that demonstrates Vorbis decoding using AVBlocks for .NET.
using System;
using PrimoSoftware.AVBlocks;
namespace CliSample
{
class Program
{
static int Main(string[] args)
{
var opt = new Options();
if (!opt.Prepare(args))
return opt.Error ? (int)ExitCodes.OptionsError : (int)ExitCodes.Success;
Library.Initialize();
// Set license information. Without this AVBlocks runs in Demo mode.
// Library.SetLicense("<license-string>");
bool decodeResult = Decode(opt);
Library.Shutdown();
return decodeResult ? (int)ExitCodes.Success : (int)ExitCodes.DecodingError;
}
static bool Decode(Options opt)
{
// transcoder will fail if output exists (by design)
DeleteFile(opt.OutputFile);
// Create output directory if needed
string outputDir = System.IO.Path.GetDirectoryName(opt.OutputFile);
if (!string.IsNullOrEmpty(outputDir))
System.IO.Directory.CreateDirectory(outputDir);
// create input socket
MediaSocket inSocket = new MediaSocket();
inSocket.File = opt.InputFile;
// create output socket
MediaSocket outSocket = CreateOutputSocket(opt);
// create Transcoder
using (Transcoder transcoder = new Transcoder())
{
transcoder.AllowDemoMode = true;
transcoder.Inputs.Add(inSocket);
transcoder.Outputs.Add(outSocket);
bool res = transcoder.Open();
PrintError("Transcoder open", transcoder.Error);
if (!res)
return false;
res = transcoder.Run();
PrintError("Transcoder run", transcoder.Error);
if (!res)
return false;
transcoder.Close();
}
return true;
}
static void DeleteFile(string filename)
{
try
{
if (System.IO.File.Exists(filename))
System.IO.File.Delete(filename);
}
catch { }
}
static MediaSocket CreateOutputSocket(Options opt)
{
MediaSocket socket = new MediaSocket();
socket.File = opt.OutputFile;
socket.StreamType = StreamType.Wave;
MediaPin pin = new MediaPin();
socket.Pins.Add(pin);
AudioStreamInfo asi = new AudioStreamInfo();
pin.StreamInfo = asi;
asi.StreamType = StreamType.LPCM;
// You can change the number of the channels
// asi.Channels = 1;
// or the sampling rate and
// asi.SampleRate = 44100;
return socket;
}
static void PrintError(string action, ErrorInfo e)
{
if (action != null)
{
Console.Write("{0}: ", action);
}
if (ErrorFacility.Success == e.Facility)
{
Console.WriteLine("Success");
return;
}
else
{
Console.WriteLine("{0}, facility:{1} code:{2} hint:{3}", e.Message ?? "", e.Facility, e.Code, e.Hint ?? "");
}
}
enum ExitCodes : int
{
Success = 0,
OptionsError = 1,
DecodingError = 2,
}
}
}
How to Run¶
See the dec_vorbis_file .NET sample for details.
Command Line¶
dec_vorbis_file --input <ogg file> --output <wav file>
Examples¶
List options:
./bin/net10.0/dec_vorbis_file --help
Decode the input file ./assets/aud/Hydrate-Kenny_Beltrey.ogg into output file ./output/dec_vorbis_file/Hydrate-Kenny_Beltrey.wav:
# Linux and macOS
mkdir -p ./output/dec_vorbis_file
./bin/net10.0/dec_vorbis_file \
--input ./assets/aud/Hydrate-Kenny_Beltrey.ogg \
--output ./output/dec_vorbis_file/Hydrate-Kenny_Beltrey.wav
# Windows
mkdir -Force -Path ./output/dec_vorbis_file
./bin/net10.0/dec_vorbis_file `
--input ./assets/aud/Hydrate-Kenny_Beltrey.ogg `
--output ./output/dec_vorbis_file/Hydrate-Kenny_Beltrey.wav