A cross-platform audio playback library that targets .NET Standard 2.1. The main purpose of this project is to provide easy to use API for playing and streaming audio especially in desktop environment.
This video demonstrate how to integrate Bufdio and NWaves to create realtime echo effect during playback (source code can be found at examples directory).
Behind the scene, it uses FFmpeg to decode audio frames (so it is possible to play video files by taking only audio stream). And PortAudio for sending buffer data or samples to output device using blocking calls mechanism.
This repository include pre-compiled PortAudio binaries for Windows, Linux, macOS that can be found at libs directory (unfortunately, the Windows binaries does not include ASIO).
As for FFmpeg, you can either install FFmpeg native libraries as system-wide libraries, or just instantiate Bufdio by providing path to FFmpeg libraries.
BufdioLib.InitializePortAudio("path/to/portaudio");
BufdioLib.InitializeFFmpeg("path/to/ffmpeg/libraries");
// Or just use system-wide libraries
BufdioLib.InitializeFFmpeg();
With PortAudio initialized, we can retrieve available output devices.
var defaultDevice = BufdioLib.DefaultOutputDevice;
Console.WriteLine(defaultDevice.Name);
Console.WriteLine(defaultDevice.MaxOutputChannels);
Console.WriteLine(defaultDevice.DefaultSampleRate);
Console.WriteLine(defaultDevice.DefaultHighOutputLatency);
// Retrieve all available output devices
foreach (var device in BufdioLib.OutputDevices)
{
Console.WriteLine(device.Name);
}
Bufdio provides high level interface for loading audio and control its playback state. The audio source can be loaded from local file, URL or .NET System.IO.Stream
.
using IAudioPlayer player = new AudioPlayer();
// Methods
player.Load("audio-url");
player.Load(fileStream);
player.Play();
player.Pause();
player.Stop();
player.SetVolume(0.9f);
player.Seek(TimeSpan.FromSeconds(2));
// Properties (read-only)
var state = player.CurrentState; // (Playing, Buferring, Paused, Stopped)
var loaded = player.IsAudioLoaded;
var duration = player.TotalDuration;
var position = player.CurrentPosition;
var volume = player.CurrentVolume;
// Events
player.AudioLoaded += OnAudioLoaded;
player.StateChanged += OnStateChanged;
player.PositionChanged += OnPositionChanged;
player.PlaybackCompleted += OnPlaybackCompleted;
player.LogCreated += OnLogCreated;
player.FrameDecoded += OnFrameDecoded;
player.FramePresented += OnFramePresented;
The AudioPlayer
constructor allows you to specify list of custom sample processors. ISampleProcessor
interface is intended to modify audio sample that will be executed before writing audio frame to output device. The most simple processor is VolumeProcessor
that simply multiply given sample by desired volume.
var processors = new ISampleProcessor[] { new EchoProcessor(), new DistortionProcessor() };
using IAudioPlayer player = new AudioPlayer(customProcessors: processors);
Bufdio also exposes low level IAudioEngine
interface for sending or writing samples to native output device.
const int SampleRate = 8000;
const float Frequency = 350f;
const float Amplitude = 0.35f * short.MaxValue;
var samples = new float[SampleRate];
var options = new AudioEngineOptions(1, SampleRate);
using IAudioEngine engine = new PortAudioEngine(options);
for (var i = 0; i < samples.Length; i++)
{
samples[i] = (float)(Amplitude * Math.Sin(2 * Math.PI * i * Frequency / SampleRate));
}
Console.WriteLine("Playing 10 times with 1 second delay..");
for (var i = 0; i < 10; i++)
{
engine.Send(samples);
Thread.Sleep(1000);
}
- Currently only resampling to
Float32
format - Still need more unit tests
- PortAudio
- FFmpeg
- FFmpeg.AutoGen (project dependency)
- NWaves (used in sample project)
- Avalonia (used in sample project)
Bufdio is licenced under the MIT license.